about summary refs log tree commit diff
path: root/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix
blob: 9587403c7802319ee1be0d0346a94267c32ac0da (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
{ config, lib, pkgs, options, ... }:

with lib;

let
  cfg = config.services.prometheus.exporters.pgbouncer;
in
{
  port = 9127;
  extraOpts = {

    telemetryPath = mkOption {
      type = types.str;
      default = "/metrics";
      description = lib.mdDoc ''
        Path under which to expose metrics.
      '';
    };

    connectionString = mkOption {
      type = types.str;
      default = "";
      example = "postgres://admin:@localhost:6432/pgbouncer?sslmode=require";
      description = lib.mdDoc ''
        Connection string for accessing pgBouncer.

        NOTE: You MUST keep pgbouncer as database name (special internal db)!!!

        NOTE: Admin user (with password or passwordless) MUST exist
        in the services.pgbouncer.authFile if authType other than any is used.

        WARNING: this secret is stored in the world-readable Nix store!
        Use {option}`connectionStringFile` instead.
      '';
    };

    connectionStringFile = mkOption {
      type = types.nullOr types.path;
      default = null;
      example = "/run/keys/pgBouncer-connection-string";
      description = lib.mdDoc ''
        File that contains pgBouncer connection string in format:
        postgres://admin:@localhost:6432/pgbouncer?sslmode=require

        NOTE: You MUST keep pgbouncer as database name (special internal db)!!!

        NOTE: Admin user (with password or passwordless) MUST exist
        in the services.pgbouncer.authFile if authType other than any is used.

        {option}`connectionStringFile` takes precedence over {option}`connectionString`
      '';
    };

    pidFile = mkOption {
      type = types.nullOr types.str;
      default = null;
      description = lib.mdDoc ''
        Path to PgBouncer pid file.

        If provided, the standard process metrics get exported for the PgBouncer
        process, prefixed with 'pgbouncer_process_...'. The pgbouncer_process exporter
        needs to have read access to files owned by the PgBouncer process. Depends on
        the availability of /proc.

        https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics.

      '';
    };

    webSystemdSocket = mkOption {
      type = types.bool;
      default = false;
      description = lib.mdDoc ''
        Use systemd socket activation listeners instead of port listeners (Linux only).
      '';
    };

    logLevel = mkOption {
      type = types.enum ["debug" "info" "warn" "error" ];
      default = "info";
      description = lib.mdDoc ''
        Only log messages with the given severity or above.
      '';
    };

    logFormat = mkOption {
      type = types.enum ["logfmt" "json"];
      default = "logfmt";
      description = lib.mdDoc ''
        Output format of log messages. One of: [logfmt, json]
      '';
    };

    webConfigFile = mkOption {
      type = types.nullOr types.path;
      default = null;
      description = lib.mdDoc ''
        Path to configuration file that can enable TLS or authentication.
      '';
    };

    extraFlags = mkOption {
      type = types.listOf types.str;
      default = [ ];
      description = lib.mdDoc ''
        Extra commandline options when launching Prometheus.
      '';
    };

  };

  serviceOpts = {
    after = [ "pgbouncer.service" ];
      serviceConfig = let
      startScript = pkgs.writeShellScriptBin "pgbouncer-start" "${concatStringsSep " " ([
            "${pkgs.prometheus-pgbouncer-exporter}/bin/pgbouncer_exporter"
            "--web.listen-address ${cfg.listenAddress}:${toString cfg.port}"
            "--pgBouncer.connectionString ${if cfg.connectionStringFile != null then
            "$(head -n1 ${cfg.connectionStringFile})" else "${escapeShellArg cfg.connectionString}"}"
          ]
            ++ optionals (cfg.telemetryPath != null) [
            "--web.telemetry-path ${escapeShellArg cfg.telemetryPath}"
          ]
            ++ optionals (cfg.pidFile != null) [
            "--pgBouncer.pid-file= ${escapeShellArg cfg.pidFile}"
          ]
            ++ optionals (cfg.logLevel != null) [
            "--log.level ${escapeShellArg cfg.logLevel}"
          ]
            ++ optionals (cfg.logFormat != null) [
            "--log.format ${escapeShellArg cfg.logFormat}"
          ]
            ++ optionals (cfg.webSystemdSocket != false) [
            "--web.systemd-socket ${escapeShellArg cfg.webSystemdSocket}"
          ]
            ++ optionals (cfg.webConfigFile != null) [
            "--web.config.file ${escapeShellArg cfg.webConfigFile}"
          ]
            ++ cfg.extraFlags)}";
      in
      {
        ExecStart = "${startScript}/bin/pgbouncer-start";
      };
  };
}