diff --git a/lib/maintainers.nix b/lib/maintainers.nix index 6665539b0e80..e76de34ba60e 100644 --- a/lib/maintainers.nix +++ b/lib/maintainers.nix @@ -255,6 +255,7 @@ romildo = "José Romildo Malaquias "; rszibele = "Richard Szibele "; rushmorem = "Rushmore Mushambi "; + rvl = "Rodney Lorrimar "; rycee = "Robert Helgesson "; samuelrivas = "Samuel Rivas "; sander = "Sander van der Burg "; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index ecdf2264d698..c4cea424c607 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -240,6 +240,7 @@ ./services/monitoring/grafana.nix ./services/monitoring/graphite.nix ./services/monitoring/heapster.nix + ./services/monitoring/longview.nix ./services/monitoring/monit.nix ./services/monitoring/munin.nix ./services/monitoring/nagios.nix diff --git a/nixos/modules/services/monitoring/longview.nix b/nixos/modules/services/monitoring/longview.nix new file mode 100644 index 000000000000..770d56e60efb --- /dev/null +++ b/nixos/modules/services/monitoring/longview.nix @@ -0,0 +1,118 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.longview; + + pidFile = "/run/longview.pid"; + + apacheConf = optionalString (cfg.apacheStatusUrl != "") '' + location ${cfg.apacheStatusUrl}?auto + ''; + mysqlConf = optionalString (cfg.mysqlUser != "") '' + username ${cfg.mysqlUser} + password ${cfg.mysqlPassword} + ''; + nginxConf = optionalString (cfg.nginxStatusUrl != "") '' + location ${cfg.nginxStatusUrl} + ''; + +in + +{ + options = { + + services.longview = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + If enabled, system metrics will be sent to Linode LongView. + ''; + }; + + apiKey = mkOption { + type = types.str; + example = "01234567-89AB-CDEF-0123456789ABCDEF"; + description = '' + Longview API key. To get this, look in Longview settings which + are found at https://manager.linode.com/longview/. + ''; + }; + + apacheStatusUrl = mkOption { + type = types.str; + default = ""; + example = "http://127.0.0.1/server-status"; + description = '' + The Apache status page URL. If provided, Longview will + gather statistics from this location. This requires Apache + mod_status to be loaded and enabled. + ''; + }; + + nginxStatusUrl = mkOption { + type = types.str; + default = ""; + example = "http://127.0.0.1/nginx_status"; + description = '' + The Nginx status page URL. Longview will gather statistics + from this URL. This requires the Nginx stub_status module to + be enabled and configured at the given location. + ''; + }; + + mysqlUser = mkOption { + type = types.str; + default = ""; + description = '' + The user for connecting to the MySQL database. If provided, + Longview will connect to MySQL and collect statistics about + queries, etc. This user does not need to have been granted + any extra privileges. + ''; + }; + + mysqlPassword = mkOption { + type = types.str; + description = '' + The password corresponding to mysqlUser. Warning: this is + stored in cleartext in the Nix store! + ''; + }; + }; + + }; + + config = mkIf cfg.enable { + systemd.services.longview = + { description = "Longview Metrics Collection"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig.Type = "forking"; + serviceConfig.ExecStop = "-${pkgs.coreutils}/bin/kill -TERM $MAINPID"; + serviceConfig.ExecReload = "-${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + serviceConfig.PIDFile = pidFile; + serviceConfig.ExecStart = "${pkgs.longview}/bin/longview"; + }; + + environment.etc."linode/longview.key" = { + mode = "0400"; + text = cfg.apiKey; + }; + environment.etc."linode/longview.d/Apache.conf" = { + mode = "0400"; + text = apacheConf; + }; + environment.etc."linode/longview.d/MySQL.conf" = { + mode = "0400"; + text = mysqlConf; + }; + environment.etc."linode/longview.d/Nginx.conf" = { + mode = "0400"; + text = nginxConf; + }; + }; +} diff --git a/pkgs/servers/monitoring/longview/default.nix b/pkgs/servers/monitoring/longview/default.nix new file mode 100644 index 000000000000..3c08f48e4101 --- /dev/null +++ b/pkgs/servers/monitoring/longview/default.nix @@ -0,0 +1,62 @@ +{stdenv, fetchFromGitHub, perl, perlPackages, makeWrapper, glibc }: + +stdenv.mkDerivation rec { + version = "1.1.5pre"; + name = "longview-${version}"; + + src = fetchFromGitHub { + owner = "linode"; + repo = "longview"; + rev = "5bcc9b60896b72de2d14f046f911477c26eb70ba"; + sha256 = "1i6va44bx2zfgbld7znf1slph0iqidlahq2xh3kd8q4lhvbrjn02"; + }; + + patches = + [ # log to systemd journal + ./log-stdout.patch + ]; + + postPatch = + '' + substituteInPlace Linode/Longview/Util.pm --replace /var/run/longview.pid /run/longview.pid + ''; + + buildInputs = [ perl makeWrapper glibc ] + ++ (with perlPackages; [ + LWPUserAgent + LWPProtocolHttps + MozillaCA + CryptSSLeay + IOSocketInet6 + LinuxDistribution + JSONPP + JSON + LogLogLite + TryTiny + DBI + DBDmysql + ]); + + buildPhase = "true"; + installPhase = '' + mkdir -p $out/bin $out/usr + mv Linode $out + ln -s ../Linode/Longview.pl $out/bin/longview + for h in syscall.h sys/syscall.h asm/unistd.h asm/unistd_32.h asm/unistd_64.h bits/wordsize.h bits/syscall.h; do + ${perl}/bin/h2ph -d $out ${glibc}/include/$h + mkdir -p $out/usr/include/$(dirname $h) + mv $out${glibc}/include/''${h%.h}.ph $out/usr/include/$(dirname $h) + done + wrapProgram $out/Linode/Longview.pl --prefix PATH : ${perl}/bin:$out/bin \ + --suffix PERL5LIB : $out/Linode --suffix PERL5LIB : $PERL5LIB \ + --suffix PERL5LIB : $out --suffix INC : $out + ''; + + meta = with stdenv.lib; { + homepage = https://www.linode.com/longview; + description = "Longview collects all of your system-level metrics and sends them to Linode."; + license = licenses.gpl2Plus; + maintainers = [ maintainers.rvl ]; + inherit version; + }; +} diff --git a/pkgs/servers/monitoring/longview/log-stdout.patch b/pkgs/servers/monitoring/longview/log-stdout.patch new file mode 100644 index 000000000000..3e009254bcad --- /dev/null +++ b/pkgs/servers/monitoring/longview/log-stdout.patch @@ -0,0 +1,38 @@ +diff -ru longview-5bcc9b60896b72de2d14f046f911477c26eb70ba-src.orig/Linode/Longview/Logger.pm longview-5bcc9b60896b72de2d14f046f911477c26eb70ba-src/Linode/Longview/Logger.pm +--- longview-5bcc9b60896b72de2d14f046f911477c26eb70ba-src.orig/Linode/Longview/Logger.pm 2015-10-28 17:15:32.816515318 +0000 ++++ longview-5bcc9b60896b72de2d14f046f911477c26eb70ba-src/Linode/Longview/Logger.pm 2015-10-28 18:00:50.760332026 +0000 +@@ -26,9 +26,7 @@ + my ( $self, $message ) = @_; + + my $ts = strftime( '%m/%d %T', localtime ); +- $self->{logger}->write( +- sprintf( '%s %s Longview[%i] - %s', $ts, uc($level), $$, $message ), +- $levels->{$level} ); ++ printf( "%s %s Longview[%i] - %s\n", $ts, uc($level), $$, $message ); + die "$message" if $level eq 'logdie'; + }; + } +@@ -37,12 +35,6 @@ + my ( $class, $level ) = @_; + my $self = {}; + +- mkpath($LOGDIR) unless (-d $LOGDIR); +- $self->{logger} +- = Log::LogLite->new( $LOGDIR . 'longview.log', $level ) +- or die "Couldn't create logger object: $!"; +- $self->{logger}->template("\n"); +- + return bless $self, $class; + } + +diff -ru longview-5bcc9b60896b72de2d14f046f911477c26eb70ba-src.orig/Linode/Longview/Util.pm longview-5bcc9b60896b72de2d14f046f911477c26eb70ba-src/Linode/Longview/Util.pm +--- longview-5bcc9b60896b72de2d14f046f911477c26eb70ba-src.orig/Linode/Longview/Util.pm 2015-10-28 17:15:32.816515318 +0000 ++++ longview-5bcc9b60896b72de2d14f046f911477c26eb70ba-src/Linode/Longview/Util.pm 2015-10-28 19:20:30.894314658 +0000 +@@ -225,7 +225,6 @@ + #<<< perltidy ignore + chdir '/' or $logger->logdie("Can't chdir to /: $!"); + open STDIN, '<', '/dev/null' or $logger->logdie("Can't read /dev/null: $!"); +- open STDOUT, '>>', '/dev/null' or $logger->logdie("Can't write to /dev/null: $!"); + open STDERR, '>>', '/dev/null' or $logger->logdie("Can't write to /dev/null: $!"); + tie *STDERR, "Linode::Longview::STDERRLogger"; + defined( my $pid = fork ) or $logger->logdie("Can't fork: $!"); diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 74b827567576..04e1542af8cc 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2150,6 +2150,8 @@ let logstalgia = callPackage ../tools/graphics/logstalgia {}; + longview = callPackage ../servers/monitoring/longview { }; + lout = callPackage ../tools/typesetting/lout { }; lrzip = callPackage ../tools/compression/lrzip { }; diff --git a/pkgs/top-level/perl-packages.nix b/pkgs/top-level/perl-packages.nix index 4c5ef9ef9db3..e5ad6a827932 100644 --- a/pkgs/top-level/perl-packages.nix +++ b/pkgs/top-level/perl-packages.nix @@ -6238,6 +6238,18 @@ let self = _self // overrides; _self = with self; { doCheck = false; }; + LinuxDistribution = buildPerlPackage { + name = "Linux-Distribution-0.23"; + src = fetchurl { + url = mirror://cpan/authors/id/C/CH/CHORNY/Linux-Distribution-0.23.tar.gz; + sha256 = "603e27da607b3e872a669d7a66d75982f0969153eab2d4b20c341347b4ebda5f"; + }; + meta = { + description = "Perl extension to detect on which Linux distribution we are running"; + license = "perl"; + }; + }; + LinuxInotify2 = buildPerlPackage rec { name = "Linux-Inotify2-1.22"; src = fetchurl { @@ -6502,6 +6514,19 @@ let self = _self // overrides; _self = with self; { }; }; + LogLogLite = buildPerlPackage rec { + name = "Log-LogLite-0.82"; + src = fetchurl { + url = "mirror://cpan/authors/id/R/RA/RANI/${name}.tar.gz"; + sha256 = "0sqsa4750wvhw4cjmxpxqg30i1jjcddadccflisrdb23qn5zn285"; + }; + propagatedBuildInputs = [ IOLockedFile ]; + meta = { + description = "Helps us create simple logs for our application."; + license = "perl"; + }; + }; + LWP = buildPerlPackage rec { name = "libwww-perl-6.13"; src = fetchurl {