Reduced the cardinality of postfix_smtpd_messages_processed_total for #38 by not aggregating per user but only for the sasl_method

This commit is contained in:
Per Abich 2020-02-23 20:41:35 +01:00
parent 0ca70fa8cb
commit 8113240edf
2 changed files with 44 additions and 53 deletions

View File

@ -277,7 +277,7 @@ var (
smtpTLSLine = regexp.MustCompile(`^(\S+) TLS connection established to \S+: (\S+) with cipher (\S+) \((\d+)/(\d+) bits\)`)
smtpConnectionTimedOut = regexp.MustCompile(`^connect\s+to\s+(.*)\[(.*)\]:(\d+):\s+(Connection timed out)$`)
smtpdFCrDNSErrorsLine = regexp.MustCompile(`^warning: hostname \S+ does not resolve to address `)
smtpdProcessesSASLLine = regexp.MustCompile(`: client=.*, sasl_username=(\S+)`)
smtpdProcessesSASLLine = regexp.MustCompile(`: client=.*, sasl_method=(\S+)`)
smtpdRejectsLine = regexp.MustCompile(`^NOQUEUE: reject: RCPT from \S+: ([0-9]+) `)
smtpdLostConnectionLine = regexp.MustCompile(`^lost connection after (\w+) from `)
smtpdSASLAuthenticationFailuresLine = regexp.MustCompile(`^warning: \S+: SASL \S+ authentication failed: `)
@ -364,8 +364,8 @@ func (e *PostfixExporter) CollectFromLogLine(line string) {
e.smtpdLostConnections.WithLabelValues(smtpdLostConnectionMatches[1]).Inc()
} else if smtpdProcessesSASLMatches := smtpdProcessesSASLLine.FindStringSubmatch(remainder); smtpdProcessesSASLMatches != nil {
e.smtpdProcesses.WithLabelValues(smtpdProcessesSASLMatches[1]).Inc()
} else if strings.Contains(logMatches[2], ": client=") {
e.smtpdProcesses.WithLabelValues("").Inc()
} else if strings.Contains(remainder, ": client=") {
e.smtpdProcesses.WithLabelValues(smtpdProcessesSASLMatches[1]).Inc()
} else if smtpdRejectsMatches := smtpdRejectsLine.FindStringSubmatch(remainder); smtpdRejectsMatches != nil {
e.smtpdRejects.WithLabelValues(smtpdRejectsMatches[1]).Inc()
} else if smtpdSASLAuthenticationFailuresLine.MatchString(remainder) {
@ -557,7 +557,7 @@ func NewPostfixExporter(showqPath string, logfilePath string, journal *Journal,
Name: "smtpd_messages_processed_total",
Help: "Total number of messages processed.",
},
[]string{"sasl_username"}),
[]string{"sasl_method"}),
smtpdRejects: prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: "postfix",

View File

@ -39,6 +39,7 @@ func TestPostfixExporter_CollectFromLogline(t *testing.T) {
removedCount int
saslFailedCount int
outgoingTLS int
smtpdMessagesProcessed int
}
tests := []struct {
name string
@ -55,7 +56,7 @@ func TestPostfixExporter_CollectFromLogline(t *testing.T) {
saslFailedCount: 0,
},
fields: fields{
qmgrRemoves: &testCounter{count: 0},
qmgrRemoves: prometheus.NewCounter(prometheus.CounterOpts{}),
unsupportedLogEntries: prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"process"}),
},
},
@ -99,7 +100,7 @@ func TestPostfixExporter_CollectFromLogline(t *testing.T) {
saslFailedCount: 0,
},
fields: fields{
qmgrRemoves: &testCounter{count: 0},
qmgrRemoves: prometheus.NewCounter(prometheus.CounterOpts{}),
unsupportedLogEntries: prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"process"}),
},
},
@ -115,10 +116,26 @@ func TestPostfixExporter_CollectFromLogline(t *testing.T) {
removedCount: 0,
},
fields: fields{
smtpdSASLAuthenticationFailures: &testCounter{count: 0},
smtpdSASLAuthenticationFailures: prometheus.NewCounter(prometheus.CounterOpts{}),
unsupportedLogEntries: prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"process"}),
},
},
{
name: "SASL login",
args: args{
line: []string{
"Oct 30 13:19:26 mailgw-out1 postfix/smtpd[27530]: EB4B2C19E2: client=xxx[1.2.3.4], sasl_method=PLAIN, sasl_username=user@domain",
},
removedCount: 0,
saslFailedCount: 0,
outgoingTLS: 0,
smtpdMessagesProcessed: 1,
},
fields: fields{
unsupportedLogEntries: prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"process"}),
smtpdProcesses: prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"sasl_method"}),
},
},
{
name: "Issue #35",
args: args{
@ -169,11 +186,12 @@ func TestPostfixExporter_CollectFromLogline(t *testing.T) {
}
assertCounterEquals(t, e.qmgrRemoves, tt.args.removedCount, "Wrong number of lines counted")
assertCounterEquals(t, e.smtpdSASLAuthenticationFailures, tt.args.saslFailedCount, "Wrong number of Sasl counter counted")
assertCounterVecEquals(t, e.smtpTLSConnects, tt.args.outgoingTLS, "Wrong number of TLS connections counted")
assertCounterEquals(t, e.smtpTLSConnects, tt.args.outgoingTLS, "Wrong number of TLS connections counted")
assertCounterEquals(t, e.smtpdProcesses, tt.args.smtpdMessagesProcessed, "Wrong number of smtpd messages processed")
})
}
}
func assertCounterVecEquals(t *testing.T, counter prometheus.Collector, expected int, message string) {
func assertCounterEquals(t *testing.T, counter prometheus.Collector, expected int, message string) {
if counter != nil && expected > 0 {
switch counter.(type) {
@ -191,48 +209,21 @@ func assertCounterVecEquals(t *testing.T, counter prometheus.Collector, expected
count += int(*metricDto.Counter.Value)
}
assert.Equal(t, expected, count, message)
case prometheus.Counter:
metricsChan := make(chan prometheus.Metric)
go func() {
counter.Collect(metricsChan)
close(metricsChan)
}()
var count int = 0
for metric := range metricsChan {
metricDto := io_prometheus_client.Metric{}
metric.Write(&metricDto)
count += int(*metricDto.Counter.Value)
}
assert.Equal(t, expected, count, message)
default:
t.Fatal("Type not implemented")
}
}
}
func assertCounterEquals(t *testing.T, counter prometheus.Counter, expected int, message string) {
if counter != nil && expected > 0 {
switch counter.(type) {
case *testCounter:
counter := counter.(*testCounter)
assert.Equal(t, expected, counter.Count(), message)
default:
t.Fatal("Type not implemented")
}
}
}
type testCounter struct {
count int
}
func (t *testCounter) setCount(count int) {
t.count = count
}
func (t *testCounter) Count() int {
return t.count
}
func (t *testCounter) Add(_ float64) {
}
func (t *testCounter) Collect(_ chan<- prometheus.Metric) {
}
func (t *testCounter) Describe(_ chan<- *prometheus.Desc) {
}
func (t *testCounter) Desc() *prometheus.Desc {
return nil
}
func (t *testCounter) Inc() {
t.count++
}
func (t *testCounter) Write(_ *io_prometheus_client.Metric) error {
return nil
}