Re: Print to several logs

2013-08-28 Thread Michael Brader
There are some good answers here so far, but I'd like to recommend a 
logging module like Log::Log4perl. If your script is more than a run-once 
throwaway, proper logging will almost certainly be of benefit.


Metacpan: https://metacpan.org/module/Log::Log4perl
FAQ: 
http://log4perl.sourceforge.net/releases/Log-Log4perl/docs/html/Log/Log4perl/FAQ.html

Tutorial: http://www.perl.com/pub/2002/09/11/log4perl.html

To log to two files:

#!/usr/bin/perl

use strict;
use warnings;

use Log::Log4perl qw(get_logger);

# Normally this would be in a separate file
my $log4perl_cfg = 'EOCFG';
# Two appenders in our logger tmplog1  tmplog2
log4perl.logger = DEBUG, tmplog1, tmplog2

log4perl.appender.tmplog1 = Log::Log4perl::Appender::File
log4perl.appender.tmplog1.filename = /var/tmp/one.log
log4perl.appender.tmplog1.layout   = PatternLayout
log4perl.appender.tmplog1.layout.ConversionPattern = %d %m%n

log4perl.appender.tmplog2 = Log::Log4perl::Appender::File
log4perl.appender.tmplog2.filename = /var/tmp/two.log
log4perl.appender.tmplog2.layout   = PatternLayout
log4perl.appender.tmplog2.layout.ConversionPattern = %d %m%n
EOCFG

Log::Log4perl-init( \$log4perl_cfg );
my $logger = get_logger();
my $rsync = 'rsync';

$logger-debug('About to rsync');
...;
$logger-info(kdkdkdkd Output from: $rsync cmdflgs);
exit 0;

Using Log4perl allows you to change how you log very easily, with appenders 
for output to files, the screen, databases etc. all available. The 
configuration format is somewhat verbose, so I generally use the Template 
Toolkit to generate it for me. The example below solves your same problem, 
but for N files instead of two:


#!/usr/bin/perl

use strict;
use warnings;

use Log::Log4perl qw(get_logger);
use Template;

my $logging_cfg_template = 'EOCFG';
[% BLOCK appenders -%]
  [% FOR section IN sections %][% section.log_appender_name %][% ,  
UNLESS loop.last %][% END %]

[%- END %]
[% BLOCK appender_sections %]
  [% FOR section IN sections %]
log4perl.appender.[% section.log_appender_name %] = 
Log::Log4perl::Appender::File
log4perl.appender.[% section.log_appender_name %].filename = [% 
section.log_file_name %]

log4perl.appender.[% section.log_appender_name %].layout = PatternLayout
log4perl.appender.[% section.log_appender_name %].layout.ConversionPattern 
= %d %m%n

  [% END %]
[% END %]
log4perl.logger = DEBUG, [% PROCESS appenders %]
[% PROCESS appender_sections %]
EOCFG

my $template = {
sections = [
{ log_appender_name = 'tmplog1', log_file_name = 
'/var/log/one.log', },
{ log_appender_name = 'tmplog2', log_file_name = 
'/var/log/two.log', },
{ log_appender_name = 'tmplog3', log_file_name = 
'/var/log/three.log', },

],
};

my $tt = Template-new();

my $log4perl_cfg;
$tt-process( \$logging_cfg_template, $template, \$log4perl_cfg ) || die 
'Template error: ' . $tt-error();


# Comment or remove this line once you are happy with the generated config
print CONFIG: $log4perl_cfg\n;

Log::Log4perl-init( \$log4perl_cfg );
my $logger = get_logger('main');
my $rsync  = 'rsync';

$logger-info(kdkdkdkd Output from: $rsync cmdflgs);

Cheers,
Michael


On 08/28/2013 06:44 AM, Harry Putnam wrote:

I happen to be scripting something that needs to have two logs written
to and was sort of taken by how awkward this construction looked:

(Simplified for discussion, from a longer script)

   my $rsync = 'rsync';
   my $tmplog = 'one.log';
   my $tmplog2 = 'two.log';
   open(LOG,$tmplog)or die Can't open $tmplog : $!;
   open(LOG2,$tmplog2)or die Can't open $tmplog2: $!;
   print LOG  kdkdkdkd Output from:\n$rsync cmdflgs;
   print LOG2 kdkdkdkd Output from:\n$rsync cmdflgs
   close(LOG);
   close(LOG2);

Is there some smooth way to write to more than one log?

I tried just adding the second one to the first print like this:

  print LOG LOG2 [...];

   But that fails with an error:

   String found where operator expected at ./t1.pl line 109, near LOG2
   kdkdkdkd Output from:\n$rsync cmdflgs

 (Do you need to predeclare LOG2?)

   syntax error at ./t1.pl line 109, near LOG2 kdkdkdkd Output
   from:\n$rsync cmdflgs

   Execution of ./t1.pl aborted due to compilation errors.




