File Coverage

blib/lib/App/Daemon.pm
Criterion Covered Total %
statement 48 242 19.8
branch 0 126 0.0
condition 0 25 0.0
subroutine 16 30 53.3
pod 1 14 7.1
total 65 437 14.8


line stmt bran cond sub pod time code
1             package App::Daemon;
2 3     3   533254 use strict;
  3         7  
  3         132  
3 3     3   18 use warnings;
  3         5  
  3         135  
4              
5             our $VERSION = '0.21';
6              
7 3     3   9615 use Getopt::Std;
  3         179  
  3         210  
8 3     3   3267 use Pod::Usage;
  3         243413  
  3         473  
9 3     3   38 use File::Basename;
  3         7  
  3         216  
10 3     3   17 use Log::Log4perl qw(:easy);
  3         9  
  3         35  
11 3     3   7343 use POSIX;
  3         37201  
  3         23  
12 3     3   11236 use Exporter;
  3         6  
  3         138  
13 3     3   17 use Fcntl qw/:flock/;
  3         7  
  3         497  
14              
15             our @ISA = qw(Exporter);
16             our @EXPORT_OK = qw(daemonize cmd_line_parse detach);
17              
18 3     3   43 use constant LSB_OK => 0;
  3         6  
  3         204  
19 3     3   15 use constant LSB_DEAD_PID_EXISTS => 1;
  3         8  
  3         137  
20 3     3   16 use constant LSB_DEAD_LOCK_EXISTS => 2;
  3         5  
  3         147  
21 3     3   16 use constant LSB_NOT_RUNNING => 3;
  3         6  
  3         137  
22 3     3   22 use constant LSB_UNKNOWN => 4;
  3         6  
  3         128  
23 3     3   16 use constant ALREADY_RUNNING => 150;
  3         6  
  3         18296  
