Merge remote-tracking branch 'kumina/master'
This commit is contained in:
commit
02162353c1
@ -282,10 +282,10 @@ var (
|
||||
lmtpPipeSMTPLine = regexp.MustCompile(`, relay=(\S+), .*, delays=([0-9\.]+)/([0-9\.]+)/([0-9\.]+)/([0-9\.]+), `)
|
||||
qmgrInsertLine = regexp.MustCompile(`:.*, size=(\d+), nrcpt=(\d+) `)
|
||||
smtpStatusDeferredLine = regexp.MustCompile(`, status=deferred`)
|
||||
smtpTLSLine = regexp.MustCompile(`^(\S+) TLS connection established to \S+: (\S+) with cipher (\S+) \((\d+)/(\d+) bits\)$`)
|
||||
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: `)
|
||||
@ -372,8 +372,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) {
|
||||
@ -452,6 +452,7 @@ func NewPostfixExporter(showqPath string, logfilePath string, journal *Journal,
|
||||
ReOpen: true, // reopen the file if it's rotated
|
||||
MustExist: true, // fail immediately if the file is missing or has incorrect permissions
|
||||
Follow: true, // run in follow mode
|
||||
Location: &tail.SeekInfo{Whence: io.SeekEnd}, // seek to end of file
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -564,7 +565,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",
|
||||
|
@ -38,6 +38,8 @@ func TestPostfixExporter_CollectFromLogline(t *testing.T) {
|
||||
line []string
|
||||
removedCount int
|
||||
saslFailedCount int
|
||||
outgoingTLS int
|
||||
smtpdMessagesProcessed int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -54,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"}),
|
||||
},
|
||||
},
|
||||
@ -98,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"}),
|
||||
},
|
||||
},
|
||||
@ -114,10 +116,42 @@ 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{
|
||||
line: []string{
|
||||
"Jul 24 04:38:17 mail postfix/smtp[30582]: Verified TLS connection established to gmail-smtp-in.l.google.com[108.177.14.26]:25: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256",
|
||||
"Jul 24 03:28:15 mail postfix/smtp[24052]: Verified TLS connection established to mx2.comcast.net[2001:558:fe21:2a::6]:25: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)",
|
||||
},
|
||||
removedCount: 0,
|
||||
saslFailedCount: 0,
|
||||
outgoingTLS: 2,
|
||||
},
|
||||
fields: fields{
|
||||
unsupportedLogEntries: prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"process"}),
|
||||
smtpTLSConnects: prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"Verified", "TLSv1.2", "ECDHE-RSA-AES256-GCM-SHA384", "256", "256"}),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@ -145,52 +179,51 @@ func TestPostfixExporter_CollectFromLogline(t *testing.T) {
|
||||
smtpdSASLAuthenticationFailures: tt.fields.smtpdSASLAuthenticationFailures,
|
||||
smtpdTLSConnects: tt.fields.smtpdTLSConnects,
|
||||
unsupportedLogEntries: tt.fields.unsupportedLogEntries,
|
||||
logUnsupportedLines: true,
|
||||
}
|
||||
for _, line := range tt.args.line {
|
||||
e.CollectFromLogLine(line)
|
||||
}
|
||||
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")
|
||||
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 assertCounterEquals(t *testing.T, counter prometheus.Counter, expected int, message string) {
|
||||
func assertCounterEquals(t *testing.T, counter prometheus.Collector, expected int, message string) {
|
||||
|
||||
if counter != nil && expected > 0 {
|
||||
switch counter.(type) {
|
||||
case *testCounter:
|
||||
counter := counter.(*testCounter)
|
||||
assert.Equal(t, expected, counter.Count(), message)
|
||||
case *prometheus.CounterVec:
|
||||
counter := counter.(*prometheus.CounterVec)
|
||||
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)
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user