1{ config, lib, pkgs, options }:
2with lib;
3let
4 cfg = config.services.prometheus.exporters.sql;
5 cfgOptions = {
6 options = with types; {
7 jobs = mkOption {
8 type = attrsOf (submodule jobOptions);
9 default = { };
10 description = lib.mdDoc "An attrset of metrics scraping jobs to run.";
11 };
12 };
13 };
14 jobOptions = {
15 options = with types; {
16 interval = mkOption {
17 type = str;
18 description = lib.mdDoc ''
19 How often to run this job, specified in
20 [Go duration](https://golang.org/pkg/time/#ParseDuration) format.
21 '';
22 };
23 connections = mkOption {
24 type = listOf str;
25 description = lib.mdDoc "A list of connection strings of the SQL servers to scrape metrics from";
26 };
27 startupSql = mkOption {
28 type = listOf str;
29 default = [];
30 description = lib.mdDoc "A list of SQL statements to execute once after making a connection.";
31 };
32 queries = mkOption {
33 type = attrsOf (submodule queryOptions);
34 description = lib.mdDoc "SQL queries to run.";
35 };
36 };
37 };
38 queryOptions = {
39 options = with types; {
40 help = mkOption {
41 type = nullOr str;
42 default = null;
43 description = lib.mdDoc "A human-readable description of this metric.";
44 };
45 labels = mkOption {
46 type = listOf str;
47 default = [ ];
48 description = lib.mdDoc "A set of columns that will be used as Prometheus labels.";
49 };
50 query = mkOption {
51 type = str;
52 description = lib.mdDoc "The SQL query to run.";
53 };
54 values = mkOption {
55 type = listOf str;
56 description = lib.mdDoc "A set of columns that will be used as values of this metric.";
57 };
58 };
59 };
60
61 configFile =
62 if cfg.configFile != null
63 then cfg.configFile
64 else
65 let
66 nameInline = mapAttrsToList (k: v: v // { name = k; });
67 renameStartupSql = j: removeAttrs (j // { startup_sql = j.startupSql; }) [ "startupSql" ];
68 configuration = {
69 jobs = map renameStartupSql
70 (nameInline (mapAttrs (k: v: (v // { queries = nameInline v.queries; })) cfg.configuration.jobs));
71 };
72 in
73 builtins.toFile "config.yaml" (builtins.toJSON configuration);
74in
75{
76 extraOpts = {
77 configFile = mkOption {
78 type = with types; nullOr path;
79 default = null;
80 description = lib.mdDoc ''
81 Path to configuration file.
82 '';
83 };
84 configuration = mkOption {
85 type = with types; nullOr (submodule cfgOptions);
86 default = null;
87 description = lib.mdDoc ''
88 Exporter configuration as nix attribute set. Mutually exclusive with 'configFile' option.
89 '';
90 };
91 };
92
93 port = 9237;
94 serviceOpts = {
95 serviceConfig = {
96 ExecStart = ''
97 ${pkgs.prometheus-sql-exporter}/bin/sql_exporter \
98 -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
99 -config.file ${configFile} \
100 ${concatStringsSep " \\\n " cfg.extraFlags}
101 '';
102 RestrictAddressFamilies = [
103 # Need AF_UNIX to collect data
104 "AF_UNIX"
105 ];
106 };
107 };
108}