rrdaemon/cgi-bin/ 40755 0 0 0 7577277140 12320 5ustar rootwheelrrdaemon/database/ 40755 0 0 0 7577277145 12561 5ustar rootwheelrrdaemon/images/ 40777 0 0 0 7577277150 12262 5ustar rootwheelrrdaemon/library/ 40755 0 0 0 7542062274 12444 5ustar rootwheelrrdaemon/library/rrdaemon.si100644 0 0 5571 7542057636 14723 0ustar rootwheel#!/usr/bin/perl #------------------------------------------------------------------------------ # v1.0 (C) 17-Sep-2002 by Hard Wisdom # usage: specify devices to monitor or '*' to gather all data $comment = 'Dump statistics about SWAP usage'; @format = ('DS:value:GAUGE:600:0:U'); ($noavg, $nomax, $nomin) = (undef(), undef(), 1); #------------------------------------------------------------------------------ # We're going to reload configuration, clear all acquired data sources sub reload { undef %DEV; undef $CMD } #------------------------------------------------------------------------------ # Acquire data source to use for subsequent updates sub acquire { my ($target, $dev)=@_; $DEV{$dev}=$target; if ($DEV{'*'}) {$CMD = '/usr/sbin/swapinfo -k'} else { $CMD = '/usr/sbin/swapinfo -k ' . join(' ',keys %DEV); } } #------------------------------------------------------------------------------ # Emit data for graphing to call site sub graph { my ($hint, $database) = @_; return < $target, inps => $incoming, outs => $outgoing, inpf => 0, outf => 0 }; } #------------------------------------------------------------------------------ # Emit data for graphing to call site sub graph { my ($hint, $database) = @_; my (@area, @line); @area = ('inp_peak', 'Incoming, peak', 'inp_avg', 'Incoming, average' ); @line = ('out_peak', 'Outgoing, peak', 'out_avg', 'Outgoing, average' ); (@area[0..3], @line) = (@line, @area) if $GRAPH{$database}; return <{inpf} = $_->{outf} = 0 for @IF; for (`$CMD`) { my ($num, $pkt, $size, $rule) = split /\s+/, $_, 4; for (@IF) { $_->{inpf} += $size if $rule =~ /$_->{inps}/; $_->{outf} += $size if $rule =~ /$_->{outs}/; } } for (@IF) { my ($file) = $_->{file}; ::WARN "Unable to update data for '$file', cause: ".RRDs::error unless RRDs::update $file, '--template', 'incoming:outgoing', "N:$_->{inpf}:$_->{outf}"; } } #------------------------------------------------------------------------------ # Inspect BOX configuration and produce initial configuration file sub wizard { my (%iface, @result); for (`/sbin/ipfw show`) { chomp; my ($num, $pkt, $size, $rule) = split /\s+/, $_, 4; next unless $rule =~ /count.*?(in recv|out xmit) (\S+)/; $iface{$2}->{rule}{$num}++; push @{$iface{$2}->{$1 eq 'in recv' ? 'incoming':'outgoing'} }, "$1 $2"; } for (sort keys %iface) { push @result, [ $_, "Traffic flow on `$_`", join(' ', keys %{$iface{$_}->{rule}}), join('|', @{$iface{$_}->{incoming}}), join('|', @{$iface{$_}->{outgoing}}) ]; } return @result; } rrdaemon/readme.txt100644 0 0 3076 7542304373 13100 0ustar rootwheel RRDaemon FrontEnd for RRDTool This is a front-end for RRDTool by Tobias Oetiker. It tries to mimic another well-known accounting utility - MRTG by Tobias Oetiker. Front-end itself is written using Perl by Larry Wall, so You need this one installed too. Create directory /usr/local/etc/rrdaemon and untar here contents of archive, then run 'make' at .../rrdaemon/settings, inspect configuration file, patch if necessary and run .../rrdaemon/rrdaemon (or place .../rrdaemon/settings/rc.d/rrdaemon.sh to local startup directory and reboot computer). Then if you wanna change configuration just do 'make' at .../rrdaemon/settings and that's all. Data acquiring/updating and graphing is done via pluggable libraries, you can find them at .../rrdaemon/library. You are free to write your own extensions. To load new extension you need to restart rrdaemon cause it sucks libraries only once at startup time (booting up executable code is a _some_kind_ dangerous operation). Patches for Apache configuration can be seen at .../rrdaemon/settings/apache Also You must make .../rrdaemon/images writeable by others This version of RRDaemon is a preliminary draft, so documentation for configuration files/libraries wasn't been written, use supplied examples for reference. 18-Sep-2002y Hard Wisdom // hw@ksue.edu.ua P.S. to do list: ~~~~~~~~~~~ - to implement loadable .html templates which can be selected from configuration file - to implement SNMP (maybe using BER.pm SNMP_Util.pm SNMP_Session.pm from the MRTG distribution) rrdaemon/rrdaemon100755 0 0 24752 7542061066 12662 0ustar rootwheel#!/usr/bin/perl #------------------------------------------------------------------------------ # v1.0 (C) 03-Sep-2002 by Hard Wisdom use POSIX 'setsid'; use Sys::Syslog qw(:DEFAULT setlogsock); use Sys::Hostname; use RRDs; # ----------------------------------------------------------------------------- BEGIN {setlogsock "unix"; openlog "rrdaemon", "pid", "daemon"} END {closelog} # ----------------------------------------------------------------------------- sub DIE { my ($package, $filename, $line) = caller; my ($msg); syslog "err", $msg="Died ${package}::${filename}::${line}, cause: @_"; die $msg; } sub WARN { my ($package, $filename, $line) = caller; my ($msg); syslog "notice", $msg="Warned ${package}::${filename}::${line}, cause: @_"; warn $msg; } $SIG{'__DIE__'} = \&DIE; $SIG{'__WARN__'} = \&WARN; sub FORK { chdir '/' or DIE "Can't chdir to /: $!"; open STDIN, '/dev/null' or DIE "Can't write to /dev/null: $!"; defined(my $pid = fork) or DIE "Can't fork: $!"; exit if $pid; setsid or DIE "Can't start a new session: $!"; open STDERR, '>&STDOUT' or DIE "Can't dup stdout: $!"; } #------------------------------------------------------------------------------ $PREFIX = "/usr/local/etc"; # Base for entire installation $CFGDIR = "$PREFIX/rrdaemon/settings"; # Path to configuration files $LIBDIR = "$PREFIX/rrdaemon/library"; # Path to additional libraries $VARDIR = "$PREFIX/rrdaemon/database"; # Path to RRD bases $CGIDIR = "$PREFIX/rrdaemon/cgi-bin"; # Path to CGI files $IMGDIR = "$PREFIX/rrdaemon/images"; # Path to PNG images $CGIWEB = "/rrdaemon"; # relative WWW-Path to CGI files $IMGWEB = "/rrdaemon/images"; # relative WWW-Path to PNG images $PIDFILE = '/var/run/rrdaemon.pid'; # file to place PID $MODE = shift; # modifiers for default behaviour #------------------------------------------------------------------------------ # User wanna know keys, let's say them to he (or she) if ($MODE eq '-?' or $MODE eq '-h') { print STDERR < * where is one of: -reload - send HUP signal to working copy (to reload configuration) -shutdown - send TERM signal to working copy (to shutdown daemon) -db - send TERM signal to (possibly) non-working copy and unlink pid file '$PIDFILE' -create - to examine system and generate configuration file even if it already exists, just right then daemon stops -parse - to parse configuration file and make all necessary scripts but don't monitor any data sources, just exit ... - perform all necessary actions and go on to monitor changes at data sources (main mode) USAGE exit; } #------------------------------------------------------------------------------ # We need to read PIDFILE and to send HUP or TERM to process... if ($MODE eq '-reload' or $MODE eq '-shutdown' or $MODE eq '-db') { if (-r $PIDFILE) { system "kill -".($MODE eq '-reload' ? 'HUP ':'TERM '). `cat $PIDFILE`; unlink $PIDFILE if $MODE eq '-db'; } else { DIE "No '$PIDFILE' of running copy"; } exit; } #------------------------------------------------------------------------------ # Scan for pluggable fetch modules (i.e. with my UID) and load them # into perl namespace LIB:: (using separate packages) sub SUCK_INTO { my ($pfx, $mask) = @_; my ($pkg, $path); for $path (grep {-O} <$mask.*>) { $pkg = $path; $pkg =~ s[^\Q$mask\E\.][]; $pkg =~ y[A-Za-z0-9][_]c; # cause package is kind of declaration (or compile level construct) # we need to lift it one level up with eval and... cause package switching # occurs at run-time, compiler is unable to correctly bind global # variables ... ($@ and so on) ... so we carry information via another # die inside eval'ed block DIE "Unable to load '$path', cause: $@" if (not eval <$CFGDIR/rrdaemon.conf" or DIE "Unable to create config"; for (keys %LIB::FETCH::) {next unless /(.*)::$/; printf CFG "!$1 # %s\n", ${"LIB::FETCH::${1}::comment"}; print CFG join(':', @{$_})."\n" for &{"LIB::FETCH::${1}::wizard"}; print CFG "\n"; } close CFG; print "Inspect $CFGDIR/rrdaemon.conf and run me again\n"; exit } #------------------------------------------------------------------------------ # Ok, libraries loaded, configuration present... let's suck it in... sub CFG_RELOAD { &{"LIB::FETCH::${_}reload"} for keys %LIB::FETCH::; open CFG,"<$CFGDIR/rrdaemon.conf" or DIE "Unable to open config at '$CFGDIR'"; my ($lib, $rebuild, $body); my ($idx) = "$CGIDIR/index.cgi"; while () { chomp; s/#.*//; next if $_ eq ''; $lib=$1, next if /^!(\S+)/; ($file, $header, @source) = split /\s*:\s*/; my ($rrd, $cgi) = ("$VARDIR/$file.rrd", "$CGIDIR/$file.cgi"); #------------------------------------------------------------------------------ unless (-w $rrd) # No RRD base, we need to create one { DIE "Unable to create database '$rrd' cause: ".RRDs::error unless RRDs::create $rrd, "--step", "300", @{"LIB::FETCH::${lib}::format"}, ("RRA:LAST:0.5:1:600", "RRA:LAST:0.5:6:700", "RRA:LAST:0.5:24:775", "RRA:LAST:0.5:288:800"), ${"LIB::FETCH::${lib}::noavg"} ?(): ("RRA:AVERAGE:0.5:1:600", "RRA:AVERAGE:0.5:6:700", "RRA:AVERAGE:0.5:24:775", "RRA:AVERAGE:0.5:288:800"), ${"LIB::FETCH::${lib}::nomin"} ?(): ("RRA:MIN:0.5:1:600", "RRA:MIN:0.5:6:700", "RRA:MIN:0.5:24:775", "RRA:MIN:0.5:288:800"), ${"LIB::FETCH::${lib}::nomax"} ?(): ("RRA:MAX:0.5:1:600", "RRA:MAX:0.5:6:700", "RRA:MAX:0.5:24:775", "RRA:MAX:0.5:288:800"); WARN "Database '$rrd' has been created\n"; } #------------------------------------------------------------------------------ &{"LIB::FETCH::${lib}::acquire"}($rrd, @source); #------------------------------------------------------------------------------ $body .= < ' --end NOW --title='$header' --height 30 --width 600 --start END-1DAY --x-grid "HOUR:1:HOUR:1:HOUR:1:0:%H" @{[&{"LIB::FETCH::${lib}::graph"}(1, $rrd)]} >
INDEX #------------------------------------------------------------------------------ unless (-r $cgi) # Create web page, set dirty flag { $rebuild=1; open CGI, ">$cgi" or DIE "Unable to create '$file' web page"; # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - print CGI < RRDaemon statistics on @{[hostname]} - $header

