When You Get There
Many scenarios make generating your own events a useful function, including reporting the success or failure of a batch file, reporting the status of a scheduled or distributed task to a central console, reporting system or application availability to a central console, and reporting the amount of time a specific task takes to complete. The script in Listing 1, GenEvent.pl, demonstrates Perl's ability to write to the NT Application Log.
GenEvent.pl includes the Perl for Win32 EventLog module. The EventLog module provides the methods in Table 1 for interacting with NT event logs. You can find additional instructions for using these functions in the Perl for Win32 documentation (see win32mod.html). I also recommend a visit to Philippe Le Berre's Perl documentation (http://www.inforoute.cgs.fr/leberre1/main.htm) for a more thorough discussion of the EventLog module.
The second line in GenEvent.pl, Listing 1, checks whether the user entered a question mark as the first command-line argument. If so, the script calls the PrintHelp subroutine, which appears in the lower half of Listing 1. PrintHelp writes how-to information to standard output (STDOUT) and then exits. PrintHelp uses the same "here document" approach as the script in the January article.
If the user didn't enter a question mark as the first command line argument, the lines at callout A in Listing 1 analyze each element in the command-line argument array, @ARGV. Through each iteration, the foreach loop assigns an element of @ARGV to Perl's default input variable $_ and compares $_ to regular expressions that match the command-line switch options (h=, s=, i=, t=, and d=). If the program finds a regular expression match, it assigns the option's value (the part following the equal sign) to a corresponding scalar variable.
Perl's split function separates the command-line switch from its value. Split chops a string into an array of strings. Here, the function splits the contents of $_ into two parts based on the "=" pattern. The [1] subscript takes the second element of the array that split returns and assigns it to the appropriate scalar variable.
After completing the foreach loop, the script assigns a default value to any options that weren't defined on the command line. Next, the code checks the user-specified or default event type (Error, Information, or Warning) and assigns the corresponding constant to the $type scalar as defined in EventLog.pm. At B, the code initializes an event record hash with the scalar values $id, $type, and $desc.
Notice the use of the and and or operators in the code so far. In Perl, we call these operations short-circuit evaluations. They're simply a more natural way to say if...then. When I say (a and b), b is evaluated only if a is true. Likewise, if I say (a or b), b is evaluated only if a is false. At C, you see that Perl also provides && (and) and || (or) versions of these operators. The difference between the two versions is precedence; the text versions (and, or) have lower precedence and are generally preferable.
At C, the script opens and writes to the NT Application Log. The Win32::EventLog::Open($EventObj, $src, $host) function opens the Application Log and returns a handle to the opened log in the $EventObj scalar. The code uses the returned handle in the $EventObj>Report(\%Event) call, which writes the event to the log. Notice that I pass a reference for the hash I initialized at B to the Report method.
Screen 1, page 193, shows GenEvent.pl in action. I execute the script via the command line by passing the script to the Perl interpreter. In Screen 1, I execute the script three consecutive times, altering the Event ID, Event Type, and Description with each invocation. Screen 2, page 193, shows the result in the target host's Application Log. (For an easy method of running Perl scripts on a Windows NT or Windows 95 machine, see the sidebar, "Executable Perl Scripts.")
What You Take With You
When you combine GenEvent.pl with one of the many third-party event log monitoring tools, you create a way to track the results of all those automation scripts you've been writing in Perl. In the event (no pun intended) you don't have an event log monitor, tune-in next month for Part 2, in which I'll continue to examine the EventLog module by writing an enterprise-capable Event Log chainsaw (or parser).