Link to home
Start Free TrialLog in
Avatar of PHrozen1
PHrozen1

asked on

Event log Help

I like the output of this script from roth. I got my last script to work. But modding this to look only for ERRORS and print to txt file with server name and date as file name is beyond me at the moment. Need to run with no user imput on system and application logs.

Thank you
use Getopt::Long;
use Time::Local;
use Win32::EventLog;
 
$SEC = 1;
$MIN = 60 * $SEC;
$HOUR = 60 * $MIN;
$DAY = 24 * $HOUR;
 
%EVENT_TYPE = (
    eval EVENTLOG_AUDIT_FAILURE     =>  'AUDIT_FAILURE',
    eval EVENTLOG_AUDIT_SUCCESS     =>  'AUDIT_SUCCESS',
    eval EVENTLOG_ERROR_TYPE        =>  'ERROR',
    eval EVENTLOG_WARNING_TYPE      =>  'WARNING',
    eval EVENTLOG_INFORMATION_TYPE  =>  'INFORMATION',
);
 
%Config = (
    log     =>  'System',
);
Configure( \%Config );
if( $Config{help} )
{
    Syntax();
    exit;
}
if( defined $Config{date} )
{
    my( $Year, $Month, $Day ) = ( $Config{date} =~ /^(\d{4}).(\d{2}).(\d{2})/ );
    $TIME_LIMIT = timelocal( 0, 0, 0, $Day, $Month - 1, $Year - 1900 );
}
elsif( $Config{hour} || $Config{day} )
{
    $TIME_LIMIT = time() - ( $DAY * $Config{day} ) - ( $HOUR * $Config{hour} );
}
 
if( ! scalar @{$Config{machine}} )
{
    push( @{$Config{machine}}, Win32::NodeName );
}
 
if( defined( $Config{type} ) )
{
    foreach my $Mask ( @{$Config{type}} )
    {
        # Try referencing the EVENTLOG_xxxx_TYPE and EVENTLOG_xxxxx
        # constants. One of them is bound to work.
        $EVENT_MASK |= eval( "EVENTLOG_" . uc( $Mask ) . "_TYPE" );
        $EVENT_MASK |= eval( "EVENTLOG_" . uc( $Mask ) );
    }
}
else
{
    map
    {
        $EVENT_MASK |= 0 + $_;
    }( keys( %EVENT_TYPE ) );
}
 
# Tell the extension to always attempt to fetch the
# event log message table text
$Win32::EventLog::GetMessageText = 1;
$~ = EventLogFormat;
foreach my $Machine ( @{$Config{machine}} )
{
    my $EventLog;
    if( $EventLog = Win32::EventLog->new( $Config{log}, $Machine ) )
    {
        my %Records;
        local %Event;
        local $Count = 0;
 
        while( ( $EventLog->Read( EVENTLOG_BACKWARDS_READ
                                 | EVENTLOG_SEQUENTIAL_READ,
                                 0,
                                 \%Event ) )
                && ( $Event{TimeGenerated} > $TIME_LIMIT ) )
        {
            # Display the event if it is one of our requested
            # event types
            $Count++;
            write if( $Event{EventType} & $EVENT_MASK );
        }
    }
    else
    {
        print "Can not connect to the $Config{log} Event Log on $Machine.\n";
    }
}
 
sub Configure
{
    my( $Config ) = @_;
 
    Getopt::Long::Configure( "prefix_pattern=(-|\/)" );
    $Result = GetOptions( $Config,
                            qw(
                                machine|m=s@
                                log|l=s
                                type|t=s@
                                hour|h=i
                                day|d=i
                                date=s
                                help|?
                            )
                        );
    $Config->{help} = 1 if( ! $Result );
    push( @{$Config->{machine}}, Win32::NodeName() ) unless( scalar @{$Config->{machine}} );
}
 
