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

I am writing a script to retrieve eventlogs from windows systems. Currently I am using Active Perl. I started by writing a script that just dumps the output to the screen but I am getting some strange results. Specifically some records seem to print out ok and others look like garbage. Has anyone had trouble with Win32::EventLog? The code is posted below. Thanks in advance.
use Win32::EventLog; use Date::Calc; use Strict; my @epoch = (1970,1,1,7,0,0); my $EventLog = Win32::EventLog->new("Application") or die "Can't open Application Log"; $EventLog->GetOldest($oldest) or die "Can't get number of oldest EventLog record\n"; $EventLog->GetNumber($lastRec) or die "Can't get number of EventLog records\n"; my $lastRecOffset = $oldest + $lastRec - 1; print $oldest . "\n"; print $lastRec . "\n"; print $lastRecOffset . "\n"; while ($lastRecOffset > $oldest ) { $EventLog->Read(EVENTLOG_BACKWARDS_READ|EVENTLOG_SEEK_READ, $lastRecOffset, $hashRef) or die "Can't read EventLog entry #$lastRecOffset\n"; Win32::EventLog::GetMessageText($hashRef); my $seconds = $hashRef->{TimeGenerated}; foreach my $key (keys %$hashRef){ if (lc($key) =~ /time/){ print $key . "\t" . FormatDate($hashRef->{$key}) . "\n"; }else{ print $key . "\t" . $hashRef->{$key} . "\n"; } } $lastRecOffset--; print "\n"; } sub FormatDate { my $seconds = shift; my @generated = Date::Calc::Add_Delta_DHMS(@epoch,0,0,0,$seconds); my $genDate = Date::Calc::Date_to_Text($generated[0],$generated[1] +,$generated[2]); my $ampm = "am"; if ($generated[3]>12){ $generated[3] -= 12; $ampm = "pm"; } return $genDate . " " .$generated[3] . ":" .$generated[4] . ":" .$ +generated[5] . " $ampm"; }

Replies are listed 'Best First'.
Re: A question regarding Win32::EventLog
by nerfherder (Monk) on Feb 02, 2005 at 00:29 UTC
    I've tried your code, and the only garbage I see are an excess of carriage returns in the output of 1 log entry that documents a hungapp Explorer.exe hang... Is this what you're getting?

    I tried regexing out the CR's from the output with s/\r//;, to no avail. I guess they are in the log file (corrupt logfile?), but it's hard to tell because my C:\WINDOZE\system32\config\AppEvent.Evt is in goofy binary format... You've piqued my curiosity; let me know if you have any other info. For instance: what did your "garbage" output look like?
      Yeah I spent a little time trying to fix the CR's to no avail. One thing I notice is that the Event ID field doesn't always accurately report. Here is a sample I ran through the windows findstr command (I'm getting around to just installing cygwin):
      perl test.pl | findstr UserID
      EventID 8001
      EventID 8000
      EventID 1073743528
      EventID 11707
      EventID 1004
      EventID 1073743528
      EventID 1073743528
      EventID 1269629470
      EventID 1269629470
      EventID 1269629470
      EventID 1269629470
      EventID 1269629470
      EventID 1269629470
      EventID 11707
      EventID 11707
      EventID 11707
      EventID 1269629470
      EventID 1269629470
      EventID 1269629470
      EventID 1269629470
      EventID 1269629470
      EventID 1269629470
      EventID 1000
      
      Those 10 digit numbers are a mystery. The other ones like 1000 seem to match up correctly. In addition there is literal garbage in parts, here is a sample:
      c}⌂▒■♂√v3Θí⌡╓T╠F31B²╬≈↓)Zσ▌ ◄Ω#!Rφ"▬;╥←↓j╒╬╧!┌‼◄b▌╓╫9┬∩╪h
      
      Thanks for your response. I'm gonna look at it some more tomorrow and I'll let you know if I can figure out anything further.
        Hi Sid, I cant quite figure out where those characters are coming from, but for the event ID bit, this should fix it:
        foreach my $key (keys %$hashRef){ if ($key =~ /EventID/) { my $id = ($hashRef->{$key} & 0xffff); print $key . "\t" . "\"$id\"" . "\n"; }
        hth !!

        Update:
        Ok, I am seeing the chars being printed against the name field. I still dont know how to fix it to print the name field, but this should give you the sid for the uid instead.
        elsif ($key =~ /User/){ my $sid = unpack("H" . 2 * length(${$hashRef}{$key}), ${$hashRef}{ +$key}); my $user = ($hashRef->{$key} & 0xffff); print "User SID: " . "\t" . "\"$sid\" " . "\n"; }