--
Michael BraderSenior Software Engineer and Perl Person
Our World Wide Web has a World Wide Network  Technology/Softdev/DevOps
Internode   http://internode.on.net/  mbra...@internode.com.au
iiNet http://iinet.net.au/ m.bra...@staff.iinet.net.au


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Print to several logs

2013-08-28 Thread Harry Putnam
Rob Dixon rob.di...@gmx.com writes:

 On 27/08/2013 23:06, John W. Krahn wrote:
 Harry Putnam wrote:

[...]

 (Simplified for discussion, from a longer script)

my $rsync = 'rsync';
my $tmplog = 'one.log';
my $tmplog2 = 'two.log';
open(LOG,$tmplog)or die Can't open $tmplog : $!;
open(LOG2,$tmplog2)or die Can't open $tmplog2: $!;
print LOG  kdkdkdkd Output from:\n$rsync cmdflgs;
print LOG2 kdkdkdkd Output from:\n$rsync cmdflgs
close(LOG);
close(LOG2);

 Is there some smooth way to write to more than one log?

 my %logs = (
  'one.log' = undef,
  'two.log' = undef,
  );

 for my $name ( keys %logs ) {
  open my $FH, '', $name or die Cannot open '$name' because: $!;
  $logs{ $name } = $FH;
  }

 for my $log_FH ( values %logs ) {
  print $log_FH kdkdkdkd Output from:\n$rsync cmdflgs;
  }

 Nice John

Yes very nice... thank you John

 It compacts neatly to

[...] snipped neatly compacted code

Nicely compacted... thank you Rob.

Thanks to all other posters.. lots of good input.



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Print to several logs

2013-08-28 Thread Shawn H Corey
On Wed, 28 Aug 2013 10:42:30 -0400
Harry Putnam rea...@newsguy.com wrote:

 Thanks to all other posters.. lots of good input.

It seems to me that recording the same information is many places is a
design flaw. If you have the same information in two or more places, it
will get out of sync. Write the program that will detect and correct
this, now, not later.


-- 
Don't stop where the ink does.
Shawn

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Make a sub routine return

2013-08-28 Thread Harry Putnam
I know the format and scripting are probably pretty backwards but I
seem to recall it being important to have a `return' line in a
function. 

The code below was a script by itself but now I need to turn it into a
function inside a larger script... I've done something that sort of
works but fails on a specific file name that looks like `.#somefile'.

I'll show the code the way I've tried to turn it into a sub routine.
So, I'd like comments both on how to write this more like a proper sub
routine and any other why ideas.

What the sub is supposed to do is plow thru a couple of directories and
reset the proper owner and group after some other operations have
changed them.

Its called like this in a getops operation:

