1 { system ? builtins.currentSystem
3 , pkgs ? import ../.. { inherit system config; }
7 inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
8 inherit (pkgs.lib) concatStringsSep maintainers mapAttrs mkMerge
9 removeSuffix replaceStrings singleton splitString makeBinPath;
12 * The attrset `exporterTests` contains one attribute
13 * for each exporter test. Each of these attributes
14 * is expected to be an attrset containing:
17 * this attribute set contains config for the exporter itself
20 * this attribute set contains test instructions
22 * `metricProvider` (optional)
23 * this attribute contains additional machine config
25 * `nodeName` (optional)
26 * override an incompatible testnode name
29 * exporterTests.<exporterName> = {
34 * services.<metricProvider>.enable = true;
37 * wait_for_unit("prometheus-<exporterName>-exporter.service")
38 * wait_for_open_port(1234)
39 * succeed("curl -sSf 'localhost:1234/metrics'")
43 * # this would generate the following test config:
45 * nodes.<exporterName> = {
46 * services.prometheus.<exporterName> = {
49 * services.<metricProvider>.enable = true;
53 * <exporterName>.start()
54 * <exporterName>.wait_for_unit("prometheus-<exporterName>-exporter.service")
55 * <exporterName>.wait_for_open_port(1234)
56 * <exporterName>.succeed("curl -sSf 'localhost:1234/metrics'")
57 * <exporterName>.shutdown()
67 services.apcupsd.enable = true;
70 wait_for_unit("apcupsd.service")
71 wait_for_open_port(3551)
72 wait_for_unit("prometheus-apcupsd-exporter.service")
73 wait_for_open_port(9162)
74 succeed("curl -sSf http://localhost:9162/metrics | grep 'apcupsd_info'")
81 artiUsername = "artifactory-username";
82 artiPassword = "artifactory-password";
85 wait_for_unit("prometheus-artifactory-exporter.service")
86 wait_for_open_port(9531)
88 "curl -sSf http://localhost:9531/metrics | grep 'artifactory_up'"
98 services.bind.enable = true;
99 services.bind.extraConfig = ''
100 statistics-channels {
101 inet 127.0.0.1 port 8053 allow { localhost; };
106 wait_for_unit("prometheus-bind-exporter.service")
107 wait_for_open_port(9119)
109 "curl -sSf http://localhost:9119/metrics | grep 'bind_query_recursions_total 0'"
119 services.bird2.enable = true;
120 services.bird2.config = ''
123 protocol kernel MyObviousTestString {
135 wait_for_unit("prometheus-bird-exporter.service")
136 wait_for_open_port(9324)
138 "curl -sSf http://localhost:9324/metrics | grep 'MyObviousTestString'"
146 rpcUser = "bitcoinrpc";
147 rpcPasswordFile = pkgs.writeText "password" "hunter2";
150 services.bitcoind.default.enable = true;
151 services.bitcoind.default.rpc.users.bitcoinrpc.passwordHMAC = "e8fe33f797e698ac258c16c8d7aadfbe$872bdb8f4d787367c26bcfd75e6c23c4f19d44a69f5d1ad329e5adf3f82710f7";
154 wait_for_unit("prometheus-bitcoin-exporter.service")
155 wait_for_unit("bitcoind-default.service")
156 wait_for_open_port(9332)
157 succeed("curl -sSf http://localhost:9332/metrics | grep '^bitcoin_blocks '")
164 configFile = pkgs.writeText "config.yml" (builtins.toJSON {
167 icmp.preferred_ip_protocol = "ip6";
172 wait_for_unit("prometheus-blackbox-exporter.service")
173 wait_for_open_port(9115)
175 "curl -sSf 'http://localhost:9115/probe?target=localhost&module=icmp_v6' | grep 'probe_success 1'"
186 services.borgmatic.enable = true;
187 services.borgmatic.settings.source_directories = [ "/home" ];
188 services.borgmatic.settings.repositories = [ { label = "local"; path = "/var/backup"; } ];
189 services.borgmatic.settings.keep_daily = 10;
192 succeed("borgmatic rcreate -e none")
194 wait_for_unit("prometheus-borgmatic-exporter.service")
195 wait_for_open_port(9996)
196 succeed("curl -sSf localhost:9996/metrics | grep 'borg_total_backups{repository=\"/var/backup\"} 1'")
203 extraFlags = [ "--web.collectd-push-path /collectd" ];
205 exporterTest = let postData = replaceStrings [ "\n" ] [ "" ] ''
212 "plugin":"testplugin",
217 wait_for_unit("prometheus-collectd-exporter.service")
218 wait_for_open_port(9103)
220 'echo \'${postData}\'> /tmp/data.json'
222 succeed('sed -ie "s DATE $(date +%s) " /tmp/data.json')
224 "curl -sSfH 'Content-Type: application/json' -X POST --data @/tmp/data.json localhost:9103/collectd"
227 "curl -sSf localhost:9103/metrics | grep 'collectd_testplugin_gauge{instance=\"testhost\"} 23'"
236 listenAddress = "127.0.0.1";
240 delugePasswordFile = pkgs.writeText "password" "weak_password";
243 services.deluge.enable = true;
244 services.deluge.declarative = true;
245 services.deluge.config.daemon_port = 2345;
246 services.deluge.authFile = pkgs.writeText "authFile" ''
247 localclient:abcdef:10
248 user:weak_password:10
252 wait_for_unit("deluged.service")
253 wait_for_open_port(2345)
254 wait_for_unit("prometheus-deluge-exporter.service")
255 wait_for_open_port(1234)
256 succeed("curl -sSf http://localhost:1234 | grep 'deluge_torrents'")
263 leasesPath = "/var/lib/dnsmasq/dnsmasq.leases";
266 services.dnsmasq.enable = true;
269 wait_for_unit("dnsmasq.service")
270 wait_for_open_port(53)
271 wait_for_file("/var/lib/dnsmasq/dnsmasq.leases")
272 wait_for_unit("prometheus-dnsmasq-exporter.service")
273 wait_for_open_port(9153)
274 succeed("curl -sSf http://localhost:9153/metrics | grep 'dnsmasq_leases 0'")
284 zone = "example.com";
290 resolvers = [ "127.0.0.1:53" ];
295 settingsFile = pkgs.writeText "knot.conf" ''
300 storage: ${pkgs.buildEnv {
302 paths = [(pkgs.writeTextDir "example.com.zone" ''
303 @ SOA ns1.example.com. noc.example.com. 2024032401 86400 7200 3600000 172800
308 zonefile-load: difference
311 - domain: example.com
312 file: example.com.zone
318 wait_for_unit("knot.service")
319 wait_for_open_port(53)
320 wait_for_unit("prometheus-dnssec-exporter.service")
321 wait_for_open_port(9204)
322 succeed("curl -sSf http://localhost:9204/metrics | grep 'example.com'")
326 # Access to WHOIS server is required to properly test this exporter, so
327 # just perform basic sanity check that the exporter is running and returns
334 wait_for_unit("prometheus-domain-exporter.service")
335 wait_for_open_port(9222)
336 succeed("curl -sSf 'http://localhost:9222/probe?target=nixos.org'")
343 scopes = [ "global" ];
344 socketPath = "/var/run/dovecot2/old-stats";
345 user = "root"; # <- don't use user root in production
348 services.dovecot2.enable = true;
351 wait_for_unit("prometheus-dovecot-exporter.service")
352 wait_for_open_port(9166)
354 "curl -sSf http://localhost:9166/metrics | grep 'dovecot_up{scope=\"global\"} 1'"
359 exportarr-sonarr = let apikey = "eccff6a992bc2e4b88e46d064b26bb4e"; in {
360 nodeName = "exportarr_sonarr";
363 url = "http://127.0.0.1:8989";
364 apiKeyFile = pkgs.writeText "dummy-api-key" apikey;
367 services.sonarr.enable = true;
368 systemd.services.sonarr.serviceConfig.ExecStartPre =
370 sonarr_config = pkgs.writeText "config.xml" ''
372 <LogLevel>info</LogLevel>
373 <EnableSsl>False</EnableSsl>
375 <SslPort>9898</SslPort>
377 <BindAddress>*</BindAddress>
378 <ApiKey>${apikey}</ApiKey>
379 <AuthenticationMethod>None</AuthenticationMethod>
380 <UpdateMechanism>BuiltIn</UpdateMechanism>
381 <Branch>main</Branch>
382 <InstanceName>Sonarr</InstanceName>
387 ''${pkgs.coreutils}/bin/install -D -m 777 ${sonarr_config} -T /var/lib/sonarr/.config/NzbDrone/config.xml''
391 wait_for_unit("sonarr.service")
392 wait_for_open_port(8989)
393 wait_for_unit("prometheus-exportarr-sonarr-exporter.service")
394 wait_for_open_port(9708)
395 succeed("curl -sSf http://localhost:9708/metrics | grep sonarr_series_total")
402 tokenPath = pkgs.writeText "token" "abc123";
406 wait_for_unit("prometheus-fastly-exporter.service")
407 wait_for_open_port(9118)
412 # TODO add proper test case
417 wait_for_unit("prometheus-fritzbox-exporter.service")
418 wait_for_open_port(9133)
420 "curl -sSf http://localhost:9133/metrics | grep 'fritzbox_exporter_collect_errors 0'"
430 mappingSettings.mappings = [{
440 wait_for_unit("prometheus-graphite-exporter.service")
441 wait_for_open_port(9108)
442 wait_for_open_port(9109)
443 succeed("echo test.tcp.foo-bar 1234 $(date +%s) | nc -w1 localhost 9109")
444 succeed("curl -sSf http://localhost:9108/metrics | grep 'testing{author=\"foo-bar\",protocol=\"tcp\"} 1234'")
454 default = { username = "username"; password = "password"; };
459 wait_for_unit("prometheus-idrac-exporter.service")
460 wait_for_open_port(9348)
461 wait_until_succeeds("curl localhost:9348")
471 wait_for_unit("prometheus-influxdb-exporter.service")
472 wait_for_open_port(9122)
474 "curl -XPOST http://localhost:9122/write --data-binary 'influxdb_exporter,distro=nixos,added_in=21.09 value=1'"
477 "curl -sSf http://localhost:9122/metrics | grep 'nixos'"
481 "curl -sSf http://localhost:9122/metrics | grep 'nixos'"
491 wait_for_unit("prometheus-ipmi-exporter.service")
492 wait_for_open_port(9290)
494 "curl -sSf http://localhost:9290/metrics | grep 'ipmi_scrape_duration_seconds'"
504 systemd.services.prometheus-jitsi-exporter.after = [ "jitsi-videobridge2.service" ];
505 services.jitsi-videobridge = {
507 colibriRestApi = true;
511 wait_for_unit("jitsi-videobridge2.service")
512 wait_for_open_port(8080)
513 wait_for_unit("prometheus-jitsi-exporter.service")
514 wait_for_open_port(9700)
516 'journalctl -eu prometheus-jitsi-exporter.service -o cat | grep "key=participants"'
518 succeed("curl -sSf 'localhost:9700/metrics' | grep 'jitsi_participants 0'")
525 configFile = pkgs.writeText "json-exporter-conf.json" (builtins.toJSON {
529 { name = "json_test_metric"; path = "{ .test }"; }
536 systemd.services.prometheus-json-exporter.after = [ "nginx.service" ];
539 virtualHosts.localhost.locations."/".extraConfig = ''
540 return 200 "{\"test\":1}";
545 wait_for_unit("nginx.service")
546 wait_for_open_port(80)
547 wait_for_unit("prometheus-json-exporter.service")
548 wait_for_open_port(7979)
550 "curl -sSf 'localhost:7979/probe?target=http://localhost' | grep 'json_test_metric 1'"
562 extraArgs = [ "-v" ];
563 settingsFile = pkgs.writeText "knot.conf" ''
569 global-module: mod-stats
572 zonefile-load: difference
573 storage: ${pkgs.buildEnv {
576 (pkgs.writeTextDir "test.zone" ''
577 @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
593 module: mod-stats/custom
598 wait_for_unit("knot.service")
599 wait_for_unit("prometheus-knot-exporter.service")
600 wait_for_open_port(9433)
601 succeed("curl -sSf 'localhost:9433' | grep '2\.019031301'")
606 # A hardware device is required to properly test this exporter, so just
607 # perform a couple of basic sanity checks that the exporter is running
608 # and requires a target, but cannot reach a specified target.
613 wait_for_unit("prometheus-keylight-exporter.service")
614 wait_for_open_port(9288)
616 "curl -sS --write-out '%{http_code}' -o /dev/null http://localhost:9288/metrics | grep '400'"
619 "curl -sS --write-out '%{http_code}' -o /dev/null http://localhost:9288/metrics?target=nosuchdevice | grep '500'"
627 lndTlsPath = "/var/lib/lnd/tls.cert";
628 lndMacaroonDir = "/var/lib/lnd";
629 extraFlags = [ "--lnd.network=regtest" ];
632 systemd.services.prometheus-lnd-exporter.serviceConfig.RestartSec = 15;
633 systemd.services.prometheus-lnd-exporter.after = [ "lnd.service" ];
634 services.bitcoind.regtest = {
637 rpcauth=bitcoinrpc:e8fe33f797e698ac258c16c8d7aadfbe$872bdb8f4d787367c26bcfd75e6c23c4f19d44a69f5d1ad329e5adf3f82710f7
638 zmqpubrawblock=tcp://127.0.0.1:28332
639 zmqpubrawtx=tcp://127.0.0.1:28333
640 # https://github.com/lightningnetwork/lnd/issues/9163
641 deprecatedrpc=warnings
643 extraCmdlineOptions = [ "-regtest" ];
645 systemd.services.lnd = {
646 serviceConfig.ExecStart = ''
647 ${pkgs.lnd}/bin/lnd \
648 --datadir=/var/lib/lnd \
649 --tlscertpath=/var/lib/lnd/tls.cert \
650 --tlskeypath=/var/lib/lnd/tls.key \
651 --logdir=/var/log/lnd \
654 --bitcoin.node=bitcoind \
655 --bitcoind.rpcuser=bitcoinrpc \
656 --bitcoind.rpcpass=hunter2 \
657 --bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 \
658 --bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 \
659 --readonlymacaroonpath=/var/lib/lnd/readonly.macaroon
661 serviceConfig.StateDirectory = "lnd";
662 wantedBy = [ "multi-user.target" ];
663 after = [ "network.target" ];
665 # initialize wallet, creates macaroon needed by exporter
666 systemd.services.lnd.postStart = ''
667 ${pkgs.curl}/bin/curl \
670 --retry-connrefused \
671 --cacert /var/lib/lnd/tls.cert \
673 https://localhost:8080/v1/genseed | ${pkgs.jq}/bin/jq -c '.cipher_seed_mnemonic' > /tmp/seed
674 ${pkgs.curl}/bin/curl \
677 --retry-connrefused \
678 --cacert /var/lib/lnd/tls.cert \
680 -d "{\"wallet_password\": \"asdfasdfasdf\", \"cipher_seed_mnemonic\": $(cat /tmp/seed | tr -d '\n')}" \
681 https://localhost:8080/v1/initwallet
685 wait_for_unit("lnd.service")
686 wait_for_open_port(10009)
687 wait_for_unit("prometheus-lnd-exporter.service")
688 wait_for_open_port(9092)
689 succeed("curl -sSf localhost:9092/metrics | grep '^lnd_peer_count'")
697 monitoringInterval = "2s";
698 mailCheckTimeout = "10s";
701 server = "localhost";
703 from = "mail-exporter@localhost";
704 to = "mail-exporter@localhost";
705 detectionDir = "/var/spool/mail/mail-exporter/new";
710 services.postfix.enable = true;
711 systemd.services.prometheus-mail-exporter = {
712 after = [ "postfix.service" ];
713 requires = [ "postfix.service" ];
716 "${pkgs.writeShellScript "create-maildir" ''
717 mkdir -p -m 0700 mail-exporter/new
722 ReadWritePaths = "/var/spool/mail";
723 WorkingDirectory = "/var/spool/mail";
726 users.users.mailexporter = {
728 group = "mailexporter";
730 users.groups.mailexporter = {};
733 wait_for_unit("postfix.service")
734 wait_for_unit("prometheus-mail-exporter.service")
735 wait_for_open_port(9225)
737 "curl -sSf http://localhost:9225/metrics | grep 'mail_deliver_success{configname=\"testserver\"} 1'"
745 extraFlags = [ "-timeout=1s" ];
750 address = "192.168.42.48";
774 wait_for_unit("prometheus-mikrotik-exporter.service")
775 wait_for_open_port(9436)
777 "curl -sSf http://localhost:9436/metrics | grep 'mikrotik_scrape_collector_success{device=\"router\"} 0'"
788 # ModemManager is installed when NetworkManager is enabled. Ensure it is
789 # started and is wanted by NM and the exporter to start everything up
790 # in the right order.
791 networking.networkmanager.enable = true;
792 systemd.services.ModemManager = {
794 wantedBy = [ "NetworkManager.service" "prometheus-modemmanager-exporter.service" ];
798 wait_for_unit("ModemManager.service")
799 wait_for_unit("prometheus-modemmanager-exporter.service")
800 wait_for_open_port(9539)
802 "curl -sSf http://localhost:9539/metrics | grep 'modemmanager_info'"
810 environmentFile = pkgs.writeText "mqtt-exporter-envfile" ''
811 MQTT_PASSWORD=testpassword
815 services.mosquitto = {
820 passwordFile = pkgs.writeText "mosquitto-password" "testpassword";
824 systemd.services.prometheus-mqtt-exporter ={
825 wants = [ "mosquitto.service" ];
826 after = [ "mosquitto.service" ];
830 wait_for_unit("mosquitto.service")
831 wait_for_unit("prometheus-mqtt-exporter.service")
832 wait_for_open_port(9000)
834 "curl -sSf http://localhost:9000/metrics | grep '^python_info'"
842 runAsLocalSuperUser = true;
843 configFile = pkgs.writeText "test-prometheus-exporter-mysqld-config.my-cnf" ''
846 password = snakeoilpassword
852 package = pkgs.mariadb;
853 initialScript = pkgs.writeText "mysql-init-script.sql" ''
854 CREATE USER 'exporter'@'localhost'
855 IDENTIFIED BY 'snakeoilpassword'
856 WITH MAX_USER_CONNECTIONS 3;
857 GRANT PROCESS, REPLICATION CLIENT, SLAVE MONITOR, SELECT ON *.* TO 'exporter'@'localhost';
862 wait_for_unit("prometheus-mysqld-exporter.service")
863 wait_for_open_port(9104)
864 wait_for_unit("mysql.service")
865 succeed("curl -sSf http://localhost:9104/metrics | grep 'mysql_up 1'")
866 systemctl("stop mysql.service")
867 succeed("curl -sSf http://localhost:9104/metrics | grep 'mysql_up 0'")
868 systemctl("start mysql.service")
869 wait_for_unit("mysql.service")
870 succeed("curl -sSf http://localhost:9104/metrics | grep 'mysql_up 1'")
877 passwordFile = "/var/nextcloud-pwfile";
878 url = "http://localhost";
881 systemd.services.nc-pwfile =
883 passfile = (pkgs.writeText "pwfile" "snakeoilpw");
886 requiredBy = [ "prometheus-nextcloud-exporter.service" ];
887 before = [ "prometheus-nextcloud-exporter.service" ];
888 serviceConfig.ExecStart = ''
889 ${pkgs.coreutils}/bin/install -o nextcloud-exporter -m 0400 ${passfile} /var/nextcloud-pwfile
894 virtualHosts."localhost" = {
895 basicAuth.nextcloud-exporter = "snakeoilpw";
897 root = "${pkgs.prometheus-nextcloud-exporter.src}/serverinfo/testdata";
898 tryFiles = "/negative-space.json =404";
904 wait_for_unit("nginx.service")
905 wait_for_unit("prometheus-nextcloud-exporter.service")
906 wait_for_open_port(9205)
907 succeed("curl -sSf http://localhost:9205/metrics | grep 'nextcloud_up 1'")
914 constLabels = [ "foo=bar" ];
920 virtualHosts."test".extraConfig = "return 204;";
924 wait_for_unit("nginx.service")
925 wait_for_unit("prometheus-nginx-exporter.service")
926 wait_for_open_port(9113)
927 succeed("curl -sSf http://localhost:9113/metrics | grep 'nginx_up{foo=\"bar\"} 1'")
940 files = [ "/var/log/nginx/filelogger.access.log" ];
947 listen_address = "udp://127.0.0.1:10000";
962 server_name filelogger.local;
963 access_log /var/log/nginx/filelogger.access.log;
967 server_name syslogger.local;
968 access_log syslog:server=127.0.0.1:10000,tag=nginx,severity=info;
974 wait_for_unit("nginx.service")
975 wait_for_unit("prometheus-nginxlog-exporter.service")
976 wait_for_open_port(9117)
977 wait_for_open_port(80)
978 wait_for_open_port(81)
979 succeed("curl http://localhost")
982 "curl -sSf http://localhost:9117/metrics | grep 'filelogger_http_response_count_total' | grep 1"
984 succeed("curl http://localhost:81")
987 "curl -sSf http://localhost:9117/metrics | grep 'syslogger_http_response_count_total' | grep 1"
997 wait_for_unit("prometheus-node-exporter.service")
998 wait_for_open_port(9100)
1000 "curl -sSf http://localhost:9100/metrics | grep 'node_exporter_build_info{.\\+} 1'"
1008 connectionEnvFile = "${pkgs.writeText "connstr-env" ''
1009 PGBOUNCER_EXPORTER_CONNECTION_STRING=postgres://admin@localhost:6432/pgbouncer?sslmode=disable
1014 services.postgresql.enable = true;
1015 services.pgbouncer = {
1021 max_client_conn = 99;
1022 # https://github.com/prometheus-community/pgbouncer_exporter#pgbouncer-configuration
1023 ignore_startup_parameters = "extra_float_digits";
1026 postgres = concatStringsSep " " [
1027 "host=/run/postgresql"
1029 "auth_user=postgres"
1037 wait_for_unit("postgresql.service")
1038 wait_for_unit("pgbouncer.service")
1039 wait_for_unit("prometheus-pgbouncer-exporter.service")
1040 wait_for_open_port(9127)
1041 succeed("curl -sSf http://localhost:9127/metrics | grep 'pgbouncer_up 1'")
1043 "curl -sSf http://localhost:9127/metrics | grep 'pgbouncer_config_max_client_connections 99'"
1049 nodeName = "php_fpm";
1052 environmentFile = pkgs.writeTextFile {
1053 name = "/tmp/prometheus-php-fpm-exporter.env";
1055 PHP_FPM_SCRAPE_URI="tcp://127.0.0.1:9000/status"
1060 users.users."php-fpm-exporter" = {
1061 isSystemUser = true;
1062 group = "php-fpm-exporter";
1064 users.groups."php-fpm-exporter" = {};
1065 services.phpfpm.pools."php-fpm-exporter" = {
1066 user = "php-fpm-exporter";
1067 group = "php-fpm-exporter";
1070 "pm.max_children" = 32;
1071 "pm.max_requests" = 500;
1072 "pm.start_servers" = 2;
1073 "pm.min_spare_servers" = 2;
1074 "pm.max_spare_servers" = 5;
1075 "pm.status_path" = "/status";
1076 "listen" = "127.0.0.1:9000";
1077 "listen.allowed_clients" = "127.0.0.1";
1079 phpEnv."PATH" = makeBinPath [ pkgs.php ];
1083 wait_for_unit("phpfpm-php-fpm-exporter.service")
1084 wait_for_unit("prometheus-php-fpm-exporter.service")
1085 succeed("curl -sSf http://localhost:9253/metrics | grep 'phpfpm_up{.*} 1'")
1096 alias = "local machine";
1102 alias = "local machine";
1107 alias = "local machine";
1127 wait_for_unit("prometheus-ping-exporter.service")
1128 wait_for_open_port(9427)
1129 succeed("curl -sSf http://localhost:9427/metrics | grep 'ping_up{.*} 1'")
1138 services.postfix.enable = true;
1141 wait_for_unit("prometheus-postfix-exporter.service")
1142 wait_for_file("/var/lib/postfix/queue/public/showq")
1143 wait_for_open_port(9154)
1144 wait_until_succeeds(
1145 "curl -sSf http://localhost:9154/metrics | grep 'postfix_up{path=\"/var/lib/postfix/queue/public/showq\"} 1'"
1148 "curl -sSf http://localhost:9154/metrics | grep 'postfix_smtpd_connects_total 0'"
1150 succeed("curl -sSf http://localhost:9154/metrics | grep 'postfix_up{.*} 1'")
1157 runAsLocalSuperUser = true;
1160 services.postgresql.enable = true;
1163 wait_for_unit("prometheus-postgres-exporter.service")
1164 wait_for_open_port(9187)
1165 wait_for_unit("postgresql.service")
1167 "curl -sSf http://localhost:9187/metrics | grep 'pg_exporter_last_scrape_error 0'"
1169 succeed("curl -sSf http://localhost:9187/metrics | grep 'pg_up 1'")
1170 systemctl("stop postgresql.service")
1172 "curl -sSf http://localhost:9187/metrics | grep -v 'pg_exporter_last_scrape_error 0'"
1174 succeed("curl -sSf http://localhost:9187/metrics | grep 'pg_up 0'")
1175 systemctl("start postgresql.service")
1176 wait_for_unit("postgresql.service")
1178 "curl -sSf http://localhost:9187/metrics | grep 'pg_exporter_last_scrape_error 0'"
1180 succeed("curl -sSf http://localhost:9187/metrics | grep 'pg_up 1'")
1187 settings.process_names = [
1188 # Remove nix store path from process name
1189 { name = "{{.Matches.Wrapped}} {{ .Matches.Args }}"; cmdline = [ "^/nix/store[^ ]*/(?P<Wrapped>[^ /]*) (?P<Args>.*)" ]; }
1193 wait_for_unit("prometheus-process-exporter.service")
1194 wait_for_open_port(9256)
1195 wait_until_succeeds(
1196 "curl -sSf localhost:9256/metrics | grep -q '{}'".format(
1197 'namedprocess_namegroup_cpu_seconds_total{groupname="process-exporter '
1204 pveExporterEnvFile = pkgs.writeTextFile {
1207 PVE_USER="test_user@pam"
1208 PVE_PASSWORD="hunter3"
1209 PVE_VERIFY_SSL="false"
1215 environmentFile = pveExporterEnvFile;
1218 wait_for_unit("prometheus-pve-exporter.service")
1219 wait_for_open_port(9221)
1220 wait_until_succeeds("curl localhost:9221")
1225 nodeName = "py_air_control";
1228 deviceHostname = "127.0.0.1";
1231 wait_for_unit("prometheus-py-air-control-exporter.service")
1232 wait_for_open_port(9896)
1234 "curl -sSf http://localhost:9896/metrics | grep 'py_air_control_sampling_error_total'"
1243 metricProvider.services.redis.servers."".enable = true;
1245 wait_for_unit("redis.service")
1246 wait_for_unit("prometheus-redis-exporter.service")
1247 wait_for_open_port(6379)
1248 wait_for_open_port(9121)
1249 wait_until_succeeds("curl -sSf localhost:9121/metrics | grep 'redis_up 1'")
1255 repository = "rest:http://127.0.0.1:8000";
1256 passwordFile = pkgs.writeText "restic-test-password" "test-password";
1261 inherit repository passwordFile;
1264 services.restic.server = {
1266 extraFlags = [ "--no-auth" ];
1268 environment.systemPackages = [ pkgs.restic ];
1271 # prometheus-restic-exporter.service fails without initialised repository
1272 systemctl("stop prometheus-restic-exporter.service")
1274 # Initialise the repository
1275 wait_for_unit("restic-rest-server.service")
1276 wait_for_open_port(8000)
1277 succeed("restic init --repo ${repository} --password-file ${passwordFile}")
1279 systemctl("start prometheus-restic-exporter.service")
1280 wait_for_unit("prometheus-restic-exporter.service")
1281 wait_for_open_port(9753)
1282 wait_until_succeeds("curl -sSf localhost:9753/metrics | grep 'restic_check_success 1.0'")
1291 services.rspamd.enable = true;
1294 wait_for_unit("rspamd.service")
1295 wait_for_unit("prometheus-rspamd-exporter.service")
1296 wait_for_open_port(11334)
1297 wait_for_open_port(7980)
1298 wait_until_succeeds(
1299 "curl -sSf 'localhost:7980/probe?target=http://localhost:11334/stat' | grep 'rspamd_scanned{host=\"rspamd\"} 0'"
1309 # Mock rtl_433 binary to return a dummy metric stream.
1310 nixpkgs.overlays = [
1312 rtl_433 = self.runCommand "rtl_433" { } ''
1314 cat <<EOF > "$out/bin/rtl_433"
1317 printf '{"time" : "2020-04-26 13:37:42", "model" : "zopieux", "id" : 55, "channel" : 3, "temperature_C" : 18.000}\n'
1321 chmod +x "$out/bin/rtl_433"
1327 wait_for_unit("prometheus-rtl_433-exporter.service")
1328 wait_for_open_port(9550)
1329 wait_until_succeeds(
1330 "curl -sSf localhost:9550/metrics | grep '{}'".format(
1331 'rtl_433_temperature_celsius{channel="3",id="55",location="",model="zopieux"} 18'
1341 baseUrl = "http://localhost:8080";
1342 apiKeyFile = "/var/sabnzbd-apikey";
1347 services.sabnzbd.enable = true;
1349 # unrar is required for sabnzbd
1350 nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (pkgs.lib.getName pkg) [ "unrar" ];
1352 # extract the generated api key before starting
1353 systemd.services.sabnzbd-apikey = {
1354 requires = [ "sabnzbd.service" ];
1355 after = [ "sabnzbd.service" ];
1356 requiredBy = [ "prometheus-sabnzbd-exporter.service" ];
1357 before = [ "prometheus-sabnzbd-exporter.service" ];
1359 grep -Po '^api_key = \K.+' /var/lib/sabnzbd/sabnzbd.ini > /var/sabnzbd-apikey
1365 wait_for_unit("sabnzbd.service")
1366 wait_for_unit("prometheus-sabnzbd-exporter.service")
1367 wait_for_open_port(8080)
1368 wait_for_open_port(9387)
1369 wait_until_succeeds(
1370 "curl -sSf 'localhost:9387/metrics' | grep 'sabnzbd_queue_size{sabnzbd_instance=\"http://localhost:8080\"} 0.0'"
1380 boot.kernelModules = [ "intel_rapl_common" ];
1383 wait_for_unit("prometheus-scaphandre-exporter.service")
1384 wait_for_open_port(8080)
1385 wait_until_succeeds(
1386 "curl -sSf 'localhost:8080/metrics'"
1394 metrics-file = "${pkgs.writeText "test.json" ''{}''}";
1397 wait_for_unit("prometheus-shelly-exporter.service")
1398 wait_for_open_port(9784)
1399 wait_until_succeeds(
1400 "curl -sSf 'localhost:9784/metrics'"
1408 settings.scripts = [
1409 { name = "success"; script = "sleep 1"; }
1413 wait_for_unit("prometheus-script-exporter.service")
1414 wait_for_open_port(9172)
1415 wait_until_succeeds(
1416 "curl -sSf 'localhost:9172/probe?name=success' | grep -q '{}'".format(
1417 'script_success{script="success"} 1'
1431 wait_until_succeeds(
1432 'journalctl -eu prometheus-smartctl-exporter.service -o cat | grep "Unable to detect device type"'
1440 hosts = [ "127.0.0.1" ];
1443 wait_for_unit("prometheus-smokeping-exporter.service")
1444 wait_for_open_port(9374)
1445 wait_until_succeeds(
1446 "curl -sSf localhost:9374/metrics | grep '{}' | grep -v ' 0$'".format(
1447 'smokeping_requests_total{host="127.0.0.1",ip="127.0.0.1",source=""} '
1450 wait_until_succeeds(
1451 "curl -sSf localhost:9374/metrics | grep '{}'".format(
1452 'smokeping_response_ttl{host="127.0.0.1",ip="127.0.0.1",source=""}'
1463 community = "public";
1469 wait_for_unit("prometheus-snmp-exporter.service")
1470 wait_for_open_port(9116)
1471 succeed("curl -sSf localhost:9116/metrics | grep 'snmp_request_errors_total 0'")
1477 configuration.jobs.points = {
1480 "postgres://prometheus-sql-exporter@/data?host=/run/postgresql&sslmode=disable"
1484 labels = [ "name" ];
1485 help = "Amount of points accumulated per person";
1486 values = [ "amount" ];
1487 query = "SELECT SUM(amount) as amount, name FROM points GROUP BY name";
1492 user = "prometheus-sql-exporter";
1495 services.postgresql = {
1497 initialScript = builtins.toFile "init.sql" ''
1498 CREATE DATABASE data;
1500 CREATE TABLE points (amount INT, name TEXT);
1501 INSERT INTO points(amount, name) VALUES (1, 'jack');
1502 INSERT INTO points(amount, name) VALUES (2, 'jill');
1503 INSERT INTO points(amount, name) VALUES (3, 'jack');
1505 CREATE USER "prometheus-sql-exporter";
1506 GRANT ALL PRIVILEGES ON DATABASE data TO "prometheus-sql-exporter";
1507 GRANT SELECT ON points TO "prometheus-sql-exporter";
1510 systemd.services.prometheus-sql-exporter.after = [ "postgresql.service" ];
1513 wait_for_unit("prometheus-sql-exporter.service")
1514 wait_for_open_port(9237)
1515 succeed("curl http://localhost:9237/metrics | grep -c 'sql_points{' | grep 2")
1524 wait_for_unit("prometheus-statsd-exporter.service")
1525 wait_for_open_port(9102)
1526 succeed("curl http://localhost:9102/metrics | grep 'statsd_exporter_build_info{'")
1527 wait_until_succeeds(
1528 "echo 'test.udp:1|c' > /dev/udp/localhost/9125 && \
1529 curl http://localhost:9102/metrics | grep 'test_udp 1'",
1532 wait_until_succeeds(
1533 "echo 'test.tcp:1|c' > /dev/tcp/localhost/9125 && \
1534 curl http://localhost:9102/metrics | grep 'test_tcp 1'",
1543 modemAddress = "localhost";
1546 systemd.services.prometheus-surfboard-exporter.after = [ "nginx.service" ];
1549 virtualHosts.localhost.locations."/cgi-bin/status".extraConfig = ''
1555 wait_for_unit("nginx.service")
1556 wait_for_open_port(80)
1557 wait_for_unit("prometheus-surfboard-exporter.service")
1558 wait_for_open_port(9239)
1559 succeed("curl -sSf localhost:9239/metrics | grep 'surfboard_up 1'")
1568 "--systemd.collector.enable-restart-count"
1571 metricProvider = { };
1573 wait_for_unit("prometheus-systemd-exporter.service")
1574 wait_for_open_port(9558)
1575 wait_until_succeeds(
1576 "curl -sSf localhost:9558/metrics | grep '{}'".format(
1577 'systemd_unit_state{name="basic.target",state="active",type="target"} 1'
1581 "curl -sSf localhost:9558/metrics | grep '{}'".format(
1582 'systemd_service_restart_total{name="prometheus-systemd-exporter.service"} 0'
1589 nodeName = "unpoller";
1590 exporterConfig.enable = true;
1591 exporterConfig.controllers = [{ }];
1593 wait_until_succeeds(
1594 'journalctl -eu prometheus-unpoller-exporter.service -o cat | grep "Connection Error"'
1602 unbound.host = "unix:///run/unbound/unbound.ctl";
1605 services.unbound = {
1607 localControlSocketPath = "/run/unbound/unbound.ctl";
1609 systemd.services.prometheus-unbound-exporter.serviceConfig = {
1610 SupplementaryGroups = [ "unbound" ];
1614 wait_for_unit("unbound.service")
1615 wait_for_unit("prometheus-unbound-exporter.service")
1616 wait_for_open_port(9167)
1617 wait_until_succeeds("curl -sSf localhost:9167/metrics | grep 'unbound_up 1'")
1627 systemd.services.prometheus-nginx-exporter.after = [ "v2ray.service" ];
1634 services = [ "StatsService" ];
1639 listen = "127.0.0.1";
1643 listen = "127.0.0.1";
1645 protocol = "dokodemo-door";
1646 settings = { address = "127.0.0.1"; };
1652 protocol = "freedom";
1655 protocol = "freedom";
1665 inboundTag = [ "api" ];
1666 outboundTag = "api";
1676 wait_for_unit("prometheus-v2ray-exporter.service")
1677 wait_for_open_port(9299)
1678 succeed("curl -sSf localhost:9299/scrape | grep 'v2ray_up 1'")
1685 instance = "/run/varnish/varnish";
1689 systemd.services.prometheus-varnish-exporter.after = [
1692 services.varnish = {
1694 stateDir = "/run/varnish/varnish";
1698 .host = "127.0.0.1";
1705 wait_for_unit("prometheus-varnish-exporter.service")
1706 wait_for_open_port(6081)
1707 wait_for_open_port(9131)
1708 succeed("curl -sSf http://localhost:9131/metrics | grep 'varnish_up 1'")
1713 snakeoil = import ./wireguard/snakeoil-keys.nix;
1714 publicKeyWithoutNewlines = replaceStrings [ "\n" ] [ "" ] snakeoil.peer1.publicKey;
1717 exporterConfig.enable = true;
1719 networking.wireguard.interfaces.wg0 = {
1720 ips = [ "10.23.42.1/32" "fc00::1/128" ];
1723 inherit (snakeoil.peer0) privateKey;
1726 allowedIPs = [ "10.23.42.2/32" "fc00::2/128" ];
1728 inherit (snakeoil.peer1) publicKey;
1731 systemd.services.prometheus-wireguard-exporter.after = [ "wireguard-wg0.service" ];
1734 wait_for_unit("prometheus-wireguard-exporter.service")
1735 wait_for_open_port(9586)
1736 wait_until_succeeds(
1737 "curl -sSf http://localhost:9586/metrics | grep '${publicKeyWithoutNewlines}'"
1747 boot.supportedFilesystems = [ "zfs" ];
1748 networking.hostId = "7327ded7";
1751 wait_for_unit("prometheus-zfs-exporter.service")
1752 wait_for_unit("zfs.target")
1753 wait_for_open_port(9134)
1754 wait_until_succeeds("curl -f localhost:9134/metrics | grep 'zfs_scrape_collector_success{.*} 1'")
1760 (exporter: testConfig: (makeTest (
1762 nodeName = testConfig.nodeName or exporter;
1766 name = "prometheus-${exporter}-exporter";
1768 nodes.${nodeName} = mkMerge [{
1769 services.prometheus.exporters.${exporter} = testConfig.exporterConfig;
1770 } testConfig.metricProvider or { }];
1774 ${concatStringsSep "\n" (map (line:
1775 if builtins.any (b: b) [
1776 (builtins.match "^[[:space:]]*$" line != null)
1777 (builtins.substring 0 1 line == "#")
1778 (builtins.substring 0 1 line == " ")
1779 (builtins.substring 0 1 line == ")")
1782 else "${nodeName}.${line}"
1783 ) (splitString "\n" (removeSuffix "\n" testConfig.exporterTest)))}
1784 ${nodeName}.shutdown()
1787 meta = with maintainers; {
1788 maintainers = [ willibutz ];