postfix-exporter 2.0.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +17 -2
- data/bin/postfix-exporter +65 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59a89aac9e188bb3a7a5cf1617425bd797ebf68f
|
4
|
+
data.tar.gz: d7fd70f12daadfd79a90c66efce6c862afd31b00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e51b58b74c279e81a3a88f9e3322f95f363571a6e959d14a8f3ebf1b3d77a5f899821f0673a9b347c1a9906574983bbc8ba297667917238a18eb933da55daed
|
7
|
+
data.tar.gz: 6e6ecffdb49e584e2592ba7d69bdc08fb67efd1abc4162024b7511a5e97a393ef6bc643ca8d44993744b0230d26d434b3eda8adff91d143b5c224ba3c12d9a02
|
data/README.md
CHANGED
@@ -7,8 +7,18 @@ server.
|
|
7
7
|
* Examines mail queue periodically and exports `postfix_mail_queue_size`;
|
8
8
|
|
9
9
|
* Reads syslog entries as they happen, and exports disposition status
|
10
|
-
counters (`
|
11
|
-
DSN;
|
10
|
+
counters (`postfix_delivery_delays_count`) per DSN, as well as delay summaries per
|
11
|
+
DSN (`postfix_delivery_delays{quantile="..."}`);
|
12
|
+
|
13
|
+
* Total number of SMTP connections (`postfix_smtpd_connections_total`) and
|
14
|
+
currently-active connections (`postfix_smtpd_active_connections`);
|
15
|
+
|
16
|
+
* Count how many delivery attempts were received
|
17
|
+
(`postfix_incoming_delivery_attempts_total`), split out by whether we
|
18
|
+
accepted or rejected the message (`status`) and the exact DSN provided to
|
19
|
+
the client (`dsn`);
|
20
|
+
|
21
|
+
* Whether or not the Postfix `master` process is running (`postfix_up`);
|
12
22
|
|
13
23
|
* Drinks from the syslog stream directly.
|
14
24
|
|
@@ -21,6 +31,11 @@ available in the container as `/var/spool/postfix`), and some env
|
|
21
31
|
vars. You can also run it directly (via the gem), with the same env vars,
|
22
32
|
and with the expectation that `/var/spool/postfix` is in the usual place.
|
23
33
|
|
34
|
+
If you configure the postfix-exporter to run in the same PID namespace as
|
35
|
+
whatever it is that's running Postfix itself (either `--pid=host` or in the
|
36
|
+
same NS namespace, a la k8s pods), then the `postfix_up` metric will be
|
37
|
+
valid, otherwise it'll be random (but unlikely to be correct).
|
38
|
+
|
24
39
|
|
25
40
|
## Environment Variables
|
26
41
|
|
data/bin/postfix-exporter
CHANGED
@@ -8,7 +8,11 @@ require 'logger'
|
|
8
8
|
|
9
9
|
prometheus = Prometheus::Client.registry
|
10
10
|
|
11
|
+
prometheus.gauge(:postfix_exporter_start_time_seconds, "When this process started up").set({}, Time.now.to_f)
|
12
|
+
|
11
13
|
mailq = prometheus.gauge(:postfix_queue_size, "Number of messages in the mail queue")
|
14
|
+
q_err = prometheus.counter(:postfix_queue_processing_error_total, "Exceptions raised whilst scanning the Postfix queue")
|
15
|
+
up = prometheus.gauge(:postfix_up, "Whether the master process is running or not")
|
12
16
|
|
13
17
|
Thread.abort_on_exception = true
|
14
18
|
|
@@ -22,18 +26,49 @@ Thread.new do
|
|
22
26
|
# deferred is special, because it's often hueg it gets sharded into
|
23
27
|
# multiple subdirectories
|
24
28
|
mailq.set({ queue: 'deferred' }, Dir["/var/spool/postfix/deferred/*/*"].size)
|
25
|
-
|
26
|
-
sleep 5
|
27
29
|
rescue StandardError => ex
|
28
30
|
$stderr.puts "Error while monitoring queue sizes: #{ex.message} (#{ex.class})"
|
29
31
|
$stderr.puts ex.backtrace.map { |l| " #{l}" }.join("\n")
|
30
|
-
|
32
|
+
q_err.increment(class: ex.class.to_s, phase: "scan")
|
31
33
|
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
master_pid = File.read("/var/spool/postfix/pid/master.pid").to_i
|
37
|
+
|
38
|
+
if master_pid > 1
|
39
|
+
Process.kill(0, master_pid)
|
40
|
+
# If we get here, then the process exists, and
|
41
|
+
# that'll do for our purposes
|
42
|
+
up.set({}, 1)
|
43
|
+
else
|
44
|
+
up.set({}, 0)
|
45
|
+
end
|
46
|
+
rescue Errno::ENOENT, Errno::ESRCH, Errno::EACCES
|
47
|
+
up.set({}, 0)
|
48
|
+
rescue Errno::EPERM
|
49
|
+
# Ironically, we don't need to be able to *actually*
|
50
|
+
# signal the process; EPERM means it exists and is running
|
51
|
+
# as someone more privileged than us, which is enough
|
52
|
+
# for our purposes
|
53
|
+
up.set({}, 1)
|
54
|
+
rescue StandardError => ex
|
55
|
+
$stderr.puts "Error while checking master process: #{ex.message} (#{ex.class})"
|
56
|
+
$stderr.puts ex.backtrace.map { |l| " #{l}" }.join("\n")
|
57
|
+
q_err.increment(class: ex.class.to_s, phase: "up")
|
58
|
+
end
|
59
|
+
|
60
|
+
sleep 5
|
61
|
+
|
32
62
|
end
|
33
63
|
end
|
34
64
|
|
35
65
|
if ENV["SYSLOG_SOCKET"]
|
36
|
-
delays
|
66
|
+
delays = prometheus.summary(:postfix_delivery_delays, "Distribution of time taken to deliver (or bounce) messages")
|
67
|
+
connects = prometheus.counter(:postfix_smtpd_connections_total, "Connections to smtpd")
|
68
|
+
active = prometheus.gauge(:postfix_smtpd_active_connections, "Current connections to smtpd")
|
69
|
+
incoming = prometheus.counter(:postfix_incoming_delivery_attempts_total, "Delivery attempts, labelled by dsn and status")
|
70
|
+
messages = prometheus.counter(:postfix_log_messages_total, "Syslog messages received, labelled by how it was handled")
|
71
|
+
log_errors = prometheus.counter(:postfix_log_processing_error_total, "Exceptions raised whilst processing log messages")
|
37
72
|
|
38
73
|
Thread.new do
|
39
74
|
begin
|
@@ -55,10 +90,36 @@ if ENV["SYSLOG_SOCKET"]
|
|
55
90
|
if status == "bounced" or status == "sent"
|
56
91
|
delays.observe({dsn: dsn, status: status}, delay)
|
57
92
|
end
|
93
|
+
|
94
|
+
messages.increment(type: "delay")
|
95
|
+
elsif msg =~ %r{postfix/smtpd\[\d+\]: connect from }
|
96
|
+
connects.increment({})
|
97
|
+
active.send(:synchronize) { active.set({}, active.get({}) || 0 + 1) }
|
98
|
+
messages.increment(type: "connect")
|
99
|
+
elsif msg =~ %r{postfix/smtpd\[\d+\]: disconnect from }
|
100
|
+
active.send(:synchronize) do
|
101
|
+
new = (active.get({}) || 0) - 1
|
102
|
+
# If we start running mid-stream,
|
103
|
+
# we might end up seeing more
|
104
|
+
# disconnects than connections,
|
105
|
+
# which would be confusing
|
106
|
+
new = 0 if new < 0
|
107
|
+
active.set({}, new)
|
108
|
+
end
|
109
|
+
messages.increment(type: "disconnect")
|
110
|
+
elsif msg =~ %r{postfix/smtpd\[\d+\]: [A-F0-9]+: client=}
|
111
|
+
incoming.increment(dsn: "2.0.0", status: "queued")
|
112
|
+
messages.increment(type: "queued")
|
113
|
+
elsif msg =~ %r{postfix/smtpd\[\d+\]: NOQUEUE: reject: RCPT from \S+: \d{3} (\d+\.\d+\.\d+) }
|
114
|
+
incoming.increment(dsn: $1, status: "rejected")
|
115
|
+
messages.increment(type: "noqueue")
|
116
|
+
else
|
117
|
+
messages.increment(type: "ignored")
|
58
118
|
end
|
59
119
|
rescue StandardError => ex
|
60
120
|
$stderr.puts "Error while receiving postfix logs: #{ex.message} (#{ex.class})"
|
61
121
|
$stderr.puts ex.backtrace.map { |l| " #{l}" }.join("\n")
|
122
|
+
log_errors.increment(class: ex.class.to_s)
|
62
123
|
sleep 1
|
63
124
|
end
|
64
125
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postfix-exporter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Palmer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prometheus-client
|
@@ -118,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
118
|
version: '0'
|
119
119
|
requirements: []
|
120
120
|
rubyforge_project:
|
121
|
-
rubygems_version: 2.
|
121
|
+
rubygems_version: 2.6.13
|
122
122
|
signing_key:
|
123
123
|
specification_version: 4
|
124
124
|
summary: Export Prometheus statistics for a Postfix server
|