<?xml version="1.0" encoding="windows-1252"?>
<node id="478964" title="Re: Writing a Perl Daemon" created="2005-07-28 09:42:05" updated="2005-08-15 08:54:09">
<type id="11">
note</type>
<author id="227005">
cees</author>
<data>
<field name="doctext">
&lt;p&gt;Using [module://Proc::PID_File] and [module://Proc::Daemon] should get you most of the way there.  Here is a chopped down version of a daemon script that I use, complete with logging.  Hope it is a helpful starting point.&lt;/p&gt;

&lt;code&gt;
#!/usr/bin/perl

use strict;
use warnings;

use constant LOG_DIR    =&gt; '/var/log/mydaemon';
use constant LOG_FILE   =&gt; 'mydaemon.log';
use constant PIDDIR     =&gt; LOG_DIR;

use Proc::PID_File;
use Proc::Daemon;
use Log::Dispatch;
use Log::Dispatch::File;
use Date::Format;
use File::Spec;

sub dienice ($);

#
# fork and background process
#
our $ME = $0; $ME =~ s|.*/||;
our $PIDFILE = PIDDIR."/$ME.pid";
startDaemon();

#
# Setup a logging agent
#
our $HOSTNAME = `hostname`;
chomp $HOSTNAME;
my $log = new Log::Dispatch(
      callbacks =&gt; sub { my %h=@_; return Date::Format::time2str('%B %e %T', time)." ".$HOSTNAME." $0\[$$]: ".$h{message}."\n"; }
);
$log-&gt;add( Log::Dispatch::File-&gt;new( name      =&gt; 'file1',
                                     min_level =&gt; 'warning',
                                     mode      =&gt; 'append',
                                     filename  =&gt; File::Spec-&gt;catfile(LOG_DIR, LOG_FILE),
                                   )
);
$log-&gt;warning("Starting Processing:  ".time());


#
# Setup signal handlers so that we have time to cleanup before shutting down
#
my $keep_going = 1;
$SIG{HUP}  = sub { $log-&gt;warning("Caught SIGHUP:  exiting gracefully"); $keep_going = 0; };
$SIG{INT}  = sub { $log-&gt;warning("Caught SIGINT:  exiting gracefully"); $keep_going = 0; };
$SIG{QUIT} = sub { $log-&gt;warning("Caught SIGQUIT:  exiting gracefully"); $keep_going = 0; };
#$SIG{TERM} = sub { $log-&gt;warning("Caught SIGTERM:  exiting gracefully"); $keep_going = 0; };


#
# enter main loop
#
while ($keep_going) {

        # do something useful here


}

#
# Mark a clean exit in the log
#
$log-&gt;warning("Stopping Processing:  ".time());


#
# startDaemon
#
# Fork and detach from the parent process
#
sub startDaemon {

  #
  # Fork and detach from the parent process
  #
#  eval { close DATA; }; # having __END__ will trigger __DATA__ to open and should be closed
  eval { Proc::Daemon::Init; };
  if ($@) {
    dienice("Unable to start daemon:  $@");
  }

  #
  # Get a PID file
  #
  dienice("Already running!") if hold_pid_file($PIDFILE);
}

#
# dienice
#
# write die messages to the log before die'ing
#
sub dienice ($) {
  my ($package, $filename, $line) = caller;
  $log-&gt;critical("$_[0] at line $line in $filename");
  die $_[0];
}
&lt;/code&gt;</field>
<field name="root_node">
478839</field>
<field name="parent_node">
478839</field>
</data>
</node>
