#!/usr/bin/perl # # mod_watch.pl # # Interface for Apache mod_watch and MRTG # # Copyright 2001, 2002 by Anthony Howe. All rights reserved. # # usage: mod_watch.pl [-f a,b] url # # Fetch the current counters associated with the given URL. The URL refers # to either a virtual host, file owner, or the SERVER. # # http://www.snert.com/watch-info # http://www.snert.com/~achowe/watch-info # http://www.snert.com/~SERVER/watch-info # # The mod_watch handler "watch-info" returns a line of plain text # containing the following space separated fields: # # ifName ifUptime ifInOctets ifOutOctets ifRequests ifDocuments # # This script returns output suitable for MRTG's target script command # directive: line with the input bytes, line with the output bytes, line # with the web server uptime, and the target name. # ########################################################################## # Nothing to be configured below this point. ########################################################################## $VERSION = '2.3'; $AUTHOR = 'achowe@snert.com'; use Socket; use Getopt::Std; use Sys::Hostname; use AnyDBM_File; my $usage = "usage: mod_watch.pl [-f a,b] url\n"; die($usage) unless getopts('f:'); die($usage) unless @ARGV == 1; ######################################################################### # Open connection to URL. ######################################################################### # Figure out who we have to call. ($host, $port, $path) = ($ARGV[0] =~ m!http://([^:/]+)(?:\:(\d*))?(/.*)!); $port = 80 unless defined $port; # Get a socket... unless (socket(HTTP, PF_INET, SOCK_STREAM, getprotobyname('tcp'))) { print("0\n0\n0\n$host:$port ($!)\n"); exit(0); } # ...set socket to be line buffered... select( (select(HTTP), $| = 1)[0] ); # .. make the connection. unless (connect(HTTP, sockaddr_in($port, inet_aton($host)))) { print("0\n0\n0\n$host:$port ($!)\n"); exit(0); } ######################################################################### # Make the HTTP request. ######################################################################### # Proxy request style. #print HTTP "GET $ARGV[0] HTTP/1.0\n\n"; print HTTP "GET $path HTTP/1.0\nHost: $host\n\n"; $answer = ; ($status, $reason) = ($answer =~ m!HTTP/1.[01] (\d+) (.*)!); unless ($status == 200) { print("0\n0\n0\n$host:$port ($reason)\n"); exit(0); } # Discard remaining HTTP headers. while () { last if /^\s*$/; } ######################################################################### # Parse the information line. ######################################################################### # Field names in order. @fieldnames = qw(ifName ifUptime ifInOctets ifOutOctets ifRequests ifDocuments); # Default fields to return. ($a, $b) = qw(ifInOctets ifOutOctets); # User wants other fields? ($a, $b) = ($opt_f =~ m!(\w+),(\w+)!) if defined $opt_f; # Get the information line. my $line = ; close(HTTP); # Select the fields to return. ($in, $out) = (0, 0); if ($line =~ /^\S+\s\d+\s\d+\s\d+\s\d+\s\d+/) { @counters{@fieldnames} = split(/\s+/, $line); ($in, $out) = ($counters{$a}, $counters{$b}); } ######################################################################### # Write MRTG output. ######################################################################### sub ml_elapsed_time { my ($s) = @_; my ($d, $h, $m); $d = int($s / 86400); $s %= 86400; $h = int($s / 3600); $s %= 3600; $m = int($s / 60); $s %= 60; return sprintf("%lu+%02d:%02d.%02d", $d, $h, $m, $s) if 0 < $d; return sprintf("%d:%02d.%02d", $h, $m, $s) if 0 < $h; return sprintf("%d.%02d", $m, $s) if 0 < $m; return sprintf("%d", $s); } print "$in\n$out\n" . ml_elapsed_time($counters{ifUptime}) . "\n$counters{ifName}\n"; exit 0; ######################################################################### # ######################################################################### __END__