# NOT FOR THE FAINT OF HEART # Multi-process multi-host log with distributed configuration # In this example # Jon and Tom both get their own logs and config files # CGI accesses receive thier own log # Images get their own log # Everything else is logged to the usual place # Caveats # -u and -g likely cannot be used, since flog needs to setuid # (which washes out to be roughly the same...) my $user; sub spawn; my %FILES= ( IMAGES=>[">>/var/log/httpd/images.log"], TOM=>[">>/home/tom/access.log"], JON=>[">>/home/jon/access.log"], CGI=>[">>/var/log/httpd/cgi.log"], CATCH=>[">>/var/log/httpd/access.log"] ); foreach $user ( qw(jon tom) ){ # package $user; package me; &flog::become($user, $user); require "~$user/.flog.pl"; } package main; sub log{ print CGI if m% /cgi-bin/%; if( m%tom\.com$% ){ return spawn sub { &flog::become("tom", "tom"); &tom::flog(); } } if( m%jon\.net$% ){ return spawn sub { &flog::become("jon", "friend"); &jon::flog(); } } # Return if you do not wish to duplicate data across logs print CATCH; } #Straight from perlipc sub REAPER { wait; $SIG{CHLD} = \&REAPER; # loathe sysV } $SIG{CHLD} = \&REAPER; sub spawn { my $coderef = shift; unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') { die("usage: spawn CODEREF"); } my $pid; if (!defined($pid = fork)) { return; } elsif ($pid) { return; } # I'm the parent # else I'm the child -- go spawn #open(STDIN, "<&Client") || die "can't dup client to stdin"; #open(STDOUT, ">&Client") || die "can't dup client to stdout"; ## open(STDERR, ">&STDOUT") || die "can't dup stdout to stderr"; exit &$coderef(); } 1;