Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
silver-platter
dovecot-exporter
Commits
4e831356
Unverified
Commit
4e831356
authored
Jan 18, 2018
by
Bart Vercoulen
Committed by
GitHub
Jan 18, 2018
Browse files
Merge pull request #6 from zoni/fix-global-scope-scraping
Support scraping of "global" scope
parents
9bbdcdbf
3e8a4ef5
Changes
1
Hide whitespace changes
Inline
Side-by-side
dovecot_exporter.go
View file @
4e831356
...
...
@@ -34,9 +34,89 @@ var dovecotUpDesc = prometheus.NewDesc(
[]
string
{
"scope"
},
nil
)
// Converts the output of Dovecot's EXPORT command to metrics.
func
CollectFromReader
(
file
io
.
Reader
,
ch
chan
<-
prometheus
.
Metric
)
error
{
scanner
:=
bufio
.
NewScanner
(
file
)
// CollectFromReader converts the output of Dovecot's EXPORT command to metrics.
func
CollectFromReader
(
file
io
.
Reader
,
scope
string
,
ch
chan
<-
prometheus
.
Metric
)
error
{
if
scope
==
"global"
{
return
collectGlobalMetricsFromReader
(
file
,
scope
,
ch
)
}
return
collectDetailMetricsFromReader
(
file
,
scope
,
ch
)
}
// CollectFromFile collects dovecot statistics from the given file
func
CollectFromFile
(
path
string
,
scope
string
,
ch
chan
<-
prometheus
.
Metric
)
error
{
conn
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
err
}
return
CollectFromReader
(
conn
,
scope
,
ch
)
}
// CollectFromSocket collects statistics from dovecot's stats socket.
func
CollectFromSocket
(
path
string
,
scope
string
,
ch
chan
<-
prometheus
.
Metric
)
error
{
conn
,
err
:=
net
.
Dial
(
"unix"
,
path
)
if
err
!=
nil
{
return
err
}
_
,
err
=
conn
.
Write
([]
byte
(
"EXPORT
\t
"
+
scope
+
"
\n
"
))
if
err
!=
nil
{
return
err
}
return
CollectFromReader
(
conn
,
scope
,
ch
)
}
// collectGlobalMetricsFromReader collects dovecot "global" scope metrics from
// the supplied reader.
func
collectGlobalMetricsFromReader
(
reader
io
.
Reader
,
scope
string
,
ch
chan
<-
prometheus
.
Metric
)
error
{
scanner
:=
bufio
.
NewScanner
(
reader
)
scanner
.
Split
(
bufio
.
ScanLines
)
// Read first line of input, containing the aggregation and column names.
if
!
scanner
.
Scan
()
{
return
fmt
.
Errorf
(
"Failed to extract columns from input"
)
}
columnNames
:=
strings
.
Fields
(
scanner
.
Text
())
if
len
(
columnNames
)
<
1
{
return
fmt
.
Errorf
(
"Input does not provide any columns"
)
}
columns
:=
[]
*
prometheus
.
Desc
{}
for
_
,
columnName
:=
range
columnNames
{
columns
=
append
(
columns
,
prometheus
.
NewDesc
(
prometheus
.
BuildFQName
(
"dovecot"
,
scope
,
columnName
),
"Help text not provided by this exporter."
,
[]
string
{},
nil
))
}
// Global metrics only have a single row containing values following the
// line with column names
if
!
scanner
.
Scan
()
{
return
scanner
.
Err
()
}
values
:=
strings
.
Fields
(
scanner
.
Text
())
if
len
(
values
)
!=
len
(
columns
)
{
return
fmt
.
Errorf
(
"error while parsing row: value count does not match column count"
)
}
for
i
,
value
:=
range
values
{
f
,
err
:=
strconv
.
ParseFloat
(
value
,
64
)
if
err
!=
nil
{
return
err
}
ch
<-
prometheus
.
MustNewConstMetric
(
columns
[
i
],
prometheus
.
UntypedValue
,
f
,
)
}
return
scanner
.
Err
()
}
// collectGlobalMetricsFromReader collects dovecot "non-global" scope metrics
// from the supplied reader.
func
collectDetailMetricsFromReader
(
reader
io
.
Reader
,
scope
string
,
ch
chan
<-
prometheus
.
Metric
)
error
{
scanner
:=
bufio
.
NewScanner
(
reader
)
scanner
.
Split
(
bufio
.
ScanLines
)
// Read first line of input, containing the aggregation and column names.
...
...
@@ -47,6 +127,7 @@ func CollectFromReader(file io.Reader, ch chan<- prometheus.Metric) error {
if
len
(
columnNames
)
<
2
{
return
fmt
.
Errorf
(
"Input does not provide any columns"
)
}
columns
:=
[]
*
prometheus
.
Desc
{}
for
_
,
columnName
:=
range
columnNames
[
1
:
]
{
columns
=
append
(
columns
,
prometheus
.
NewDesc
(
...
...
@@ -58,10 +139,16 @@ func CollectFromReader(file io.Reader, ch chan<- prometheus.Metric) error {
// Read successive lines, containing the values.
for
scanner
.
Scan
()
{
values
:=
strings
.
Fields
(
scanner
.
Text
()
)
if
len
(
values
)
!
=
len
(
columns
)
+
1
{
row
:=
scanner
.
Text
()
if
strings
.
TrimSpace
(
row
)
=
=
""
{
break
}
values
:=
strings
.
Fields
(
row
)
if
len
(
values
)
!=
len
(
columns
)
+
1
{
return
fmt
.
Errorf
(
"error while parsing rows: value count does not match column count"
)
}
for
i
,
value
:=
range
values
[
1
:
]
{
f
,
err
:=
strconv
.
ParseFloat
(
value
,
64
)
if
err
!=
nil
{
...
...
@@ -77,26 +164,6 @@ func CollectFromReader(file io.Reader, ch chan<- prometheus.Metric) error {
return
scanner
.
Err
()
}
func
CollectFromFile
(
path
string
,
ch
chan
<-
prometheus
.
Metric
)
error
{
conn
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
err
}
return
CollectFromReader
(
conn
,
ch
)
}
func
CollectFromSocket
(
path
string
,
scope
string
,
ch
chan
<-
prometheus
.
Metric
)
error
{
conn
,
err
:=
net
.
Dial
(
"unix"
,
path
)
if
err
!=
nil
{
return
err
}
_
,
err
=
conn
.
Write
([]
byte
(
"EXPORT
\t
"
+
scope
+
"
\n
"
))
if
err
!=
nil
{
return
err
}
return
CollectFromReader
(
conn
,
ch
)
}
type
DovecotExporter
struct
{
scopes
[]
string
socketPath
string
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment