add grafana service (#108)

This commit is contained in:
Abhishek Singh 2024-02-22 22:25:51 +05:30 committed by GitHub
parent 15d573f319
commit 625f207034
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 174 additions and 0 deletions

40
doc/grafana.md Normal file
View File

@ -0,0 +1,40 @@
# Grafana
[Grafana open source](https://grafana.com/docs/grafana/latest/) is open source visualization and analytics software. It allows you to query, visualize, alert on, and explore your metrics, logs, and traces no matter where they are stored. It provides you with tools to turn your time-series database (TSDB) data into insightful graphs and visualizations.
## Getting Started
```nix
# In `perSystem.process-compose.<name>`
{
services.grafana."gf1".enable = true;
}
```
{#tips}
## Tips & Tricks
{#change-database}
### Changing Grafana database
By default, Grafana stores data in the `sqlite3` [database](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#database). It also supports `mysql` and `postgres`.
To change the database to `postgres`, we can use the following config:
```nix
services.postgres.pg1 = {
enable = true;
listen_addresses = "127.0.0.1";
initialScript.after = "CREATE USER root SUPERUSER;";
};
services.grafana.gf1 = {
enable = true;
extraConf.database = with config.services.postgres.pg1; {
type = "postgres";
host = "${listen_addresses}:${builtins.toString port}";
name = "postgres"; # database name
};
};
settings.processes."gf1".depends_on."pg1".condition = "process_healthy";
};
```

View File

@ -16,6 +16,7 @@ short-title: Services
- [ ] Redis
- [ ] Redis Cluster
- [ ] Zookeeper
- [ ] [[grafana]]#
- [ ] ...
[gh]: https://github.com/juspay/services-flake

View File

@ -13,5 +13,6 @@ in
./redis-cluster.nix
./redis.nix
./zookeeper.nix
./grafana.nix
];
}

99
nix/grafana.nix Normal file
View File

@ -0,0 +1,99 @@
{ pkgs, lib, name, config, ... }:
let
inherit (lib) types;
iniFormat = pkgs.formats.ini { };
in
{
options = {
description = ''
Configure grafana.
'';
enable = lib.mkEnableOption name;
package = lib.mkPackageOption pkgs "grafana" { };
http_port = lib.mkOption {
type = types.int;
description = "Which port to run grafana on.";
default = 3000;
};
domain = lib.mkOption {
type = types.str;
description = "The public facing domain name used to access grafana from a browser.";
default = "localhost";
};
protocol = lib.mkOption {
type = types.str;
description = "Protocol (http, https, h2, socket).";
default = "http";
};
dataDir = lib.mkOption {
type = types.str;
description = "Directory where grafana stores its logs and data.";
default = "./data/${name}";
};
extraConf = lib.mkOption {
type = iniFormat.type;
description = "Extra configuration for grafana.";
default = { };
example = ''
{
security.admin_user = "patato";
security.admin_password = "potato";
}
'';
};
outputs.settings = lib.mkOption {
type = types.deferredModule;
internal = true;
readOnly = true;
default = {
processes."${name}" =
let
grafanaConfig = lib.recursiveUpdate
{
server = {
inherit (config) protocol http_port domain;
};
}
config.extraConf;
grafanaConfigIni = iniFormat.generate "defaults.ini" grafanaConfig;
startScript = pkgs.writeShellApplication {
name = "start-grafana";
runtimeInputs = [ config.package ];
text = ''
grafana server --config ${grafanaConfigIni} \
--homepath ${config.package}/share/grafana \
cfg:paths.data="$(readlink -m ${config.dataDir})"
'';
};
in
{
command = startScript;
readiness_probe = {
http_get = {
host = config.domain;
scheme = config.protocol;
port = config.http_port;
path = "/api/health";
};
initial_delay_seconds = 15;
period_seconds = 10;
timeout_seconds = 2;
success_threshold = 1;
failure_threshold = 5;
};
namespace = name;
# https://github.com/F1bonacc1/process-compose#-auto-restart-if-not-healthy
availability.restart = "on_failure";
};
};
};
};
}

32
nix/grafana_test.nix Normal file
View File

@ -0,0 +1,32 @@
{ pkgs, config, ... }: {
services.grafana."gf1" =
{
enable = true;
http_port = 3000;
extraConf = {
security.admin_user = "patato";
security.admin_password = "potato";
};
};
settings.processes.test =
let
cfg = config.services.grafana."gf1";
in
{
# Tests based on: https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/grafana/basic.nix
command = pkgs.writeShellApplication {
runtimeInputs = [ cfg.package pkgs.gnugrep pkgs.curl pkgs.uutils-coreutils-noprefix ];
text =
''
ADMIN=${cfg.extraConf.security.admin_user}
PASSWORD=${cfg.extraConf.security.admin_password}
ROOT_URL="${cfg.protocol}://${cfg.domain}:${builtins.toString cfg.http_port}";
curl -sSfN -u $ADMIN:$PASSWORD $ROOT_URL/api/org/users -i
curl -sSfN -u $ADMIN:$PASSWORD $ROOT_URL/api/org/users | grep admin\@localhost
'';
name = "grafana-test";
};
depends_on."gf1".condition = "process_healthy";
};
}

View File

@ -46,6 +46,7 @@
"${inputs.services-flake}/nix/redis_test.nix"
"${inputs.services-flake}/nix/redis-cluster_test.nix"
"${inputs.services-flake}/nix/zookeeper_test.nix"
"${inputs.services-flake}/nix/grafana_test.nix"
]);
};
};