windows-eventlog-reader
v1.1.0
Published
Read windows event logs
Downloads
14
Maintainers
Readme
windows-eventlog-reader
NOTE This module has not proved useful to myself or my colleagues who it was written for, so I have decided to no longer maintain this project. If you would like to take over maintenance of this project please let me know via [email protected]. For the record, the following Microsoft Windows bug is the core reason I am no longer maintaining this project - this bug still seems to affect the Windows platforms I am targetting - https://support.microsoft.com/en-us/kb/177199.
This modules provides Node.js programs the ability to read events from a Windows event log.
This module is installed using node package manager (npm):
# This module contains C++ source code which will be compiled
# during installation using node-gyp. A suitable build chain
# must be configured before installation.
npm install windows-eventlog-reader
It is loaded using the require()
function:
var eventlog = require ("windows-eventlog-reader");
Individual logs can then be opened and tail'ed:
var reader = eventlog.createReader ("Application");
function feedCb (event) {
console.dir (event);
}
function doneCb (error) {
if (error)
console.error (error.toString ());
}
reader.readAll (1, feedCb, doneCb);
reader.tail (1, function (error, event) {
if (error)
console.error (error.toString ());
else
console.dir (event);
});
Non-Blocking Operations
Windows event logs are typically stored in files on a hard disk. Opening and reading an event log involves reading these files from disk, and the Windows API to do so operates in a blocking mode, i.e. each read request will block the calling program from performing other operations. In the context of Node.js this will introduce a pause of an undefined amount of time into the Node.js event loop.
NOTE Although event log contents may come directly from the operating systems file/page cache, the blocking I/O side effect is still passed on to the calling program, i.e. something in the call chain may decide to block and a calling Node.js program cannot do anything about it. Also, to obtain formatted messages for each event log event, one or more DLL's need to be loaded directly from disk, which involves more blocking I/O.
This module utilises the libuv
library to integrate into the
Node.js event loop - this library is also used by Node.js.
The libuv
function uv_queue_work()
is used to queue operations to run in
the background. As a result this module will not block the Node.js
event loop when blocking operations are performed.
There is one exception to this claim. The close()
method exposed by
this module is performed within the Node.js event loop. This
function will call the Win32 API function CloseEventLog()
, which might
block. However, during development this function always seemed to return
pretty much instantly.
Event Objects
This module uses JavaScript objects to represent events, for example:
{
sourceName: 'gupdate',
computerName: 'as00041.uk.internal',
recordNumber: 6330,
timeGenerated: 1372576636,
timeWritten: 1372576636,
eventId: 5104,
eventType: 'Information',
eventCategory: 0,
message: 'Service started'
}
Each event object will have following parameters:
sourceName
- String specifying the event source for the event, e.g.MSSQLServer
computerName
- String specifying the computer on which the event was generated, e.g.sql-server.test.com
recordNumber
- Identifies the event in this event logtimeGenerated
- Instance of the JavaScriptDate
class specifying the date and time at which the event was generatedtimeWritten
- Instance of the JavaScriptDate
class specifying the date and time at which the event was actually written to the event logeventId
- Number specifying the event identifier, this is specifiec to the event sourceeventType
- String specifying event type, this can be one ofError
,Warning
,Information
,AuditSuccess
,AuditFailure
orUnknown
eventCategory
- Number specifying the event category, this is specific to the event source and is not defined by this modulemessage
- String containing the formatted event message
Event identifiers, i.e. the eventId
attribute, contain multiple sub-fields.
Refer to Win32 API documentation for details on each field. To obtain the
event code field, as it is displayed in the Windows event log viewer, bitwise
&
the eventId
attribute with 0xffff
:
var eventCode = event.eventId & 0xffff;
Error Handling
Each operation exposed by this module typically requires a mandatory callback function which will be called when an operation completes.
Callback functions are typically provided an error
argument, and almost all
errors are instances of the Error
class.
In the event a Windows event log is cleared while a reader is reading from it
the Win32 API will return the error code ERROR_EVENTLOG_FILE_CHANGED
. In
this case the error
argument will be an instance of the
eventlog.EventLogClearedError
class.
This type of error will typically only occur for operations that involve a
read from the event log, e.g. read()
or tail()
.
If this error is experienced, the event log can be closed, re-opened, and the original request re-submitted:
var offset = 1;
function cb (error) {
if (error) {
// When an error occurs this operation will complete, and in the
// case of an event log being cleared we want to re-open it and
// re-submit our original request
if (error instanceof eventlog.EventLogClearedError) {
reader.close ();
reader.open (function (error) {
if (error)
console.error (error.toString ());
else
reader.tail (offset, cb);
});
} else {
console.error (error.toString ());
}
} else {
offset = event.recordNumber;
console.dir (event);
}
}
reader.tail (offset, cb);
Using This Module
Event log readers are represented by an instance of the Reader
class. This
module exports the createReader()
function which is used to create instances
of the Reader
class.
Readers can be used to read all or part of an event log, and to tail the event log and notify users of new events.
eventlog.createReader (name)
The createReader()
function instantiates and returns an instance of the
Reader
class:
var reader = eventlog.createReader ("Application");
The name
parameter is the name of the event log to create a reader for.
An exception will be thrown if the reader could not be created. The error
will be an instance of the Error
class.
After calling this function and creating a reader the underlying Windows event
log will not have been opened. The open()
method must be called on the
reader for the underlying Windows event log to be opened.
NOTE When the open()
method is called this module will use the Win32 API
OpenEventLog()
function. The documentation for this function states that if
the event log could not be found then the Application
event log will be
opened instead.
reader.on ("close", callback)
The close
event is emitted by the reader when the underlying event log
handle is closed.
No arguments are passed to the callback.
The following example prints a message to the console when the reader is closed:
reader.on ("close", function () {
console.log ("event log closed");
});
reader.open (callback)
The open()
method opens the underlying Windows event log represented by the
reader.
The callback
function is called once the underlying Windows event log has
been opened. The following arguments will be passed to the callback
function:
error
- Instance of theError
class or a sub-class, ornull
if no error occurred
The following example opens the Application
Windows event log:
reader.open (function (error) {
if (error)
console.error (error.toString ());
});
reader.close ()
The close()
method closes the underlying Windows event log represented by
the reader.
NOTE This function will call the Win32 API function CloseEventLog()
,
which might block. However, during development this function always seemed to
return pretty much instantly.
The following example opens the Application
Windows event log:
reader.open (function (error) {
if (error)
console.error (error.toString ());
else
reader.close ();
});
reader.read (offset, feedCallback, doneCallback)
The read()
method reads zero or more events from the underlying Windows
event log.
The offset
parameter specifies at what record number to start reading from
(note that the event with this record number will also be returned if it
exists).
This method will not call a single callback once some events have been read.
Instead the feedCallback
function will be called for each event read. The
following arguments will be passed to the feedCallback
function:
event
- An object describing the event (see the "Event Objects" section for more information on event objects)
Once the read has completed, or an error has occurred, the doneCallback
function will be called. The following arguments will be passed to the
doneCallback
function:
error
- Instance of theError
class or a sub-class, ornull
if no error occurred
If the feedCallback
function returns a true
value when called no more
events will be read or passed to the feedCallback
function, and the
doneCallback
will be called.
Once the doneCallback
function has been called the read is complete and
the feedCallback
function will no longer be called.
The following example reads a number of events starting at offset 1,000:
function feedCb (event) {
console.dir (event);
}
function doneCb (error) {
if (error)
console.error (error.toString ());
}
var reader = eventlog.createReader (name);
var offset = 1000;
reader.open (function (error) {
if (error) {
console.error (error.toString ());
} else {
reader.read (offset, feedCb, doneCb);
}
});
reader.readAll (offset, feedCallback, doneCallback)
The readAll()
method reads zero or more events from the underlying Windows
event log until no more events are available.
The offset
parameter specifies at what record number to start reading from
(note that the event with this record number will also be returned if it
exists).
This method will not call a single callback once all events have been read.
Instead the feedCallback
function will be called for each event read. The
following arguments will be passed to the feedCallback
function:
event
- An object describing the event (see the "Event Objects" section for more information on event objects)
Once the read has completed, or an error has occurred, the doneCallback
function will be called. The following arguments will be passed to the
doneCallback
function:
error
- Instance of theError
class or a sub-class, ornull
if no error occurred
If the feedCallback
function returns a true
value when called no more
events will be read or passed to the feedCallback
function, and the
doneCallback
will be called.
Once the doneCallback
function has been called all available events will
have been read and the feedCallback
function will no longer be called.
The following example reads all events starting at offset 2,000:
function feedCb (event) {
console.dir (event);
}
function doneCb (error) {
if (error)
console.error (error.toString ());
}
var reader = eventlog.createReader (name);
var offset = 2000;
reader.open (function (error) {
if (error) {
console.error (error.toString ());
} else {
reader.readAll (offset, feedCb, doneCb);
}
});
reader.tail (offset, [interval], callback)
The tail()
method periodically reads zero or more events from the underlying
Windows event log as they become available.
The offset
parameter specifies at what record number to start reading from
(note that the event with this record number will also be returned if it
exists). The optional interval
parameter is the number of milliseconds
between each read call, and defaults to 3000
.
The callback
function will be called as each event is read from the event
log, or if an error occurs. The following arguments will be passed to the
callback
function:
error
- Instance of theError
class or a sub-class, ornull
if no error occurredevent
- An object describing the event (see the "Event Objects" section for more information on event objects)
NOTE If an error occurs the callback
function will be called with the
first error
argument defined, and after the callback
function returns the
tail operation will be stopped.
If the callback
function returns a true
value when called no more events
will be read, and the callback
function will not be called again.
The following example reads all events starting at offset 6,000, and then
tails the Windows event log, calling the cb
function as and when events
become available:
function cb (error, event) {
if (error)
console.error (error.toString ());
else
console.dir (event);
}
var reader = eventlog.createReader (name);
var offset = 6000;
reader.open (function (error) {
if (error) {
console.error (error.toString ());
} else {
reader.tail (offset, cb);
}
});
Example Programs
Example programs are included under the modules example
directory.
Bugs & Known Issues
None, yet!
Bug reports should be sent to [email protected].
Changes
Version 1.0.0 - 30/06/2013
- Initial release
Version 1.0.1 - 01/07/2013
- Add "Error Handling" section to the README.md file
Version 1.0.2 - 01/07/2013
- Feed callback functions can return
true
to indicate an operation should stop feeding events - Silence some compilation warnings
- Throw an exception when the event log name provided is not valid
Version 1.0.3 - 11/07/2013
- Added
eventId
attribute to the event object - Added missing documentation for the
close()
method to the README.md file
Version 1.0.4 - 15/08/2013
- Address various issues reported by cppcheck
Version 1.0.5 - 15/12/2014
- Not initializing event log handle results in random invalid handle messages
Version 1.1.0 - 09/10/2015
- Add note to the README.md that the project is no longer maintained
Roadmap
Suggestions and requirements should be sent to [email protected].
License
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses.
Author
Stephen Vickers [email protected]