2 ##------------------------------------------------------------------------##
4 ## $Id: logcmd,v 1.1 2002/10/01 22:49:46 ehood Exp $
6 ## Earl Hood earl@earlhood.com
8 ## Program to log the output of a program.
10 ##------------------------------------------------------------------------##
11 ## Copyright (C) 2002 Earl Hood, earl@earlhood.com
13 ## This program is free software; you can redistribute it and/or modify
14 ## it under the terms of the GNU General Public License as published by
15 ## the Free Software Foundation; either version 2 of the License, or
16 ## (at your option) any later version.
18 ## This program is distributed in the hope that it will be useful,
19 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ## GNU General Public License for more details.
23 ## You should have received a copy of the GNU General Public License
24 ## along with this program; if not, write to the Free Software
25 ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 ##------------------------------------------------------------------------##
29 package Devtools
::locmd
;
35 my $our_name = 'logcmd';
38 my $time_fmt = '%Y-%m-%d %H:%M:%S';
50 'log=s' => \
$log_file,
51 'mailto=s@' => \
@mailto, # not implemented, yet
52 'time-fmt=s' => \
$time_fmt,
56 ) || die qq/ERROR: Use -help for usage information\n/;
57 usage
(1, 0) if ($help);
58 usage
(2, 0) if ($man);
61 die qq/ERROR: No command specified\n/;
63 ($cmd_name = $ARGV[0]) =~ s/.*\///;
66 $child_pid = open(CMD
, "-|");
67 if ($child_pid) { # parent
69 local @SIG{'PIPE','TERM','INT'} = (sub {
70 log_line
($our_name, $$, "Caught signal: SIG$_[0]\n");
74 log_line
($cmd_name, $child_pid, $_);
78 log_line
($our_name, $$, qq/Non-zero exit for [$child_pid]: $?\n/);
83 open(STDERR
, '>&STDOUT');
84 exec(@cmd) || die qq/ERROR: Cannot exec "@cmd": $!\n/;
89 ##=========================================================================##
92 POSIX
::strftime
($time_fmt, localtime);
99 my $have_newline = $line =~ /\n\Z/;
100 my $eol = ($have_newline) ?
"" : "\n";
104 print $log_fh join('', '[',format_time
(),']',' [',$$,'] ',$our_name,': ',
105 "Command: [$child_pid] @cmd\n");
107 print $log_fh join('', '[',format_time
(),']',' [',$pid,'] ',$label,': ',
113 if (!defined($file) || $file eq '-') {
116 open(LOG
, ">>$file") ||
117 die qq/ERROR: Unable to open "$file" for appending: $!\n/;
124 if ($log_fh != \
*STDOUT
) {
126 warn qq/Warning: Problem closing log file: $!\n/;
133 my $verbose = shift || 0;
134 my $exit_code = shift;
137 Pod
::Usage
::pod2usage
(-verbose
=> $verbose);
139 my $pager = $ENV{'PAGER'} || 'more';
141 my $fh = (-t STDOUT
&& open(PAGER
, "|$pager")) ? \
*PAGER
: \
*STDOUT
;
142 Pod
::Usage
::pod2usage
(-verbose
=> $verbose,
144 close(PAGER
) if ($fh == \
*PAGER
);
146 defined($exit_code) && exit($exit_code);
149 ##=========================================================================##
154 logcmd - Log the output of a program.
158 logcmd [options] -- <command> [command-args ...]
162 B<logcmd> logs the output of a program. This program is useful
163 for logging program output for programs that do not have a built-in
166 Typical usage is to use B<logcmd> in crontabs to log any command
167 output to a file instead of mail automatically being sent to the
170 When invoking B<logcmd>, you B<must> use "C<-->" to separate the
171 B<logcmd> and its options from the command you are invoking. For
174 logcmd -log out.log -- some-cmd arg1 arg2 arg3
176 This tells B<logcmd> to run "C<some-cmd arg1 arg2 arg3>" and have
177 any output goto C<out.log>.
179 Each line logged will be preceded by a timestamp, the process ID, and
180 the name of the command. Also, before the first log message for a command
181 is printed, B<logcmd> will print out a line giving the full command-line
182 of the command invoked. Example:
184 [2002-07-30 14:52:13] [25392] logcmd: Command: [25393] mhonarc -quiet -out out /var/archiver/mail
185 [2002-07-30 14:52:13] [25393] mhonarc:
186 [2002-07-30 14:52:13] [25393] mhonarc: Warning: Unrecognized character set: utf-8
187 [2002-07-30 14:52:13] [25393] mhonarc: Message-Id: <1022714308.2028.1.camel@xxx.xxx.xxx>
188 [2002-07-30 14:52:13] [25393] mhonarc: Message Number: 00367
189 [2002-07-30 14:52:13] [25393] mhonarc:
190 [2002-07-30 14:52:13] [25393] mhonarc: Warning: Unrecognized character set: utf-8
191 [2002-07-30 14:52:13] [25393] mhonarc: Message-Id: <1022716087.2028.3.camel@xxx.xxx.xxx>
192 [2002-07-30 14:52:13] [25393] mhonarc: Message Number: 00368
193 [2002-07-30 14:52:14] [25393] mhonarc:
194 [2002-07-30 14:52:14] [25393] mhonarc: Warning: Unrecognized character set: utf-8
195 [2002-07-30 14:52:14] [25393] mhonarc: Message-Id: <1024365245.9394.0.camel@xxx.xxx.xxx>
196 [2002-07-30 14:52:14] [25393] mhonarc: Message Number: 00398
205 Display SYNOPSIS and OPTIONS sections.
207 =item C<-log> I<pathname>
209 Command output will be logged to I<pathname>. If this option is
210 not specified, then standard out is used.
216 =item C<-time-fmt> I<fmt>
218 Date/time format to use when printing time before each logged line.
219 The format string should be in C<strftime>(3) format. If this
220 option is not specified, then "C<%Y-%m-%d %H:%M:%S>" is used.
224 Terminate option processing for B<logcmd>. Any arguments after
225 C<--> comprise the command that B<logcmd> should execute.
231 The following is an example crontab entries of a user that has
232 any output of commands goto a personal log file:
234 0 2 * * * logcmd -log $HOME/log/cron.log -- $HOME/bin/clean_account
235 0 3 * * * logcmd -log $HOME/log/cron.log -- $HOME/bin/pack_mail
243 B<logcmd> performs no file locking on the log file specified. To help
244 minimize that a single output line to the log does not get broken up
245 due to multiple writers, the entire line is dumped in a single call
246 to Perl's C<print> operator.
252 C<Getopt::Long>, C<POSIX>.
256 Earl Hood, earl@earlhood.com
258 This program comes with ABSOLUTELY NO WARRANTY and may be copied only
259 under the terms of the GNU General Public License.