nixos/prometheus-sql-exporter: new module

This commit is contained in:
Justinas Stankevicius 2020-08-06 09:56:35 +03:00 committed by Maximilian Bosch
parent 01762fec0a
commit d447c2413c
No known key found for this signature in database
GPG Key ID: 091DBF4D1FC46B8E
3 changed files with 157 additions and 0 deletions

View File

@ -44,6 +44,7 @@ let
"redis"
"rspamd"
"snmp"
"sql"
"surfboard"
"tor"
"unifi"
@ -217,6 +218,14 @@ in
Please specify either 'services.prometheus.exporters.mail.configuration'
or 'services.prometheus.exporters.mail.configFile'.
'';
} {
assertion = cfg.sql.enable -> (
(cfg.sql.configFile == null) != (cfg.sql.configuration == null)
);
message = ''
Please specify either 'services.prometheus.exporters.sql.configuration' or
'services.prometheus.exporters.sql.configFile'
'';
} ];
}] ++ [(mkIf config.services.minio.enable {
services.prometheus.exporters.minio.minioAddress = mkDefault "http://localhost:9000";

View File

@ -0,0 +1,104 @@
{ 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}
'';
};
};
}

View File

@ -578,6 +578,50 @@ let
'';
};
sql = {
exporterConfig = {
configuration.jobs.points = {
interval = "1m";
connections = [
"postgres://prometheus-sql-exporter@/data?host=/run/postgresql&sslmode=disable"
];
queries = {
points = {
labels = [ "name" ];
help = "Amount of points accumulated per person";
values = [ "amount" ];
query = "SELECT SUM(amount) as amount, name FROM points GROUP BY name";
};
};
};
enable = true;
user = "postgres";
};
metricProvider = {
services.postgresql = {
enable = true;
initialScript = builtins.toFile "init.sql" ''
CREATE DATABASE data;
\c data;
CREATE TABLE points (amount INT, name TEXT);
INSERT INTO points(amount, name) VALUES (1, 'jack');
INSERT INTO points(amount, name) VALUES (2, 'jill');
INSERT INTO points(amount, name) VALUES (3, 'jack');
CREATE USER "prometheus-sql-exporter";
GRANT ALL PRIVILEGES ON DATABASE data TO "prometheus-sql-exporter";
GRANT SELECT ON points TO "prometheus-sql-exporter";
'';
};
systemd.services.prometheus-sql-exporter.after = [ "postgresql.service" ];
};
exporterTest = ''
wait_for_unit("prometheus-sql-exporter.service")
wait_for_open_port(9237)
succeed("curl http://localhost:9237/metrics | grep -c 'sql_points{' | grep -q 2")
'';
};
surfboard = {
exporterConfig = {
enable = true;