sub Syntax
{
    my( $Script ) = ( $0 =~ /([^\\]*?)$/ );
    my $Whitespace = " " x length( $Script );
    print<< "EOT";
 
Syntax:
    $Script [-m Machine] [-t EventType] [-l Log]
    $Whitespace [-h Hours] [-d Days] [-date Date]
    $Whitespace [-help]
        -m Machine......Name of machine whose Event Log is to be examined.
                        This switch can be specified multiple times.
        -t EventType....Type of event to display:
                            ERROR
                            WARNING
                            INFORMATION
                            AUDIT_SUCCESS
                            AUDIT_FAILURE
                        This switch can be specified multiple times.
        -l Log..........Name of Event Log to examine. Common examples:
                            Application
                            Security
                            System
                        This switch can be specified multiple times.
        -h Hours........Will consider events between now and the specified
                        number of hours previous.
        -d Days.........Will consider events between now and the specified
                        number of days previous.
        -date Date......Will consider events between now and the specified
                        date.  Date is in international time format
                        (eg. 2000.07.18)
EOT
}
 
format EventLogFormat =
--------------------------------
@>>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$Event{RecordNumber}, "\\\\" . $Event{Computer},     $Event{Message}
       @<<<<<<<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
scalar localtime( $Event{TimeGenerated} ), $Event{Message}
       Type: @<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$EVENT_TYPE{$Event{EventType}}, $Event{Message}
       Source: @<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$Event{Source},                       $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
 
.

Open in new window

Avatar of Adam314
Adam314

How are you calling the script?

You should be able to use the -type option to specify which event types you want displayed.
Avatar of PHrozen1

ASKER

this script works fine, I was trying to incorporate its functionality into another script i am working on.
From this script i needed the output format and the print errors from date range (last 24 hours) to a txt file.
To redirect the output to a file, you can do:
    script.pl -h 24 -t ERROR > output.txt
how would i write this script without accepting user input from the command ? IE get rid of everything except just reading the eventlog and matching to error and time with the formatted output using Clean simple code?
from the command line?
I'm not sure what you are trying to do?  What I gave above is what you would run from the command line.
I would like to have a "self contained" script on that  *does not* need input from the command line to run. to have the error and time conditions hard coded into the program.  To have it as simple and clean as possible.

ASKER CERTIFIED SOLUTION
Avatar of Adam314
Adam314

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
yes, that would work, but would leave unneeded code, i am asking for a rewrite.

use Time::Local;
use Win32::EventLog;
 
$SEC = 1;
$MIN = 60 * $SEC;
$HOUR = 60 * $MIN;
$DAY = 24 * $HOUR;
 
%EVENT_TYPE = (
    eval EVENTLOG_AUDIT_FAILURE     =>  'AUDIT_FAILURE',
    eval EVENTLOG_AUDIT_SUCCESS     =>  'AUDIT_SUCCESS',
    eval EVENTLOG_ERROR_TYPE        =>  'ERROR',
    eval EVENTLOG_WARNING_TYPE      =>  'WARNING',
    eval EVENTLOG_INFORMATION_TYPE  =>  'INFORMATION',
);
 
%Config = (
    log     =>  'System',
    hour    => 24,
    day     => 0,
    machine => [Win32::NodeName],
);
$TIME_LIMIT = time() - ( $DAY * $Config{day} ) - ( $HOUR * $Config{hour} );
 
foreach my $Mask ( @{$Config{type}} ) {
    # Try referencing the EVENTLOG_xxxx_TYPE and EVENTLOG_xxxxx
    # constants. One of them is bound to work.
    $EVENT_MASK |= eval( "EVENTLOG_" . uc( $Mask ) . "_TYPE" );
    $EVENT_MASK |= eval( "EVENTLOG_" . uc( $Mask ) );
}
 
# Tell the extension to always attempt to fetch the
# event log message table text
$Win32::EventLog::GetMessageText = 1;
$~ = EventLogFormat;
foreach my $Machine ( @{$Config{machine}} )
{
    my $EventLog;
    if( $EventLog = Win32::EventLog->new( $Config{log}, $Machine ) )
    {
        my %Records;
        local %Event;
        local $Count = 0;
 
        while( ( $EventLog->Read( EVENTLOG_BACKWARDS_READ
                                 | EVENTLOG_SEQUENTIAL_READ,
                                 0,
                                 \%Event ) )
                && ( $Event{TimeGenerated} > $TIME_LIMIT ) )
        {
            # Display the event if it is one of our requested
            # event types
            $Count++;
            write if( $Event{EventType} & $EVENT_MASK );
        }
    }
    else
    {
        print "Can not connect to the $Config{log} Event Log on $Machine.\n";
    }
}
 
 
format EventLogFormat =
--------------------------------
@>>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$Event{RecordNumber}, "\\\\" . $Event{Computer},     $Event{Message}
       @<<<<<<<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
