From 09c8d909fbad6fb47fa683de78d959067b914e51 Mon Sep 17 00:00:00 2001 From: Jaka Hudoklin Date: Mon, 20 Oct 2014 13:27:21 +0200 Subject: [PATCH] nixos/graphite: update docs, add graphite pager --- .../modules/services/monitoring/graphite.nix | 390 +++++++++++------- 1 file changed, 234 insertions(+), 156 deletions(-) diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix index 3d97c31b7a1..43e0fa05f66 100644 --- a/nixos/modules/services/monitoring/graphite.nix +++ b/nixos/modules/services/monitoring/graphite.nix @@ -24,6 +24,8 @@ let GRAPHITE_URL = cfg.seyren.graphiteUrl; } // cfg.seyren.extraConfig; + pagerConfig = pkgs.writeText "alarms.yaml" cfg.pager.alerts; + configDir = pkgs.buildEnv { name = "graphite-config"; paths = lists.filter (el: el != null) [ @@ -83,13 +85,21 @@ in { api = { enable = mkOption { - description = "Whether to enable graphite api."; + description = '' + Whether to enable graphite api. Graphite api is lightweight alternative + to graphite web, with api and without dashboard. It's advised to use + grafana as alternative dashboard and influxdb as alternative to + graphite carbon. + + For more information visit + + ''; default = false; type = types.uniq types.bool; }; finders = mkOption { - description = "List of finder plugins load."; + description = "List of finder plugins to load."; default = []; example = [ pkgs.python27Packages.graphite_influxdb ]; type = types.listOf types.package; @@ -301,170 +311,238 @@ in { ''; }; }; + + pager = { + enable = mkOption { + description = '' + Whether to enable graphite-pager service. For more information visit + + ''; + default = false; + type = types.uniq types.bool; + }; + + redisUrl = mkOption { + description = "Redis connection string."; + default = "redis://localhost:${toString config.services.redis.port}/"; + type = types.str; + }; + + graphiteUrl = mkOption { + description = "URL to your graphite service."; + default = "http://${cfg.web.host}:${toString cfg.web.port}"; + type = types.str; + }; + + alerts = mkOption { + description = "Alerts configuration for graphite-pager."; + default = '' + alerts: + - target: constantLine(100) + warning: 90 + critical: 200 + name: Test + ''; + example = literalExample '' + pushbullet_key: pushbullet_api_key + alerts: + - target: stats.seatgeek.app.deal_quality.venue_info_cache.hit + warning: .5 + critical: 1 + name: Deal quality venue cache hits + ''; + type = types.lines; + }; + }; }; ###### implementation - config = mkIf ( - cfg.carbon.enableAggregator || - cfg.carbon.enableCache || - cfg.carbon.enableRelay || - cfg.web.enable || - cfg.api.enable || - cfg.seyren.enable - ) { - systemd.services.carbonCache = { - enable = cfg.carbon.enableCache; - description = "Graphite Data Storage Backend"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; - environment = carbonEnv; - serviceConfig = { - ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-cache"}"; - User = "graphite"; - Group = "graphite"; - PermissionsStartOnly = true; - }; - preStart = '' - mkdir -p ${cfg.dataDir}/whisper - chmod 0700 ${cfg.dataDir}/whisper - chown -R graphite:graphite ${cfg.dataDir} - ''; - }; - - systemd.services.carbonAggregator = { - enable = cfg.carbon.enableAggregator; - description = "Carbon Data Aggregator"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; - environment = carbonEnv; - serviceConfig = { - ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-aggregator"}"; - User = "graphite"; - Group = "graphite"; - }; - }; - - systemd.services.carbonRelay = { - enable = cfg.carbon.enableRelay; - description = "Carbon Data Relay"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; - environment = carbonEnv; - serviceConfig = { - ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-relay"}"; - User = "graphite"; - Group = "graphite"; - }; - }; - - systemd.services.graphiteWeb = { - enable = cfg.web.enable; - description = "Graphite Web Interface"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; - path = [ pkgs.perl ]; - environment = { - PYTHONPATH = "${pkgs.python27Packages.graphite_web}/lib/python2.7/site-packages"; - DJANGO_SETTINGS_MODULE = "graphite.settings"; - GRAPHITE_CONF_DIR = configDir; - GRAPHITE_STORAGE_DIR = dataDir; - }; - serviceConfig = { - ExecStart = '' - ${pkgs.python27Packages.waitress}/bin/waitress-serve \ - --host=${cfg.web.host} --port=${toString cfg.web.port} \ - --call django.core.handlers.wsgi:WSGIHandler''; - User = "graphite"; - Group = "graphite"; - PermissionsStartOnly = true; - }; - preStart = '' - if ! test -e ${dataDir}/db-created; then - mkdir -p ${dataDir}/{whisper/,log/webapp/} - chmod 0700 ${dataDir}/{whisper/,log/webapp/} - - # populate database - ${pkgs.python27Packages.graphite_web}/bin/manage-graphite.py syncdb --noinput - - # create index - ${pkgs.python27Packages.graphite_web}/bin/build-index.sh - - touch ${dataDir}/db-created - + config = mkMerge [ + (mkIf cfg.carbon.enableCache { + systemd.services.carbonCache = { + description = "Graphite Data Storage Backend"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" ]; + environment = carbonEnv; + serviceConfig = { + ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-cache"}"; + User = "graphite"; + Group = "graphite"; + PermissionsStartOnly = true; + }; + preStart = '' + mkdir -p ${cfg.dataDir}/whisper + chmod 0700 ${cfg.dataDir}/whisper chown -R graphite:graphite ${cfg.dataDir} - fi - ''; - }; - - systemd.services.graphiteApi = { - enable = cfg.api.enable; - description = "Graphite Api Interface"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" ]; - environment = { - PYTHONPATH = - "${cfg.api.package}/lib/python2.7/site-packages:" + - concatMapStringsSep ":" (f: f + "/lib/python2.7/site-packages") cfg.api.finders; - GRAPHITE_API_CONFIG = graphiteApiConfig; - LD_LIBRARY_PATH = "${pkgs.cairo}/lib"; - }; - serviceConfig = { - ExecStart = '' - ${pkgs.python27Packages.waitress}/bin/waitress-serve \ - --host=${cfg.api.host} --port=${toString cfg.api.port} \ - graphite_api.app:app ''; - User = "graphite"; - Group = "graphite"; - PermissionsStartOnly = true; }; - preStart = '' - if ! test -e ${dataDir}/db-created; then - mkdir -p ${dataDir}/cache/ - chmod 0700 ${dataDir}/cache/ + }) - touch ${dataDir}/db-created - - chown -R graphite:graphite ${cfg.dataDir} - fi - ''; - }; - - systemd.services.seyren = { - enable = cfg.seyren.enable; - description = "Graphite Alerting Dashboard"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-interfaces.target" "mongodb.service" ]; - environment = seyrenConfig; - serviceConfig = { - ExecStart = "${pkgs.seyren}/bin/seyren -httpPort ${toString cfg.seyren.port}"; - WorkingDirectory = dataDir; - User = "graphite"; - Group = "graphite"; + (mkIf cfg.carbon.enableAggregator { + systemd.services.carbonAggregator = { + enable = cfg.carbon.enableAggregator; + description = "Carbon Data Aggregator"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" ]; + environment = carbonEnv; + serviceConfig = { + ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-aggregator"}"; + User = "graphite"; + Group = "graphite"; + }; }; - preStart = '' - if ! test -e ${dataDir}/db-created; then - mkdir -p ${dataDir} - chown -R graphite:graphite ${dataDir} - fi - ''; - }; + }) - services.mongodb.enable = mkDefault cfg.seyren.enable; + (mkIf cfg.carbon.enableRelay { + systemd.services.carbonRelay = { + description = "Carbon Data Relay"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" ]; + environment = carbonEnv; + serviceConfig = { + ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-relay"}"; + User = "graphite"; + Group = "graphite"; + }; + }; + }) - environment.systemPackages = [ - pkgs.pythonPackages.carbon - pkgs.python27Packages.graphite_web - pkgs.python27Packages.waitress - ]; + (mkIf (cfg.carbon.enableCache || cfg.carbon.enableAggregator || cfg.carbon.enableRelay) { + environment.systemPackages = [ + pkgs.pythonPackages.carbon + ]; + }) - users.extraUsers = singleton { - name = "graphite"; - uid = config.ids.uids.graphite; - description = "Graphite daemon user"; - home = dataDir; - }; - users.extraGroups.graphite.gid = config.ids.gids.graphite; - }; + (mkIf cfg.web.enable { + systemd.services.graphiteWeb = { + description = "Graphite Web Interface"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" ]; + path = [ pkgs.perl ]; + environment = { + PYTHONPATH = "${pkgs.python27Packages.graphite_web}/lib/python2.7/site-packages"; + DJANGO_SETTINGS_MODULE = "graphite.settings"; + GRAPHITE_CONF_DIR = configDir; + GRAPHITE_STORAGE_DIR = dataDir; + }; + serviceConfig = { + ExecStart = '' + ${pkgs.python27Packages.waitress}/bin/waitress-serve \ + --host=${cfg.web.host} --port=${toString cfg.web.port} \ + --call django.core.handlers.wsgi:WSGIHandler''; + User = "graphite"; + Group = "graphite"; + PermissionsStartOnly = true; + }; + preStart = '' + if ! test -e ${dataDir}/db-created; then + mkdir -p ${dataDir}/{whisper/,log/webapp/} + chmod 0700 ${dataDir}/{whisper/,log/webapp/} + + # populate database + ${pkgs.python27Packages.graphite_web}/bin/manage-graphite.py syncdb --noinput + + # create index + ${pkgs.python27Packages.graphite_web}/bin/build-index.sh + + touch ${dataDir}/db-created + + chown -R graphite:graphite ${cfg.dataDir} + fi + ''; + }; + + environment.systemPackages = [ pkgs.python27Packages.graphite_web ]; + }) + + (mkIf cfg.api.enable { + systemd.services.graphiteApi = { + description = "Graphite Api Interface"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" ]; + environment = { + PYTHONPATH = + "${cfg.api.package}/lib/python2.7/site-packages:" + + concatMapStringsSep ":" (f: f + "/lib/python2.7/site-packages") cfg.api.finders; + GRAPHITE_API_CONFIG = graphiteApiConfig; + LD_LIBRARY_PATH = "${pkgs.cairo}/lib"; + }; + serviceConfig = { + ExecStart = '' + ${pkgs.python27Packages.waitress}/bin/waitress-serve \ + --host=${cfg.api.host} --port=${toString cfg.api.port} \ + graphite_api.app:app + ''; + User = "graphite"; + Group = "graphite"; + PermissionsStartOnly = true; + }; + preStart = '' + if ! test -e ${dataDir}/db-created; then + mkdir -p ${dataDir}/cache/ + chmod 0700 ${dataDir}/cache/ + + touch ${dataDir}/db-created + + chown -R graphite:graphite ${cfg.dataDir} + fi + ''; + }; + }) + + (mkIf cfg.seyren.enable { + systemd.services.seyren = { + description = "Graphite Alerting Dashboard"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" "mongodb.service" ]; + environment = seyrenConfig; + serviceConfig = { + ExecStart = "${pkgs.seyren}/bin/seyren -httpPort ${toString cfg.seyren.port}"; + WorkingDirectory = dataDir; + User = "graphite"; + Group = "graphite"; + }; + preStart = '' + if ! test -e ${dataDir}/db-created; then + mkdir -p ${dataDir} + chown -R graphite:graphite ${dataDir} + fi + ''; + }; + + services.mongodb.enable = mkDefault true; + }) + + (mkIf cfg.pager.enable { + systemd.services.graphitePager = { + description = "Graphite Pager Alerting Daemon"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-interfaces.target" "redis.service" ]; + environment = { + REDIS_URL = cfg.pager.redisUrl; + GRAPHITE_URL = cfg.pager.graphiteUrl; + }; + serviceConfig = { + ExecStart = "${pkgs.pythonPackages.graphite_pager}/bin/graphite-pager --config ${pagerConfig}"; + User = "graphite"; + Group = "graphite"; + }; + }; + + services.redis.enable = mkDefault true; + + environment.systemPackages = [ pkgs.pythonPackages.graphite_pager ]; + }) + + { + users.extraUsers = singleton { + name = "graphite"; + uid = config.ids.uids.graphite; + description = "Graphite daemon user"; + home = dataDir; + }; + users.extraGroups.graphite.gid = config.ids.gids.graphite; + } + ]; }