1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8let
9 inherit (lib)
10 mkEnableOption
11 mkIf
12 mkOption
13 types
14 ;
15
16 cfg = config.services.tempo;
17
18 settingsFormat = pkgs.formats.yaml { };
19in
20{
21 options.services.tempo = {
22 enable = mkEnableOption "Grafana Tempo";
23
24 settings = mkOption {
25 type = settingsFormat.type;
26 default = { };
27 description = ''
28 Specify the configuration for Tempo in Nix.
29
30 See <https://grafana.com/docs/tempo/latest/configuration/> for available options.
31 '';
32 };
33
34 configFile = mkOption {
35 type = types.nullOr types.path;
36 default = null;
37 description = ''
38 Specify a path to a configuration file that Tempo should use.
39 '';
40 };
41
42 extraFlags = mkOption {
43 type = types.listOf types.str;
44 default = [ ];
45 example = lib.literalExpression ''
46 [ "-config.expand-env=true" ]
47 '';
48 description = ''
49 Additional flags to pass to the `ExecStart=` in `tempo.service`.
50 '';
51 };
52 };
53
54 config = mkIf cfg.enable {
55 # for tempo-cli and friends
56 environment.systemPackages = [ pkgs.tempo ];
57
58 assertions = [
59 {
60 assertion = ((cfg.settings == { }) != (cfg.configFile == null));
61 message = ''
62 Please specify a configuration for Tempo with either
63 'services.tempo.settings' or
64 'services.tempo.configFile'.
65 '';
66 }
67 ];
68
69 systemd.services.tempo = {
70 description = "Grafana Tempo Service Daemon";
71 wantedBy = [ "multi-user.target" ];
72
73 serviceConfig =
74 let
75 conf =
76 if cfg.configFile == null then
77 settingsFormat.generate "config.yaml" cfg.settings
78 else
79 cfg.configFile;
80 in
81 {
82 ExecStart = "${pkgs.tempo}/bin/tempo --config.file=${conf} ${lib.escapeShellArgs cfg.extraFlags}";
83 DynamicUser = true;
84 Restart = "always";
85 ProtectSystem = "full";
86 DevicePolicy = "closed";
87 NoNewPrivileges = true;
88 WorkingDirectory = "/var/lib/tempo";
89 StateDirectory = "tempo";
90 };
91 };
92 };
93}