scalar localtime( $Event{TimeGenerated} ), $Event{Message}
       Type: @<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$EVENT_TYPE{$Event{EventType}}, $Event{Message}
       Source: @<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$Event{Source},                       $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
 
.

Open in new window

I get uninitialized error at 54.
Is that the exact output?
Yes,

Taking a different tack, and going to accept your earlier answer. Sorry for the pain. Thank you for your help.
This is what I was looking for.

I still need to clean  it up some more.

Thank you for your answer.

use Getopt::Long;
use Time::Local;
use Win32::EventLog;
 
$SEC = 1;
$MIN = 60 * $SEC;
$HOUR = 60 * $MIN;
$DAY = 24 * $HOUR;
 
%EVENT_TYPE = (
    eval EVENTLOG_AUDIT_FAILURE     =>  'AUDIT_FAILURE',
    eval EVENTLOG_AUDIT_SUCCESS     =>  'AUDIT_SUCCESS',
    eval EVENTLOG_ERROR_TYPE        =>  'ERROR',
    eval EVENTLOG_WARNING_TYPE      =>  'WARNING',
    eval EVENTLOG_INFORMATION_TYPE  =>  'INFORMATION',
);
my @logs = qw(security application system);
my @servers = qw(bg2);
 
 
 
#Configure( $log );
Configure( \%Config );
if( $Config{hour} || $Config{day} )
{
    $TIME_LIMIT = time() - ( $DAY * $Config{day} ) - ( $HOUR * $Config{hour} );
}
 
 
if( defined( $Config{type} ) )
{
    foreach my $Mask ( @{$Config{type}} )
    {
        # Try referencing the EVENTLOG_xxxx_TYPE and EVENTLOG_xxxxx
        # constants. One of them is bound to work.
        $EVENT_MASK |= eval( "EVENTLOG_" . uc( $Mask ) . "_TYPE" );
        #$EVENT_MASK |= eval( "EVENTLOG_" . uc( $Mask ) );
    }
}
else
{
    map
    {
        $EVENT_MASK |= 0 + $_;
    }( keys( %EVENT_TYPE ) );
}
 
# Tell the extension to always attempt to fetch the
# event log message table text
$Win32::EventLog::GetMessageText = 1;
$~ = EventLogFormat;
 foreach my $server (@servers){
foreach my $log (@logs) {
 
    my $EventLog;
    if( $EventLog = Win32::EventLog->new( $log , $server ) )
    {
        my %Records;
        local %Event;
        local $Count = 0;
 
        while( ( $EventLog->Read( EVENTLOG_BACKWARDS_READ
                                 | EVENTLOG_SEQUENTIAL_READ,
                                 0,
                                 \%Event ) )
                && ( $Event{TimeGenerated} > $TIME_LIMIT ) )
        {
            # Display the event if it is one of our requested
            # event types
            $Count++;
            write if( $Event{EventType} & $EVENT_MASK );
        }
    }
    else
    {
        print "Can not connect to the $log Event Log on $server.\n";
    }
 
   }    }
sub Configure
{
    my( $Config ) = @_;
    $Config->{hour} = 96;
    $Config->{day} = 0;
    $Config->{type} = ['ERROR'];
 
 
}
 
 
 
format EventLogFormat =
--------------------------------
@>>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$Event{RecordNumber}, "\\\\" . $Event{Computer},     $Event{Message}
       @<<<<<<<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
scalar localtime( $Event{TimeGenerated} ), $Event{Message}
       Type: @<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$EVENT_TYPE{$Event{EventType}}, $Event{Message}
       Source: @<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$Event{Source},                       $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
~                                     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                      $Event{Message}
 
.

Open in new window