$header

Last Modified:
HEADER # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # CDEF:tickarea=tick,POP,LTIME,86400,%,0,LE,INF,UNKN,IF' # AREA:tickarea#FF0000 for( ['daily', "`Daily` Graph (5 Minute Average)", '--start END-1DAY --x-grid "HOUR:1:HOUR:1:HOUR:1:0:%H"'], ['weekly', "`Weekly` Graph (30 Minute Average)", '--start END-7DAY --x-grid "HOUR:6:DAY:1:DAY:1:260000:%a"'], ['monthly', "`Monthly` Graph (2 Hour Average)", '--start END-1MONTH --x-grid "DAY:1:WEEK:1:WEEK:1:660000:Week %W"'], ['yearly', "`Yearly` Graph (1 Day Average)", '--start END-1YEAR --x-grid "DAY:7:MONTH:1:MONTH:1:7800000:%b"']) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { print CGI <[0].gif --imgformat GIF --lazy --imginfo '$_->[1]' --end NOW --title='$_->[1]' --height 100 --width 600 $_->[2] @{[&{"LIB::FETCH::${lib}::graph"}(undef(), $rrd)]} >
TEMPLATE # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } print CGI <System Administrator FOOTER # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - close CGI; chmod 0755, $cgi; WARN "Web page '$cgi' has been created\n"; } } close CFG; # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if ($rebuild) # Ok, index page is dirty, we need to drop it on disk { open CGI, ">$idx" or DIE "Unable to create index web page '$idx'"; print CGI < RRDaemon statistics on @{[hostname]}

