queue_exporter as subproject. checks only queue. lesser dependencies, lesser footprint.

master
Denis Knauf 2022-10-09 15:54:54 +02:00
parent 4fa76393e6
commit bbac461ec7
7 changed files with 136 additions and 0 deletions

View File

@ -4,6 +4,16 @@ postfix_exporter
Collects continuesly events from postfix and dovecot via journald.
Exports the collected event-counters and the currently count of queued messages.
queue_exporter
==============
If you only want to check the count of mails in queue, use the `queue_exporter` in the subdirectory.
It has lesser dependencies and a smaller footprint:
* No journald, no ffi, no puma
* ffi and puma need a compiler, which you do not need to install
* Instead of puma, use simple rackup, which provides a simpler webserver.
Usage
-----

4
queue_exporter/Gemfile Normal file
View File

@ -0,0 +1,4 @@
source 'https://rubygems.org'
gem 'prometheus-client'
gem 'rack'

View File

@ -0,0 +1,15 @@
GEM
remote: https://rubygems.org/
specs:
prometheus-client (4.0.0)
rack (3.0.0)
PLATFORMS
x86_64-linux
DEPENDENCIES
prometheus-client
rack
BUNDLED WITH
2.3.9

48
queue_exporter/config.ru Normal file
View File

@ -0,0 +1,48 @@
require 'rack'
require 'socket'
showqpath = '/var/spool/postfix/public/showq'
prometheus = Prometheus::Client.registry
metrics = OpenStruct.new(
queued: prometheus.gauge( :postfix_queued, docstring: "Queued mails per queue and sender/recipient", labels: %i[queue sender recipient]),
)
def determine_domain str
case str
when /@([^.]+\.(?:(?:co|ac)\.)?[^.]+)\.?\z/
$1
when /\.([^.]+\.(?:(?:co|ac)\.)?[^.]+)\?.\z/
"any.#$1"
when 'MAILER-DAEMON'
'MAILER-DAEMON'
else
'any'
end
end
run lambda {|env|
req = Rack::Request.new env
case req.path
when "/metrics"
showq = ''
UNIXSocket.open showqpath do |s|
while '' != (r = s.read)
showq += r
end
end
showq =
showq.split( "\x00\x00").map do |x|
y = x.split "\x00"
y.push '' if y.length.odd?
Hash[*y]
end
showq.group_by do |e|
{queue: e['queue_name'], sender: determine_domain( e['sender']), recipient: determine_domain( e['recipient'])}
end.each do |labels, entries|
metrics.queued.set entries.length, labels: labels if labels and labels[:queue]
end
[200, {"Content-Type" => "text/plain"}, [Prometheus::Client::Formats::Text.marshal( prometheus)]]
else
[404, {"Content-Type" => "text/plain"}, ["Not found\nYou want to try /metrics?\n"]]
end
}

22
queue_exporter/gemset.nix Normal file
View File

@ -0,0 +1,22 @@
{
prometheus-client = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "11k1r8mfr0bnd574yy08wmpzbgq8yqw3shx7fn5f6hlmayacc4bh";
type = "gem";
};
version = "4.0.0";
};
rack = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1772yq480iffns36zisgsnaxf6cr6r7m8v7y14cwlpaqbnzdnyhr";
type = "gem";
};
version = "3.0.0";
};
}

View File

@ -0,0 +1,16 @@
<% require 'pathname'; path = Pathname.new( __FILE__).expand_path.dirname %>
[Unit]
Description=Postfix Queue exporter
Documentation=https://git.denkn.at/deac/postfix_exporter
After=network.target
[Service]
Restart=always
User=postfix_exporter
WorkingDirectory=<%=path%>
ExecStart=<%=`which bundle`.chomp%> exec rackup --bind 'tcp://[::]:9124' --environment production --tag queue_exporter
ExecReload=/bin/kill -USR1 $MAINPID
KillMode=mixed
[Install]
WantedBy=multi-user.target

21
queue_exporter/shell.nix Normal file
View File

@ -0,0 +1,21 @@
with (import <nixpkgs> {});
let
env = bundlerEnv {
name = "queue_exporter-bundler-env";
inherit ruby;
gemfile = ./Gemfile;
lockfile = ./Gemfile.lock;
gemset = ./gemset.nix;
};
in stdenv.mkDerivation {
name = "queue-exporter";
buildInputs = [ pkgs.ruby env env.gems.rack ];
#buildPhase = ''
# echo "Build queue_exporter
# mkdir -p "$out/lib"
# for f in ${pkgs.systemd}/lib/libsystemd*
# do
# ln -s "$f" "$out/lib/"
# done
#'';
}