Merge pull request #68221 from WilliButz/remove-prometheus1
remove prometheus 1
This commit is contained in:
commit
cfe51be04f
@ -464,7 +464,14 @@
|
|||||||
<literal>packetbeat5</literal>) of the ELK-stack and Elastic beats have been removed.
|
<literal>packetbeat5</literal>) of the ELK-stack and Elastic beats have been removed.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
For NixOS 19.03, both Prometheus 1 and 2 were available to allow for
|
||||||
|
a seamless transition from version 1 to 2 with existing setups.
|
||||||
|
Because Prometheus 1 is no longer developed, it was removed.
|
||||||
|
Prometheus 2 is now configured with <literal>services.prometheus</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -52,10 +52,11 @@ with lib;
|
|||||||
(mkRemovedOptionModule [ "services" "misc" "nzbget" "openFirewall" ] "The port used by nzbget is managed through the web interface so you should adjust your firewall rules accordingly.")
|
(mkRemovedOptionModule [ "services" "misc" "nzbget" "openFirewall" ] "The port used by nzbget is managed through the web interface so you should adjust your firewall rules accordingly.")
|
||||||
(mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "user" ] "The alertmanager service is now using systemd's DynamicUser mechanism which obviates a user setting.")
|
(mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "user" ] "The alertmanager service is now using systemd's DynamicUser mechanism which obviates a user setting.")
|
||||||
(mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "group" ] "The alertmanager service is now using systemd's DynamicUser mechanism which obviates a group setting.")
|
(mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "group" ] "The alertmanager service is now using systemd's DynamicUser mechanism which obviates a group setting.")
|
||||||
(mkRemovedOptionModule [ "services" "prometheus2" "alertmanagerURL" ] ''
|
(mkRemovedOptionModule [ "services" "prometheus" "alertmanagerURL" ] ''
|
||||||
Due to incompatibility, the alertmanagerURL option has been removed,
|
Due to incompatibility, the alertmanagerURL option has been removed,
|
||||||
please use 'services.prometheus2.alertmanagers' instead.
|
please use 'services.prometheus2.alertmanagers' instead.
|
||||||
'')
|
'')
|
||||||
|
(mkRenamedOptionModule [ "services" "prometheus2" ] [ "services" "prometheus" ])
|
||||||
(mkRenamedOptionModule [ "services" "tor" "relay" "portSpec" ] [ "services" "tor" "relay" "port" ])
|
(mkRenamedOptionModule [ "services" "tor" "relay" "portSpec" ] [ "services" "tor" "relay" "port" ])
|
||||||
(mkRenamedOptionModule [ "services" "vmwareGuest" ] [ "virtualisation" "vmware" "guest" ])
|
(mkRenamedOptionModule [ "services" "vmwareGuest" ] [ "virtualisation" "vmware" "guest" ])
|
||||||
(mkRenamedOptionModule [ "jobs" ] [ "systemd" "services" ])
|
(mkRenamedOptionModule [ "jobs" ] [ "systemd" "services" ])
|
||||||
|
@ -4,37 +4,14 @@ with lib;
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.prometheus;
|
cfg = config.services.prometheus;
|
||||||
cfg2 = config.services.prometheus2;
|
|
||||||
promUser = "prometheus";
|
|
||||||
promGroup = "prometheus";
|
|
||||||
|
|
||||||
stateDir =
|
workingDir = "/var/lib/" + cfg.stateDir;
|
||||||
if cfg.stateDir != null
|
|
||||||
then cfg.stateDir
|
|
||||||
else
|
|
||||||
if cfg.dataDir != null
|
|
||||||
then
|
|
||||||
# This assumes /var/lib/ is a prefix of cfg.dataDir.
|
|
||||||
# This is checked as an assertion below.
|
|
||||||
removePrefix stateDirBase cfg.dataDir
|
|
||||||
else "prometheus";
|
|
||||||
stateDirBase = "/var/lib/";
|
|
||||||
workingDir = stateDirBase + stateDir;
|
|
||||||
workingDir2 = stateDirBase + cfg2.stateDir;
|
|
||||||
|
|
||||||
# a wrapper that verifies that the configuration is valid
|
# a wrapper that verifies that the configuration is valid
|
||||||
promtoolCheck = what: name: file: pkgs.runCommand "${name}-${what}-checked"
|
promtoolCheck = what: name: file:
|
||||||
{ buildInputs = [ cfg.package ]; } ''
|
|
||||||
ln -s ${file} $out
|
|
||||||
promtool ${what} $out
|
|
||||||
'';
|
|
||||||
|
|
||||||
# a wrapper that verifies that the configuration is valid for
|
|
||||||
# prometheus 2
|
|
||||||
prom2toolCheck = what: name: file:
|
|
||||||
pkgs.runCommand
|
pkgs.runCommand
|
||||||
"${name}-${replaceStrings [" "] [""] what}-checked"
|
"${name}-${replaceStrings [" "] [""] what}-checked"
|
||||||
{ buildInputs = [ cfg2.package ]; } ''
|
{ buildInputs = [ cfg.package ]; } ''
|
||||||
ln -s ${file} $out
|
ln -s ${file} $out
|
||||||
promtool ${what} $out
|
promtool ${what} $out
|
||||||
'';
|
'';
|
||||||
@ -45,61 +22,34 @@ let
|
|||||||
echo '${builtins.toJSON x}' | ${pkgs.jq}/bin/jq . > $out
|
echo '${builtins.toJSON x}' | ${pkgs.jq}/bin/jq . > $out
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# This becomes the main config file for Prometheus 1
|
generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig;
|
||||||
|
|
||||||
|
# This becomes the main config file for Prometheus
|
||||||
promConfig = {
|
promConfig = {
|
||||||
global = filterValidPrometheus cfg.globalConfig;
|
global = filterValidPrometheus cfg.globalConfig;
|
||||||
rule_files = map (promtoolCheck "check-rules" "rules") (cfg.ruleFiles ++ [
|
rule_files = map (promtoolCheck "check rules" "rules") (cfg.ruleFiles ++ [
|
||||||
(pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg.rules))
|
(pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg.rules))
|
||||||
]);
|
]);
|
||||||
scrape_configs = filterValidPrometheus cfg.scrapeConfigs;
|
scrape_configs = filterValidPrometheus cfg.scrapeConfigs;
|
||||||
|
alerting = {
|
||||||
|
inherit (cfg) alertmanagers;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig;
|
|
||||||
|
|
||||||
prometheusYml = let
|
prometheusYml = let
|
||||||
yml = if cfg.configText != null then
|
yml = if cfg.configText != null then
|
||||||
pkgs.writeText "prometheus.yml" cfg.configText
|
pkgs.writeText "prometheus.yml" cfg.configText
|
||||||
else generatedPrometheusYml;
|
else generatedPrometheusYml;
|
||||||
in promtoolCheck "check-config" "prometheus.yml" yml;
|
in promtoolCheck "check config" "prometheus.yml" yml;
|
||||||
|
|
||||||
cmdlineArgs = cfg.extraFlags ++ [
|
cmdlineArgs = cfg.extraFlags ++ [
|
||||||
"-storage.local.path=${workingDir}/metrics"
|
"--storage.tsdb.path=${workingDir}/data/"
|
||||||
"-config.file=${prometheusYml}"
|
"--config.file=${prometheusYml}"
|
||||||
"-web.listen-address=${cfg.listenAddress}"
|
"--web.listen-address=${cfg.listenAddress}"
|
||||||
"-alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}"
|
"--alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}"
|
||||||
"-alertmanager.timeout=${toString cfg.alertmanagerTimeout}s"
|
"--alertmanager.timeout=${toString cfg.alertmanagerTimeout}s"
|
||||||
] ++
|
] ++
|
||||||
optional (cfg.alertmanagerURL != []) "-alertmanager.url=${concatStringsSep "," cfg.alertmanagerURL}" ++
|
optional (cfg.webExternalUrl != null) "--web.external-url=${cfg.webExternalUrl}";
|
||||||
optional (cfg.webExternalUrl != null) "-web.external-url=${cfg.webExternalUrl}";
|
|
||||||
|
|
||||||
# This becomes the main config file for Prometheus 2
|
|
||||||
promConfig2 = {
|
|
||||||
global = filterValidPrometheus cfg2.globalConfig;
|
|
||||||
rule_files = map (prom2toolCheck "check rules" "rules") (cfg2.ruleFiles ++ [
|
|
||||||
(pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg2.rules))
|
|
||||||
]);
|
|
||||||
scrape_configs = filterValidPrometheus cfg2.scrapeConfigs;
|
|
||||||
alerting = {
|
|
||||||
inherit (cfg2) alertmanagers;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
generatedPrometheus2Yml = writePrettyJSON "prometheus.yml" promConfig2;
|
|
||||||
|
|
||||||
prometheus2Yml = let
|
|
||||||
yml = if cfg2.configText != null then
|
|
||||||
pkgs.writeText "prometheus.yml" cfg2.configText
|
|
||||||
else generatedPrometheus2Yml;
|
|
||||||
in prom2toolCheck "check config" "prometheus.yml" yml;
|
|
||||||
|
|
||||||
cmdlineArgs2 = cfg2.extraFlags ++ [
|
|
||||||
"--storage.tsdb.path=${workingDir2}/data/"
|
|
||||||
"--config.file=${prometheus2Yml}"
|
|
||||||
"--web.listen-address=${cfg2.listenAddress}"
|
|
||||||
"--alertmanager.notification-queue-capacity=${toString cfg2.alertmanagerNotificationQueueCapacity}"
|
|
||||||
"--alertmanager.timeout=${toString cfg2.alertmanagerTimeout}s"
|
|
||||||
] ++
|
|
||||||
optional (cfg2.webExternalUrl != null) "--web.external-url=${cfg2.webExternalUrl}";
|
|
||||||
|
|
||||||
filterValidPrometheus = filterAttrsListRecursive (n: v: !(n == "_module" || v == null));
|
filterValidPrometheus = filterAttrsListRecursive (n: v: !(n == "_module" || v == null));
|
||||||
filterAttrsListRecursive = pred: x:
|
filterAttrsListRecursive = pred: x:
|
||||||
@ -514,343 +464,159 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
options = {
|
options.services.prometheus = {
|
||||||
services.prometheus = {
|
|
||||||
|
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Enable the Prometheus monitoring daemon.
|
Enable the Prometheus monitoring daemon.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.prometheus;
|
default = pkgs.prometheus;
|
||||||
defaultText = "pkgs.prometheus";
|
defaultText = "pkgs.prometheus";
|
||||||
description = ''
|
description = ''
|
||||||
The prometheus package that should be used.
|
The prometheus package that should be used.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
listenAddress = mkOption {
|
listenAddress = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "0.0.0.0:9090";
|
default = "0.0.0.0:9090";
|
||||||
description = ''
|
description = ''
|
||||||
Address to listen on for the web interface, API, and telemetry.
|
Address to listen on for the web interface, API, and telemetry.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
dataDir = mkOption {
|
stateDir = mkOption {
|
||||||
type = types.nullOr types.path;
|
type = types.str;
|
||||||
default = null;
|
default = "prometheus2";
|
||||||
description = ''
|
description = ''
|
||||||
Directory to store Prometheus metrics data.
|
Directory below <literal>/var/lib</literal> to store Prometheus metrics data.
|
||||||
This option is deprecated, please use <option>services.prometheus.stateDir</option>.
|
This directory will be created automatically using systemd's StateDirectory mechanism.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
stateDir = mkOption {
|
extraFlags = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.listOf types.str;
|
||||||
default = null;
|
default = [];
|
||||||
description = ''
|
description = ''
|
||||||
Directory below <literal>${stateDirBase}</literal> to store Prometheus metrics data.
|
Extra commandline options when launching Prometheus.
|
||||||
This directory will be created automatically using systemd's StateDirectory mechanism.
|
'';
|
||||||
Defaults to <literal>prometheus</literal>.
|
};
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
configText = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.nullOr types.lines;
|
||||||
default = [];
|
default = null;
|
||||||
description = ''
|
description = ''
|
||||||
Extra commandline options when launching Prometheus.
|
If non-null, this option defines the text that is written to
|
||||||
'';
|
prometheus.yml. If null, the contents of prometheus.yml is generated
|
||||||
};
|
from the structured config options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
configText = mkOption {
|
globalConfig = mkOption {
|
||||||
type = types.nullOr types.lines;
|
type = promTypes.globalConfig;
|
||||||
default = null;
|
default = {};
|
||||||
description = ''
|
description = ''
|
||||||
If non-null, this option defines the text that is written to
|
Parameters that are valid in all configuration contexts. They
|
||||||
prometheus.yml. If null, the contents of prometheus.yml is generated
|
also serve as defaults for other configuration sections
|
||||||
from the structured config options.
|
'';
|
||||||
'';
|
};
|
||||||
};
|
|
||||||
|
|
||||||
globalConfig = mkOption {
|
rules = mkOption {
|
||||||
type = promTypes.globalConfig;
|
type = types.listOf types.str;
|
||||||
default = {};
|
default = [];
|
||||||
description = ''
|
description = ''
|
||||||
Parameters that are valid in all configuration contexts. They
|
Alerting and/or Recording rules to evaluate at runtime.
|
||||||
also serve as defaults for other configuration sections
|
'';
|
||||||
'';
|
};
|
||||||
};
|
|
||||||
|
|
||||||
rules = mkOption {
|
ruleFiles = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.path;
|
||||||
default = [];
|
default = [];
|
||||||
description = ''
|
description = ''
|
||||||
Alerting and/or Recording rules to evaluate at runtime.
|
Any additional rules files to include in this configuration.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
ruleFiles = mkOption {
|
scrapeConfigs = mkOption {
|
||||||
type = types.listOf types.path;
|
type = types.listOf promTypes.scrape_config;
|
||||||
default = [];
|
default = [];
|
||||||
description = ''
|
description = ''
|
||||||
Any additional rules files to include in this configuration.
|
A list of scrape configurations.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
scrapeConfigs = mkOption {
|
alertmanagers = mkOption {
|
||||||
type = types.listOf promTypes.scrape_config;
|
type = types.listOf types.attrs;
|
||||||
default = [];
|
example = literalExample ''
|
||||||
description = ''
|
[ {
|
||||||
A list of scrape configurations.
|
scheme = "https";
|
||||||
'';
|
path_prefix = "/alertmanager";
|
||||||
};
|
static_configs = [ {
|
||||||
|
targets = [
|
||||||
|
"prometheus.domain.tld"
|
||||||
|
];
|
||||||
|
} ];
|
||||||
|
} ]
|
||||||
|
'';
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
A list of alertmanagers to send alerts to.
|
||||||
|
See <link xlink:href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alertmanager_config">the official documentation</link> for more information.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
alertmanagerURL = mkOption {
|
alertmanagerNotificationQueueCapacity = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.int;
|
||||||
default = [];
|
default = 10000;
|
||||||
description = ''
|
description = ''
|
||||||
List of Alertmanager URLs to send notifications to.
|
The capacity of the queue for pending alert manager notifications.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
alertmanagerNotificationQueueCapacity = mkOption {
|
alertmanagerTimeout = mkOption {
|
||||||
type = types.int;
|
type = types.int;
|
||||||
default = 10000;
|
default = 10;
|
||||||
description = ''
|
description = ''
|
||||||
The capacity of the queue for pending alert manager notifications.
|
Alert manager HTTP API timeout (in seconds).
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
alertmanagerTimeout = mkOption {
|
webExternalUrl = mkOption {
|
||||||
type = types.int;
|
type = types.nullOr types.str;
|
||||||
default = 10;
|
default = null;
|
||||||
description = ''
|
example = "https://example.com/";
|
||||||
Alert manager HTTP API timeout (in seconds).
|
description = ''
|
||||||
'';
|
The URL under which Prometheus is externally reachable (for example,
|
||||||
};
|
if Prometheus is served via a reverse proxy).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
webExternalUrl = mkOption {
|
config = mkIf cfg.enable {
|
||||||
type = types.nullOr types.str;
|
users.groups.prometheus.gid = config.ids.gids.prometheus;
|
||||||
default = null;
|
users.users.prometheus = {
|
||||||
example = "https://example.com/";
|
description = "Prometheus daemon user";
|
||||||
description = ''
|
uid = config.ids.uids.prometheus;
|
||||||
The URL under which Prometheus is externally reachable (for example,
|
group = "prometheus";
|
||||||
if Prometheus is served via a reverse proxy).
|
};
|
||||||
'';
|
systemd.services.prometheus = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${cfg.package}/bin/prometheus" +
|
||||||
|
optionalString (length cmdlineArgs != 0) (" \\\n " +
|
||||||
|
concatStringsSep " \\\n " cmdlineArgs);
|
||||||
|
User = "prometheus";
|
||||||
|
Restart = "always";
|
||||||
|
WorkingDirectory = workingDir;
|
||||||
|
StateDirectory = cfg.stateDir;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
services.prometheus2 = {
|
};
|
||||||
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Enable the Prometheus 2 monitoring daemon.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.prometheus_2;
|
|
||||||
defaultText = "pkgs.prometheus_2";
|
|
||||||
description = ''
|
|
||||||
The prometheus2 package that should be used.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
listenAddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "0.0.0.0:9090";
|
|
||||||
description = ''
|
|
||||||
Address to listen on for the web interface, API, and telemetry.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
stateDir = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "prometheus2";
|
|
||||||
description = ''
|
|
||||||
Directory below <literal>${stateDirBase}</literal> to store Prometheus metrics data.
|
|
||||||
This directory will be created automatically using systemd's StateDirectory mechanism.
|
|
||||||
Defaults to <literal>prometheus2</literal>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching Prometheus 2.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
configText = mkOption {
|
|
||||||
type = types.nullOr types.lines;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
If non-null, this option defines the text that is written to
|
|
||||||
prometheus.yml. If null, the contents of prometheus.yml is generated
|
|
||||||
from the structured config options.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
globalConfig = mkOption {
|
|
||||||
type = promTypes.globalConfig;
|
|
||||||
default = {};
|
|
||||||
description = ''
|
|
||||||
Parameters that are valid in all configuration contexts. They
|
|
||||||
also serve as defaults for other configuration sections
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
rules = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Alerting and/or Recording rules to evaluate at runtime.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
ruleFiles = mkOption {
|
|
||||||
type = types.listOf types.path;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Any additional rules files to include in this configuration.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
scrapeConfigs = mkOption {
|
|
||||||
type = types.listOf promTypes.scrape_config;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
A list of scrape configurations.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
alertmanagers = mkOption {
|
|
||||||
type = types.listOf types.attrs;
|
|
||||||
example = literalExample ''
|
|
||||||
[ {
|
|
||||||
scheme = "https";
|
|
||||||
path_prefix = "/alertmanager";
|
|
||||||
static_configs = [ {
|
|
||||||
targets = [
|
|
||||||
"prometheus.domain.tld"
|
|
||||||
];
|
|
||||||
} ];
|
|
||||||
} ]
|
|
||||||
'';
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
A list of alertmanagers to send alerts to.
|
|
||||||
See <link xlink:href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alertmanager_config">the official documentation</link> for more information.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
alertmanagerNotificationQueueCapacity = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 10000;
|
|
||||||
description = ''
|
|
||||||
The capacity of the queue for pending alert manager notifications.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
alertmanagerTimeout = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 10;
|
|
||||||
description = ''
|
|
||||||
Alert manager HTTP API timeout (in seconds).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
webExternalUrl = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
example = "https://example.com/";
|
|
||||||
description = ''
|
|
||||||
The URL under which Prometheus is externally reachable (for example,
|
|
||||||
if Prometheus is served via a reverse proxy).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkMerge [
|
|
||||||
(mkIf (cfg.enable || cfg2.enable) {
|
|
||||||
users.groups.${promGroup}.gid = config.ids.gids.prometheus;
|
|
||||||
users.users.${promUser} = {
|
|
||||||
description = "Prometheus daemon user";
|
|
||||||
uid = config.ids.uids.prometheus;
|
|
||||||
group = promGroup;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(mkIf cfg.enable {
|
|
||||||
warnings =
|
|
||||||
optional (cfg.dataDir != null) ''
|
|
||||||
The option services.prometheus.dataDir is deprecated, please use
|
|
||||||
services.prometheus.stateDir.
|
|
||||||
'';
|
|
||||||
assertions = [
|
|
||||||
{
|
|
||||||
assertion = !(cfg.dataDir != null && cfg.stateDir != null);
|
|
||||||
message =
|
|
||||||
"The options services.prometheus.dataDir and services.prometheus.stateDir" +
|
|
||||||
" can't both be set at the same time! It's recommended to only set the latter" +
|
|
||||||
" since the former is deprecated.";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
assertion = cfg.dataDir != null -> hasPrefix stateDirBase cfg.dataDir;
|
|
||||||
message =
|
|
||||||
"The option services.prometheus.dataDir should have ${stateDirBase} as a prefix!";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
assertion = cfg.stateDir != null -> !hasPrefix "/" cfg.stateDir;
|
|
||||||
message =
|
|
||||||
"The option services.prometheus.stateDir shouldn't be an absolute directory." +
|
|
||||||
" It should be a directory relative to ${stateDirBase}.";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
assertion = cfg2.stateDir != null -> !hasPrefix "/" cfg2.stateDir;
|
|
||||||
message =
|
|
||||||
"The option services.prometheus2.stateDir shouldn't be an absolute directory." +
|
|
||||||
" It should be a directory relative to ${stateDirBase}.";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
systemd.services.prometheus = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "network.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${cfg.package}/bin/prometheus" +
|
|
||||||
optionalString (length cmdlineArgs != 0) (" \\\n " +
|
|
||||||
concatStringsSep " \\\n " cmdlineArgs);
|
|
||||||
User = promUser;
|
|
||||||
Restart = "always";
|
|
||||||
WorkingDirectory = workingDir;
|
|
||||||
StateDirectory = stateDir;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(mkIf cfg2.enable {
|
|
||||||
systemd.services.prometheus2 = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "network.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${cfg2.package}/bin/prometheus" +
|
|
||||||
optionalString (length cmdlineArgs2 != 0) (" \\\n " +
|
|
||||||
concatStringsSep " \\\n " cmdlineArgs2);
|
|
||||||
User = promUser;
|
|
||||||
Restart = "always";
|
|
||||||
WorkingDirectory = workingDir2;
|
|
||||||
StateDirectory = cfg2.stateDir;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
@ -218,8 +218,8 @@ let
|
|||||||
toArgs = optionToArgs;
|
toArgs = optionToArgs;
|
||||||
option = mkOption {
|
option = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "/var/lib/${config.services.prometheus2.stateDir}/data";
|
default = "/var/lib/${config.services.prometheus.stateDir}/data";
|
||||||
defaultText = "/var/lib/\${config.services.prometheus2.stateDir}/data";
|
defaultText = "/var/lib/\${config.services.prometheus.stateDir}/data";
|
||||||
description = ''
|
description = ''
|
||||||
Data directory of TSDB.
|
Data directory of TSDB.
|
||||||
'';
|
'';
|
||||||
@ -679,22 +679,22 @@ in {
|
|||||||
(mkIf cfg.sidecar.enable {
|
(mkIf cfg.sidecar.enable {
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
assertion = config.services.prometheus2.enable;
|
assertion = config.services.prometheus.enable;
|
||||||
message =
|
message =
|
||||||
"Please enable services.prometheus2 when enabling services.thanos.sidecar.";
|
"Please enable services.prometheus when enabling services.thanos.sidecar.";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
assertion = !(config.services.prometheus2.globalConfig.external_labels == null ||
|
assertion = !(config.services.prometheus.globalConfig.external_labels == null ||
|
||||||
config.services.prometheus2.globalConfig.external_labels == {});
|
config.services.prometheus.globalConfig.external_labels == {});
|
||||||
message =
|
message =
|
||||||
"services.thanos.sidecar requires uniquely identifying external labels " +
|
"services.thanos.sidecar requires uniquely identifying external labels " +
|
||||||
"to be configured in the Prometheus server. " +
|
"to be configured in the Prometheus server. " +
|
||||||
"Please set services.prometheus2.globalConfig.external_labels.";
|
"Please set services.prometheus.globalConfig.external_labels.";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
systemd.services.thanos-sidecar = {
|
systemd.services.thanos-sidecar = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" "prometheus2.service" ];
|
after = [ "network.target" "prometheus.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
User = "prometheus";
|
User = "prometheus";
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
|
@ -224,7 +224,6 @@ in
|
|||||||
predictable-interface-names = handleTest ./predictable-interface-names.nix {};
|
predictable-interface-names = handleTest ./predictable-interface-names.nix {};
|
||||||
printing = handleTest ./printing.nix {};
|
printing = handleTest ./printing.nix {};
|
||||||
prometheus = handleTest ./prometheus.nix {};
|
prometheus = handleTest ./prometheus.nix {};
|
||||||
prometheus2 = handleTest ./prometheus-2.nix {};
|
|
||||||
prometheus-exporters = handleTest ./prometheus-exporters.nix {};
|
prometheus-exporters = handleTest ./prometheus-exporters.nix {};
|
||||||
prosody = handleTest ./xmpp/prosody.nix {};
|
prosody = handleTest ./xmpp/prosody.nix {};
|
||||||
prosodyMysql = handleTest ./xmpp/prosody-mysql.nix {};
|
prosodyMysql = handleTest ./xmpp/prosody-mysql.nix {};
|
||||||
|
@ -1,239 +0,0 @@
|
|||||||
let
|
|
||||||
grpcPort = 19090;
|
|
||||||
queryPort = 9090;
|
|
||||||
minioPort = 9000;
|
|
||||||
pushgwPort = 9091;
|
|
||||||
|
|
||||||
s3 = {
|
|
||||||
accessKey = "BKIKJAA5BMMU2RHO6IBB";
|
|
||||||
secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12";
|
|
||||||
};
|
|
||||||
|
|
||||||
objstore.config = {
|
|
||||||
type = "S3";
|
|
||||||
config = {
|
|
||||||
bucket = "thanos-bucket";
|
|
||||||
endpoint = "s3:${toString minioPort}";
|
|
||||||
region = "us-east-1";
|
|
||||||
access_key = s3.accessKey;
|
|
||||||
secret_key = s3.secretKey;
|
|
||||||
insecure = true;
|
|
||||||
signature_version2 = false;
|
|
||||||
encrypt_sse = false;
|
|
||||||
put_user_metadata = {};
|
|
||||||
http_config = {
|
|
||||||
idle_conn_timeout = "0s";
|
|
||||||
insecure_skip_verify = false;
|
|
||||||
};
|
|
||||||
trace = {
|
|
||||||
enable = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
in import ./make-test.nix {
|
|
||||||
name = "prometheus-2";
|
|
||||||
|
|
||||||
nodes = {
|
|
||||||
prometheus = { pkgs, ... }: {
|
|
||||||
virtualisation.diskSize = 2 * 1024;
|
|
||||||
environment.systemPackages = [ pkgs.jq ];
|
|
||||||
networking.firewall.allowedTCPPorts = [ grpcPort ];
|
|
||||||
services.prometheus2 = {
|
|
||||||
enable = true;
|
|
||||||
scrapeConfigs = [
|
|
||||||
{
|
|
||||||
job_name = "prometheus";
|
|
||||||
static_configs = [
|
|
||||||
{
|
|
||||||
targets = [ "127.0.0.1:${toString queryPort}" ];
|
|
||||||
labels = { instance = "localhost"; };
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
job_name = "pushgateway";
|
|
||||||
scrape_interval = "1s";
|
|
||||||
static_configs = [
|
|
||||||
{
|
|
||||||
targets = [ "127.0.0.1:${toString pushgwPort}" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
rules = [
|
|
||||||
''
|
|
||||||
groups:
|
|
||||||
- name: test
|
|
||||||
rules:
|
|
||||||
- record: testrule
|
|
||||||
expr: count(up{job="prometheus"})
|
|
||||||
''
|
|
||||||
];
|
|
||||||
globalConfig = {
|
|
||||||
external_labels = {
|
|
||||||
some_label = "required by thanos";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
extraFlags = [
|
|
||||||
# Required by thanos
|
|
||||||
"--storage.tsdb.min-block-duration=5s"
|
|
||||||
"--storage.tsdb.max-block-duration=5s"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
services.prometheus.pushgateway = {
|
|
||||||
enable = true;
|
|
||||||
web.listen-address = ":${toString pushgwPort}";
|
|
||||||
persistMetrics = true;
|
|
||||||
persistence.interval = "1s";
|
|
||||||
stateDir = "prometheus-pushgateway";
|
|
||||||
};
|
|
||||||
services.thanos = {
|
|
||||||
sidecar = {
|
|
||||||
enable = true;
|
|
||||||
grpc-address = "0.0.0.0:${toString grpcPort}";
|
|
||||||
inherit objstore;
|
|
||||||
};
|
|
||||||
|
|
||||||
# TODO: Add some tests for these services:
|
|
||||||
#rule = {
|
|
||||||
# enable = true;
|
|
||||||
# http-address = "0.0.0.0:19194";
|
|
||||||
# grpc-address = "0.0.0.0:19193";
|
|
||||||
# query.addresses = [
|
|
||||||
# "localhost:19191"
|
|
||||||
# ];
|
|
||||||
# labels = {
|
|
||||||
# just = "some";
|
|
||||||
# nice = "labels";
|
|
||||||
# };
|
|
||||||
#};
|
|
||||||
#
|
|
||||||
#receive = {
|
|
||||||
# http-address = "0.0.0.0:19195";
|
|
||||||
# enable = true;
|
|
||||||
# labels = {
|
|
||||||
# just = "some";
|
|
||||||
# nice = "labels";
|
|
||||||
# };
|
|
||||||
#};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
query = { pkgs, ... }: {
|
|
||||||
environment.systemPackages = [ pkgs.jq ];
|
|
||||||
services.thanos.query = {
|
|
||||||
enable = true;
|
|
||||||
http-address = "0.0.0.0:${toString queryPort}";
|
|
||||||
store.addresses = [
|
|
||||||
"prometheus:${toString grpcPort}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
store = { pkgs, ... }: {
|
|
||||||
virtualisation.diskSize = 2 * 1024;
|
|
||||||
environment.systemPackages = with pkgs; [ jq thanos ];
|
|
||||||
services.thanos.store = {
|
|
||||||
enable = true;
|
|
||||||
http-address = "0.0.0.0:10902";
|
|
||||||
grpc-address = "0.0.0.0:${toString grpcPort}";
|
|
||||||
inherit objstore;
|
|
||||||
sync-block-duration = "1s";
|
|
||||||
};
|
|
||||||
services.thanos.compact = {
|
|
||||||
enable = true;
|
|
||||||
http-address = "0.0.0.0:10903";
|
|
||||||
inherit objstore;
|
|
||||||
consistency-delay = "5s";
|
|
||||||
};
|
|
||||||
services.thanos.query = {
|
|
||||||
enable = true;
|
|
||||||
http-address = "0.0.0.0:${toString queryPort}";
|
|
||||||
store.addresses = [
|
|
||||||
"localhost:${toString grpcPort}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
s3 = { pkgs, ... } : {
|
|
||||||
# Minio requires at least 1GiB of free disk space to run.
|
|
||||||
virtualisation.diskSize = 2 * 1024;
|
|
||||||
networking.firewall.allowedTCPPorts = [ minioPort ];
|
|
||||||
|
|
||||||
services.minio = {
|
|
||||||
enable = true;
|
|
||||||
inherit (s3) accessKey secretKey;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.minio-client ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
testScript = { nodes, ... } : ''
|
|
||||||
# Before starting the other machines we first make sure that our S3 service is online
|
|
||||||
# and has a bucket added for thanos:
|
|
||||||
$s3->start;
|
|
||||||
$s3->waitForUnit("minio.service");
|
|
||||||
$s3->waitForOpenPort(${toString minioPort});
|
|
||||||
$s3->succeed(
|
|
||||||
"mc config host add minio " .
|
|
||||||
"http://localhost:${toString minioPort} ${s3.accessKey} ${s3.secretKey} S3v4");
|
|
||||||
$s3->succeed("mc mb minio/thanos-bucket");
|
|
||||||
|
|
||||||
# Now that s3 has started we can start the other machines:
|
|
||||||
$prometheus->start;
|
|
||||||
$query->start;
|
|
||||||
$store->start;
|
|
||||||
|
|
||||||
# Check if prometheus responds to requests:
|
|
||||||
$prometheus->waitForUnit("prometheus2.service");
|
|
||||||
$prometheus->waitForOpenPort(${toString queryPort});
|
|
||||||
$prometheus->succeed("curl -s http://127.0.0.1:${toString queryPort}/metrics");
|
|
||||||
|
|
||||||
# Let's test if pushing a metric to the pushgateway succeeds:
|
|
||||||
$prometheus->waitForUnit("pushgateway.service");
|
|
||||||
$prometheus->succeed(
|
|
||||||
"echo 'some_metric 3.14' | " .
|
|
||||||
"curl --data-binary \@- http://127.0.0.1:${toString pushgwPort}/metrics/job/some_job");
|
|
||||||
|
|
||||||
# Now check whether that metric gets ingested by prometheus.
|
|
||||||
# Since we'll check for the metric several times on different machines
|
|
||||||
# we abstract the test using the following function:
|
|
||||||
|
|
||||||
# Function to check if the metric "some_metric" has been received and returns the correct value.
|
|
||||||
local *Machine::waitForMetric = sub {
|
|
||||||
my ($self) = @_;
|
|
||||||
$self->waitUntilSucceeds(
|
|
||||||
"curl -sf 'http://127.0.0.1:${toString queryPort}/api/v1/query?query=some_metric' " .
|
|
||||||
"| jq '.data.result[0].value[1]' | grep '\"3.14\"'");
|
|
||||||
};
|
|
||||||
|
|
||||||
$prometheus->waitForMetric;
|
|
||||||
|
|
||||||
# Let's test if the pushgateway persists metrics to the configured location.
|
|
||||||
$prometheus->waitUntilSucceeds("test -e /var/lib/prometheus-pushgateway/metrics");
|
|
||||||
|
|
||||||
# Test thanos
|
|
||||||
$prometheus->waitForUnit("thanos-sidecar.service");
|
|
||||||
|
|
||||||
# Test if the Thanos query service can correctly retrieve the metric that was send above.
|
|
||||||
$query->waitForUnit("thanos-query.service");
|
|
||||||
$query->waitForMetric;
|
|
||||||
|
|
||||||
# Test if the Thanos sidecar has correctly uploaded its TSDB to S3, if the
|
|
||||||
# Thanos storage service has correctly downloaded it from S3 and if the Thanos
|
|
||||||
# query service running on $store can correctly retrieve the metric:
|
|
||||||
$store->waitForUnit("thanos-store.service");
|
|
||||||
$store->waitForMetric;
|
|
||||||
|
|
||||||
$store->waitForUnit("thanos-compact.service");
|
|
||||||
|
|
||||||
# Test if the Thanos bucket command is able to retrieve blocks from the S3 bucket
|
|
||||||
# and check if the blocks have the correct labels:
|
|
||||||
$store->succeed(
|
|
||||||
"thanos bucket ls" .
|
|
||||||
" --objstore.config-file=${nodes.store.config.services.thanos.store.objstore.config-file}" .
|
|
||||||
" --output=json | jq .thanos.labels.some_label | grep 'required by thanos'");
|
|
||||||
'';
|
|
||||||
}
|
|
@ -1,48 +1,239 @@
|
|||||||
import ./make-test.nix {
|
let
|
||||||
name = "prometheus";
|
grpcPort = 19090;
|
||||||
|
queryPort = 9090;
|
||||||
|
minioPort = 9000;
|
||||||
|
pushgwPort = 9091;
|
||||||
|
|
||||||
nodes = {
|
s3 = {
|
||||||
one = { ... }: {
|
accessKey = "BKIKJAA5BMMU2RHO6IBB";
|
||||||
services.prometheus = {
|
secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12";
|
||||||
enable = true;
|
};
|
||||||
scrapeConfigs = [{
|
|
||||||
job_name = "prometheus";
|
|
||||||
static_configs = [{
|
|
||||||
targets = [ "127.0.0.1:9090" ];
|
|
||||||
labels = { instance = "localhost"; };
|
|
||||||
}];
|
|
||||||
}];
|
|
||||||
rules = [ ''testrule = count(up{job="prometheus"})'' ];
|
|
||||||
|
|
||||||
# a very simple version of the alertmanager configuration just to see if
|
objstore.config = {
|
||||||
# configuration checks & service startup are working
|
type = "S3";
|
||||||
alertmanager = {
|
config = {
|
||||||
enable = true;
|
bucket = "thanos-bucket";
|
||||||
listenAddress = "[::1]";
|
endpoint = "s3:${toString minioPort}";
|
||||||
port = 9093;
|
region = "us-east-1";
|
||||||
configuration = {
|
access_key = s3.accessKey;
|
||||||
route.receiver = "webhook";
|
secret_key = s3.secretKey;
|
||||||
receivers = [
|
insecure = true;
|
||||||
{
|
signature_version2 = false;
|
||||||
name = "webhook";
|
encrypt_sse = false;
|
||||||
webhook_configs = [
|
put_user_metadata = {};
|
||||||
{ url = "http://localhost"; }
|
http_config = {
|
||||||
];
|
idle_conn_timeout = "0s";
|
||||||
}
|
insecure_skip_verify = false;
|
||||||
];
|
};
|
||||||
};
|
trace = {
|
||||||
};
|
enable = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
in import ./make-test.nix {
|
||||||
startAll;
|
name = "prometheus";
|
||||||
$one->waitForUnit("prometheus.service");
|
|
||||||
$one->waitForOpenPort(9090);
|
nodes = {
|
||||||
$one->succeed("curl -s http://127.0.0.1:9090/metrics");
|
prometheus = { pkgs, ... }: {
|
||||||
$one->waitForUnit("alertmanager.service");
|
virtualisation.diskSize = 2 * 1024;
|
||||||
$one->waitForOpenPort("9093");
|
environment.systemPackages = [ pkgs.jq ];
|
||||||
$one->succeed("curl -f -s http://localhost:9093/");
|
networking.firewall.allowedTCPPorts = [ grpcPort ];
|
||||||
|
services.prometheus = {
|
||||||
|
enable = true;
|
||||||
|
scrapeConfigs = [
|
||||||
|
{
|
||||||
|
job_name = "prometheus";
|
||||||
|
static_configs = [
|
||||||
|
{
|
||||||
|
targets = [ "127.0.0.1:${toString queryPort}" ];
|
||||||
|
labels = { instance = "localhost"; };
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
job_name = "pushgateway";
|
||||||
|
scrape_interval = "1s";
|
||||||
|
static_configs = [
|
||||||
|
{
|
||||||
|
targets = [ "127.0.0.1:${toString pushgwPort}" ];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
rules = [
|
||||||
|
''
|
||||||
|
groups:
|
||||||
|
- name: test
|
||||||
|
rules:
|
||||||
|
- record: testrule
|
||||||
|
expr: count(up{job="prometheus"})
|
||||||
|
''
|
||||||
|
];
|
||||||
|
globalConfig = {
|
||||||
|
external_labels = {
|
||||||
|
some_label = "required by thanos";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
extraFlags = [
|
||||||
|
# Required by thanos
|
||||||
|
"--storage.tsdb.min-block-duration=5s"
|
||||||
|
"--storage.tsdb.max-block-duration=5s"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
services.prometheus.pushgateway = {
|
||||||
|
enable = true;
|
||||||
|
web.listen-address = ":${toString pushgwPort}";
|
||||||
|
persistMetrics = true;
|
||||||
|
persistence.interval = "1s";
|
||||||
|
stateDir = "prometheus-pushgateway";
|
||||||
|
};
|
||||||
|
services.thanos = {
|
||||||
|
sidecar = {
|
||||||
|
enable = true;
|
||||||
|
grpc-address = "0.0.0.0:${toString grpcPort}";
|
||||||
|
inherit objstore;
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO: Add some tests for these services:
|
||||||
|
#rule = {
|
||||||
|
# enable = true;
|
||||||
|
# http-address = "0.0.0.0:19194";
|
||||||
|
# grpc-address = "0.0.0.0:19193";
|
||||||
|
# query.addresses = [
|
||||||
|
# "localhost:19191"
|
||||||
|
# ];
|
||||||
|
# labels = {
|
||||||
|
# just = "some";
|
||||||
|
# nice = "labels";
|
||||||
|
# };
|
||||||
|
#};
|
||||||
|
#
|
||||||
|
#receive = {
|
||||||
|
# http-address = "0.0.0.0:19195";
|
||||||
|
# enable = true;
|
||||||
|
# labels = {
|
||||||
|
# just = "some";
|
||||||
|
# nice = "labels";
|
||||||
|
# };
|
||||||
|
#};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
query = { pkgs, ... }: {
|
||||||
|
environment.systemPackages = [ pkgs.jq ];
|
||||||
|
services.thanos.query = {
|
||||||
|
enable = true;
|
||||||
|
http-address = "0.0.0.0:${toString queryPort}";
|
||||||
|
store.addresses = [
|
||||||
|
"prometheus:${toString grpcPort}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
store = { pkgs, ... }: {
|
||||||
|
virtualisation.diskSize = 2 * 1024;
|
||||||
|
environment.systemPackages = with pkgs; [ jq thanos ];
|
||||||
|
services.thanos.store = {
|
||||||
|
enable = true;
|
||||||
|
http-address = "0.0.0.0:10902";
|
||||||
|
grpc-address = "0.0.0.0:${toString grpcPort}";
|
||||||
|
inherit objstore;
|
||||||
|
sync-block-duration = "1s";
|
||||||
|
};
|
||||||
|
services.thanos.compact = {
|
||||||
|
enable = true;
|
||||||
|
http-address = "0.0.0.0:10903";
|
||||||
|
inherit objstore;
|
||||||
|
consistency-delay = "5s";
|
||||||
|
};
|
||||||
|
services.thanos.query = {
|
||||||
|
enable = true;
|
||||||
|
http-address = "0.0.0.0:${toString queryPort}";
|
||||||
|
store.addresses = [
|
||||||
|
"localhost:${toString grpcPort}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
s3 = { pkgs, ... } : {
|
||||||
|
# Minio requires at least 1GiB of free disk space to run.
|
||||||
|
virtualisation.diskSize = 2 * 1024;
|
||||||
|
networking.firewall.allowedTCPPorts = [ minioPort ];
|
||||||
|
|
||||||
|
services.minio = {
|
||||||
|
enable = true;
|
||||||
|
inherit (s3) accessKey secretKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [ pkgs.minio-client ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = { nodes, ... } : ''
|
||||||
|
# Before starting the other machines we first make sure that our S3 service is online
|
||||||
|
# and has a bucket added for thanos:
|
||||||
|
$s3->start;
|
||||||
|
$s3->waitForUnit("minio.service");
|
||||||
|
$s3->waitForOpenPort(${toString minioPort});
|
||||||
|
$s3->succeed(
|
||||||
|
"mc config host add minio " .
|
||||||
|
"http://localhost:${toString minioPort} ${s3.accessKey} ${s3.secretKey} S3v4");
|
||||||
|
$s3->succeed("mc mb minio/thanos-bucket");
|
||||||
|
|
||||||
|
# Now that s3 has started we can start the other machines:
|
||||||
|
$prometheus->start;
|
||||||
|
$query->start;
|
||||||
|
$store->start;
|
||||||
|
|
||||||
|
# Check if prometheus responds to requests:
|
||||||
|
$prometheus->waitForUnit("prometheus.service");
|
||||||
|
$prometheus->waitForOpenPort(${toString queryPort});
|
||||||
|
$prometheus->succeed("curl -s http://127.0.0.1:${toString queryPort}/metrics");
|
||||||
|
|
||||||
|
# Let's test if pushing a metric to the pushgateway succeeds:
|
||||||
|
$prometheus->waitForUnit("pushgateway.service");
|
||||||
|
$prometheus->succeed(
|
||||||
|
"echo 'some_metric 3.14' | " .
|
||||||
|
"curl --data-binary \@- http://127.0.0.1:${toString pushgwPort}/metrics/job/some_job");
|
||||||
|
|
||||||
|
# Now check whether that metric gets ingested by prometheus.
|
||||||
|
# Since we'll check for the metric several times on different machines
|
||||||
|
# we abstract the test using the following function:
|
||||||
|
|
||||||
|
# Function to check if the metric "some_metric" has been received and returns the correct value.
|
||||||
|
local *Machine::waitForMetric = sub {
|
||||||
|
my ($self) = @_;
|
||||||
|
$self->waitUntilSucceeds(
|
||||||
|
"curl -sf 'http://127.0.0.1:${toString queryPort}/api/v1/query?query=some_metric' " .
|
||||||
|
"| jq '.data.result[0].value[1]' | grep '\"3.14\"'");
|
||||||
|
};
|
||||||
|
|
||||||
|
$prometheus->waitForMetric;
|
||||||
|
|
||||||
|
# Let's test if the pushgateway persists metrics to the configured location.
|
||||||
|
$prometheus->waitUntilSucceeds("test -e /var/lib/prometheus-pushgateway/metrics");
|
||||||
|
|
||||||
|
# Test thanos
|
||||||
|
$prometheus->waitForUnit("thanos-sidecar.service");
|
||||||
|
|
||||||
|
# Test if the Thanos query service can correctly retrieve the metric that was send above.
|
||||||
|
$query->waitForUnit("thanos-query.service");
|
||||||
|
$query->waitForMetric;
|
||||||
|
|
||||||
|
# Test if the Thanos sidecar has correctly uploaded its TSDB to S3, if the
|
||||||
|
# Thanos storage service has correctly downloaded it from S3 and if the Thanos
|
||||||
|
# query service running on $store can correctly retrieve the metric:
|
||||||
|
$store->waitForUnit("thanos-store.service");
|
||||||
|
$store->waitForMetric;
|
||||||
|
|
||||||
|
$store->waitForUnit("thanos-compact.service");
|
||||||
|
|
||||||
|
# Test if the Thanos bucket command is able to retrieve blocks from the S3 bucket
|
||||||
|
# and check if the blocks have the correct labels:
|
||||||
|
$store->succeed(
|
||||||
|
"thanos bucket ls" .
|
||||||
|
" --objstore.config-file=${nodes.store.config.services.thanos.store.objstore.config-file}" .
|
||||||
|
" --output=json | jq .thanos.labels.some_label | grep 'required by thanos'");
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
@ -1,54 +1,46 @@
|
|||||||
{ stdenv, go, buildGoPackage, fetchFromGitHub }:
|
{ lib, go, buildGoPackage, fetchFromGitHub }:
|
||||||
|
|
||||||
let
|
let
|
||||||
goPackagePath = "github.com/prometheus/prometheus";
|
goPackagePath = "github.com/prometheus/prometheus";
|
||||||
in rec {
|
in
|
||||||
buildPrometheus = { version, sha256, doCheck ? true, ... }@attrs:
|
buildGoPackage rec {
|
||||||
let attrs' = builtins.removeAttrs attrs ["version" "sha256"]; in
|
pname = "prometheus";
|
||||||
buildGoPackage ({
|
version = "2.12.0";
|
||||||
name = "prometheus-${version}";
|
|
||||||
|
|
||||||
inherit goPackagePath;
|
inherit goPackagePath;
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
owner = "prometheus";
|
owner = "prometheus";
|
||||||
repo = "prometheus";
|
repo = "prometheus";
|
||||||
inherit sha256;
|
|
||||||
};
|
|
||||||
|
|
||||||
buildFlagsArray = let t = "${goPackagePath}/vendor/github.com/prometheus/common/version"; in ''
|
|
||||||
-ldflags=
|
|
||||||
-X ${t}.Version=${version}
|
|
||||||
-X ${t}.Revision=unknown
|
|
||||||
-X ${t}.Branch=unknown
|
|
||||||
-X ${t}.BuildUser=nix@nixpkgs
|
|
||||||
-X ${t}.BuildDate=unknown
|
|
||||||
-X ${t}.GoVersion=${stdenv.lib.getVersion go}
|
|
||||||
'';
|
|
||||||
|
|
||||||
preInstall = ''
|
|
||||||
mkdir -p "$bin/share/doc/prometheus" "$bin/etc/prometheus"
|
|
||||||
cp -a $src/documentation/* $bin/share/doc/prometheus
|
|
||||||
cp -a $src/console_libraries $src/consoles $bin/etc/prometheus
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with stdenv.lib; {
|
|
||||||
description = "Service monitoring system and time series database";
|
|
||||||
homepage = https://prometheus.io;
|
|
||||||
license = licenses.asl20;
|
|
||||||
maintainers = with maintainers; [ benley fpletz globin ];
|
|
||||||
platforms = platforms.unix;
|
|
||||||
};
|
|
||||||
} // attrs');
|
|
||||||
|
|
||||||
prometheus_1 = buildPrometheus {
|
|
||||||
version = "1.8.2";
|
|
||||||
sha256 = "088flpg3qgnj9afl9vbaa19v2s1d21yxy38nrlv5m7cxwy2pi5pv";
|
|
||||||
};
|
|
||||||
|
|
||||||
prometheus_2 = buildPrometheus {
|
|
||||||
version = "2.12.0";
|
|
||||||
sha256 = "1ci9dc512c1hry1b8jqif0mrnks6w3yagwm3jf69ihcwilr2n7vs";
|
sha256 = "1ci9dc512c1hry1b8jqif0mrnks6w3yagwm3jf69ihcwilr2n7vs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
buildFlagsArray = let
|
||||||
|
t = "${goPackagePath}/vendor/github.com/prometheus/common/version";
|
||||||
|
in ''
|
||||||
|
-ldflags=
|
||||||
|
-X ${t}.Version=${version}
|
||||||
|
-X ${t}.Revision=unknown
|
||||||
|
-X ${t}.Branch=unknown
|
||||||
|
-X ${t}.BuildUser=nix@nixpkgs
|
||||||
|
-X ${t}.BuildDate=unknown
|
||||||
|
-X ${t}.GoVersion=${lib.getVersion go}
|
||||||
|
'';
|
||||||
|
|
||||||
|
preInstall = ''
|
||||||
|
mkdir -p "$bin/share/doc/prometheus" "$bin/etc/prometheus"
|
||||||
|
cp -a $src/documentation/* $bin/share/doc/prometheus
|
||||||
|
cp -a $src/console_libraries $src/consoles $bin/etc/prometheus
|
||||||
|
'';
|
||||||
|
|
||||||
|
doCheck = true;
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Service monitoring system and time series database";
|
||||||
|
homepage = "https://prometheus.io";
|
||||||
|
license = licenses.asl20;
|
||||||
|
maintainers = with maintainers; [ benley fpletz globin willibutz ];
|
||||||
|
platforms = platforms.unix;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -15014,13 +15014,8 @@ in
|
|||||||
|
|
||||||
postgresql_jdbc = callPackage ../development/java-modules/postgresql_jdbc { };
|
postgresql_jdbc = callPackage ../development/java-modules/postgresql_jdbc { };
|
||||||
|
|
||||||
inherit (callPackage ../servers/monitoring/prometheus { }) prometheus_1;
|
|
||||||
|
|
||||||
inherit (callPackage ../servers/monitoring/prometheus { })
|
|
||||||
prometheus_2;
|
|
||||||
|
|
||||||
prom2json = callPackage ../servers/monitoring/prometheus/prom2json.nix { };
|
prom2json = callPackage ../servers/monitoring/prometheus/prom2json.nix { };
|
||||||
prometheus = prometheus_1;
|
prometheus = callPackage ../servers/monitoring/prometheus { };
|
||||||
prometheus-alertmanager = callPackage ../servers/monitoring/prometheus/alertmanager.nix { };
|
prometheus-alertmanager = callPackage ../servers/monitoring/prometheus/alertmanager.nix { };
|
||||||
prometheus-aws-s3-exporter = callPackage ../servers/monitoring/prometheus/aws-s3-exporter.nix { };
|
prometheus-aws-s3-exporter = callPackage ../servers/monitoring/prometheus/aws-s3-exporter.nix { };
|
||||||
prometheus-bind-exporter = callPackage ../servers/monitoring/prometheus/bind-exporter.nix { };
|
prometheus-bind-exporter = callPackage ../servers/monitoring/prometheus/bind-exporter.nix { };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user