if($opt_o ) {
  if (@ARGV) {
usage();
print The \`-o' flag must be used by itself and\n,
   \`-o' flag requires user to be root .. exiting\n ;
exit;
  }
  chOwnGrp();
  exit;
}

sub chOwnGrp {
  use File::Find;
  my $buffer = '/merb';
  my $module = '/usr/local/common/merc';
  my $uname = $ENV{'LOGNAME'};
  my $uid = '1000';
  my $gid = '1050';

  if ($uname =~ /root/) {
print Would you like to set owner:group on BUFFER and MODULE?\n,
  If so, we will run chown -R $uid:$gid $buffer and\n,
  chown -R $uid:$gid $module\n,
  [y/n]  ;

my $answer = STDIN;
if ($answer =~ /^y$/) {
  find(
   sub {
 chown $uid, $gid, $_ or warn could not chown '$_': $!;
   },
   $buffer, $module
  );
}
  } else {
print You must be root to run with this flag (-o)  effectively.. 
exiting\n;
print Not root - tripped at line:  . __LINE__ . \n;
exit;
  }
}


-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Print to several logs

2013-08-28 Thread Harry Putnam
Shawn H Corey shawnhco...@gmail.com writes:

 On Wed, 28 Aug 2013 10:42:30 -0400
 Harry Putnam rea...@newsguy.com wrote:

 Thanks to all other posters.. lots of good input.

 It seems to me that recording the same information is many places is a
 design flaw. If you have the same information in two or more places, it
 will get out of sync. Write the program that will detect and correct
 this, now, not later.

Good thinking thanks.  It might not really apply here though.
I'm no kind of data manager... just a homeboy hillbilly.

What I had in mind is writing to a single log file that is dated on
the file name for each run of the program.  That file will sooner or
later be deleted by another part of the script that will try to leave
5 of the most recent logs.

I was going to just cat the fresh log, onto an accumlative log after
each run so the info would stick around for a while longer in case
some kind of problem came up requiring research into previous
runs older than the 5 dated logs.

So the info is really only duplicated for a few weeks.

That accumulative file might grow quite a bit.  I find it handier to
look thru a few dated logs that are much smaller ... but if it comes
down to it and the dated logs don't go back far enough then I can find
it in the accumulative log. That too, will get trimmed back
eventually,

That sounds quite a bit like what cron could do with this hmm.


-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Print to several logs

2013-08-28 Thread Shawn H Corey
On Wed, 28 Aug 2013 12:34:40 -0400
Harry Putnam rea...@newsguy.com wrote:

 That sounds quite a bit like what cron could do with this hmm.

Or use a hard link to preserve the file.


-- 
Don't stop where the ink does.
Shawn

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Print to several logs

2013-08-28 Thread John W. Krahn

Rob Dixon wrote:


On 27/08/2013 23:06, John W. Krahn wrote:


my %logs = (
'one.log' = undef,
'two.log' = undef,
);

for my $name ( keys %logs ) {
open my $FH, '', $name or die Cannot open '$name' because: $!;
$logs{ $name } = $FH;
}

for my $log_FH ( values %logs ) {
print $log_FH kdkdkdkd Output from:\n$rsync cmdflgs;
}


Nice John

It compacts neatly to

use strict;
use warnings;
use autodie;

my $rsync = 'rsync';
my $tmplog = 'one.log';
my $tmplog2 = 'two.log';

my %logs = map {
open my $FH, '', $_;


What if open fails?!


($_ = $FH);
} $tmplog, $tmplog2;


Or a bit more compact:

my %logs = map {
open my $FH, '', $_ or die Cannot open '$name' because: $!;
( $_ = $FH );
} my ( $tmplog, $tmplog2 ) = qw( one.log two.log );



John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction.   -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Make a sub routine return

2013-08-28 Thread Rob Dixon

On 28/08/2013 16:48, Harry Putnam wrote:


The code below was a script by itself but now I need to turn it into a
function inside a larger script... I've done something that sort of
works but fails on a specific file name that looks like `.#somefile'.


What does fails mean? Does it crash?, produce an error message?, seem
to work but have no effect?...

Rob



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Print to several logs

2013-08-28 Thread Rob Dixon

On 28/08/2013 19:06, John W. Krahn wrote:

Rob Dixon wrote:


use strict;
use warnings;
use autodie;

my $rsync = 'rsync';
my $tmplog = 'one.log';
my $tmplog2 = 'two.log';

my %logs = map {
open my $FH, '', $_;


What if open fails?!


I have `use autodie`.

Rob


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Print to several logs

2013-08-28 Thread Shawn H Corey
On Wed, 28 Aug 2013 12:34:40 -0400
Harry Putnam rea...@newsguy.com wrote:

 Good thinking thanks.  It might not really apply here though.
 I'm no kind of data manager... just a homeboy hillbilly.
 
 What I had in mind is writing to a single log file that is dated on
 the file name for each run of the program.  That file will sooner or
 later be deleted by another part of the script that will try to leave
 5 of the most recent logs.

Try this. It will keep rotating log files for the day-of-month, month,
and year.

# --
#   Name: start_logging
#  Usage: $log_fh = start_logging( $log_file );
#Purpose: To open log file and set a day-of-month, month, and year
# file that tracks it.
# Parameters: $log_file -- full path to log file
#Returns:   $log_fh -- file handle to open log file
#
use Carp;
use English   qw( -no_match_vars );  # Avoids regex performance penalty
use File::Basename;
use POSIX;

sub start_logging {
  my $log_file = shift @_;
  my @now  = localtime;

  open my $log_fh, '', $log_file or croak could not open $log_file because: 
$OS_ERROR\n;
  my $dir = dirname( $log_file );

  # link to day-of-month log file
  my $day_file = strftime $dir/day_%d.log, @now;
  unlink $day_file; # ignore errors
  link $log_file, $day_file or carp could not link to day-of-month file, 
$day_file because: $OS_ERROR\n;

  # link to month log file
  my $month_file = strftime $dir/mo_%m.log, @now;
  unlink $month_file; # ignore errors
  link $log_file, $month_file or carp could not link to day-of-month file, 
$month_file because: $OS_ERROR\n;

  # link to year log file
  my $year_file = strftime $dir/yr_%Y.log, @now;
  unlink $year_file; # ignore errors
  link $log_file, $year_file or carp could not link to day-of-month file, 
$year_file because: $OS_ERROR\n;

  return $log_fh;
}



-- 
Don't stop where the ink does.
Shawn

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/