Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uunet!convex!convex.COM From: tchrist@convex.COM (Tom Christiansen) Newsgroups: comp.lang.perl Subject: Re: openlog(3), syslog(3) in perl Message-ID: <100571@convex.convex.com> Date: 14 Mar 90 11:30:47 GMT References: <39461@apple.Apple.COM> Sender: news@convex.com Reply-To: tchrist@convex.COM (Tom Christiansen) Organization: CONVEX Software Development, Richardson, TX Lines: 106 In article <39461@apple.Apple.COM> fair@apple.com (Erik E. Fair) writes: >Has anybody duplicated these routines for perl 3.0 yet, in such a >manner that you don't have to spawn a process for every line you log >(i.e. that hack I saw already isn't acceptable)? Eric, the problem is I can't get to arbitrary C library calls from section 3 as I can to arbitrary system calls from section 2, and Larry hasn't made syslog(3) a built-in to perl (yet?). This means I can't really use openlog(3) and syslog(3), but must use a pipe to logger(8) instead. The "hack" you're complaining about attempts to provide the same functionality as syslog(3) at the expense of an exec per line. Here's a version which does not do an exec per line, but rather an exec per (priority, facility) pair, because I can't make logger switch these things in mid-steam. I really don't see how to do better than this without getting Larry to put syslog(3) into perl itself. --tom # # syslog.pl # # tom christiansen # # call syslog() with a string priority and a list of printf() args # like syslog(3) but using logger(8). will only open a new pipe # to logger if it needs to. # # usage: do 'syslog.pl' || die "syslog.pl: $@"; # # then (put these all in a script to test function) # # # do openlog($program,'user'); # do syslog('info','this is another test'); # do syslog('warn','this is a better test: %d', time); # do closelog(); # # do syslog('debug','this is the last test'); # do openlog("$program $$",'user'); # do syslog('notice','fooprogram: this is really done'); # # $! = 55; # do syslog('info','problem was %m'); # %m == $! in syslog(3) package syslog; $logpath = '/usr/ucb/logger'; $opriority = $ofacility = $facility = $ident = ''; die "syslog: can't call $logpath: $!" unless -x $logpath; sub main'openlog { &main'closelog if $logopen; ($ident, $facility) = @_; # package vars } sub main'closelog { $facility = $ident = ''; if ($logopen) { $logopen = 0; close LOG; } } sub main'syslog { local($priority) = shift; local($mask) = shift; local($message, $whoami, $oldfh); $whoami = $ident; die "syslog: expected both priority and mask" unless $mask && $priority; $facility = "user" unless $facility; if (!$ident && $mask =~ /^(\S.*):\s?(.*)/) { $whoami = $1; $mask = $2; } $mask =~ s/%m/$!/g; $mask .= "\n" unless $mask =~ /\n$/; $whoami = sprintf ("%s %d", $ENV{'USER'}, $$) unless $whoami; if ($opriority ne $priority || $ofacility ne $facility) { $opriority = $priority; $ofacility = $facility; close LOG if $logopen++; open(LOG, "| $logpath -t '$whoami' -p '$facility.$priority'"); $oldfh = select(LOG); $| = 1; select($oldfh); } printf LOG "$mask", @_; } 1; -- Tom Christiansen {uunet,uiucdcs,sun}!convex!tchrist Convex Computer Corporation tchrist@convex.COM "EMACS belongs in : Editor too big!"