Merge pull request #94673 from justinas/prom-sql-exporter

prometheus-sql-exporter: init at 0.3.0

Changed files
+181
nixos
modules
services
monitoring
prometheus
tests
pkgs
servers
monitoring
prometheus
top-level
+9
nixos/modules/services/monitoring/prometheus/exporters.nix
···
"rspamd"
"rtl_433"
"snmp"
+
"sql"
"surfboard"
"tor"
"unifi"
···
message = ''
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 {
+104
nixos/modules/services/monitoring/prometheus/exporters/sql.nix
···
+
{ 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}
+
'';
+
};
+
};
+
}
+44
nixos/tests/prometheus-exporters.nix
···
'';
};
+
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 = "prometheus-sql-exporter";
+
};
+
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;
+23
pkgs/servers/monitoring/prometheus/sql-exporter.nix
···
+
{ stdenv, buildGoModule, fetchFromGitHub, nixosTests }:
+
+
buildGoModule rec {
+
pname = "sql_exporter";
+
version = "0.3.0";
+
+
vendorSha256 = null;
+
+
src = fetchFromGitHub {
+
owner = "justwatchcom";
+
repo = "sql_exporter";
+
rev = "v${version}";
+
sha256 = "125brlxgwhkn3z5v0522gpm0sk6v905ghh05c4c3wf1hlm7bhnrc";
+
};
+
+
meta = with stdenv.lib; {
+
description = "Flexible SQL exporter for Prometheus";
+
homepage = "https://github.com/justwatchcom/sql_exporter";
+
license = licenses.mit;
+
maintainers = with maintainers; [ justinas ];
+
platforms = platforms.unix;
+
};
+
}
+1
pkgs/top-level/all-packages.nix
···
prometheus-rabbitmq-exporter = callPackage ../servers/monitoring/prometheus/rabbitmq-exporter.nix { };
prometheus-rtl_433-exporter = callPackage ../servers/monitoring/prometheus/rtl_433-exporter.nix { };
prometheus-snmp-exporter = callPackage ../servers/monitoring/prometheus/snmp-exporter.nix { };
+
prometheus-sql-exporter = callPackage ../servers/monitoring/prometheus/sql-exporter.nix { };
prometheus-tor-exporter = callPackage ../servers/monitoring/prometheus/tor-exporter.nix { };
prometheus-statsd-exporter = callPackage ../servers/monitoring/prometheus/statsd-exporter.nix { };
prometheus-surfboard-exporter = callPackage ../servers/monitoring/prometheus/surfboard-exporter.nix { };