Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

[Resolved] Perl watcher daemon

by kazak (Beadle)
on Jan 18, 2012 at 21:35 UTC ( #948627=perlquestion: print w/replies, xml ) Need Help??

kazak has asked for the wisdom of the Perl Monks concerning the following question:

Hi to all . I tried to make a simple and extensible skeleton ( sentinel.pl) , simple enough ( I'm new to perl), and extensible enough for me to be able to extend this script. The first task was to watch over two background scripts( greylister.pl, repeater.pl). It seems like daemon works, and death of any of background scripts is detectable for script, but one thing looks odd for me. Sentinel.pl is able to start greylister.pl\repeater.pl only if they weren't running at the moment of sentinel's first start, but if any of scripts will die later when sentinel.pl is running, this event is logged but scripts ( repeater\greylister) are not restarted.
#!/usr/bin/perl -w # Watchdog daemon, made for watching and restarting of all system elem +ents. use warnings; use POSIX; use File::Pid; use Proc::Background; use POSIX qw(setsid); use lib '/etc/squid/repeater/lib/HTTP'; my $daemonName = "sentinel"; my $dieNow = 0; my $SleepMainLoop = 5; my $logging = 1; my $logFilePath = "/var/log/"; my $logFile = $logFilePath . $daemonName . ".log"; my $pidFilePath = "/var/run/"; my $pidFile = $pidFilePath . $daemonName . ".pid"; my $greylister = Proc::Background->new('/etc/squid/all_ban.pl'); my $repeater = Proc::Background->new('/etc/squid/repeater/lib/repeater +.pl'); chdir '/'; umask 0; open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!"; open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!"; defined( my $pid = fork ) or die "Can't fork: $!"; exit if $pid; POSIX::setsid() or die "Can't start a new session."; $SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signalHandler; $SIG{PIPE} = 'ignore'; my $pidfile = File::Pid->new( { file => $pidFile, } ); $pidfile->write or die "Can't write PID file, /dev/null: $!"; if ($logging) { open LOG, ">>$logFile"; print LOG "Sentinel started.\n"; select((select(LOG), $|=1)[0]); } until ($dieNow) { sleep($SleepMainLoop); if (!$repeater->alive()) { logEntry ("Repeater isn't running, attempting to restart") +; $repeater = Proc::Background->new('/etc/squid/repeater/lib/ +repeater.pl'); } if (!$greylister->alive()) { logEntry ("Greyliter isn't running, attempting to res +tart"); $greylister = Proc::Background->new('/etc/squid/all_b +an.pl'); } } sub logEntry { my ($logText) = @_; my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) + = localtime(time); my $dateTime = sprintf "%4d-%02d-%02d %02d:%02d:%02d", $year + 190 +0, $mon + 1, $mday, $hour, $min, $sec; if ($logging) { print LOG "$dateTime $logText\n"; } } sub signalHandler { $dieNow = 1; } END { if ($logging) { close LOG } $pidfile->remove if defined $pidfile; }

Replies are listed 'Best First'.
Re: Perl watcher daemon
by Crackers2 (Parson) on Jan 18, 2012 at 22:27 UTC
    if (system(@args1) != 0) { logEntry ("No repeater.pl is running, attempting to re +start"); $repeater; }

    I don't think that's doing what you think it does. As far as I can tell the bare $repeater doesn't do anything. You probably want something like

    if (system(@args1) != 0) { logEntry ("No repeater.pl is running, attempting to re +start"); $repeater = Proc::Background->new('/etc/squid/repeater +/lib/repeater.pl'); }

    Also, Proc::Background has functions for checking whether or not the process is still running, so you may want to use those instead of shelling out to pgrep:

    if (!$repeater->alive()) { logEntry ("No repeater.pl is running, attempting to re +start"); $repeater = Proc::Background->new('/etc/squid/repeater +/lib/repeater.pl'); }

    Of course that would not detect a process that was already started when your watcher begins. (But in that case you'd currently have 2 running processes anyway since you unconditionally start one with the initial Proc::Background->new call.)

      Thank you so much Crackers2 , now it works as a charm.
Re: Perl watcher daemon
by JavaFan (Canon) on Jan 18, 2012 at 21:52 UTC
    You know, you could just use make a respawn entry in your inittab.
      Respawn is not quite what I need, because only the first task is about restarting some scripts, other tasks will be much more complex.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://948627]
Approved by davies
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (1)
As of 2021-12-01 06:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?