24              
25             our ($pidfile, $logfile, $l4p_conf, $as_user, $as_group, $background,
26             $loglevel, $action, $appname, $default_pid_dir, $default_log_dir);
27             $action = "";
28             $appname = appname();
29              
30             $default_pid_dir = ".";
31             $default_log_dir = ".";
32              
33             our $kill_retries = 3;
34             our $kill_sig = SIGTERM; # maps to 15 via POSIX.pm
35              
36             ###########################################
37             sub cmd_line_parse {
38             ###########################################
39              
40 0 0   0 0 0 if( find_option("-h") ) {
41 0         0 pod2usage();
42             }
43              
44 0 0       0 if(my $_pidfile = find_option('-p', 1)) {
45 0         0 $pidfile = $_pidfile;
46             }
47             else {
48 0   0     0 $pidfile ||= ( "$default_pid_dir/" . $appname . ".pid" );
49             }
50              
51 0 0       0 if(my $_logfile = find_option('-l', 1)) {
52 0         0 $logfile = $_logfile;
53             }
54             else {
55 0   0     0 $logfile ||= ( "$default_log_dir/" . $appname . ".log" );
56             }
57              
58 0 0       0 if(my $_l4p_conf = find_option('-l4p', 1)) {
59 0         0 $l4p_conf = $_l4p_conf;
60             }
61              
62 0 0       0 if(my $_as_user = find_option('-u', 1)) {
63 0         0 $as_user = $_as_user;
64             }
65             else {
66 0   0     0 $as_user ||= 'nobody';
67             }
68              
69 0 0       0 if(my $_as_group = find_option('-g', 1)) {
70 0         0 $as_group = $_as_group;
71             }
72             else {
73 0   0     0 $as_group ||= 'nogroup';
74             }
75              
76 0 0       0 if($> != 0) {
77             # Not root? Then we're ourselves
78 0         0 ($as_user) = getpwuid($>);
79 0         0 ($as_group) = getgrgid(POSIX::getgid());
80             }
81              
82 0 0       0 $background = 1 if(!defined $background);
83 0 0       0 $background = find_option('-X') ? 0 : $background;
84              
85 0 0       0 $loglevel = $background ? $INFO : $DEBUG
    0          
86             if(!defined $loglevel);
87 0 0       0 $loglevel = find_option('-v') ? $DEBUG : $loglevel;
88              
89 0         0 for (qw(start stop restart status)) {
90 0 0       0 if( find_option( $_ ) ) {
91 0         0 $action = $_;
92 0         0 last;
93             }
94             }
95            
96 0 0 0     0 if($action eq "stop" or $action eq "status") {
97 0         0 $background = 0;
98             }
99              
100 0 0       0 if( Log::Log4perl->initialized() ) {
    0          
    0          
    0          
101 0         0 DEBUG "Log4perl already initialized, doing nothing";
102             } elsif( $action eq "status" ) {
103 0         0 Log::Log4perl->easy_init( $loglevel );
104             } elsif( $l4p_conf ) {
105 0         0 Log::Log4perl->init( $l4p_conf );
106             } elsif( $logfile ) {
107 0         0 my $levelstring = Log::Log4perl::Level::to_level( $loglevel );
108 0         0 Log::Log4perl->init(\ qq{
109             log4perl.logger = $levelstring, FileApp
110             log4perl.appender.FileApp = Log::Log4perl::Appender::File
111             log4perl.appender.FileApp.filename = $logfile
112             log4perl.appender.FileApp.owner = $as_user
113             # this umask is only temporary
114             log4perl.appender.FileApp.umask = 0133
115             log4perl.appender.FileApp.layout = PatternLayout
116             log4perl.appender.FileApp.layout.ConversionPattern = %d %m%n
117             });
118             }
119              
120 0 0       0 if(!$background) {
121 0         0 DEBUG "Running in foreground";
122             }
123             }
124              
125             ###########################################
126             sub daemonize {
127             ###########################################
128 0     0 0 0 cmd_line_parse();
129              
130             # Check beforehand so the user knows what's going on.
131 0 0 0     0 if(! -w dirname($pidfile) or -f $pidfile and ! -w $pidfile) {
      0        
132 0         0 my ($name,$passwd,$uid) = getpwuid($>);
133 0         0 LOGDIE "$pidfile not writable by user $name";
134             }
135            
136 0 0       0 if($action eq "status") {
137 0         0 exit status();
138             }
139              
140 0 0 0     0 if($action eq "stop" or $action eq "restart") {
141 0         0 my $exit_code = LSB_NOT_RUNNING;
142              
143 0 0       0 if(-f $pidfile) {
144 0         0 my $pid = pid_file_read();
145 0 0       0 if(kill 0, $pid) {
146 0         0 kill $kill_sig, $pid;
147 0         0 my $killed = 0;
148 0         0 for (1..$kill_retries) {
149 0 0       0 if(!kill 0, $pid) {
150 0         0 INFO "Process $pid stopped successfully.";
151 0 0       0 unlink $pidfile or die "Can't remove $pidfile ($!)";
152 0         0 $exit_code = LSB_OK;
153 0         0 $killed++;
154 0         0 last;
155             }
156 0         0 INFO "Process $pid still running, waiting ...";
157 0         0 sleep 1;
158             }
159 0 0       0 if(! $killed) {
160 0         0 ERROR "Process $pid still up, out of retries, giving up.";
161 0         0 $exit_code = LSB_DEAD_PID_EXISTS;
162             }
163             } else {
164 0         0 ERROR "Process $pid not running\n";
165 0 0       0 unlink $pidfile or die "Can't remove $pidfile ($!)";
166 0         0 $exit_code = LSB_NOT_RUNNING;
167             }
168             } else {
169 0         0 ERROR "According to my pidfile, there's no instance ",
170             "of me running.";
171 0         0 $exit_code = LSB_NOT_RUNNING;
172             }
173              
174 0 0       0 if($action eq "restart") {
175 0         0 sleep 1;
176             } else {
177 0         0 exit $exit_code;
178             }
179             }
180            
181 0 0       0 if ( my $num = pid_file_process_running() ) {
182 0         0 LOGWARN "Already running: $num (pidfile=$pidfile)\n";
183 0         0 exit ALREADY_RUNNING;
184             }
185              
186 0 0       0 if( $background ) {
    0          
187 0         0 detach( $as_user );
188             } elsif ($as_user) {
189 0         0 id_switch();
190             }
191              
192 0         0 my $prev_sig = $SIG{__DIE__};
193 0         0 my $master_pid = $$;
194              
195 0         0 DEBUG "Defining die handler";
196              
197             $SIG{__DIE__} = sub {
198 0     0   0 DEBUG __PACKAGE__, " die handler triggered.";
199             # In case we had a previously defined signal handler, call
200             # it first and add ours to the end of the chain.
201 0 0       0 $prev_sig->(@_) if ($prev_sig);
202              
203 0 0 0     0 if( $master_pid != $$ ) {
    0          
204             # Verify that it's the main process calling the
205             # handler and not a previously forked child.
206 0         0 DEBUG "Die handler called for pid $$ but master pid is $master_pid";
207             } elsif( !defined $^S or $^S != 0 ) {
208             # Make sure it's not an eval{} triggering the handler.
209 0         0 DEBUG "Die handler called by eval. Ignored.";
210             } else {
211 0         0 DEBUG "Die handler removes pidfile $pidfile";
212 0 0       0 unlink $pidfile or warn "Cannot remove $pidfile";
213             }
214 0         0 };
215            
216 0         0 return 1;
217             }
218              
219             ###########################################
220             sub detach {
221             ###########################################
222 0     0 0 0 my($as_user) = @_;
223              
224             # [rt #75219]
225 0         0 umask(0);
226            
227             # Make sure the child isn't killed when the user closes the
228             # terminal session before the child detaches from the tty.
229 0         0 $SIG{'HUP'} = 'IGNORE';
230            
231 0         0 my $child = fork();
232            
233 0 0       0 if(! defined $child ) {
234 0         0 LOGDIE "Fork failed ($!)";
235             }
236            
237 0 0       0 if( $child ) {
238             # parent doesn't do anything
239 0         0 exit 0;
240             }
241            
242             # Become the session leader of a new session, become the
243             # process group leader of a new process group.
244 0         0 POSIX::setsid();
245            
246 0 0       0 if( defined $pidfile ) {
247 0         0 INFO "Process ID is $$";
248 0         0 pid_file_write($$);
249 0         0 INFO "Written to $pidfile";
250             }
251              
252 0 0       0 if($as_user) {
253 0         0 id_switch();
254             }
255            
256             # close std file descriptors
257 0 0       0 if(-e "/dev/null") {
258             # On Unix, we want to point these file descriptors at /dev/null,
259             # so that any libary routines that try to read form stdin or
260             # write to stdout/err will have no effect (Stevens, APitUE, p. 426
261             # and [RT 51066].
262 0         0 open STDIN, '/dev/null';
263 0         0 open STDOUT, '>>/dev/null';
264 0         0 open STDERR, '>>/dev/null';
265             } else {
266 0         0 close(STDIN);
267 0         0 close(STDOUT);
268 0         0 close(STDERR);
269             }
270             }
271              
272             ###########################################
273             sub id_switch {
274             ###########################################
275 0 0   0 0 0 if($> == 0) {
276             # If we're root, become user set as 'as_user' and the group in
277             # 'as_group'.
278              
279             # Set the group first because it only works when still root
280 0         0 my ($group,undef,$gid) = getgrnam($as_group);
281              
282 0 0       0 if(! defined $group) {
283 0         0 LOGDIE "Cannot switch to group $as_group";
284             }
285 0         0 POSIX::setgid($gid);
286              
287 0         0 my ($name,$passwd,$uid) = getpwnam($as_user);
288 0 0       0 if(! defined $name) {
289 0         0 LOGDIE "Cannot switch to user $as_user";
290             }
291 0         0 POSIX::setuid( $uid );
292             }
293             }
294            
295             ###########################################
296             sub status {
297             ###########################################
298              
299             # Define exit codes according to
300             # http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
301 0     0 1 0 my $exit_code = LSB_UNKNOWN;
302              
303 0         0 print "Pid file: $pidfile\n";
304 0 0       0 if(-f $pidfile) {
305 0         0 my $pid = pid_file_read();
306 0         0 my $running = process_running($pid);
307 0         0 print "Pid in file: $pid\n";
308 0 0       0 print "Running: ", $running ? "yes" : "no", "\n";
309 0 0       0 if($running) {
310             # see above
311 0         0 $exit_code = LSB_OK;
312             } else {
313             # see above
314 0         0 $exit_code = LSB_DEAD_PID_EXISTS;
315             }
316             } else {
317 0         0 print "No pidfile found\n";
318 0         0 $exit_code = LSB_NOT_RUNNING;
319             }
320              
321 0 0       0 if( proc_processtable_available() ) {
322 0         0 my @cmdlines = processes_running_by_name( $appname );
323 0         0 print "Name match: ", scalar @cmdlines, "\n";
324 0         0 for(@cmdlines) {
325 0         0 print " ", $_, "\n";
326             }
327             }
328              
329 0         0 return $exit_code;
330             }
331              
332              
333             ###########################################
334             sub process_running {
335             ###########################################
336 0     0 0 0 my($pid) = @_;
337              
338 0         0 my $rc = kill( 0, $pid );
339              
340 0 0       0 if( $rc ) {
    0          
    0          
341             # pseudo signal got delivered, process exists
342 0         0 return 1;
343             } elsif( $! == ESRCH ) {
344             # process doesn't exist
345 0         0 return 0;
346             } elsif( $! == EPERM ) {
347             # process does exist, but we don't have permission to
348             # send the signal
349 0         0 return 1;
350             }
351              
352             # Weirdness ensued.
353 0         0 return 0;
354             }
355              
356             ###########################################
357             sub processes_running_by_name {
358             ###########################################
359 0     0 0 0 my($name) = @_;
360              
361 0         0 require Proc::ProcessTable;
362              
363 0         0 $name = basename($name);
364 0         0 my @procs = ();
365              
366 0         0 my $t = Proc::ProcessTable->new();
367              
368 0         0 foreach my $p ( @{$t->table} ){
  0         0  
369 0 0       0 if($p->cmndline() =~ /\b\Q${name}\E\b/) {
370 0 0       0 next if $p->pid() == $$;
371 0         0 DEBUG "Match: ", $p->cmndline();
372 0         0 push @procs, $p->cmndline();
373             }
374             }
375 0         0 return @procs;
376             }
377              
378             ###########################################
379             sub appname {
380             ###########################################
381 3     3 0 233 my $appname = basename($0);
382              
383             # Make sure -T regards it as untainted now
384 3         14 ($appname) = ($appname =~ /([\w-]+)/);
385              
386 3         10 return $appname;
387             }
388              
389             ###########################################
390             sub find_option {
391             ###########################################
392 0     0 0   my($opt, $has_arg) = @_;
393              
394 0           my $idx = 0;
395              
396 0           for my $argv (@ARGV) {
397 0 0         if($argv eq $opt) {
398 0 0         if( $has_arg ) {
399 0           my @args = splice @ARGV, $idx, 2;
400 0           return $args[1];
401             } else {
402 0           return splice @ARGV, $idx, 1;
403             }
404             }
405              
406 0           $idx++;
407             }
408              
409 0           return undef;
410             }
411              
412             ###########################################
413             sub def_or {
414             ###########################################
415 0 0   0 0   if(! defined $_[0]) {
416 0           $_[0] = $_[1];
417             }
418             }
419              
420             ###########################################
421             sub pid_file_write {
422             ###########################################
423 0     0 0   my($pid) = @_;
424              
425 0 0         sysopen FILE, $pidfile, O_RDWR|O_CREAT, 0644 or
426             LOGDIE "Cannot open pidfile $pidfile";
427 0           flock FILE, LOCK_EX;
428 0           seek(FILE, 0, 0);
429 0           print FILE "$pid\n";
430 0           close FILE;
431             }
432              
433             ###########################################
434             sub pid_file_read {
435             ###########################################
436 0 0   0 0   open FILE, "<$pidfile" or LOGDIE "Cannot open pidfile $pidfile";
437 0           flock FILE, LOCK_SH;
438 0           my $pid = <FILE>;
439 0 0         chomp $pid if defined $pid;
440 0           close FILE;
441 0           $pid =~ /^(\d+)$/; # Untaint
442 0           return $1;
443             }
444              
445             ###########################################
446             sub pid_file_process_running {
447             ###########################################
448 0 0   0 0   if(! -f $pidfile) {
449 0           return undef;
450             }
451 0           my $pid = pid_file_read();
452 0 0         if(! $pid) {
453 0           return undef;
454             }
455 0 0         if(process_running($pid)) {
456 0           return $pid;
457             }
458              
459 0           return undef;
460             }
461              
462             ###########################################
463             sub proc_processtable_available {
464             ###########################################
465 0     0 0   my $module = "Proc::ProcessTable";
466              
467 0           eval "require $module;";
468              
469 0 0         if( $@ ) {
470 0           return 0;
471             }
472              
473 0           return 1;
474             }
475              
476             1;
477              
478             __END__
479              
480             =head1 NAME
481              
482             App::Daemon - Start an Application as a Daemon
483              
484             =head1 SYNOPSIS
485              
486             # Program:
487             use App::Daemon qw( daemonize );
488             daemonize();
489             do_something_useful(); # your application
490              
491             # Then, in the shell: start application,
492             # which returns immediately, but continues
493             # to run do_something_useful() in the background
494             $ app start
495             $
496              
497             # stop application
498             $ app stop
499              
500             # start app in foreground (for testing)
501             $ app -X
502              
503             # show if app is currently running
504             $ app status
505              
506             =head1 DESCRIPTION
507              
508             C<App::Daemon> helps running an application as a daemon. The idea is
509             that you prepend your script with the
510              
511             use App::Daemon qw( daemonize );
512             daemonize();
513              
514             and 'daemonize' it that way. That means, that if you write
515              
516             use App::Daemon qw( daemonize );
517              
518             daemonize();
519             sleep(10);
520              
521             you'll get a script that, when called from the command line, returns
522             immediatly, but continues to run as a daemon for 10 seconds.
523              
524             Along with the
525             common features offered by similar modules on CPAN, it
526              
527             =over 4
528              
529             =item *
530              
531             supports logging with Log4perl: In background mode, it logs to a
532             logfile. In foreground mode, log messages go directly to the screen.
533              
534             =item *
535              
536             detects if another instance is already running and ends itself
537             automatically in this case.
538              
539             =item *
540              
541             shows with the 'status' command if an instance is already running
542             and which PID it has:
543              
544             ./my-app status
545             Pid file: ./tt.pid
546             Pid in file: 14914
547             Running: no
548             Name match: 0
549              
550             =back
551              
552             =head2 Actions
553              
554             C<App::Daemon> recognizes three different actions:
555              
556             =over 4
557              
558             =item my-app start
559              
560             will start up the daemon. "start" itself is optional, as this is the
561             default action,
562            
563             $ ./my-app
564             $
565            
566             will also run the 'start' action. By default, it will create a pid file
567             and a log file in the current directory
568             (named C<my-app.pid> and C<my-app.log>. To change these locations, see
569             the C<-l> and C<-p> options.
570              
571             If the -X option is given, the program
572             is running in foreground mode for testing purposes:
573              
574             $ ./my-app -X
575             ...
576              
577             =item stop
578              
579             will find the daemon's PID in the pidfile and send it a SIGTERM signal. It
580             will verify $App::Daemon::kill_retries times if the process is still alive,
581             with 1-second sleeps in between.
582              
583             To have App::Daemon send a different signal than SIGTERM (e.g., SIGINT), set
584              
585             use POSIX;
586             $App::Daemon::kill_sig = SIGINT;
587              
588             Note that his requires the numerial value (SIGINT via POSIX.pm), not a
589             string like "SIGINT".
590              
591             =item status
592              
593             will print out diagnostics on what the status of the daemon is. Typically,
594             the output looks like this:
595              
596             Pid file: ./tt.pid
597             Pid in file: 15562
598             Running: yes
599             Name match: 1
600             /usr/local/bin/perl -w test.pl
601              
602             This indicates that the pidfile says that the daemon has PID 15562 and
603             that a process with this PID is actually running at this moment. Also,
604             a name grep on the process name in the process table results in 1 match,
605             according to the output above.
606              
607             Note that the name match is unreliable, as it just looks for a command line
608             that looks approximately like the script itself. So if the script is
609             C<test.pl>, it will match lines like "perl -w test.pl" or
610             "perl test.pl start", but unfortunately also lines like
611             "vi test.pl".
612              
613             If the process is no longer running, the status output might look like
614             this instead:
615              
616             Pid file: ./tt.pid
617             Pid in file: 14914
618             Running: no
619             Name match: 0
620              
621             The status commands exit code complies with
622              
623             http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
624              
625             and returns
626              
627             0: if the process is up and running
628             1: the process is dead but the pid file still exists
629             3: the process is not running
630              
631             These constants are defined within App::Daemon to help writing test
632             scripts:
633              
634             use constant LSB_OK => 0;
635             use constant LSB_DEAD_PID_EXISTS => 1;
636             use constant LSB_DEAD_LOCK_EXISTS => 2;
637             use constant LSB_NOT_RUNNING => 3;
638             use constant LSB_UNKNOWN => 4;
639             use constant ALREADY_RUNNING => 150;
640              
641             =back
642              
643             =head2 Command Line Options
644              
645             =over 4
646              
647             =item -X
648              
649             Foreground mode. Log messages go to the screen.
650              
651             =item -l logfile
652              
653             Logfile to send Log4perl messages to in background mode. Defaults
654             to C<./[appname].log>. Note that having a logfile in the current directory
655             doesn't make sense except for testing environments, make sure to set this
656             to somewhere within C</var/log> for production use.
657              
658             =item -u as_user
659              
660             User to run as if started as root. Defaults to 'nobody'.
661              
662             =item -g as_group
663              
664             Group to run as if started as root. Defaults to 'nogroup'.
665              
666             =item -l4p l4p.conf
667              
668             Path to Log4perl configuration file. Note that in this case the -v option
669             will be ignored.
670              
671             =item -p pidfile
672              
673             Where to save the pid of the started process.
674             Defaults to C<./[appname].pid>.
675             Note that
676             having a pidfile in the current directory
677             doesn't make sense except for testing environments, make sure to set this
678             to somewhere within C</var/run> for production use.
679              
680             =item -v
681              
682             Increase default Log4perl verbosity from $INFO to $DEBUG. Note that this
683             option will be ignored if Log4perl is initialized independently or if
684             a user-provided Log4perl configuration file is used.
685              
686             =back
687              
688             =head2 Setting Parameters
689              
690             Instead of setting paramteters like the logfile, the pidfile etc. from
691             the command line, you can directly manipulate App::Daemon's global
692             variables:
693              
694             use App::Daemon qw(daemonize);
695              
696             $App::Daemon::logfile = "mylog.log";
697             $App::Daemon::pidfile = "mypid.log";
698             $App::Daemon::l4p_conf = "myconf.l4p";
699             $App::Daemon::background = 1;
700             $App::Daemon::as_user = "nobody";
701             $App::Daemon::as_group = "nogroup";
702              
703             use Log::Log4perl qw(:levels);
704             $App::Daemon::loglevel = $DEBUG;
705              
706             daemonize();
707              
708             =head2 Application-specific command line options
709              
710             If an application needs additional command line options, it can
711             use whatever is not yet taken by App::Daemon, as described previously
712             in the L<Command Line Options> section.
713              
714             However, it needs to make sure to remove these additional options before
715             calling daemonize(), or App::Daemon will complain. To do this, create
716             an options hash C<%opts> and store application-specific options in there
717             while removing them from @ARGV:
718              
719             my %opts = ();
720              
721             for my $opt (qw(-k -P -U)) {
722             my $v = App::Daemon::find_option( $opt, 1 );
723             $opts{ $opt } = $v if defined $v;
724             }
725              
726             After this, options C<-k>, C<-P>, and C<-U> will have disappeared from
727             @ARGV and can be checked in C<$opts{k}>, C<$opts{P}>, and C<$opts{U}>.
728              
729             =head2 Gotchas
730              
731             =over 4
732              
733             =item Log File Permissions
734              
735             If the process is started as root but later drops permissions to a
736             non-priviledged user for security purposes, it's important that
737             logfiles are created with correct permissions.
738              
739             If they're created as root when the program starts, the non-priviledged
740             user won't be able to write to them later (unless they're world-writable
741             which is also undesirable because of security concerns).
742              
743             The best strategy to handle this case is to specify the non-priviledged
744             user as the owner of the logfile in the Log4perl configuration:
745              
746             log4perl.logger = DEBUG, FileApp
747             log4perl.appender.FileApp = Log::Log4perl::Appender::File
748             log4perl.appender.FileApp.filename = /var/log/foo-app.log
749             log4perl.appender.FileApp.owner = nobody
750             log4perl.appender.FileApp.layout = PatternLayout
751             log4perl.appender.FileApp.layout.ConversionPattern = %d %m%n
752              
753             This way, the process starts up as root, creates the logfile if it
754             doesn't exist yet, and changes its owner to 'nobody'. Later, when the
755             process assumes the identity of the user 'nobody', it will continue
756             to write to the logfile without permission problems.
757              
758             =item Log4perl Categories
759              
760             Note that App::Daemon is logging messages in Log4perl's App::Daemon
761             namespace. So, if you're running your own Log4perl configuration and
762             define a root logger like
763              
764             log4perl.logger=DEBUG, appendername
765              
766             then App::Daemon's messages will bubble up to it and be visible in
767             the output. If you don't want that, either use
768              
769             log4perl.logger.My.App=DEBUG, appendername
770              
771             to explicitly enable verbose logging in your application namespace
772             (and not in App::Daemon's) or tone down App::Daemon's verbosity via
773              
774             log4perl.logger.App.Daemon=ERROR
775              
776             explicitly. If you want more details on basic Log4perl features,
777             check out the L<Log::Log4perl> manual page.
778              
779             =back
780              
781             =head2 Detach only
782              
783             If you want to create a daemon without the fancy command line parsing
784             and PID file checking functions, use
785              
786             use App::Daemon qw(detach);
787             detach();
788             # ... some code here
789              
790             This will fork a child, terminate the parent and detach the child from
791             the terminal. Issued from the command line, the program above will
792             continue to run the code following the detach() call but return to the
793             shell prompt immediately.
794              
795             =head1 AUTHOR
796              
797             2008, Mike Schilli <cpan@perlmeister.com>
798            
799             =head1 LICENSE
800              
801             Copyright 2008-2012 by Mike Schilli, all rights reserved.
802             This program is free software, you can redistribute it and/or
803             modify it under the same terms as Perl itself.
804