[Win32utils-devel] Possible problems with EventLog#write

Daniel Berger djberg96 at gmail.com
Sun May 21 23:48:11 EDT 2006


Heesob Park wrote:

<snip>

> One workaround is open event log every time like this:
> 
>       def notify_change(&block)
>          @handle = OpenEventLog(@server, @source)
>          unless block_given?
>             raise EventLogError, 'block missing for notify_change()'
>          end
>          event = CreateEvent(0, 0, 0, 0)
>          unless NotifyChangeEventLog(@handle, event)
>             error = 'NotifyChangeEventLog() failed: ' + get_last_error
>             raise EventLogError, error
>          end
>          wait_result = WaitForSingleObject(event, INFINITE)
>          CloseHandle(event)
> 
>          if wait_result == WAIT_FAILED
>             error = 'WaitForSingleObject() failed: ' + get_last_error
>             raise EventLogError, error
>          else
>             last = read_last_event
>             block.call(last)
>          end
>          CloseEventLog(@handle)
>          self
>       end

For some reason this didn't work right.  It would start returning empty 
structs if too many events happened too quickly.

> The other is GetNumberOfEventLogRecords instead of NotifyChangeEventLog
> refer to http://support.microsoft.com/kb/q245609/

The problem with that approach is that, according to other docs I've 
read, the record numbers can get reused.  That leads me to believe that 
GetNumberOfEventLogRecords() would not necessarily correspond to the 
last record number.

However, I took that general idea and came up with this solution:

# Remove references to the @last instance variable first
def tail(frequency=5)
    unless block_given?
       raise EventLogError, 'block missing for tail()'
    end

    old_total = total_records()
    flags     = FORWARDS_READ | SEEK_READ
    rec_num   = read_last_event.record_number

    while true
       new_total = total_records()
       if new_total != old_total
          read(flags, rec_num).each{ |log| yield log }
          old_total = new_total
          rec_num   = read_last_event.record_number
       end
       sleep frequency
    end
end

I tail'd the Security log (where I could force lots of log entries by 
doing some random things with user accounts) and it handled it just fine.

If you see any problems with this approach please let me know. 
Otherwise, I'm going to commit it later this week (along with updated docs).

However, that still leaves us with the bigint/long issue.

Many thanks,

Dan


More information about the win32utils-devel mailing list