`Daily` Graph (5 Minute Average)

$body Maintainer: System Administrator INDEX close CGI; chmod 0755, $idx; WARN "Index web page '$idx' has been created\n"; } } #------------------------------------------------------------------------------ # User wanna just to parse conf-files and to produce necessary scripts... &CFG_RELOAD(); exit if $MODE eq '-parse'; #------------------------------------------------------------------------------ DIE "Already ran, shutdown previous copy please" if -r $PIDFILE; #------------------------------------------------------------------------------ # Store self PID, hook signals and daemonise undef $REQ; $SIG{'TERM'} = $SIG{'HUP'} = sub {($REQ)=@_}; FORK; system "echo $$ >$PIDFILE"; # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WARN "Started Up"; CYCLE: { &{"LIB::FETCH::${_}update"} for keys %LIB::FETCH::; $tm = 299 - (time % 300); $tm=299 if $tm <= 1; sleep $tm; if ($REQ) { last CYCLE if $REQ eq 'TERM'; undef $REQ; # So, this is HUP request, reread configuration WARN "Loading configuration..."; CFG_RELOAD; } redo CYCLE; } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - unlink $PIDFILE; WARN "Shutdown"; rrdaemon/settings/ 40755 0 0 0 7577277176 12661 5ustar rootwheelrrdaemon/settings/makefile100644 0 0 1624 7541370010 14425 0ustar rootwheel# ---------------------------------------------------------------------------- # Automatic settings regeneration... # (C) 03-Sep-2002y by *HW* # parse = ../rrdaemon flag = @echo Last reconfiguration was at `date` >rrdaemon.flag # ----------------------------------------------------------------------------- # Produce configuration file and stop, allow human to examine and change it # then use this file for parsing and producing configurations reload: rrdaemon.conf rrdaemon.flag # ----------------------------------------------------------------------------- # Parse configuration file and produce update and graph scripts rrdaemon.flag: rrdaemon.conf ${parse} -reload ${flag} # ----------------------------------------------------------------------------- # Examine system and produce default configuration file rrdaemon.conf: ${parse} -create ${flag} rrdaemon/settings/rrdaemon.flag100644 0 0 72 7542072536 15340 0ustar rootwheelLast reconfiguration was at Wed Sep 18 15:45:18 EEST 2002 rrdaemon/settings/apache/ 40755 0 0 0 7542060626 14060 5ustar rootwheelrrdaemon/settings/apache/access.conf100644 0 0 410 7542060143 16232 0ustar rootwheel# # RRDaemon (access restrictions for Apache) # Options FollowSymLinks ExecCGI AllowOverride None Options FollowSymLinks AllowOverride None rrdaemon/settings/apache/srm.conf100644 0 0 404 7542060244 15577 0ustar rootwheel# # RRDaemon (directories configurations for Apache) # Alias /rrdaemon/images /usr/local/etc/rrdaemon/images Alias /rrdaemon /usr/local/etc/rrdaemon/cgi-bin AddHandler cgi-script .cgi rrdaemon/settings/rc.d/ 40755 0 0 0 7542061225 13461 5ustar rootwheelrrdaemon/settings/rc.d/rrdaemon.sh100751 0 0 1461 7542101471 15720 0ustar rootwheel#!/bin/sh # # RRDaemon startup script v1.0 # (C) 18-Sep-2002y by *HW* # # ----------------------------------------------------------------------------- if ! PREFIX=`expr $0 : "\(/.*\)/etc/rc\.d/$(basename $0)\$"`; then echo "$0: Cannot determine the PREFIX" >&2 exit 1 fi # ----------------------------------------------------------------------------- case "$1" in start) if [ -r ${PREFIX}/etc/rrdaemon/settings/rrdaemon.conf ]; then ${PREFIX}/etc/rrdaemon/rrdaemon echo -n ' rrdaemon' fi ;; stop) ${PREFIX}/etc/rrdaemon/rrdaemon -shutdown echo -n ' rrdaemon' ;; restart) $0 stop $0 start ;; *) echo "Usage: `basename $0` {start|stop|restart}" >&2 ;; esac # ----------------------------------------------------------------------------- exit 0 rrdaemon/settings/rrdaemon.conf.sample100644 0 0 1434 7543565372 16705 0ustar rootwheel!fw # Dump statistics about IF usage fxp0:Traffic flow on `fxp0` - Internal link:510:in recv fxp0:out xmit fxp0:swap fxp1:Traffic flow on `fxp1` - External fast link:530 730:in recv fxp1:out xmit fxp1|fwd 80\.92\.224\.65 ppp0:Traffic flow on `ppp0` - External slow link:520:in recv ppp0:out xmit ppp0:swap !df # Dump statistics about FS usage root:`/` on `/dev/ad0s1a`:/ usr:`/usr` on `/dev/ad0s1g`:/usr var:`/var` on `/dev/ad0s1e`:/var squid:`/usr/local/squid` on `/dev/ad0s1h`:/usr/local/squid mail:`/var/mail` on `/dev/ad0s1f`:/var/mail archive:`/archive` on `/dev/ad0s1d`:/archive !si # Dump statistics about SWAP usage swap:Total Swap Space:* !vm # Dump statistics about Virtual Memory usage memory:Active Virtual Memory: !ld # Dump statistics about System usage load:Total System Load: