Grafana: Difference between revisions

Klinger (talk | contribs)
Axka (talk | contribs)
Add infobox and Template:File-based codeblocks
 
(6 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[https://grafana.com/ Grafana] is an open-source, general purpose dashboarding tool, which runs as a web application. It can be used to create a variety of time-series graphs and also for displaying logs. It supports Prometheus, graphite, InfluxDB, opentsdb, Grafana Loki, PostgreSQL and many other data sources.
'''[https://grafana.com/grafana/ Grafana]''' is an open-source, general purpose visualization and dashboarding tool, which runs as a web application. It can be used to create time-series graphs and display logs. For data sources, it supports [[Prometheus]], graphite, InfluxDB, opentsdb, [[Grafana Loki]], [[PostgreSQL]] and more.


See [https://search.nixos.org/options?query=services.grafana Grafana options]
{{infobox application
  |name=Grafana
  |image=Grafana logo.svg
  |developer=Grafana Labs
  |type=Visualization and dashboarding tool
  |status=Active
  |license=GNU Affero General Public License v3.0 only
  |programmingLanguage=Go and TypeScript
  |github=grafana/grafana
  |documentation=https://grafana.com/docs/grafana/latest/
}}


== Installation ==
== Installation ==


Grafana is available as NixOS module, it can be enabled using the following config:
Grafana is available as NixOS module: {{nixos:option|services.grafana}}. [https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/ Official documentation] for the options inside <code>settings</code>. Here is a basic config:


<syntaxhighlight lang=nix>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
services.grafana = {
{
  enable = true;
  services.grafana = {
  settings = {
    enable = true;
    server = {
    settings = {
      # Listening Address
      server = {
      http_addr = "127.0.0.1";
        http_addr = "127.0.0.1";
      # and Port
        http_port = 3000;
      http_port = 3000;
        enforce_domain = true;
      # Grafana needs to know on which domain and URL it's running
        enable_gzip = true;
      domain = "your.domain";
        domain = "grafana.your.domain";
      root_url = "https://your.domain/grafana/"; # Not needed if it is `https://your.domain/`
 
       serve_from_sub_path = true;
        # Alternatively, if you want to serve Grafana from a subpath:
        # domain = "your.domain";
        # root_url = "https://your.domain/grafana/";
        # serve_from_sub_path = true;
      };
 
      # Prevents Grafana from phoning home
       #analytics.reporting_enabled = false;
     };
     };
   };
   };
};
}
</syntaxhighlight>
</nowiki>}}
 
== Usage ==
Grafana can be used through tunnels, like a SSH tunnel, or a VPN tunnel like Wireguard or Headscale. This way, Grafana can be completely shielded from the outside.
 
Another way is to make it publicly available, usually behind a reverse proxy.


This will make Grafana available only at localhost. On a server, it might be used through SSH tunnel or made publicly available using nginx with TLS. For example the follwing [[Nginx]] configuration can be used:
==== Nginx ====
<syntaxhighlight lang=nix>
Here is how to setup [[Nginx]] such that it proxies <code>your.domain/grafana</code> to your Grafana instance:
services.nginx.virtualHosts."your.domain" = {
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
  addSSL = true;
{
  enableACME = true;
  services.nginx.virtualHosts."your.domain" = {
  locations."/grafana/" = {
    addSSL = true;
    enableACME = true;
    locations."/grafana/" = {
       proxyPass = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}";
       proxyPass = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}";
       proxyWebsockets = true;
       proxyWebsockets = true;
       recommendedProxySettings = true;
       recommendedProxySettings = true;
    };
  };
}
</nowiki>}}
==== Traefik ====
[[Traefik]] is another common reverse proxy, for which the configuration relevant to Grafana would like this:
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{
  services.traefik = {
    # ...
    dynamicConfigOptions = {
      http.routers."your.domain" = {
          rule = "Host(`your.domain`) && PathPrefix(`/grafana`)";
          service = "grafana";
      }
      http.services."grafana" = {
          loadBalancer.servers = [ {
              url = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}";
          } ]
      };
    # ...
   };
   };
};
}
</nowiki>}}
 
Alternatively, to use Grafana on <code>grafana.your.domain</code> instead of <code>your.domain/grafana</code>, you could change line 5 above to:
 
<syntaxhighlight lang="diff">
-rule = "Host(`your.domain`) && PathPrefix(`/grafana`)";
+rule = "Host(`grafana.your.domain`)";
</syntaxhighlight>
</syntaxhighlight>


== Configuration ==
== Configuration ==


Everything else (data sources, users, dashboards, ...) can be configured either in the Web UI, or as code.
Everything (data sources, users, dashboards, ...) can be configured either in the Web UI or provisioned as code using Nix.


=== Via Web UI ===
=== Via Web UI ===
Line 52: Line 105:
=== Declarative configuration ===
=== Declarative configuration ===


<syntaxhighlight lang="nix">
Grafana supports [https://grafana.com/docs/grafana/latest/administration/provisioning/ provisioning] data sources, dashboards and alerting using {{nixos:option|services.grafana.provision}}. Note that removing a provision and switching to the new NixOS configuration does not currently remove the provisioned items; you have to define them, for example, in <code>deleteDatasources</code>.
services.grafana = {
 
  declarativePlugins = with pkgs.grafanaPlugins; [ ... ];
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{
  services.grafana = {
    declarativePlugins = with pkgs.grafanaPlugins; [ ... ];


  provision = {
    provision = {
    enable = true;
      enable = true;


    dashboards.settings.providers = [{
      # Creates a *mutable* dashboard provider, pulling from /etc/grafana-dashboards.
      name = "my dashboards";
      # With this, you can manually provision dashboards from JSON with `environment.etc` like below.
      options.path = "/etc/grafana-dashboards";
      dashboards.settings.providers = [{
    }];
        name = "my dashboards";
        disableDeletion = true;
        options = {
          path = "/etc/grafana-dashboards";
          foldersFromFilesStructure = true;
        };
      }];


    datasources.settings.datasources = [
      datasources.settings.datasources = [
      # "Built-in" datasources can be provisioned - c.f. https://grafana.com/docs/grafana/latest/administration/provisioning/#data-sources
        # Provisioning a built-in data source
      {
        {
        name = "Prometheus";
          name = "Prometheus";
        type = "prometheus";
          type = "prometheus";
        url = "http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}";
          url = "http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}";
      }
          isDefault = true;
      # Some plugins also can - c.f. https://grafana.com/docs/plugins/yesoreyeram-infinity-datasource/latest/setup/provisioning/
          editable = false;
      {
        }
        name = "Infinity";
        # All plugins can be provisioned but it's not always documented: https://github.com/fr-ser/grafana-sqlite-datasource/blob/main/docs/faq.md#can-i-use-provisioning-with-this-plugin
        type = "yesoreyeram-infinity-datasource";
        # Compare below with https://grafana.com/docs/plugins/yesoreyeram-infinity-datasource/latest/setup/provisioning/
      }
        {
       # But not all - c.f. https://github.com/fr-ser/grafana-sqlite-datasource/issues/141
          name = "Infinity";
    ];
          type = "yesoreyeram-infinity-datasource";
          editable = false;
        }
       ];


    # Note: removing attributes from the above `datasources.settings.datasources` is not enough for them to be deleted on `grafana`;
      # Note: removing attributes from the above `datasources.settings.datasources` is not currently enough for them to be deleted;
    # One needs to use the following option:
      # One needs to use the following option:
    # datasources.settings.deleteDatasources = [ { name = "foo"; orgId = 1; } { name = "bar"; orgId = 1; } ];
      # datasources.settings.deleteDatasources = [ { name = "foo"; orgId = 1; } { name = "bar"; orgId = 1; } ];
    };
   };
   };
};


environment.etc = [{
 
   source = ./. + "/grafana-dashboards/some-dashboard.json";
  # see `dashboards.settings.providers` above
  group = "grafana";
   environment.etc."grafana-dashboards/some-dashboard.json".source = ./some-dashboard.json;
  user = "grafana";
}
}];
</nowiki>}}
</syntaxhighlight>


== External Links ==
== External Links ==