Merge pull request #44 from UnikumAB/Issue#38

Fixes #38 List of postfix_smtpd_messages_processed_total growing over time
This commit is contained in:
Ivaylo Korakov 2020-02-24 11:18:16 +01:00 committed by GitHub
commit 52ac4648f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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
}