uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead
https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948 this can do it nicely. Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
commit
56de2bcd43
30691 changed files with 3076956 additions and 0 deletions
|
|
@ -0,0 +1,38 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.apcupsd;
|
||||
in
|
||||
{
|
||||
port = 9162;
|
||||
extraOpts = {
|
||||
apcupsdAddress = mkOption {
|
||||
type = types.str;
|
||||
default = ":3551";
|
||||
description = ''
|
||||
Address of the apcupsd Network Information Server (NIS).
|
||||
'';
|
||||
};
|
||||
|
||||
apcupsdNetwork = mkOption {
|
||||
type = types.enum ["tcp" "tcp4" "tcp6"];
|
||||
default = "tcp";
|
||||
description = ''
|
||||
Network of the apcupsd Network Information Server (NIS): one of "tcp", "tcp4", or "tcp6".
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-apcupsd-exporter}/bin/apcupsd_exporter \
|
||||
-telemetry.addr ${cfg.listenAddress}:${toString cfg.port} \
|
||||
-apcupsd.addr ${cfg.apcupsdAddress} \
|
||||
-apcupsd.network ${cfg.apcupsdNetwork} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.artifactory;
|
||||
in
|
||||
{
|
||||
port = 9531;
|
||||
extraOpts = {
|
||||
scrapeUri = mkOption {
|
||||
type = types.str;
|
||||
default = "http://localhost:8081/artifactory";
|
||||
description = ''
|
||||
URI on which to scrape JFrog Artifactory.
|
||||
'';
|
||||
};
|
||||
|
||||
artiUsername = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Username for authentication against JFrog Artifactory API.
|
||||
'';
|
||||
};
|
||||
|
||||
artiPassword = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Password for authentication against JFrog Artifactory API.
|
||||
One of the password or access token needs to be set.
|
||||
'';
|
||||
};
|
||||
|
||||
artiAccessToken = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Access token for authentication against JFrog Artifactory API.
|
||||
One of the password or access token needs to be set.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-artifactory-exporter}/bin/artifactory_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--artifactory.scrape-uri ${cfg.scrapeUri} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
Environment = [
|
||||
"ARTI_USERNAME=${cfg.artiUsername}"
|
||||
"ARTI_PASSWORD=${cfg.artiPassword}"
|
||||
"ARTI_ACCESS_TOKEN=${cfg.artiAccessToken}"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.bind;
|
||||
in
|
||||
{
|
||||
port = 9119;
|
||||
extraOpts = {
|
||||
bindURI = mkOption {
|
||||
type = types.str;
|
||||
default = "http://localhost:8053/";
|
||||
description = ''
|
||||
HTTP XML API address of an Bind server.
|
||||
'';
|
||||
};
|
||||
bindTimeout = mkOption {
|
||||
type = types.str;
|
||||
default = "10s";
|
||||
description = ''
|
||||
Timeout for trying to get stats from Bind.
|
||||
'';
|
||||
};
|
||||
bindVersion = mkOption {
|
||||
type = types.enum [ "xml.v2" "xml.v3" "auto" ];
|
||||
default = "auto";
|
||||
description = ''
|
||||
BIND statistics version. Can be detected automatically.
|
||||
'';
|
||||
};
|
||||
bindGroups = mkOption {
|
||||
type = types.listOf (types.enum [ "server" "view" "tasks" ]);
|
||||
default = [ "server" "view" ];
|
||||
description = ''
|
||||
List of statistics to collect. Available: [server, view, tasks]
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-bind-exporter}/bin/bind_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--bind.pid-file /var/run/named/named.pid \
|
||||
--bind.timeout ${toString cfg.bindTimeout} \
|
||||
--bind.stats-url ${cfg.bindURI} \
|
||||
--bind.stats-version ${cfg.bindVersion} \
|
||||
--bind.stats-groups ${concatStringsSep "," cfg.bindGroups} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.bird;
|
||||
in
|
||||
{
|
||||
port = 9324;
|
||||
extraOpts = {
|
||||
birdVersion = mkOption {
|
||||
type = types.enum [ 1 2 ];
|
||||
default = 2;
|
||||
description = ''
|
||||
Specifies whether BIRD1 or BIRD2 is in use.
|
||||
'';
|
||||
};
|
||||
birdSocket = mkOption {
|
||||
type = types.path;
|
||||
default = "/run/bird/bird.ctl";
|
||||
description = ''
|
||||
Path to BIRD2 (or BIRD1 v4) socket.
|
||||
'';
|
||||
};
|
||||
newMetricFormat = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enable the new more-generic metric format.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
SupplementaryGroups = singleton (if cfg.birdVersion == 1 then "bird" else "bird2");
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-bird-exporter}/bin/bird_exporter \
|
||||
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
-bird.socket ${cfg.birdSocket} \
|
||||
-bird.v2=${if cfg.birdVersion == 2 then "true" else "false"} \
|
||||
-format.new=${if cfg.newMetricFormat then "true" else "false"} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_UNIX to collect data
|
||||
"AF_UNIX"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.bitcoin;
|
||||
in
|
||||
{
|
||||
port = 9332;
|
||||
extraOpts = {
|
||||
rpcUser = mkOption {
|
||||
type = types.str;
|
||||
default = "bitcoinrpc";
|
||||
description = ''
|
||||
RPC user name.
|
||||
'';
|
||||
};
|
||||
|
||||
rpcPasswordFile = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
File containing RPC password.
|
||||
'';
|
||||
};
|
||||
|
||||
rpcScheme = mkOption {
|
||||
type = types.enum [ "http" "https" ];
|
||||
default = "http";
|
||||
description = ''
|
||||
Whether to connect to bitcoind over http or https.
|
||||
'';
|
||||
};
|
||||
|
||||
rpcHost = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
RPC host.
|
||||
'';
|
||||
};
|
||||
|
||||
rpcPort = mkOption {
|
||||
type = types.port;
|
||||
default = 8332;
|
||||
description = ''
|
||||
RPC port number.
|
||||
'';
|
||||
};
|
||||
|
||||
refreshSeconds = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 300;
|
||||
description = ''
|
||||
How often to ask bitcoind for metrics.
|
||||
'';
|
||||
};
|
||||
|
||||
extraEnv = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
description = ''
|
||||
Extra environment variables for the exporter.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
script = ''
|
||||
export BITCOIN_RPC_PASSWORD=$(cat ${cfg.rpcPasswordFile})
|
||||
exec ${pkgs.prometheus-bitcoin-exporter}/bin/bitcoind-monitor.py
|
||||
'';
|
||||
|
||||
environment = {
|
||||
BITCOIN_RPC_USER = cfg.rpcUser;
|
||||
BITCOIN_RPC_SCHEME = cfg.rpcScheme;
|
||||
BITCOIN_RPC_HOST = cfg.rpcHost;
|
||||
BITCOIN_RPC_PORT = toString cfg.rpcPort;
|
||||
METRICS_ADDR = cfg.listenAddress;
|
||||
METRICS_PORT = toString cfg.port;
|
||||
REFRESH_SECONDS = toString cfg.refreshSeconds;
|
||||
} // cfg.extraEnv;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
logPrefix = "services.prometheus.exporter.blackbox";
|
||||
cfg = config.services.prometheus.exporters.blackbox;
|
||||
|
||||
# This ensures that we can deal with string paths, path types and
|
||||
# store-path strings with context.
|
||||
coerceConfigFile = file:
|
||||
if (builtins.isPath file) || (lib.isStorePath file) then
|
||||
file
|
||||
else
|
||||
(lib.warn ''
|
||||
${logPrefix}: configuration file "${file}" is being copied to the nix-store.
|
||||
If you would like to avoid that, please set enableConfigCheck to false.
|
||||
'' /. + file);
|
||||
checkConfigLocation = file:
|
||||
if lib.hasPrefix "/tmp/" file then
|
||||
throw
|
||||
"${logPrefix}: configuration file must not reside within /tmp - it won't be visible to the systemd service."
|
||||
else
|
||||
true;
|
||||
checkConfig = file:
|
||||
pkgs.runCommand "checked-blackbox-exporter.conf" {
|
||||
preferLocalBuild = true;
|
||||
buildInputs = [ pkgs.buildPackages.prometheus-blackbox-exporter ];
|
||||
} ''
|
||||
ln -s ${coerceConfigFile file} $out
|
||||
blackbox_exporter --config.check --config.file $out
|
||||
'';
|
||||
in {
|
||||
port = 9115;
|
||||
extraOpts = {
|
||||
configFile = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path to configuration file.
|
||||
'';
|
||||
};
|
||||
enableConfigCheck = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to run a correctness check for the configuration file. This depends
|
||||
on the configuration file residing in the nix-store. Paths passed as string will
|
||||
be copied to the store.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
serviceOpts = let
|
||||
adjustedConfigFile = if cfg.enableConfigCheck then
|
||||
checkConfig cfg.configFile
|
||||
else
|
||||
checkConfigLocation cfg.configFile;
|
||||
in {
|
||||
serviceConfig = {
|
||||
AmbientCapabilities = [ "CAP_NET_RAW" ]; # for ping probes
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-blackbox-exporter}/bin/blackbox_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--config.file ${escapeShellArg adjustedConfigFile} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.buildkite-agent;
|
||||
in
|
||||
{
|
||||
port = 9876;
|
||||
extraOpts = {
|
||||
tokenPath = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
apply = final: if final == null then null else toString final;
|
||||
description = ''
|
||||
The token from your Buildkite "Agents" page.
|
||||
|
||||
A run-time path to the token file, which is supposed to be provisioned
|
||||
outside of Nix store.
|
||||
'';
|
||||
};
|
||||
interval = mkOption {
|
||||
type = types.str;
|
||||
default = "30s";
|
||||
example = "1min";
|
||||
description = ''
|
||||
How often to update metrics.
|
||||
'';
|
||||
};
|
||||
endpoint = mkOption {
|
||||
type = types.str;
|
||||
default = "https://agent.buildkite.com/v3";
|
||||
description = ''
|
||||
The Buildkite Agent API endpoint.
|
||||
'';
|
||||
};
|
||||
queues = mkOption {
|
||||
type = with types; nullOr (listOf str);
|
||||
default = null;
|
||||
example = literalExpression ''[ "my-queue1" "my-queue2" ]'';
|
||||
description = ''
|
||||
Which specific queues to process.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
script =
|
||||
let
|
||||
queues = concatStringsSep " " (map (q: "-queue ${q}") cfg.queues);
|
||||
in
|
||||
''
|
||||
export BUILDKITE_AGENT_TOKEN="$(cat ${toString cfg.tokenPath})"
|
||||
exec ${pkgs.buildkite-agent-metrics}/bin/buildkite-agent-metrics \
|
||||
-backend prometheus \
|
||||
-interval ${cfg.interval} \
|
||||
-endpoint ${cfg.endpoint} \
|
||||
${optionalString (cfg.queues != null) queues} \
|
||||
-prometheus-addr "${cfg.listenAddress}:${toString cfg.port}" ${concatStringsSep " " cfg.extraFlags}
|
||||
'';
|
||||
serviceConfig = {
|
||||
DynamicUser = false;
|
||||
RuntimeDirectory = "buildkite-agent-metrics";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.collectd;
|
||||
in
|
||||
{
|
||||
port = 9103;
|
||||
extraOpts = {
|
||||
collectdBinary = {
|
||||
enable = mkEnableOption "collectd binary protocol receiver";
|
||||
|
||||
authFile = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
description = "File mapping user names to pre-shared keys (passwords).";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
default = 25826;
|
||||
description = "Network address on which to accept collectd binary network packets.";
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "0.0.0.0";
|
||||
description = ''
|
||||
Address to listen on for binary network packets.
|
||||
'';
|
||||
};
|
||||
|
||||
securityLevel = mkOption {
|
||||
type = types.enum ["None" "Sign" "Encrypt"];
|
||||
default = "None";
|
||||
description = ''
|
||||
Minimum required security level for accepted packets.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
logFormat = mkOption {
|
||||
type = types.enum [ "logfmt" "json" ];
|
||||
default = "logfmt";
|
||||
example = "json";
|
||||
description = ''
|
||||
Set the log format.
|
||||
'';
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum ["debug" "info" "warn" "error" "fatal"];
|
||||
default = "info";
|
||||
description = ''
|
||||
Only log messages with the given severity or above.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = let
|
||||
collectSettingsArgs = if (cfg.collectdBinary.enable) then ''
|
||||
--collectd.listen-address ${cfg.collectdBinary.listenAddress}:${toString cfg.collectdBinary.port} \
|
||||
--collectd.security-level ${cfg.collectdBinary.securityLevel} \
|
||||
'' else "";
|
||||
in {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-collectd-exporter}/bin/collectd_exporter \
|
||||
--log.format ${escapeShellArg cfg.logFormat} \
|
||||
--log.level ${cfg.logLevel} \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
${collectSettingsArgs} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
117
nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix
Normal file
117
nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.dmarc;
|
||||
|
||||
json = builtins.toJSON {
|
||||
inherit (cfg) folders port;
|
||||
listen_addr = cfg.listenAddress;
|
||||
storage_path = "$STATE_DIRECTORY";
|
||||
imap = (builtins.removeAttrs cfg.imap [ "passwordFile" ]) // { password = "$IMAP_PASSWORD"; use_ssl = true; };
|
||||
poll_interval_seconds = cfg.pollIntervalSeconds;
|
||||
deduplication_max_seconds = cfg.deduplicationMaxSeconds;
|
||||
logging = {
|
||||
version = 1;
|
||||
disable_existing_loggers = false;
|
||||
};
|
||||
};
|
||||
in {
|
||||
port = 9797;
|
||||
extraOpts = {
|
||||
imap = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
Hostname of IMAP server to connect to.
|
||||
'';
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 993;
|
||||
description = ''
|
||||
Port of the IMAP server to connect to.
|
||||
'';
|
||||
};
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
example = "postmaster@example.org";
|
||||
description = ''
|
||||
Login username for the IMAP connection.
|
||||
'';
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = types.str;
|
||||
example = "/run/secrets/dovecot_pw";
|
||||
description = ''
|
||||
File containing the login password for the IMAP connection.
|
||||
'';
|
||||
};
|
||||
};
|
||||
folders = {
|
||||
inbox = mkOption {
|
||||
type = types.str;
|
||||
default = "INBOX";
|
||||
description = ''
|
||||
IMAP mailbox that is checked for incoming DMARC aggregate reports
|
||||
'';
|
||||
};
|
||||
done = mkOption {
|
||||
type = types.str;
|
||||
default = "Archive";
|
||||
description = ''
|
||||
IMAP mailbox that successfully processed reports are moved to.
|
||||
'';
|
||||
};
|
||||
error = mkOption {
|
||||
type = types.str;
|
||||
default = "Invalid";
|
||||
description = ''
|
||||
IMAP mailbox that emails are moved to that could not be processed.
|
||||
'';
|
||||
};
|
||||
};
|
||||
pollIntervalSeconds = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 60;
|
||||
description = ''
|
||||
How often to poll the IMAP server in seconds.
|
||||
'';
|
||||
};
|
||||
deduplicationMaxSeconds = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 604800;
|
||||
defaultText = "7 days (in seconds)";
|
||||
description = ''
|
||||
How long individual report IDs will be remembered to avoid
|
||||
counting double delivered reports twice.
|
||||
'';
|
||||
};
|
||||
debug = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to declare enable <literal>--debug</literal>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
path = with pkgs; [ envsubst coreutils ];
|
||||
serviceConfig = {
|
||||
StateDirectory = "prometheus-dmarc-exporter";
|
||||
WorkingDirectory = "/var/lib/prometheus-dmarc-exporter";
|
||||
ExecStart = "${pkgs.writeShellScript "setup-cfg" ''
|
||||
export IMAP_PASSWORD="$(<${cfg.imap.passwordFile})"
|
||||
envsubst \
|
||||
-i ${pkgs.writeText "dmarc-exporter.json.template" json} \
|
||||
-o ''${STATE_DIRECTORY}/dmarc-exporter.json
|
||||
|
||||
exec ${pkgs.dmarc-metrics-exporter}/bin/dmarc-metrics-exporter \
|
||||
--configuration /var/lib/prometheus-dmarc-exporter/dmarc-exporter.json \
|
||||
${optionalString cfg.debug "--debug"}
|
||||
''}";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.dnsmasq;
|
||||
in
|
||||
{
|
||||
port = 9153;
|
||||
extraOpts = {
|
||||
dnsmasqListenAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost:53";
|
||||
description = ''
|
||||
Address on which dnsmasq listens.
|
||||
'';
|
||||
};
|
||||
leasesPath = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/misc/dnsmasq.leases";
|
||||
example = "/var/lib/dnsmasq/dnsmasq.leases";
|
||||
description = ''
|
||||
Path to the <literal>dnsmasq.leases</literal> file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-dnsmasq-exporter}/bin/dnsmasq_exporter \
|
||||
--listen ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--dnsmasq ${cfg.dnsmasqListenAddress} \
|
||||
--leases_path ${escapeShellArg cfg.leasesPath} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.domain;
|
||||
in
|
||||
{
|
||||
port = 9222;
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-domain-exporter}/bin/domain_exporter \
|
||||
--bind ${cfg.listenAddress}:${toString cfg.port} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.dovecot;
|
||||
in
|
||||
{
|
||||
port = 9166;
|
||||
extraOpts = {
|
||||
telemetryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
socketPath = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/run/dovecot/stats";
|
||||
example = "/var/run/dovecot2/old-stats";
|
||||
description = ''
|
||||
Path under which the stats socket is placed.
|
||||
The user/group under which the exporter runs,
|
||||
should be able to access the socket in order
|
||||
to scrape the metrics successfully.
|
||||
|
||||
Please keep in mind that the stats module has changed in
|
||||
<link xlink:href="https://wiki2.dovecot.org/Upgrading/2.3">Dovecot 2.3+</link> which
|
||||
is not <link xlink:href="https://github.com/kumina/dovecot_exporter/issues/8">compatible with this exporter</link>.
|
||||
|
||||
The following extra config has to be passed to Dovecot to ensure that recent versions
|
||||
work with this exporter:
|
||||
<programlisting>
|
||||
{
|
||||
<xref linkend="opt-services.prometheus.exporters.dovecot.enable" /> = true;
|
||||
<xref linkend="opt-services.prometheus.exporters.dovecot.socketPath" /> = "/var/run/dovecot2/old-stats";
|
||||
<xref linkend="opt-services.dovecot2.mailPlugins.globally.enable" /> = [ "old_stats" ];
|
||||
<xref linkend="opt-services.dovecot2.extraConfig" /> = '''
|
||||
service old-stats {
|
||||
unix_listener old-stats {
|
||||
user = dovecot-exporter
|
||||
group = dovecot-exporter
|
||||
mode = 0660
|
||||
}
|
||||
fifo_listener old-stats-mail {
|
||||
mode = 0660
|
||||
user = dovecot
|
||||
group = dovecot
|
||||
}
|
||||
fifo_listener old-stats-user {
|
||||
mode = 0660
|
||||
user = dovecot
|
||||
group = dovecot
|
||||
}
|
||||
}
|
||||
plugin {
|
||||
old_stats_refresh = 30 secs
|
||||
old_stats_track_cmds = yes
|
||||
}
|
||||
''';
|
||||
}
|
||||
</programlisting>
|
||||
'';
|
||||
};
|
||||
scopes = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "user" ];
|
||||
example = [ "user" "global" ];
|
||||
description = ''
|
||||
Stats scopes to query.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
DynamicUser = false;
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-dovecot-exporter}/bin/dovecot_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--web.telemetry-path ${cfg.telemetryPath} \
|
||||
--dovecot.socket-path ${escapeShellArg cfg.socketPath} \
|
||||
--dovecot.scopes ${concatStringsSep "," cfg.scopes} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_UNIX to collect data
|
||||
"AF_UNIX"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.services.prometheus.exporters.fastly;
|
||||
in
|
||||
{
|
||||
port = 9118;
|
||||
extraOpts = {
|
||||
debug = mkEnableOption "Debug logging mode for fastly-exporter";
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to a fastly-exporter configuration file.
|
||||
Example one can be generated with <literal>fastly-exporter --config-file-example</literal>.
|
||||
'';
|
||||
example = "./fastly-exporter-config.txt";
|
||||
};
|
||||
|
||||
tokenPath = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
apply = final: if final == null then null else toString final;
|
||||
description = ''
|
||||
A run-time path to the token file, which is supposed to be provisioned
|
||||
outside of Nix store.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
script = ''
|
||||
${optionalString (cfg.tokenPath != null)
|
||||
"export FASTLY_API_TOKEN=$(cat ${toString cfg.tokenPath})"}
|
||||
${pkgs.prometheus-fastly-exporter}/bin/fastly-exporter \
|
||||
-listen http://${cfg.listenAddress}:${toString cfg.port}
|
||||
${optionalString cfg.debug "-debug true"} \
|
||||
${optionalString (cfg.configFile != null) "-config-file ${cfg.configFile}"}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.flow;
|
||||
in {
|
||||
port = 9590;
|
||||
extraOpts = {
|
||||
brokers = mkOption {
|
||||
type = types.listOf types.str;
|
||||
example = literalExpression ''[ "kafka.example.org:19092" ]'';
|
||||
description = "List of Kafka brokers to connect to.";
|
||||
};
|
||||
|
||||
asn = mkOption {
|
||||
type = types.ints.positive;
|
||||
example = 65542;
|
||||
description = "The ASN being monitored.";
|
||||
};
|
||||
|
||||
partitions = mkOption {
|
||||
type = types.listOf types.int;
|
||||
default = [];
|
||||
description = ''
|
||||
The number of the partitions to consume, none means all.
|
||||
'';
|
||||
};
|
||||
|
||||
topic = mkOption {
|
||||
type = types.str;
|
||||
example = "pmacct.acct";
|
||||
description = "The Kafka topic to consume from.";
|
||||
};
|
||||
};
|
||||
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-flow-exporter}/bin/flow-exporter \
|
||||
-asn ${toString cfg.asn} \
|
||||
-topic ${cfg.topic} \
|
||||
-brokers ${concatStringsSep "," cfg.brokers} \
|
||||
${optionalString (cfg.partitions != []) "-partitions ${concatStringsSep "," cfg.partitions}"} \
|
||||
-addr ${cfg.listenAddress}:${toString cfg.port} ${concatStringsSep " " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.fritzbox;
|
||||
in
|
||||
{
|
||||
port = 9133;
|
||||
extraOpts = {
|
||||
gatewayAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "fritz.box";
|
||||
description = ''
|
||||
The hostname or IP of the FRITZ!Box.
|
||||
'';
|
||||
};
|
||||
|
||||
gatewayPort = mkOption {
|
||||
type = types.int;
|
||||
default = 49000;
|
||||
description = ''
|
||||
The port of the FRITZ!Box UPnP service.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-fritzbox-exporter}/bin/exporter \
|
||||
-listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
-gateway-address ${cfg.gatewayAddress} \
|
||||
-gateway-port ${toString cfg.gatewayPort} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.influxdb;
|
||||
in
|
||||
{
|
||||
port = 9122;
|
||||
extraOpts = {
|
||||
sampleExpiry = mkOption {
|
||||
type = types.str;
|
||||
default = "5m";
|
||||
example = "10m";
|
||||
description = "How long a sample is valid for";
|
||||
};
|
||||
udpBindAddress = mkOption {
|
||||
type = types.str;
|
||||
default = ":9122";
|
||||
example = "192.0.2.1:9122";
|
||||
description = "Address on which to listen for udp packets";
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
RuntimeDirectory = "prometheus-influxdb-exporter";
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-influxdb-exporter}/bin/influxdb_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--influxdb.sample-expiry ${cfg.sampleExpiry} ${concatStringsSep " " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.jitsi;
|
||||
in
|
||||
{
|
||||
port = 9700;
|
||||
extraOpts = {
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
default = "http://localhost:8080/colibri/stats";
|
||||
description = ''
|
||||
Jitsi Videobridge metrics URL to monitor.
|
||||
This is usually /colibri/stats on port 8080 of the jitsi videobridge host.
|
||||
'';
|
||||
};
|
||||
interval = mkOption {
|
||||
type = types.str;
|
||||
default = "30s";
|
||||
example = "1min";
|
||||
description = ''
|
||||
How often to scrape new data
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-jitsi-exporter}/bin/jitsiexporter \
|
||||
-url ${escapeShellArg cfg.url} \
|
||||
-host ${cfg.listenAddress} \
|
||||
-port ${toString cfg.port} \
|
||||
-interval ${toString cfg.interval} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.json;
|
||||
in
|
||||
{
|
||||
port = 7979;
|
||||
extraOpts = {
|
||||
configFile = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path to configuration file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-json-exporter}/bin/json_exporter \
|
||||
--config.file ${escapeShellArg cfg.configFile} \
|
||||
--web.listen-address="${cfg.listenAddress}:${toString cfg.port}" \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "url" ] ''
|
||||
This option was removed. The URL of the endpoint serving JSON
|
||||
must now be provided to the exporter by prometheus via the url
|
||||
parameter `target'.
|
||||
|
||||
In prometheus a scrape URL would look like this:
|
||||
|
||||
http://some.json-exporter.host:7979/probe?target=https://example.com/some/json/endpoint
|
||||
|
||||
For more information, take a look at the official documentation
|
||||
(https://github.com/prometheus-community/json_exporter) of the json_exporter.
|
||||
'')
|
||||
({ options.warnings = options.warnings; options.assertions = options.assertions; })
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, options
|
||||
}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.kea;
|
||||
in {
|
||||
port = 9547;
|
||||
extraOpts = {
|
||||
controlSocketPaths = mkOption {
|
||||
type = types.listOf types.str;
|
||||
example = literalExpression ''
|
||||
[
|
||||
"/run/kea/kea-dhcp4.socket"
|
||||
"/run/kea/kea-dhcp6.socket"
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
Paths to kea control sockets
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
after = [
|
||||
"kea-dhcp4-server.service"
|
||||
"kea-dhcp6-server.service"
|
||||
];
|
||||
serviceConfig = {
|
||||
User = "kea";
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-kea-exporter}/bin/kea-exporter \
|
||||
--address ${cfg.listenAddress} \
|
||||
--port ${toString cfg.port} \
|
||||
${concatStringsSep " \\n" cfg.controlSocketPaths}
|
||||
'';
|
||||
SupplementaryGroups = [ "kea" ];
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_UNIX to collect data
|
||||
"AF_UNIX"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.keylight;
|
||||
in
|
||||
{
|
||||
port = 9288;
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-keylight-exporter}/bin/keylight_exporter \
|
||||
-metrics.addr ${cfg.listenAddress}:${toString cfg.port} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.knot;
|
||||
in {
|
||||
port = 9433;
|
||||
extraOpts = {
|
||||
knotLibraryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "${pkgs.knot-dns.out}/lib/libknot.so";
|
||||
defaultText = literalExpression ''"''${pkgs.knot-dns.out}/lib/libknot.so"'';
|
||||
description = ''
|
||||
Path to the library of <package>knot-dns</package>.
|
||||
'';
|
||||
};
|
||||
|
||||
knotSocketPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/run/knot/knot.sock";
|
||||
description = ''
|
||||
Socket path of <citerefentry><refentrytitle>knotd</refentrytitle>
|
||||
<manvolnum>8</manvolnum></citerefentry>.
|
||||
'';
|
||||
};
|
||||
|
||||
knotSocketTimeout = mkOption {
|
||||
type = types.int;
|
||||
default = 2000;
|
||||
description = ''
|
||||
Timeout in seconds.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-knot-exporter}/bin/knot_exporter \
|
||||
--web-listen-addr ${cfg.listenAddress} \
|
||||
--web-listen-port ${toString cfg.port} \
|
||||
--knot-library-path ${cfg.knotLibraryPath} \
|
||||
--knot-socket-path ${cfg.knotSocketPath} \
|
||||
--knot-socket-timeout ${toString cfg.knotSocketTimeout} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
SupplementaryGroups = [ "knot" ];
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_UNIX to collect data
|
||||
"AF_UNIX"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.lnd;
|
||||
in
|
||||
{
|
||||
port = 9092;
|
||||
extraOpts = {
|
||||
lndHost = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost:10009";
|
||||
description = ''
|
||||
lnd instance gRPC address:port.
|
||||
'';
|
||||
};
|
||||
|
||||
lndTlsPath = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path to lnd TLS certificate.
|
||||
'';
|
||||
};
|
||||
|
||||
lndMacaroonDir = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path to lnd macaroons.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts.serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-lnd-exporter}/bin/lndmon \
|
||||
--prometheus.listenaddr=${cfg.listenAddress}:${toString cfg.port} \
|
||||
--prometheus.logdir=/var/log/prometheus-lnd-exporter \
|
||||
--lnd.host=${cfg.lndHost} \
|
||||
--lnd.tlspath=${cfg.lndTlsPath} \
|
||||
--lnd.macaroondir=${cfg.lndMacaroonDir} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
LogsDirectory = "prometheus-lnd-exporter";
|
||||
ReadOnlyPaths = [ cfg.lndTlsPath cfg.lndMacaroonDir ];
|
||||
};
|
||||
}
|
||||
176
nixos/modules/services/monitoring/prometheus/exporters/mail.nix
Normal file
176
nixos/modules/services/monitoring/prometheus/exporters/mail.nix
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.mail;
|
||||
|
||||
configurationFile = pkgs.writeText "prometheus-mail-exporter.conf" (builtins.toJSON (
|
||||
# removes the _module attribute, null values and converts attrNames to lowercase
|
||||
mapAttrs' (name: value:
|
||||
if name == "servers"
|
||||
then nameValuePair (toLower name)
|
||||
((map (srv: (mapAttrs' (n: v: nameValuePair (toLower n) v)
|
||||
(filterAttrs (n: v: !(n == "_module" || v == null)) srv)
|
||||
))) value)
|
||||
else nameValuePair (toLower name) value
|
||||
) (filterAttrs (n: _: !(n == "_module")) cfg.configuration)
|
||||
));
|
||||
|
||||
serverOptions.options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Value for label 'configname' which will be added to all metrics.
|
||||
'';
|
||||
};
|
||||
server = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Hostname of the server that should be probed.
|
||||
'';
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
example = 587;
|
||||
description = ''
|
||||
Port to use for SMTP.
|
||||
'';
|
||||
};
|
||||
from = mkOption {
|
||||
type = types.str;
|
||||
example = "exporteruser@domain.tld";
|
||||
description = ''
|
||||
Content of 'From' Header for probing mails.
|
||||
'';
|
||||
};
|
||||
to = mkOption {
|
||||
type = types.str;
|
||||
example = "exporteruser@domain.tld";
|
||||
description = ''
|
||||
Content of 'To' Header for probing mails.
|
||||
'';
|
||||
};
|
||||
detectionDir = mkOption {
|
||||
type = types.path;
|
||||
example = "/var/spool/mail/exporteruser/new";
|
||||
description = ''
|
||||
Directory in which new mails for the exporter user are placed.
|
||||
Note that this needs to exist when the exporter starts.
|
||||
'';
|
||||
};
|
||||
login = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "exporteruser@domain.tld";
|
||||
description = ''
|
||||
Username to use for SMTP authentication.
|
||||
'';
|
||||
};
|
||||
passphrase = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Password to use for SMTP authentication.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
exporterOptions.options = {
|
||||
monitoringInterval = mkOption {
|
||||
type = types.str;
|
||||
example = "10s";
|
||||
description = ''
|
||||
Time interval between two probe attempts.
|
||||
'';
|
||||
};
|
||||
mailCheckTimeout = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Timeout until mails are considered "didn't make it".
|
||||
'';
|
||||
};
|
||||
disableFileDeletion = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Disables the exporter's function to delete probing mails.
|
||||
'';
|
||||
};
|
||||
servers = mkOption {
|
||||
type = types.listOf (types.submodule serverOptions);
|
||||
default = [];
|
||||
example = literalExpression ''
|
||||
[ {
|
||||
name = "testserver";
|
||||
server = "smtp.domain.tld";
|
||||
port = 587;
|
||||
from = "exporteruser@domain.tld";
|
||||
to = "exporteruser@domain.tld";
|
||||
detectionDir = "/path/to/Maildir/new";
|
||||
} ]
|
||||
'';
|
||||
description = ''
|
||||
List of servers that should be probed.
|
||||
|
||||
<emphasis>Note:</emphasis> if your mailserver has <citerefentry>
|
||||
<refentrytitle>rspamd</refentrytitle><manvolnum>8</manvolnum></citerefentry> configured,
|
||||
it can happen that emails from this exporter are marked as spam.
|
||||
|
||||
It's possible to work around the issue with a config like this:
|
||||
<programlisting>
|
||||
{
|
||||
<link linkend="opt-services.rspamd.locals._name_.text">services.rspamd.locals."multimap.conf".text</link> = '''
|
||||
ALLOWLIST_PROMETHEUS {
|
||||
filter = "email:domain:tld";
|
||||
type = "from";
|
||||
map = "''${pkgs.writeText "allowmap" "domain.tld"}";
|
||||
score = -100.0;
|
||||
}
|
||||
''';
|
||||
}
|
||||
</programlisting>
|
||||
'';
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
port = 9225;
|
||||
extraOpts = {
|
||||
configFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Specify the mailexporter configuration file to use.
|
||||
'';
|
||||
};
|
||||
configuration = mkOption {
|
||||
type = types.nullOr (types.submodule exporterOptions);
|
||||
default = null;
|
||||
description = ''
|
||||
Specify the mailexporter configuration file to use.
|
||||
'';
|
||||
};
|
||||
telemetryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
DynamicUser = false;
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-mail-exporter}/bin/mailexporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--web.telemetry-path ${cfg.telemetryPath} \
|
||||
--config.file ${
|
||||
if cfg.configuration != null then configurationFile else (escapeShellArg cfg.configFile)
|
||||
} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.mikrotik;
|
||||
in
|
||||
{
|
||||
port = 9436;
|
||||
extraOpts = {
|
||||
configFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to a mikrotik exporter configuration file. Mutually exclusive with
|
||||
<option>configuration</option> option.
|
||||
'';
|
||||
example = literalExpression "./mikrotik.yml";
|
||||
};
|
||||
|
||||
configuration = mkOption {
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
description = ''
|
||||
Mikrotik exporter configuration as nix attribute set. Mutually exclusive with
|
||||
<option>configFile</option> option.
|
||||
|
||||
See <link xlink:href="https://github.com/nshttpd/mikrotik-exporter/blob/master/README.md"/>
|
||||
for the description of the configuration file format.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
devices = [
|
||||
{
|
||||
name = "my_router";
|
||||
address = "10.10.0.1";
|
||||
user = "prometheus";
|
||||
password = "changeme";
|
||||
}
|
||||
];
|
||||
features = {
|
||||
bgp = true;
|
||||
dhcp = true;
|
||||
routes = true;
|
||||
optics = true;
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = let
|
||||
configFile = if cfg.configFile != null
|
||||
then cfg.configFile
|
||||
else "${pkgs.writeText "mikrotik-exporter.yml" (builtins.toJSON cfg.configuration)}";
|
||||
in {
|
||||
serviceConfig = {
|
||||
# -port is misleading name, it actually accepts address too
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-mikrotik-exporter}/bin/mikrotik-exporter \
|
||||
-config-file=${escapeShellArg configFile} \
|
||||
-port=${cfg.listenAddress}:${toString cfg.port} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.minio;
|
||||
in
|
||||
{
|
||||
port = 9290;
|
||||
extraOpts = {
|
||||
minioAddress = mkOption {
|
||||
type = types.str;
|
||||
example = "https://10.0.0.1:9000";
|
||||
description = ''
|
||||
The URL of the minio server.
|
||||
Use HTTPS if Minio accepts secure connections only.
|
||||
By default this connects to the local minio server if enabled.
|
||||
'';
|
||||
};
|
||||
|
||||
minioAccessKey = mkOption {
|
||||
type = types.str;
|
||||
example = "yourMinioAccessKey";
|
||||
description = ''
|
||||
The value of the Minio access key.
|
||||
It is required in order to connect to the server.
|
||||
By default this uses the one from the local minio server if enabled
|
||||
and <literal>config.services.minio.accessKey</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
minioAccessSecret = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
The value of the Minio access secret.
|
||||
It is required in order to connect to the server.
|
||||
By default this uses the one from the local minio server if enabled
|
||||
and <literal>config.services.minio.secretKey</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
minioBucketStats = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Collect statistics about the buckets and files in buckets.
|
||||
It requires more computation, use it carefully in case of large buckets..
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-minio-exporter}/bin/minio-exporter \
|
||||
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
-minio.server ${cfg.minioAddress} \
|
||||
-minio.access-key ${escapeShellArg cfg.minioAccessKey} \
|
||||
-minio.access-secret ${escapeShellArg cfg.minioAccessSecret} \
|
||||
${optionalString cfg.minioBucketStats "-minio.bucket-stats"} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.modemmanager;
|
||||
in
|
||||
{
|
||||
port = 9539;
|
||||
extraOpts = {
|
||||
refreshRate = mkOption {
|
||||
type = types.str;
|
||||
default = "5s";
|
||||
description = ''
|
||||
How frequently ModemManager will refresh the extended signal quality
|
||||
information for each modem. The duration should be specified in seconds
|
||||
("5s"), minutes ("1m"), or hours ("1h").
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
# Required in order to authenticate with ModemManager via D-Bus.
|
||||
SupplementaryGroups = "networkmanager";
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-modemmanager-exporter}/bin/modemmanager_exporter \
|
||||
-addr ${cfg.listenAddress}:${toString cfg.port} \
|
||||
-rate ${cfg.refreshRate} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_UNIX to collect data
|
||||
"AF_UNIX"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.nextcloud;
|
||||
in
|
||||
{
|
||||
port = 9205;
|
||||
extraOpts = {
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
example = "https://domain.tld";
|
||||
description = ''
|
||||
URL to the Nextcloud serverinfo page.
|
||||
Adding the path to the serverinfo API is optional, it defaults
|
||||
to <literal>/ocs/v2.php/apps/serverinfo/api/v1/info</literal>.
|
||||
'';
|
||||
};
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
default = "nextcloud-exporter";
|
||||
description = ''
|
||||
Username for connecting to Nextcloud.
|
||||
Note that this account needs to have admin privileges in Nextcloud.
|
||||
'';
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/path/to/password-file";
|
||||
description = ''
|
||||
File containing the password for connecting to Nextcloud.
|
||||
Make sure that this file is readable by the exporter user.
|
||||
'';
|
||||
};
|
||||
timeout = mkOption {
|
||||
type = types.str;
|
||||
default = "5s";
|
||||
description = ''
|
||||
Timeout for getting server info document.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
DynamicUser = false;
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-nextcloud-exporter}/bin/nextcloud-exporter \
|
||||
--addr ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--username ${cfg.username} \
|
||||
--timeout ${cfg.timeout} \
|
||||
--server ${cfg.url} \
|
||||
--password ${escapeShellArg "@${cfg.passwordFile}"} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.nginx;
|
||||
in
|
||||
{
|
||||
port = 9113;
|
||||
extraOpts = {
|
||||
scrapeUri = mkOption {
|
||||
type = types.str;
|
||||
default = "http://localhost/nginx_status";
|
||||
description = ''
|
||||
Address to access the nginx status page.
|
||||
Can be enabled with services.nginx.statusPage = true.
|
||||
'';
|
||||
};
|
||||
telemetryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
sslVerify = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to perform certificate verification for https.
|
||||
'';
|
||||
};
|
||||
constLabels = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [
|
||||
"label1=value1"
|
||||
"label2=value2"
|
||||
];
|
||||
description = ''
|
||||
A list of constant labels that will be used in every metric.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = mkMerge ([{
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-nginx-exporter}/bin/nginx-prometheus-exporter \
|
||||
--nginx.scrape-uri='${cfg.scrapeUri}' \
|
||||
--nginx.ssl-verify=${boolToString cfg.sslVerify} \
|
||||
--web.listen-address=${cfg.listenAddress}:${toString cfg.port} \
|
||||
--web.telemetry-path=${cfg.telemetryPath} \
|
||||
--prometheus.const-labels=${concatStringsSep "," cfg.constLabels} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
}] ++ [(mkIf config.services.nginx.enable {
|
||||
after = [ "nginx.service" ];
|
||||
requires = [ "nginx.service" ];
|
||||
})]);
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "telemetryEndpoint" ] [ "telemetryPath" ])
|
||||
(mkRemovedOptionModule [ "insecure" ] ''
|
||||
This option was replaced by 'prometheus.exporters.nginx.sslVerify'.
|
||||
'')
|
||||
({ options.warnings = options.warnings; options.assertions = options.assertions; })
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.nginxlog;
|
||||
in {
|
||||
port = 9117;
|
||||
extraOpts = {
|
||||
settings = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = ''
|
||||
All settings of nginxlog expressed as an Nix attrset.
|
||||
|
||||
Check the official documentation for the corresponding YAML
|
||||
settings that can all be used here: https://github.com/martin-helmich/prometheus-nginxlog-exporter
|
||||
|
||||
The `listen` object is already generated by `port`, `listenAddress` and `metricsEndpoint` and
|
||||
will be merged with the value of `settings` before writting it as JSON.
|
||||
'';
|
||||
};
|
||||
|
||||
metricsEndpoint = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
serviceOpts = let
|
||||
listenConfig = {
|
||||
listen = {
|
||||
port = cfg.port;
|
||||
address = cfg.listenAddress;
|
||||
metrics_endpoint = cfg.metricsEndpoint;
|
||||
};
|
||||
};
|
||||
completeConfig = pkgs.writeText "nginxlog-exporter.yaml" (builtins.toJSON (lib.recursiveUpdate listenConfig cfg.settings));
|
||||
in {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-nginxlog-exporter}/bin/prometheus-nginxlog-exporter -config-file ${completeConfig}
|
||||
'';
|
||||
Restart="always";
|
||||
ProtectSystem="full";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.node;
|
||||
in
|
||||
{
|
||||
port = 9100;
|
||||
extraOpts = {
|
||||
enabledCollectors = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "systemd" ];
|
||||
description = ''
|
||||
Collectors to enable. The collectors listed here are enabled in addition to the default ones.
|
||||
'';
|
||||
};
|
||||
disabledCollectors = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "timex" ];
|
||||
description = ''
|
||||
Collectors to disable which are enabled by default.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
DynamicUser = false;
|
||||
RuntimeDirectory = "prometheus-node-exporter";
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-node-exporter}/bin/node_exporter \
|
||||
${concatMapStringsSep " " (x: "--collector." + x) cfg.enabledCollectors} \
|
||||
${concatMapStringsSep " " (x: "--no-collector." + x) cfg.disabledCollectors} \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} ${concatStringsSep " " cfg.extraFlags}
|
||||
'';
|
||||
RestrictAddressFamilies = optionals (any (collector: (collector == "logind" || collector == "systemd")) cfg.enabledCollectors) [
|
||||
# needs access to dbus via unix sockets (logind/systemd)
|
||||
"AF_UNIX"
|
||||
] ++ optionals (any (collector: (collector == "network_route" || collector == "wifi")) cfg.enabledCollectors) [
|
||||
# needs netlink sockets for wireless collector
|
||||
"AF_NETLINK"
|
||||
];
|
||||
# The timex collector needs to access clock APIs
|
||||
ProtectClock = any (collector: collector == "timex") cfg.disabledCollectors;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.openldap;
|
||||
in {
|
||||
port = 9330;
|
||||
extraOpts = {
|
||||
ldapCredentialFile = mkOption {
|
||||
type = types.path;
|
||||
example = "/run/keys/ldap_pass";
|
||||
description = ''
|
||||
Environment file to contain the credentials to authenticate against
|
||||
<package>openldap</package>.
|
||||
|
||||
The file should look like this:
|
||||
<programlisting>
|
||||
---
|
||||
ldapUser: "cn=monitoring,cn=Monitor"
|
||||
ldapPass: "secret"
|
||||
</programlisting>
|
||||
'';
|
||||
};
|
||||
protocol = mkOption {
|
||||
default = "tcp";
|
||||
example = "udp";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Which protocol to use to connect against <package>openldap</package>.
|
||||
'';
|
||||
};
|
||||
ldapAddr = mkOption {
|
||||
default = "localhost:389";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Address of the <package>openldap</package>-instance.
|
||||
'';
|
||||
};
|
||||
metricsPath = mkOption {
|
||||
default = "/metrics";
|
||||
type = types.str;
|
||||
description = ''
|
||||
URL path where metrics should be exposed.
|
||||
'';
|
||||
};
|
||||
interval = mkOption {
|
||||
default = "30s";
|
||||
type = types.str;
|
||||
example = "1m";
|
||||
description = ''
|
||||
Scrape interval of the exporter.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts.serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-openldap-exporter}/bin/openldap_exporter \
|
||||
--promAddr ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--metrPath ${cfg.metricsPath} \
|
||||
--ldapNet ${cfg.protocol} \
|
||||
--interval ${cfg.interval} \
|
||||
--config ${cfg.ldapCredentialFile} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.openvpn;
|
||||
in {
|
||||
port = 9176;
|
||||
extraOpts = {
|
||||
statusPaths = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
Paths to OpenVPN status files. Please configure the OpenVPN option
|
||||
<literal>status</literal> accordingly.
|
||||
'';
|
||||
};
|
||||
telemetryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
PrivateDevices = true;
|
||||
ProtectKernelModules = true;
|
||||
NoNewPrivileges = true;
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-openvpn-exporter}/bin/openvpn_exporter \
|
||||
-openvpn.status_paths "${concatStringsSep "," cfg.statusPaths}" \
|
||||
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
-web.telemetry-path ${cfg.telemetryPath}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.pihole;
|
||||
in
|
||||
{
|
||||
port = 9617;
|
||||
extraOpts = {
|
||||
apiToken = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "580a770cb40511eb85290242ac130003580a770cb40511eb85290242ac130003";
|
||||
description = ''
|
||||
pi-hole API token which can be used instead of a password
|
||||
'';
|
||||
};
|
||||
interval = mkOption {
|
||||
type = types.str;
|
||||
default = "10s";
|
||||
example = "30s";
|
||||
description = ''
|
||||
How often to scrape new data
|
||||
'';
|
||||
};
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "password";
|
||||
description = ''
|
||||
The password to login into pihole. An api token can be used instead.
|
||||
'';
|
||||
};
|
||||
piholeHostname = mkOption {
|
||||
type = types.str;
|
||||
default = "pihole";
|
||||
example = "127.0.0.1";
|
||||
description = ''
|
||||
Hostname or address where to find the pihole webinterface
|
||||
'';
|
||||
};
|
||||
piholePort = mkOption {
|
||||
type = types.port;
|
||||
default = 80;
|
||||
example = 443;
|
||||
description = ''
|
||||
The port pihole webinterface is reachable on
|
||||
'';
|
||||
};
|
||||
protocol = mkOption {
|
||||
type = types.enum [ "http" "https" ];
|
||||
default = "http";
|
||||
example = "https";
|
||||
description = ''
|
||||
The protocol which is used to connect to pihole
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.bash}/bin/bash -c "${pkgs.prometheus-pihole-exporter}/bin/pihole-exporter \
|
||||
-interval ${cfg.interval} \
|
||||
${optionalString (cfg.apiToken != "") "-pihole_api_token ${cfg.apiToken}"} \
|
||||
-pihole_hostname ${cfg.piholeHostname} \
|
||||
${optionalString (cfg.password != "") "-pihole_password ${cfg.password}"} \
|
||||
-pihole_port ${toString cfg.piholePort} \
|
||||
-pihole_protocol ${cfg.protocol} \
|
||||
-port ${toString cfg.port}"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.postfix;
|
||||
in
|
||||
{
|
||||
port = 9154;
|
||||
extraOpts = {
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Group under which the postfix exporter shall be run.
|
||||
It should match the group that is allowed to access the
|
||||
<literal>showq</literal> socket in the <literal>queue/public/</literal> directory.
|
||||
Defaults to <literal>services.postfix.setgidGroup</literal> when postfix is enabled.
|
||||
'';
|
||||
};
|
||||
telemetryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
logfilePath = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/log/postfix_exporter_input.log";
|
||||
example = "/var/log/mail.log";
|
||||
description = ''
|
||||
Path where Postfix writes log entries.
|
||||
This file will be truncated by this exporter!
|
||||
'';
|
||||
};
|
||||
showqPath = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/postfix/queue/public/showq";
|
||||
example = "/var/spool/postfix/public/showq";
|
||||
description = ''
|
||||
Path where Postfix places its showq socket.
|
||||
'';
|
||||
};
|
||||
systemd = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable reading metrics from the systemd journal instead of from a logfile
|
||||
'';
|
||||
};
|
||||
unit = mkOption {
|
||||
type = types.str;
|
||||
default = "postfix.service";
|
||||
description = ''
|
||||
Name of the postfix systemd unit.
|
||||
'';
|
||||
};
|
||||
slice = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Name of the postfix systemd slice.
|
||||
This overrides the <option>systemd.unit</option>.
|
||||
'';
|
||||
};
|
||||
journalPath = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the systemd journal.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
DynamicUser = false;
|
||||
# By default, each prometheus exporter only gets AF_INET & AF_INET6,
|
||||
# but AF_UNIX is needed to read from the `showq`-socket.
|
||||
RestrictAddressFamilies = [ "AF_UNIX" ];
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--web.telemetry-path ${cfg.telemetryPath} \
|
||||
--postfix.showq_path ${escapeShellArg cfg.showqPath} \
|
||||
${concatStringsSep " \\\n " (cfg.extraFlags
|
||||
++ optional cfg.systemd.enable "--systemd.enable"
|
||||
++ optional cfg.systemd.enable (if cfg.systemd.slice != null
|
||||
then "--systemd.slice ${cfg.systemd.slice}"
|
||||
else "--systemd.unit ${cfg.systemd.unit}")
|
||||
++ optional (cfg.systemd.enable && (cfg.systemd.journalPath != null))
|
||||
"--systemd.journal_path ${escapeShellArg cfg.systemd.journalPath}"
|
||||
++ optional (!cfg.systemd.enable) "--postfix.logfile_path ${escapeShellArg cfg.logfilePath}")}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.postgres;
|
||||
in
|
||||
{
|
||||
port = 9187;
|
||||
extraOpts = {
|
||||
telemetryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
dataSourceName = mkOption {
|
||||
type = types.str;
|
||||
default = "user=postgres database=postgres host=/run/postgresql sslmode=disable";
|
||||
example = "postgresql://username:password@localhost:5432/postgres?sslmode=disable";
|
||||
description = ''
|
||||
Accepts PostgreSQL URI form and key=value form arguments.
|
||||
'';
|
||||
};
|
||||
runAsLocalSuperUser = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to run the exporter as the local 'postgres' super user.
|
||||
'';
|
||||
};
|
||||
|
||||
# TODO perhaps LoadCredential would be more appropriate
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/root/prometheus-postgres-exporter.env";
|
||||
description = ''
|
||||
Environment file as defined in <citerefentry>
|
||||
<refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum>
|
||||
</citerefentry>.
|
||||
|
||||
Secrets may be passed to the service without adding them to the
|
||||
world-readable Nix store, by specifying placeholder variables as
|
||||
the option value in Nix and setting these variables accordingly in the
|
||||
environment file.
|
||||
|
||||
Environment variables from this file will be interpolated into the
|
||||
config file using envsubst with this syntax:
|
||||
<literal>$ENVIRONMENT ''${VARIABLE}</literal>
|
||||
|
||||
The main use is to set the DATA_SOURCE_NAME that contains the
|
||||
postgres password
|
||||
|
||||
note that contents from this file will override dataSourceName
|
||||
if you have set it from nix.
|
||||
|
||||
<programlisting>
|
||||
# Content of the environment file
|
||||
DATA_SOURCE_NAME=postgresql://username:password@localhost:5432/postgres?sslmode=disable
|
||||
</programlisting>
|
||||
|
||||
Note that this file needs to be available on the host on which
|
||||
this exporter is running.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
serviceOpts = {
|
||||
environment.DATA_SOURCE_NAME = cfg.dataSourceName;
|
||||
serviceConfig = {
|
||||
DynamicUser = false;
|
||||
User = mkIf cfg.runAsLocalSuperUser (mkForce "postgres");
|
||||
EnvironmentFile = mkIf (cfg.environmentFile != null) [ cfg.environmentFile ];
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-postgres-exporter}/bin/postgres_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--web.telemetry-path ${cfg.telemetryPath} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_UNIX to collect data
|
||||
"AF_UNIX"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.process;
|
||||
configFile = pkgs.writeText "process-exporter.yaml" (builtins.toJSON cfg.settings);
|
||||
in
|
||||
{
|
||||
port = 9256;
|
||||
extraOpts = {
|
||||
settings.process_names = mkOption {
|
||||
type = types.listOf types.anything;
|
||||
default = [];
|
||||
example = literalExpression ''
|
||||
[
|
||||
# Remove nix store path from process name
|
||||
{ name = "{{.Matches.Wrapped}} {{ .Matches.Args }}"; cmdline = [ "^/nix/store[^ ]*/(?P<Wrapped>[^ /]*) (?P<Args>.*)" ]; }
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
All settings expressed as an Nix attrset.
|
||||
|
||||
Check the official documentation for the corresponding YAML
|
||||
settings that can all be used here: <link xlink:href="https://github.com/ncabatoff/process-exporter" />
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
DynamicUser = false;
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-process-exporter}/bin/process-exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--config.path ${configFile} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
NoNewPrivileges = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
118
nixos/modules/services/monitoring/prometheus/exporters/pve.nix
Normal file
118
nixos/modules/services/monitoring/prometheus/exporters/pve.nix
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.pve;
|
||||
|
||||
# pve exporter requires a config file so create an empty one if configFile is not provided
|
||||
emptyConfigFile = pkgs.writeTextFile {
|
||||
name = "pve.yml";
|
||||
text = "default:";
|
||||
};
|
||||
|
||||
computedConfigFile = "${if cfg.configFile == null then emptyConfigFile else cfg.configFile}";
|
||||
in
|
||||
{
|
||||
port = 9221;
|
||||
extraOpts = {
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.prometheus-pve-exporter;
|
||||
defaultText = literalExpression "pkgs.prometheus-pve-exporter";
|
||||
example = literalExpression "pkgs.prometheus-pve-exporter";
|
||||
description = ''
|
||||
The package to use for prometheus-pve-exporter
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
example = "/etc/prometheus-pve-exporter/pve.env";
|
||||
description = ''
|
||||
Path to the service's environment file. This path can either be a computed path in /nix/store or a path in the local filesystem.
|
||||
|
||||
The environment file should NOT be stored in /nix/store as it contains passwords and/or keys in plain text.
|
||||
|
||||
Environment reference: https://github.com/prometheus-pve/prometheus-pve-exporter#authentication
|
||||
'';
|
||||
};
|
||||
|
||||
configFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
example = "/etc/prometheus-pve-exporter/pve.yml";
|
||||
description = ''
|
||||
Path to the service's config file. This path can either be a computed path in /nix/store or a path in the local filesystem.
|
||||
|
||||
The config file should NOT be stored in /nix/store as it will contain passwords and/or keys in plain text.
|
||||
|
||||
If both configFile and environmentFile are provided, the configFile option will be ignored.
|
||||
|
||||
Configuration reference: https://github.com/prometheus-pve/prometheus-pve-exporter/#authentication
|
||||
'';
|
||||
};
|
||||
|
||||
collectors = {
|
||||
status = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Collect Node/VM/CT status
|
||||
'';
|
||||
};
|
||||
version = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Collect PVE version info
|
||||
'';
|
||||
};
|
||||
node = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Collect PVE node info
|
||||
'';
|
||||
};
|
||||
cluster = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Collect PVE cluster info
|
||||
'';
|
||||
};
|
||||
resources = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Collect PVE resources info
|
||||
'';
|
||||
};
|
||||
config = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Collect PVE onboot status
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/pve_exporter \
|
||||
--${if cfg.collectors.status == true then "" else "no-"}collector.status \
|
||||
--${if cfg.collectors.version == true then "" else "no-"}collector.version \
|
||||
--${if cfg.collectors.node == true then "" else "no-"}collector.node \
|
||||
--${if cfg.collectors.cluster == true then "" else "no-"}collector.cluster \
|
||||
--${if cfg.collectors.resources == true then "" else "no-"}collector.resources \
|
||||
--${if cfg.collectors.config == true then "" else "no-"}collector.config \
|
||||
${computedConfigFile} \
|
||||
${toString cfg.port} ${cfg.listenAddress}
|
||||
'';
|
||||
} // optionalAttrs (cfg.environmentFile != null) {
|
||||
EnvironmentFile = cfg.environmentFile;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.py-air-control;
|
||||
|
||||
workingDir = "/var/lib/${cfg.stateDir}";
|
||||
|
||||
in
|
||||
{
|
||||
port = 9896;
|
||||
extraOpts = {
|
||||
deviceHostname = mkOption {
|
||||
type = types.str;
|
||||
example = "192.168.1.123";
|
||||
description = ''
|
||||
The hostname of the air purification device from which to scrape the metrics.
|
||||
'';
|
||||
};
|
||||
protocol = mkOption {
|
||||
type = types.str;
|
||||
default = "http";
|
||||
description = ''
|
||||
The protocol to use when communicating with the air purification device.
|
||||
Available: [http, coap, plain_coap]
|
||||
'';
|
||||
};
|
||||
stateDir = mkOption {
|
||||
type = types.str;
|
||||
default = "prometheus-py-air-control-exporter";
|
||||
description = ''
|
||||
Directory below <literal>/var/lib</literal> to store runtime data.
|
||||
This directory will be created automatically using systemd's StateDirectory mechanism.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
DynamicUser = false;
|
||||
StateDirectory = cfg.stateDir;
|
||||
WorkingDirectory = workingDir;
|
||||
ExecStart = ''
|
||||
${pkgs.python3Packages.py-air-control-exporter}/bin/py-air-control-exporter \
|
||||
--host ${cfg.deviceHostname} \
|
||||
--protocol ${cfg.protocol} \
|
||||
--listen-port ${toString cfg.port} \
|
||||
--listen-address ${cfg.listenAddress}
|
||||
'';
|
||||
Environment = [ "HOME=${workingDir}" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.redis;
|
||||
in
|
||||
{
|
||||
port = 9121;
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-redis-exporter}/bin/redis_exporter \
|
||||
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.rspamd;
|
||||
|
||||
mkFile = conf:
|
||||
pkgs.writeText "rspamd-exporter-config.yml" (builtins.toJSON conf);
|
||||
|
||||
generateConfig = extraLabels: {
|
||||
metrics = (map (path: {
|
||||
name = "rspamd_${replaceStrings [ "[" "." " " "]" "\\" "'" ] [ "_" "_" "_" "" "" "" ] path}";
|
||||
path = "{ .${path} }";
|
||||
labels = extraLabels;
|
||||
}) [
|
||||
"actions['add\\ header']"
|
||||
"actions['no\\ action']"
|
||||
"actions['rewrite\\ subject']"
|
||||
"actions['soft\\ reject']"
|
||||
"actions.greylist"
|
||||
"actions.reject"
|
||||
"bytes_allocated"
|
||||
"chunks_allocated"
|
||||
"chunks_freed"
|
||||
"chunks_oversized"
|
||||
"connections"
|
||||
"control_connections"
|
||||
"ham_count"
|
||||
"learned"
|
||||
"pools_allocated"
|
||||
"pools_freed"
|
||||
"read_only"
|
||||
"scanned"
|
||||
"shared_chunks_allocated"
|
||||
"spam_count"
|
||||
"total_learns"
|
||||
]) ++ [{
|
||||
name = "rspamd_statfiles";
|
||||
type = "object";
|
||||
path = "{.statfiles[*]}";
|
||||
labels = recursiveUpdate {
|
||||
symbol = "{.symbol}";
|
||||
type = "{.type}";
|
||||
} extraLabels;
|
||||
values = {
|
||||
revision = "{.revision}";
|
||||
size = "{.size}";
|
||||
total = "{.total}";
|
||||
used = "{.used}";
|
||||
languages = "{.languages}";
|
||||
users = "{.users}";
|
||||
};
|
||||
}];
|
||||
};
|
||||
in
|
||||
{
|
||||
port = 7980;
|
||||
extraOpts = {
|
||||
extraLabels = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {
|
||||
host = config.networking.hostName;
|
||||
};
|
||||
defaultText = literalExpression "{ host = config.networking.hostName; }";
|
||||
example = literalExpression ''
|
||||
{
|
||||
host = config.networking.hostName;
|
||||
custom_label = "some_value";
|
||||
}
|
||||
'';
|
||||
description = "Set of labels added to each metric.";
|
||||
};
|
||||
};
|
||||
serviceOpts.serviceConfig.ExecStart = ''
|
||||
${pkgs.prometheus-json-exporter}/bin/json_exporter \
|
||||
--config.file ${mkFile (generateConfig cfg.extraLabels)} \
|
||||
--web.listen-address "${cfg.listenAddress}:${toString cfg.port}" \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "url" ] ''
|
||||
This option was removed. The URL of the rspamd metrics endpoint
|
||||
must now be provided to the exporter by prometheus via the url
|
||||
parameter `target'.
|
||||
|
||||
In prometheus a scrape URL would look like this:
|
||||
|
||||
http://some.rspamd-exporter.host:7980/probe?target=http://some.rspamd.host:11334/stat
|
||||
|
||||
For more information, take a look at the official documentation
|
||||
(https://github.com/prometheus-community/json_exporter) of the json_exporter.
|
||||
'')
|
||||
({ options.warnings = options.warnings; options.assertions = options.assertions; })
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.rtl_433;
|
||||
in
|
||||
{
|
||||
port = 9550;
|
||||
|
||||
extraOpts = let
|
||||
mkMatcherOptionType = field: description: with lib.types;
|
||||
listOf (submodule {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = str;
|
||||
description = "Name to match.";
|
||||
};
|
||||
"${field}" = lib.mkOption {
|
||||
type = int;
|
||||
inherit description;
|
||||
};
|
||||
location = lib.mkOption {
|
||||
type = str;
|
||||
description = "Location to match.";
|
||||
};
|
||||
};
|
||||
});
|
||||
in
|
||||
{
|
||||
rtl433Flags = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "-C si";
|
||||
example = "-C si -R 19";
|
||||
description = ''
|
||||
Flags passed verbatim to rtl_433 binary.
|
||||
Having <literal>-C si</literal> (the default) is recommended since only Celsius temperatures are parsed.
|
||||
'';
|
||||
};
|
||||
channels = lib.mkOption {
|
||||
type = mkMatcherOptionType "channel" "Channel to match.";
|
||||
default = [];
|
||||
example = [
|
||||
{ name = "Acurite"; channel = 6543; location = "Kitchen"; }
|
||||
];
|
||||
description = ''
|
||||
List of channel matchers to export.
|
||||
'';
|
||||
};
|
||||
ids = lib.mkOption {
|
||||
type = mkMatcherOptionType "id" "ID to match.";
|
||||
default = [];
|
||||
example = [
|
||||
{ name = "Nexus"; id = 1; location = "Bedroom"; }
|
||||
];
|
||||
description = ''
|
||||
List of ID matchers to export.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
# rtl-sdr udev rules make supported USB devices +rw by plugdev.
|
||||
SupplementaryGroups = "plugdev";
|
||||
# rtl_433 needs rw access to the USB radio.
|
||||
PrivateDevices = lib.mkForce false;
|
||||
DeviceAllow = lib.mkForce "char-usb_device rw";
|
||||
RestrictAddressFamilies = [ "AF_NETLINK" ];
|
||||
|
||||
ExecStart = let
|
||||
matchers = (map (m:
|
||||
"--channel_matcher '${m.name},${toString m.channel},${m.location}'"
|
||||
) cfg.channels) ++ (map (m:
|
||||
"--id_matcher '${m.name},${toString m.id},${m.location}'"
|
||||
) cfg.ids); in ''
|
||||
${pkgs.prometheus-rtl_433-exporter}/bin/rtl_433_prometheus \
|
||||
-listen ${cfg.listenAddress}:${toString cfg.port} \
|
||||
-subprocess "${pkgs.rtl_433}/bin/rtl_433 -F json ${cfg.rtl433Flags}" \
|
||||
${lib.concatStringsSep " \\\n " matchers} \
|
||||
${lib.concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.script;
|
||||
configFile = pkgs.writeText "script-exporter.yaml" (builtins.toJSON cfg.settings);
|
||||
in
|
||||
{
|
||||
port = 9172;
|
||||
extraOpts = {
|
||||
settings.scripts = mkOption {
|
||||
type = with types; listOf (submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = str;
|
||||
example = "sleep";
|
||||
description = "Name of the script.";
|
||||
};
|
||||
script = mkOption {
|
||||
type = str;
|
||||
example = "sleep 5";
|
||||
description = "Shell script to execute when metrics are requested.";
|
||||
};
|
||||
timeout = mkOption {
|
||||
type = nullOr int;
|
||||
default = null;
|
||||
example = 60;
|
||||
description = "Optional timeout for the script in seconds.";
|
||||
};
|
||||
};
|
||||
});
|
||||
example = literalExpression ''
|
||||
{
|
||||
scripts = [
|
||||
{ name = "sleep"; script = "sleep 5"; }
|
||||
];
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
All settings expressed as an Nix attrset.
|
||||
|
||||
Check the official documentation for the corresponding YAML
|
||||
settings that can all be used here: <link xlink:href="https://github.com/adhocteam/script_exporter#sample-configuration" />
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-script-exporter}/bin/script_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--config.file ${configFile} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
NoNewPrivileges = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.smartctl;
|
||||
format = pkgs.formats.yaml {};
|
||||
configFile = format.generate "smartctl-exporter.yml" {
|
||||
smartctl_exporter = {
|
||||
bind_to = "${cfg.listenAddress}:${toString cfg.port}";
|
||||
url_path = "/metrics";
|
||||
smartctl_location = "${pkgs.smartmontools}/bin/smartctl";
|
||||
collect_not_more_than_period = cfg.maxInterval;
|
||||
devices = cfg.devices;
|
||||
};
|
||||
};
|
||||
in {
|
||||
port = 9633;
|
||||
|
||||
extraOpts = {
|
||||
devices = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = literalExpression ''
|
||||
[ "/dev/sda", "/dev/nvme0n1" ];
|
||||
'';
|
||||
description = ''
|
||||
Paths to the disks that will be monitored. Will autodiscover
|
||||
all disks if none given.
|
||||
'';
|
||||
};
|
||||
maxInterval = mkOption {
|
||||
type = types.str;
|
||||
default = "60s";
|
||||
example = "2m";
|
||||
description = ''
|
||||
Interval that limits how often a disk can be queried.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
AmbientCapabilities = [
|
||||
"CAP_SYS_RAWIO"
|
||||
"CAP_SYS_ADMIN"
|
||||
];
|
||||
CapabilityBoundingSet = [
|
||||
"CAP_SYS_RAWIO"
|
||||
"CAP_SYS_ADMIN"
|
||||
];
|
||||
DevicePolicy = "closed";
|
||||
DeviceAllow = lib.mkOverride 100 (
|
||||
if cfg.devices != [] then
|
||||
cfg.devices
|
||||
else [
|
||||
"block-blkext rw"
|
||||
"block-sd rw"
|
||||
"char-nvme rw"
|
||||
]
|
||||
);
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-smartctl-exporter}/bin/smartctl_exporter -config ${configFile}
|
||||
'';
|
||||
PrivateDevices = lib.mkForce false;
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "pid";
|
||||
SupplementaryGroups = [ "disk" ];
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@privileged @resources"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.smokeping;
|
||||
goDuration = types.mkOptionType {
|
||||
name = "goDuration";
|
||||
description = "Go duration (https://golang.org/pkg/time/#ParseDuration)";
|
||||
check = x: types.str.check x && builtins.match "(-?[0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+" x != null;
|
||||
inherit (types.str) merge;
|
||||
};
|
||||
in
|
||||
{
|
||||
port = 9374;
|
||||
extraOpts = {
|
||||
telemetryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
pingInterval = mkOption {
|
||||
type = goDuration;
|
||||
default = "1s";
|
||||
description = ''
|
||||
Interval between pings.
|
||||
'';
|
||||
};
|
||||
buckets = mkOption {
|
||||
type = types.commas;
|
||||
default = "5e-05,0.0001,0.0002,0.0004,0.0008,0.0016,0.0032,0.0064,0.0128,0.0256,0.0512,0.1024,0.2048,0.4096,0.8192,1.6384,3.2768,6.5536,13.1072,26.2144";
|
||||
description = ''
|
||||
List of buckets to use for the response duration histogram.
|
||||
'';
|
||||
};
|
||||
hosts = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = ''
|
||||
List of endpoints to probe.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
AmbientCapabilities = [ "CAP_NET_RAW" ];
|
||||
CapabilityBoundingSet = [ "CAP_NET_RAW" ];
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-smokeping-prober}/bin/smokeping_prober \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--web.telemetry-path ${cfg.telemetryPath} \
|
||||
--buckets ${cfg.buckets} \
|
||||
--ping.interval ${cfg.pingInterval} \
|
||||
--privileged \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags} \
|
||||
${concatStringsSep " " cfg.hosts}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.snmp;
|
||||
in
|
||||
{
|
||||
port = 9116;
|
||||
extraOpts = {
|
||||
configurationPath = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to a snmp exporter configuration file. Mutually exclusive with 'configuration' option.
|
||||
'';
|
||||
example = literalExpression "./snmp.yml";
|
||||
};
|
||||
|
||||
configuration = mkOption {
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
description = ''
|
||||
Snmp exporter configuration as nix attribute set. Mutually exclusive with 'configurationPath' option.
|
||||
'';
|
||||
example = {
|
||||
"default" = {
|
||||
"version" = 2;
|
||||
"auth" = {
|
||||
"community" = "public";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
logFormat = mkOption {
|
||||
type = types.enum ["logfmt" "json"];
|
||||
default = "logfmt";
|
||||
description = ''
|
||||
Output format of log messages.
|
||||
'';
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum ["debug" "info" "warn" "error"];
|
||||
default = "info";
|
||||
description = ''
|
||||
Only log messages with the given severity or above.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = let
|
||||
configFile = if cfg.configurationPath != null
|
||||
then cfg.configurationPath
|
||||
else "${pkgs.writeText "snmp-exporter-conf.yml" (builtins.toJSON cfg.configuration)}";
|
||||
in {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-snmp-exporter}/bin/snmp_exporter \
|
||||
--config.file=${escapeShellArg configFile} \
|
||||
--log.format=${escapeShellArg cfg.logFormat} \
|
||||
--log.level=${cfg.logLevel} \
|
||||
--web.listen-address=${cfg.listenAddress}:${toString cfg.port} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
108
nixos/modules/services/monitoring/prometheus/exporters/sql.nix
Normal file
108
nixos/modules/services/monitoring/prometheus/exporters/sql.nix
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.sql;
|
||||
cfgOptions = {
|
||||
options = with types; {
|
||||
jobs = mkOption {
|
||||
type = attrsOf (submodule jobOptions);
|
||||
default = { };
|
||||
description = "An attrset of metrics scraping jobs to run.";
|
||||
};
|
||||
};
|
||||
};
|
||||
jobOptions = {
|
||||
options = with types; {
|
||||
interval = mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
How often to run this job, specified in
|
||||
<link xlink:href="https://golang.org/pkg/time/#ParseDuration">Go duration</link> format.
|
||||
'';
|
||||
};
|
||||
connections = mkOption {
|
||||
type = listOf str;
|
||||
description = "A list of connection strings of the SQL servers to scrape metrics from";
|
||||
};
|
||||
startupSql = mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
description = "A list of SQL statements to execute once after making a connection.";
|
||||
};
|
||||
queries = mkOption {
|
||||
type = attrsOf (submodule queryOptions);
|
||||
description = "SQL queries to run.";
|
||||
};
|
||||
};
|
||||
};
|
||||
queryOptions = {
|
||||
options = with types; {
|
||||
help = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = "A human-readable description of this metric.";
|
||||
};
|
||||
labels = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
description = "A set of columns that will be used as Prometheus labels.";
|
||||
};
|
||||
query = mkOption {
|
||||
type = str;
|
||||
description = "The SQL query to run.";
|
||||
};
|
||||
values = mkOption {
|
||||
type = listOf str;
|
||||
description = "A set of columns that will be used as values of this metric.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
configFile =
|
||||
if cfg.configFile != null
|
||||
then cfg.configFile
|
||||
else
|
||||
let
|
||||
nameInline = mapAttrsToList (k: v: v // { name = k; });
|
||||
renameStartupSql = j: removeAttrs (j // { startup_sql = j.startupSql; }) [ "startupSql" ];
|
||||
configuration = {
|
||||
jobs = map renameStartupSql
|
||||
(nameInline (mapAttrs (k: v: (v // { queries = nameInline v.queries; })) cfg.configuration.jobs));
|
||||
};
|
||||
in
|
||||
builtins.toFile "config.yaml" (builtins.toJSON configuration);
|
||||
in
|
||||
{
|
||||
extraOpts = {
|
||||
configFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to configuration file.
|
||||
'';
|
||||
};
|
||||
configuration = mkOption {
|
||||
type = with types; nullOr (submodule cfgOptions);
|
||||
default = null;
|
||||
description = ''
|
||||
Exporter configuration as nix attribute set. Mutually exclusive with 'configFile' option.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
port = 9237;
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-sql-exporter}/bin/sql_exporter \
|
||||
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
-config.file ${configFile} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_UNIX to collect data
|
||||
"AF_UNIX"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.surfboard;
|
||||
in
|
||||
{
|
||||
port = 9239;
|
||||
extraOpts = {
|
||||
modemAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "192.168.100.1";
|
||||
description = ''
|
||||
The hostname or IP of the cable modem.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
description = "Prometheus exporter for surfboard cable modem";
|
||||
unitConfig.Documentation = "https://github.com/ipstatic/surfboard_exporter";
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-surfboard-exporter}/bin/surfboard_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--modem-address ${cfg.modemAddress} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.services.prometheus.exporters.systemd;
|
||||
|
||||
in {
|
||||
port = 9558;
|
||||
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-systemd-exporter}/bin/systemd_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} ${concatStringsSep " " cfg.extraFlags}
|
||||
'';
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_UNIX to collect data
|
||||
"AF_UNIX"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.tor;
|
||||
in
|
||||
{
|
||||
port = 9130;
|
||||
extraOpts = {
|
||||
torControlAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = ''
|
||||
Tor control IP address or hostname.
|
||||
'';
|
||||
};
|
||||
|
||||
torControlPort = mkOption {
|
||||
type = types.int;
|
||||
default = 9051;
|
||||
description = ''
|
||||
Tor control port.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-tor-exporter}/bin/prometheus-tor-exporter \
|
||||
-b ${cfg.listenAddress} \
|
||||
-p ${toString cfg.port} \
|
||||
-a ${cfg.torControlAddress} \
|
||||
-c ${toString cfg.torControlPort} \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
|
||||
# CPython requires a process to either have $HOME defined or run as a UID
|
||||
# defined in /etc/passwd. The latter is false with DynamicUser, so define a
|
||||
# dummy $HOME. https://bugs.python.org/issue10496
|
||||
environment = { HOME = "/var/empty"; };
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.unbound;
|
||||
in
|
||||
{
|
||||
port = 9167;
|
||||
extraOpts = {
|
||||
fetchType = mkOption {
|
||||
# TODO: add shm when upstream implemented it
|
||||
type = types.enum [ "tcp" "uds" ];
|
||||
default = "uds";
|
||||
description = ''
|
||||
Which methods the exporter uses to get the information from unbound.
|
||||
'';
|
||||
};
|
||||
|
||||
telemetryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
|
||||
controlInterface = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/run/unbound/unbound.socket";
|
||||
description = ''
|
||||
Path to the unbound socket for uds mode or the control interface port for tcp mode.
|
||||
|
||||
Example:
|
||||
uds-mode: /run/unbound/unbound.socket
|
||||
tcp-mode: 127.0.0.1:8953
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
serviceOpts = mkMerge ([{
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-unbound-exporter}/bin/unbound-telemetry \
|
||||
${cfg.fetchType} \
|
||||
--bind ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--path ${cfg.telemetryPath} \
|
||||
${optionalString (cfg.controlInterface != null) "--control-interface ${cfg.controlInterface}"} \
|
||||
${toString cfg.extraFlags}
|
||||
'';
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_UNIX to collect data
|
||||
"AF_UNIX"
|
||||
];
|
||||
};
|
||||
}] ++ [
|
||||
(mkIf config.services.unbound.enable {
|
||||
after = [ "unbound.service" ];
|
||||
requires = [ "unbound.service" ];
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.unifi-poller;
|
||||
|
||||
configFile = pkgs.writeText "prometheus-unifi-poller-exporter.json" (generators.toJSON {} {
|
||||
poller = { inherit (cfg.log) debug quiet; };
|
||||
unifi = { inherit (cfg) controllers; };
|
||||
influxdb.disable = true;
|
||||
prometheus = {
|
||||
http_listen = "${cfg.listenAddress}:${toString cfg.port}";
|
||||
report_errors = cfg.log.prometheusErrors;
|
||||
};
|
||||
});
|
||||
|
||||
in {
|
||||
port = 9130;
|
||||
|
||||
extraOpts = {
|
||||
inherit (options.services.unifi-poller.unifi) controllers;
|
||||
log = {
|
||||
debug = mkEnableOption "debug logging including line numbers, high resolution timestamps, per-device logs.";
|
||||
quiet = mkEnableOption "startup and error logs only.";
|
||||
prometheusErrors = mkEnableOption "emitting errors to prometheus.";
|
||||
};
|
||||
};
|
||||
|
||||
serviceOpts.serviceConfig = {
|
||||
ExecStart = "${pkgs.unifi-poller}/bin/unifi-poller --config ${configFile}";
|
||||
DynamicUser = false;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.unifi;
|
||||
in
|
||||
{
|
||||
port = 9130;
|
||||
extraOpts = {
|
||||
unifiAddress = mkOption {
|
||||
type = types.str;
|
||||
example = "https://10.0.0.1:8443";
|
||||
description = ''
|
||||
URL of the UniFi Controller API.
|
||||
'';
|
||||
};
|
||||
|
||||
unifiInsecure = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If enabled skip the verification of the TLS certificate of the UniFi Controller API.
|
||||
Use with caution.
|
||||
'';
|
||||
};
|
||||
|
||||
unifiUsername = mkOption {
|
||||
type = types.str;
|
||||
example = "ReadOnlyUser";
|
||||
description = ''
|
||||
username for authentication against UniFi Controller API.
|
||||
'';
|
||||
};
|
||||
|
||||
unifiPassword = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Password for authentication against UniFi Controller API.
|
||||
'';
|
||||
};
|
||||
|
||||
unifiTimeout = mkOption {
|
||||
type = types.str;
|
||||
default = "5s";
|
||||
example = "2m";
|
||||
description = ''
|
||||
Timeout including unit for UniFi Controller API requests.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-unifi-exporter}/bin/unifi_exporter \
|
||||
-telemetry.addr ${cfg.listenAddress}:${toString cfg.port} \
|
||||
-unifi.addr ${cfg.unifiAddress} \
|
||||
-unifi.username ${escapeShellArg cfg.unifiUsername} \
|
||||
-unifi.password ${escapeShellArg cfg.unifiPassword} \
|
||||
-unifi.timeout ${cfg.unifiTimeout} \
|
||||
${optionalString cfg.unifiInsecure "-unifi.insecure" } \
|
||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.varnish;
|
||||
in
|
||||
{
|
||||
port = 9131;
|
||||
extraOpts = {
|
||||
noExit = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Do not exit server on Varnish scrape errors.
|
||||
'';
|
||||
};
|
||||
withGoMetrics = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Export go runtime and http handler metrics.
|
||||
'';
|
||||
};
|
||||
verbose = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable verbose logging.
|
||||
'';
|
||||
};
|
||||
raw = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable raw stdout logging without timestamps.
|
||||
'';
|
||||
};
|
||||
varnishStatPath = mkOption {
|
||||
type = types.str;
|
||||
default = "varnishstat";
|
||||
description = ''
|
||||
Path to varnishstat.
|
||||
'';
|
||||
};
|
||||
instance = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = config.services.varnish.stateDir;
|
||||
defaultText = lib.literalExpression "config.services.varnish.stateDir";
|
||||
description = ''
|
||||
varnishstat -n value.
|
||||
'';
|
||||
};
|
||||
healthPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Path under which to expose healthcheck. Disabled unless configured.
|
||||
'';
|
||||
};
|
||||
telemetryPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/metrics";
|
||||
description = ''
|
||||
Path under which to expose metrics.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
path = [ config.services.varnish.package ];
|
||||
serviceConfig = {
|
||||
RestartSec = mkDefault 1;
|
||||
DynamicUser = false;
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-varnish-exporter}/bin/prometheus_varnish_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--web.telemetry-path ${cfg.telemetryPath} \
|
||||
--varnishstat-path ${escapeShellArg cfg.varnishStatPath} \
|
||||
${concatStringsSep " \\\n " (cfg.extraFlags
|
||||
++ optional (cfg.healthPath != null) "--web.health-path ${cfg.healthPath}"
|
||||
++ optional (cfg.instance != null) "-n ${escapeShellArg cfg.instance}"
|
||||
++ optional cfg.noExit "--no-exit"
|
||||
++ optional cfg.withGoMetrics "--with-go-metrics"
|
||||
++ optional cfg.verbose "--verbose"
|
||||
++ optional cfg.raw "--raw")}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
{ config, lib, pkgs, options }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.wireguard;
|
||||
in {
|
||||
port = 9586;
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "addr" ] [ "listenAddress" ])
|
||||
({ options.warnings = options.warnings; options.assertions = options.assertions; })
|
||||
];
|
||||
extraOpts = {
|
||||
verbose = mkEnableOption "Verbose logging mode for prometheus-wireguard-exporter";
|
||||
|
||||
wireguardConfig = mkOption {
|
||||
type = with types; nullOr (either path str);
|
||||
default = null;
|
||||
|
||||
description = ''
|
||||
Path to the Wireguard Config to
|
||||
<link xlink:href="https://github.com/MindFlavor/prometheus_wireguard_exporter/tree/2.0.0#usage">add the peer's name to the stats of a peer</link>.
|
||||
|
||||
Please note that <literal>networking.wg-quick</literal> is required for this feature
|
||||
as <literal>networking.wireguard</literal> uses
|
||||
<citerefentry><refentrytitle>wg</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
to set the peers up.
|
||||
'';
|
||||
};
|
||||
|
||||
singleSubnetPerField = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
By default, all allowed IPs and subnets are comma-separated in the
|
||||
<literal>allowed_ips</literal> field. With this option enabled,
|
||||
a single IP and subnet will be listed in fields like <literal>allowed_ip_0</literal>,
|
||||
<literal>allowed_ip_1</literal> and so on.
|
||||
'';
|
||||
};
|
||||
|
||||
withRemoteIp = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether or not the remote IP of a WireGuard peer should be exposed via prometheus.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
path = [ pkgs.wireguard-tools ];
|
||||
|
||||
serviceConfig = {
|
||||
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-wireguard-exporter}/bin/prometheus_wireguard_exporter \
|
||||
-p ${toString cfg.port} \
|
||||
-l ${cfg.listenAddress} \
|
||||
${optionalString cfg.verbose "-v"} \
|
||||
${optionalString cfg.singleSubnetPerField "-s"} \
|
||||
${optionalString cfg.withRemoteIp "-r"} \
|
||||
${optionalString (cfg.wireguardConfig != null) "-n ${escapeShellArg cfg.wireguardConfig}"}
|
||||
'';
|
||||
RestrictAddressFamilies = [
|
||||
# Need AF_NETLINK to collect data
|
||||
"AF_NETLINK"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue