Merge pull request #59828 from basvandijk/prometheus-refactoring

nixos/prometheus: refactored & added more missing options
This commit is contained in:
Bas van Dijk 2019-04-18 13:43:53 +02:00 committed by GitHub
commit cccc7a93d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -22,9 +22,6 @@ let
workingDir = stateDirBase + stateDir; workingDir = stateDirBase + stateDir;
workingDir2 = stateDirBase + cfg2.stateDir; workingDir2 = stateDirBase + cfg2.stateDir;
# Get a submodule without any embedded metadata:
_filter = x: filterAttrs (k: v: k != "_module") x;
# 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: pkgs.runCommand "${name}-${what}-checked"
{ buildInputs = [ cfg.package ]; } '' { buildInputs = [ cfg.package ]; } ''
@ -50,11 +47,11 @@ let
# This becomes the main config file for Prometheus 1 # This becomes the main config file for Prometheus 1
promConfig = { promConfig = {
global = 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 = filterEmpty cfg.scrapeConfigs; scrape_configs = filterValidPrometheus cfg.scrapeConfigs;
}; };
generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig; generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig;
@ -77,11 +74,11 @@ let
# This becomes the main config file for Prometheus 2 # This becomes the main config file for Prometheus 2
promConfig2 = { promConfig2 = {
global = cfg2.globalConfig; global = filterValidPrometheus cfg2.globalConfig;
rule_files = map (prom2toolCheck "check rules" "rules") (cfg2.ruleFiles ++ [ rule_files = map (prom2toolCheck "check rules" "rules") (cfg2.ruleFiles ++ [
(pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg2.rules)) (pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg2.rules))
]); ]);
scrape_configs = filterEmpty cfg2.scrapeConfigs; scrape_configs = filterValidPrometheus cfg2.scrapeConfigs;
alerting = optionalAttrs (cfg2.alertmanagerURL != []) { alerting = optionalAttrs (cfg2.alertmanagerURL != []) {
alertmanagers = [{ alertmanagers = [{
static_configs = [{ static_configs = [{
@ -108,7 +105,7 @@ let
] ++ ] ++
optional (cfg2.webExternalUrl != null) "--web.external-url=${cfg2.webExternalUrl}"; optional (cfg2.webExternalUrl != null) "--web.external-url=${cfg2.webExternalUrl}";
filterEmpty = filterAttrsListRecursive (_n: v: !(v == null || v == [] || v == {})); filterValidPrometheus = filterAttrsListRecursive (n: v: !(n == "_module" || v == null));
filterAttrsListRecursive = pred: x: filterAttrsListRecursive = pred: x:
if isAttrs x then if isAttrs x then
listToAttrs ( listToAttrs (
@ -123,41 +120,37 @@ let
map (filterAttrsListRecursive pred) x map (filterAttrsListRecursive pred) x
else x; else x;
mkDefOpt = type : defaultStr : description : mkOpt type (description + ''
Defaults to <literal>${defaultStr}</literal> in prometheus
when set to <literal>null</literal>.
'');
mkOpt = type : description : mkOption {
type = types.nullOr type;
default = null;
inherit description;
};
promTypes.globalConfig = types.submodule { promTypes.globalConfig = types.submodule {
options = { options = {
scrape_interval = mkOption { scrape_interval = mkDefOpt types.str "1m" ''
type = types.str;
default = "1m";
description = ''
How frequently to scrape targets by default. How frequently to scrape targets by default.
''; '';
};
scrape_timeout = mkOption { scrape_timeout = mkDefOpt types.str "10s" ''
type = types.str;
default = "10s";
description = ''
How long until a scrape request times out. How long until a scrape request times out.
''; '';
};
evaluation_interval = mkOption { evaluation_interval = mkDefOpt types.str "1m" ''
type = types.str;
default = "1m";
description = ''
How frequently to evaluate rules by default. How frequently to evaluate rules by default.
''; '';
};
external_labels = mkOption { external_labels = mkOpt (types.attrsOf types.str) ''
type = types.attrsOf types.str;
description = ''
The labels to add to any time series or alerts when The labels to add to any time series or alerts when
communicating with external systems (federation, remote communicating with external systems (federation, remote
storage, Alertmanager). storage, Alertmanager).
''; '';
default = {};
};
}; };
}; };
@ -169,33 +162,21 @@ let
The job name assigned to scraped metrics by default. The job name assigned to scraped metrics by default.
''; '';
}; };
scrape_interval = mkOption { scrape_interval = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
How frequently to scrape targets from this job. Defaults to the How frequently to scrape targets from this job. Defaults to the
globally configured default. globally configured default.
''; '';
};
scrape_timeout = mkOption { scrape_timeout = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
Per-target timeout when scraping this job. Defaults to the Per-target timeout when scraping this job. Defaults to the
globally configured default. globally configured default.
''; '';
};
metrics_path = mkOption { metrics_path = mkDefOpt types.str "/metrics" ''
type = types.str;
default = "/metrics";
description = ''
The HTTP resource path on which to fetch metrics from targets. The HTTP resource path on which to fetch metrics from targets.
''; '';
};
honor_labels = mkOption { honor_labels = mkDefOpt types.bool "false" ''
type = types.bool;
default = false;
description = ''
Controls how Prometheus handles conflicts between labels Controls how Prometheus handles conflicts between labels
that are already present in scraped data and labels that that are already present in scraped data and labels that
Prometheus would attach server-side ("job" and "instance" Prometheus would attach server-side ("job" and "instance"
@ -214,23 +195,27 @@ let
federation, where all labels specified in the target should federation, where all labels specified in the target should
be preserved. be preserved.
''; '';
};
scheme = mkOption { honor_timestamps = mkDefOpt types.bool "true" ''
type = types.enum ["http" "https"]; honor_timestamps controls whether Prometheus respects the timestamps present
default = "http"; in scraped data.
description = ''
If honor_timestamps is set to <literal>true</literal>, the timestamps of the metrics exposed
by the target will be used.
If honor_timestamps is set to <literal>false</literal>, the timestamps of the metrics exposed
by the target will be ignored.
'';
scheme = mkDefOpt (types.enum ["http" "https"]) "http" ''
The URL scheme with which to fetch metrics from targets. The URL scheme with which to fetch metrics from targets.
''; '';
};
params = mkOption { params = mkOpt (types.attrsOf (types.listOf types.str)) ''
type = types.attrsOf (types.listOf types.str);
default = {};
description = ''
Optional HTTP URL parameters. Optional HTTP URL parameters.
''; '';
};
basic_auth = mkOption { basic_auth = mkOpt (types.submodule {
type = types.nullOr (types.submodule {
options = { options = {
username = mkOption { username = mkOption {
type = types.str; type = types.str;
@ -245,69 +230,59 @@ let
''; '';
}; };
}; };
}); }) ''
default = null;
apply = x: mapNullable _filter x;
description = ''
Optional http login credentials for metrics scraping. Optional http login credentials for metrics scraping.
''; '';
};
tls_config = mkOption { bearer_token = mkOpt types.str ''
type = types.nullOr promTypes.tls_config; Sets the `Authorization` header on every scrape request with
default = null; the configured bearer token. It is mutually exclusive with
apply = x: mapNullable _filter x; <option>bearer_token_file</option>.
description = '' '';
bearer_token_file = mkOpt types.str ''
Sets the `Authorization` header on every scrape request with
the bearer token read from the configured file. It is mutually
exclusive with <option>bearer_token</option>.
'';
tls_config = mkOpt promTypes.tls_config ''
Configures the scrape request's TLS settings. Configures the scrape request's TLS settings.
''; '';
};
dns_sd_configs = mkOption { proxy_url = mkOpt types.str ''
type = types.listOf promTypes.dns_sd_config; Optional proxy URL.
default = [];
apply = x: map _filter x;
description = ''
List of DNS service discovery configurations.
''; '';
};
consul_sd_configs = mkOption { ec2_sd_configs = mkOpt (types.listOf promTypes.ec2_sd_config) ''
type = types.listOf promTypes.consul_sd_config;
default = [];
apply = x: map _filter x;
description = ''
List of Consul service discovery configurations.
'';
};
file_sd_configs = mkOption {
type = types.listOf promTypes.file_sd_config;
default = [];
apply = x: map _filter x;
description = ''
List of file service discovery configurations.
'';
};
static_configs = mkOption {
type = types.listOf promTypes.static_config;
default = [];
apply = x: map _filter x;
description = ''
List of labeled target groups for this job.
'';
};
ec2_sd_configs = mkOption {
type = types.listOf promTypes.ec2_sd_config;
default = [];
apply = x: map _filter x;
description = ''
List of EC2 service discovery configurations. List of EC2 service discovery configurations.
''; '';
};
relabel_configs = mkOption { dns_sd_configs = mkOpt (types.listOf promTypes.dns_sd_config) ''
type = types.listOf promTypes.relabel_config; List of DNS service discovery configurations.
default = []; '';
apply = x: map _filter x;
description = '' consul_sd_configs = mkOpt (types.listOf promTypes.consul_sd_config) ''
List of Consul service discovery configurations.
'';
file_sd_configs = mkOpt (types.listOf promTypes.file_sd_config) ''
List of file service discovery configurations.
'';
static_configs = mkOpt (types.listOf promTypes.static_config) ''
List of labeled target groups for this job.
'';
relabel_configs = mkOpt (types.listOf promTypes.relabel_config) ''
List of relabel configurations. List of relabel configurations.
''; '';
};
sample_limit = mkDefOpt types.int "0" ''
Per-scrape limit on number of scraped samples that will be accepted.
If more than this number of samples are present after metric relabelling
the entire scrape will be treated as failed. 0 means no limit.
'';
}; };
}; };
@ -337,68 +312,43 @@ let
The AWS Region. The AWS Region.
''; '';
}; };
endpoint = mkOption { endpoint = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
Custom endpoint to be used. Custom endpoint to be used.
''; '';
};
access_key = mkOption { access_key = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
The AWS API key id. If blank, the environment variable The AWS API key id. If blank, the environment variable
<literal>AWS_ACCESS_KEY_ID</literal> is used. <literal>AWS_ACCESS_KEY_ID</literal> is used.
''; '';
};
secret_key = mkOption { secret_key = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
The AWS API key secret. If blank, the environment variable The AWS API key secret. If blank, the environment variable
<literal>AWS_SECRET_ACCESS_KEY</literal> is used. <literal>AWS_SECRET_ACCESS_KEY</literal> is used.
''; '';
};
profile = mkOption { profile = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
Named AWS profile used to connect to the API. Named AWS profile used to connect to the API.
''; '';
};
role_arn = mkOption { role_arn = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
AWS Role ARN, an alternative to using AWS API keys. AWS Role ARN, an alternative to using AWS API keys.
''; '';
};
refresh_interval = mkOption { refresh_interval = mkDefOpt types.str "60s" ''
type = types.nullOr types.str;
default = null;
description = ''
Refresh interval to re-read the instance list. Refresh interval to re-read the instance list.
''; '';
};
port = mkOption { port = mkDefOpt types.int "80" ''
type = types.int;
default = 80;
description = ''
The port to scrape metrics from. If using the public IP The port to scrape metrics from. If using the public IP
address, this must instead be specified in the relabeling address, this must instead be specified in the relabeling
rule. rule.
''; '';
};
filters = mkOption { filters = mkOpt (types.listOf promTypes.filter) ''
type = types.nullOr (types.listOf promTypes.filter);
default = null;
description = ''
Filters can be used optionally to filter the instance list by other criteria. Filters can be used optionally to filter the instance list by other criteria.
''; '';
}; };
}; };
};
promTypes.filter = types.submodule { promTypes.filter = types.submodule {
options = { options = {
@ -409,6 +359,7 @@ let
for the available filters. for the available filters.
''; '';
}; };
value = mkOption { value = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [];
@ -427,56 +378,63 @@ let
A list of DNS SRV record names to be queried. A list of DNS SRV record names to be queried.
''; '';
}; };
refresh_interval = mkOption {
type = types.str; refresh_interval = mkDefOpt types.str "30s" ''
default = "30s";
description = ''
The time after which the provided names are refreshed. The time after which the provided names are refreshed.
''; '';
}; };
}; };
};
promTypes.consul_sd_config = types.submodule { promTypes.consul_sd_config = types.submodule {
options = { options = {
server = mkOption { server = mkDefOpt types.str "localhost:8500" ''
type = types.str; Consul server to query.
description = "Consul server to query."; '';
};
token = mkOption {
type = types.nullOr types.str;
description = "Consul token";
};
datacenter = mkOption {
type = types.nullOr types.str;
description = "Consul datacenter";
};
scheme = mkOption {
type = types.nullOr types.str;
description = "Consul scheme";
};
username = mkOption {
type = types.nullOr types.str;
description = "Consul username";
};
password = mkOption {
type = types.nullOr types.str;
description = "Consul password";
};
services = mkOption { token = mkOpt types.str "Consul token";
type = types.listOf types.str;
description = '' datacenter = mkOpt types.str "Consul datacenter";
scheme = mkDefOpt types.str "http" "Consul scheme";
username = mkOpt types.str "Consul username";
password = mkOpt types.str "Consul password";
tls_config = mkOpt promTypes.tls_config ''
Configures the Consul request's TLS settings.
'';
services = mkOpt (types.listOf types.str) ''
A list of services for which targets are retrieved. A list of services for which targets are retrieved.
''; '';
};
tag_separator = mkOption { tags = mkOpt (types.listOf types.str) ''
type = types.str; An optional list of tags used to filter nodes for a given
default = ","; service. Services must contain all tags in the list.
description = '' '';
node_meta = mkOpt (types.attrsOf types.str) ''
Node metadata used to filter nodes for a given service.
'';
tag_separator = mkDefOpt types.str "," ''
The string by which Consul tags are joined into the tag label. The string by which Consul tags are joined into the tag label.
''; '';
};
allow_stale = mkOpt types.bool ''
Allow stale Consul results
(see <link xlink:href="https://www.consul.io/api/index.html#consistency-modes"/>).
Will reduce load on Consul.
'';
refresh_interval = mkDefOpt types.str "30s" ''
The time after which the provided names are refreshed.
On large setup it might be a good idea to increase this value
because the catalog will change all the time.
'';
}; };
}; };
@ -488,110 +446,76 @@ let
Patterns for files from which target groups are extracted. Refer Patterns for files from which target groups are extracted. Refer
to the Prometheus documentation for permitted filename patterns to the Prometheus documentation for permitted filename patterns
and formats. and formats.
''; '';
}; };
refresh_interval = mkOption {
type = types.str; refresh_interval = mkDefOpt types.str "5m" ''
default = "30s";
description = ''
Refresh interval to re-read the files. Refresh interval to re-read the files.
''; '';
}; };
}; };
};
promTypes.relabel_config = types.submodule { promTypes.relabel_config = types.submodule {
options = { options = {
source_labels = mkOption { source_labels = mkOpt (types.listOf types.str) ''
type = with types; nullOr (listOf str);
default = null;
description = ''
The source labels select values from existing labels. Their content The source labels select values from existing labels. Their content
is concatenated using the configured separator and matched against is concatenated using the configured separator and matched against
the configured regular expression. the configured regular expression.
''; '';
};
separator = mkOption { separator = mkDefOpt types.str ";" ''
type = types.str;
default = ";";
description = ''
Separator placed between concatenated source label values. Separator placed between concatenated source label values.
''; '';
};
target_label = mkOption { target_label = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
Label to which the resulting value is written in a replace action. Label to which the resulting value is written in a replace action.
It is mandatory for replace actions. It is mandatory for replace actions.
''; '';
};
regex = mkOption { regex = mkDefOpt types.str "(.*)" ''
type = types.str;
default = "(.*)";
description = ''
Regular expression against which the extracted value is matched. Regular expression against which the extracted value is matched.
''; '';
};
replacement = mkOption { modulus = mkOpt types.int ''
type = types.str; Modulus to take of the hash of the source label values.
default = "$1"; '';
description = ''
replacement = mkDefOpt types.str "$1" ''
Replacement value against which a regex replace is performed if the Replacement value against which a regex replace is performed if the
regular expression matches. regular expression matches.
''; '';
};
action = mkOption { action = mkDefOpt (types.enum ["replace" "keep" "drop"]) "replace" ''
type = types.enum ["replace" "keep" "drop"];
default = "replace";
description = ''
Action to perform based on regex matching. Action to perform based on regex matching.
''; '';
};
}; };
}; };
promTypes.tls_config = types.submodule { promTypes.tls_config = types.submodule {
options = { options = {
ca_file = mkOption { ca_file = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
CA certificate to validate API server certificate with. CA certificate to validate API server certificate with.
''; '';
};
cert_file = mkOption { cert_file = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
Certificate file for client cert authentication to the server. Certificate file for client cert authentication to the server.
''; '';
};
key_file = mkOption { key_file = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
Key file for client cert authentication to the server. Key file for client cert authentication to the server.
''; '';
};
server_name = mkOption { server_name = mkOpt types.str ''
type = types.nullOr types.str;
default = null;
description = ''
ServerName extension to indicate the name of the server. ServerName extension to indicate the name of the server.
http://tools.ietf.org/html/rfc4366#section-3.1 http://tools.ietf.org/html/rfc4366#section-3.1
''; '';
};
insecure_skip_verify = mkOption { insecure_skip_verify = mkOpt types.bool ''
type = types.bool;
default = false;
description = ''
Disable validation of the server certificate. Disable validation of the server certificate.
''; '';
}; };
}; };
};
in { in {
options = { options = {
@ -662,7 +586,6 @@ in {
globalConfig = mkOption { globalConfig = mkOption {
type = promTypes.globalConfig; type = promTypes.globalConfig;
default = {}; default = {};
apply = _filter;
description = '' description = ''
Parameters that are valid in all configuration contexts. They Parameters that are valid in all configuration contexts. They
also serve as defaults for other configuration sections also serve as defaults for other configuration sections
@ -688,7 +611,6 @@ in {
scrapeConfigs = mkOption { scrapeConfigs = mkOption {
type = types.listOf promTypes.scrape_config; type = types.listOf promTypes.scrape_config;
default = []; default = [];
apply = x: map _filter x;
description = '' description = ''
A list of scrape configurations. A list of scrape configurations.
''; '';
@ -786,7 +708,6 @@ in {
globalConfig = mkOption { globalConfig = mkOption {
type = promTypes.globalConfig; type = promTypes.globalConfig;
default = {}; default = {};
apply = _filter;
description = '' description = ''
Parameters that are valid in all configuration contexts. They Parameters that are valid in all configuration contexts. They
also serve as defaults for other configuration sections also serve as defaults for other configuration sections
@ -812,7 +733,6 @@ in {
scrapeConfigs = mkOption { scrapeConfigs = mkOption {
type = types.listOf promTypes.scrape_config; type = types.listOf promTypes.scrape_config;
default = []; default = [];
apply = x: map _filter x;
description = '' description = ''
A list of scrape configurations. A list of scrape configurations.
''; '';