http://www.perlmonks.org?node_id=184857

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

Background

I wrote this to take a list of servers from a text file, and backup their event logs to .evt files in a central location. I am running the script from a Win2000 Server against a mix of 2000 and NT4 servers, and for 80% of them there is no problem.

Problem

  1. For eventlogs over 300MB, the script backs up a 1KB file. When opened, the log file is blank, but will say 1.8 million records. Manual backing up will back up the full 300 MB.
  2. For NT4 Servers, I am getting "Access is Denied" when trying to back up the logs. I can back up the eventlogs manually with the same account used by the script.

What I've Tried

Tried different accounts, waded through activestate mailing lists, upgraded the activestate build from 631 to 633, searched google, begged, pleaded, and sacrificed two goats.

The Code

# Jonathan Dyer X-XXXX, # Written to take input of list of servers in eventlogs_in.txt and bac +kup the # event logs to \\XXXXXXX\EVENTLOGS\SERVER\LOGNAME\DATE use strict; use Win32::EventLog; use File::Copy; open IN, "<//XXXXXXX/c\$/scripts/eventlogs/eventlogs_in.txt"; while (<IN>){ chomp; my $server="$_"; print "\n$server\n"; my($date)=join("-", ((split(/\s+/, scalar(localtime)))[1,2,4])); my $remdir="//XXXXXXX/eventlogs/$server"; open OUT, ">>//XXXXXXX/eventlogs/backuperrors.log" || die "BackupE +rrors.log cannot be written. Stopping."; print OUT "$date\n"; for my $eventlog ("Application", "System", "Security") { print "\t$eventlog"; my $locdir="//$server/c\$/temp/$eventlog"; my $dest="$locdir/$date.evt"; if (!-e $locdir){mkdir ("$locdir") || print OUT "ERR: Can't cr +eate local log directory on $server: ($^E)\n";} if (!-e $remdir){mkdir ("$remdir") || print OUT "ERR: Can't cr +eate $remdir: ($^E)\n";} if (!-e "$remdir/$eventlog"){mkdir ("$remdir/$eventlog") || pr +int OUT "ERR: Can't create $remdir/$eventlog: ($^E)\n";} if ((-e "$remdir/$eventlog")&&(-e "$locdir")){ my %event=( 'Computer',"$server", 'EventID','777', 'EventType',EVENTLOG_INFORMATION_TYPE, 'Category','None', 'Strings',"The $eventlog Event log was backed up to $remdi +r.", 'Data',"The $eventlog Event log was backed up.", ); my $handle=Win32::EventLog->new($eventlog, "\\\\$server") +|| print OUT "ERR: Can't read $eventlog EventLog on $server:($^E)\n"; $handle->Backup($dest) || print OUT "ERR: Could not backup + the $eventlog EventLog on $server to $dest ($^E)\n"; #$handle->Clear($dest) || print OUT "ERR: Could not clear +the $eventlog EventLog on $server:($^E)\n"; $handle->Report(\%event) || print OUT "ERR: Could not writ +e to the $eventlog event log:($^E)\n" unless ($eventlog=="Security"); + #Needed b/c writing to Security log is not allowed $handle->Close; copy($dest,"$remdir/$eventlog/$date.evt") || print OUT "ER +R: Couldn't Copy $eventlog Log on $server from $dest to $remdir/$even +tlog:($!)\n"; #unlink "$dest"; } } print OUT "----------\n"; close OUT; }

Any ideas are welcome. I'm ready to scrap this and go with a co-worker's C-Solution, but it would be a shot to Perl here.

Thanks.

-OzzyOsbourne

Replies are listed 'Best First'.
Re: Win32::Eventlog Issues: Access Denied, Incorrect log size
by BrowserUk (Patriarch) on Jul 24, 2002 at 16:25 UTC

    A couple of things

    It would be useful if you could isolate/tell us where the "Access is denied" msg is being displayed? Also, if you could isolate which line of your script is causing it.

    Maybe the easiest way to do this would be to use Perl's built-in debugger.

    Second point, and I hesitate to mention it as you say that "this is working 80% of the time", but...according to the Win32::EventLog docs:

    $handle->Backup(FILENAME); The Backup() method backs up the EventLog represented by $handle. It t +akes a single arguemt, FILENAME. When $handle represents an EventLog +on a remote machine, <b>FILENAME is filename on the remote machine an +d cannot be a UNC path</b> (i.e you must use C:\TEMP\App.EVT). The me +thod will fail if the log file already exists.

    Which if interpret correctly means that the built-in Backup() method will only work if the source and destination are on the same machine? And reading your code, it appears that you are suppling a local path ($locdir) whilst processing a remote machines logs?

    It strikes me that the size related problem could be due to memory exhaustion?

    Kick me if I mis-read this.

      Here's my two cents... Change the code around to suit your needs. This code will do away with opening a file of servers (nodes in my case), no sense in creating more files to make a mess of things? ya know?

      By the way this has been tested on windows 2000 server 2000 pro and windows Xp

      Hope it helps!
      #!/usr/bin/perl -w use strict; use Win32::EventLog; my @nodes = qw(NODE1 NODE2 NODE3); foreach my $node(@nodes) { &GetEvents($node); } sub GetEvents { my($myServer) = @_; my($date)=join("-", ((split(/\s+/, scalar(localtime)))[0,1,2,4])); my($dest); my @logs =qw(Security System Application); foreach my $eventLog (@logs) { my $handle=Win32::EventLog->new($eventLog, $myServer) || die " +Can't open Application EventLog on $myServer $!"; $dest="C:\\Perl\\scripts\\$eventLog\\$date.evt"; $handle->Backup($dest) || die "Could not backup and clear the +$eventLog EventLog on $myServer ($^E)\n"; $handle->Close; } }