Event Log for Windows (im_msvistalog)

This module collects Windows Event Log data on Microsoft Windows systems that support the modern Windows Event Log API (Windows Vista, Windows Server 2008, and later). It can collect events from System, Application, Security, and custom event channels. By default, the module enumerates available channels and monitors all of them unless the Query or Channel directives are explicitly configured. The module can also collect events from remote systems using MSRPC. Refer to the official Microsoft documentation for details on Windows Event Logs.

This module relies on the Windows Event Log subsystem, which does not support collecting events from Analytic and Debug channels. To collect events from these channels, use the Event Tracing for Windows input module instead.

For older Windows versions (Windows XP, Windows 2000, and Windows Server 2003), use the Event Log for Windows XP/2000/2003 input module instead.

To examine the supported platforms, see the list of installation packages.

Backward-compatibility

NXLog Agent version 6 uses a faster algorithm to read Windows events, which may result in slightly different output than previous versions. You can emulate the output of older versions by setting the ParseEventXML directive to TRUE. However, some differences in fields may still occur, including but not limited to:

Keywords

A hexadecimal number instead of a decimal.

Message

\n\r for a newline instead of \n.

ProviderGuid

The field is set to NULL when empty instead of removing the field.

Opcode

Not present in older versions.

Level

Not always present in older versions.

Performance considerations

NXLog Agent version 6 includes several performance optimizations for parsing Windows events and setting the $Message field compared to previous versions.

Parsing events

Starting from version 6, NXLog Agent uses optimized logic to parse event values. Although the new method is faster, in some server configurations it may produce fields that differ from those in the event template. If the module detects such a discrepancy, it falls back to the previous parsing method using the event XML, which is slower but more accurate.

Setting the message field

Setting the event $Message field is a time-consuming process. NXLog Agent version 6 introduces a new CaptureMessage directive to define whether the module retrieves the event message. If you do not use this field, you can set the directive to FALSE to reduce the event processing time. The directive is set to TRUE by default to maintain backward compatibility with older versions.

When the CaptureMessage directive is TRUE, the module can use one of two methods to set the $Message field. The first method, also used in older NXLog Agent versions, is to use the native Windows function. The second method, which is the default in version 6, is to use the message template. The latter is faster but may produce slightly different results. You can switch to using the native Windows function by setting the CaptureMessageFast directive to FALSE.

There are instances where the module cannot use the optimized method even when CaptureMessageFast is TRUE, including if:

  • The message template is not available on the system.

  • The module parses the event with the older method.

The following are examples of different message field values when using the native Windows versus the custom NXLog Agent function.

Table 1. Event ID 6 - Driver loaded
Method Result

Windows

File System Filter 'FileCrypt' (10.0, 2002-03-01T12:12:42.000000000Z) has successfully loaded and registered with Filter Manager.

NXLog Agent

File System Filter 'FileCrypt' (10.0, 2002-03-01T12:12:42.0000000Z) has successfully loaded and registered with Filter Manager.

Table 2. Event ID 25 - Boot menu policy
Method Result

Windows

The boot menu policy was 1.

NXLog Agent

The boot menu policy was 0x1.

Table 3. Event ID 109 - Kernel power manager
Method Result

Windows

The kernel power manager has initiated a shutdown transition.\r\n\r\nShutdown Reason: 5

NXLog Agent

The kernel power manager has initiated a shutdown transition.\r\n\r\nShutdown Reason: Kernel API

Table 4. Event ID 98 - Volume healthy
Method Result

Windows

Volume C: (\\Device\\HarddiskVolume3) is healthy. No action is needed.

NXLog Agent

Volume C: (\\Device\\HarddiskVolume3) 0

Table 5. Event ID 172 - Connectivity state in standby
Method Result

Windows

Connectivity state in standby: Disconnected, Reason: NIC compliance

NXLog Agent

Connectivity state in standby: 2, Reason: 6

Table 6. Event ID 5235 - Group Policy received notification
Method Result

Windows

Group Policy received Preshutdown notification from Service Control Manager.

NXLog Agent

Group Policy received 0 notification from Service Control Manager.

Resolving SIDs

When the CaptureMessage and ResolveSID directives are TRUE, the module resolves SIDs in the $Message field to usernames. This process impacts performance when the module uses the native Windows function to set the message field, because it must parse the field again to find and replace SIDs.

Performance comparison

The following table compares event processing times in milliseconds. We ran the test on a Windows Server 2016 virtual machine with the following event counts:

  • 70178 total events

  • 14746 events where the module parses events with the older method

  • 28823 events where the module sets the message field using the native Windows function

milliseconds CaptureMessage CaptureMessageFast ResolveSID ResolvedIDOutput

5103

FALSE

TRUE

FALSE

n/a

5542

TRUE

TRUE

FALSE

n/a

5947

FALSE

TRUE

TRUE

BOTH

5887

TRUE

FALSE

FALSE

n/a

6902

TRUE

TRUE

TRUE

BOTH

8569

TRUE

FALSE

TRUE

BOTH

If you enable NXLog Agent debug logging, you can determine which parsing and message rendering methods the module uses. The module logs:

  • parsing from xml event when the old parsing method is applied.

  • using slower Message render method when it sets the message field using the native Windows function.

  • Replacing SID on message field when resolving SIDs in the $Message field is enabled.

Non-printable characters

Windows event data may include non-printable characters (such as CR, LF, TAB, NUL, and multibyte UTF) in field names, field values, or resolved text. The module forwards non-printable characters as-is; therefore, the destination must be able to handle them.

If non-printable characters can break your data forwarding logic, for example, by representing an artificial end-of-message, you can handle them with the Character Set Conversion extension or replace them using a regular expression.

Additional event data

In addition to the standard fields available under the System section, event providers can define a custom schema for logging additional data under the EventData or UserData sections. For example, the following XML shows additional data for a security event:

<EventData>
  <Data Name="SubjectUserSid">S-1-5-18</Data>
  <Data Name="SubjectUserName">WIN-OUNNPISDHIG$</Data>
  <Data Name="SubjectDomainName">WORKGROUP</Data>
  <Data Name="SubjectLogonId">0x3e7</Data>
  <Data Name="TargetUserSid">S-1-5-18</Data>
  <Data Name="TargetUserName">SYSTEM</Data>
  <Data Name="TargetDomainName">NT AUTHORITY</Data>
  <Data Name="TargetLogonId">0x3e7</Data>
  <Data Name="LogonType">5</Data>
  <Data Name="LogonProcessName">Advapi</Data>
  <Data Name="AuthenticationPackageName">Negotiate</Data>
  <Data Name="WorkstationName" />
  <Data Name="LogonGuid">{00000000-0000-0000-0000-000000000000}</Data>
  <Data Name="TransmittedServices">-</Data>
  <Data Name="LmPackageName">-</Data>
  <Data Name="KeyLength">0</Data>
  <Data Name="ProcessId">0x1dc</Data>
  <Data Name="ProcessName">C:\Windows\System32\services.exe</Data>
  <Data Name="IpAddress">-</Data>
  <Data Name="IpPort">-</Data>
</EventData>

NXLog Agent extracts this additional event data, making the fields available for the NXLog Agent record. You can use these fields to apply filtering rules or trigger actions. For example, the following configuration snippet filters records based on the TargetUserName field available with the additional event data:

<Input windows_events>
    Module    im_msvistalog
    <Exec>
        if ($TargetUserName == 'SYSTEM') {
          drop();
        }
    </Exec>
</Input>

Configuration

The im_msvistalog module accepts the following directives in addition to the common module directives.

Optional directives

AddPrefix

Set this directive to TRUE to distinguish fields parsed from <EventData> and <UserData> by prefixing them with their section name. For example, $SubjectUserName becomes $EventData.SubjectUserName. This helps prevent naming collisions and makes the origin of each field explicit. The default is FALSE; the module adds fields without a prefix.

CaptureEventXML

Set this directive to TRUE to retain the original event XML in the $EventXML field. This allows you to preserve the raw event payload for auditing, troubleshooting, or downstream processing. The default is FALSE; the module does not add the $EventXML field to the record.

CaptureMessage

Set this directive to TRUE to populate the $Message field from the event’s UserData and EventData content. This provides a human-readable explanation of the event. The default is TRUE. If you do not require the $Message field, set this directive to FALSE to reduce processing overhead.

CaptureMessageFast

Set this directive to TRUE to generate the $Message field using NXLog Agent’s custom rendering function. This method is faster but may produce a slightly different message than the one displayed in Windows Event Viewer.

Alternatively, set this directive to FALSE to use the native Windows rendering function, ensuring that the $Message field matches the value shown in Event Viewer.

The default is TRUE. However, when ParseEventXML is set to TRUE, the agent will automatically set this directive to FALSE.

Channel

Set this directive to limit event collection to a particular Windows Event Log channel. This allows you to target specific event sources and reduce unnecessary data collection.

If you do not specify a channel, the module reads events from all sources defined in the registry. Refer to the Microsoft documentation on Event Selection for more information.

File

Set this directive to read events from a Windows Event Log file instead of a live channel. Provide the full path to a .evt or .evtx file.

You can also use this directive to read .etl files. However, the module cannot search within these files and reads them sequentially from start to end.

When this directive is set, the module automatically activates SavePos to ensure it tracks the last processed event in the file.

You may specify this directive multiple times to read from multiple files. The module checks files only when the module instance starts; files added later are not processed until the module is restarted. If new records are added to a specified log file while the agent is running, the module detects and processes them without requiring a restart.

Reading Windows Event Log files directly is primarily useful for forensic analysis. For example, to read the System log file directly:

File    "C:\Windows\System32\winevt\Logs\System.evtx"

You can use wildcards to match file names and directories. These patterns follow standard globbing rules and are not regular expressions.

?

Matches any single character.

*

Matches any string, including the empty string.

\*

Matches the asterisk (*) character.

\?

Matches the question mark (?) character.

[…​]

Matches one character specified within the brackets. The brackets should contain a single character (for example, [a]) or a range of characters ([a-z]). If the first character in the brackets is ^ or !, it reverses the wildcard matching logic (the wildcard matches any character not in the brackets). The backslash (\) characters are ignored and should be used to escape ] and - characters as well as ^ and ! at the beginning of the pathname.

Language

Set this directive to specify the language used to render event messages. Provide the language as a hyphen-separated language/region code (for example, fr-FR).

The required language pack must be installed on the system. If not specified, the module uses the system’s default locale.

ParseEventXML

Set this directive to TRUE to parse events using the legacy XML-based method, producing output consistent with NXLog Agent version 5. This is useful when maintaining backward compatibility with existing configurations or downstream processing that depends on the earlier field structure.

The default is FALSE; the module uses a custom NXLog Agent parsing method that improves performance but may produce slightly different results. See Backward-compatibility for additional details.

PollInterval

Set this directive to control how frequently the module checks for new events. The value is specified in seconds. You can specify fractional values. For example, 0.5 causes the module to check twice per second. The default is 1 second.

Query

Specify this directive to filter which Windows Event Log sources the module collects. Provide the query as a single-line parameter. If you need to use multiple lines, apply line continuation:

Query  <QueryList> \
         <Query Id='1'> \
           <Select Path='Security'>*[System/Level=4]</Select> \
         </Query> \
       </QueryList>

See the Microsoft documentation on Event Selection for query syntax details.

When using an XPath-style expression, you must also specify the Channel. When using a full XML query, do not specify Channel, as the query itself defines the target channels.

QueryXML

Use this directive to specify an XML-based event query as a configuration block. It provides the same functionality as Query but allows you to use multi-line XML without line continuation. You can copy the XML query directly from Windows Event Viewer and paste it into this directive.

<QueryXML>
  <QueryList>
    <!-- Commenting with # is not supported in QueryXML blocks.
         Use XML-style comments like this instead.
    -->
    <Query Id='1'>
      <Select Path='Security'>*[System/Level=4]</Select>
    </Query>
  </QueryList>
</QueryXML>

ReadBatchSize

Set this directive to control how many events the Windows Event Log API delivers to the module per batch. Larger values may increase throughput.

The default is 31. We do not recommend increasing this due to a known limitation in the Windows Event Log subsystem: when set above 31, retrieving events can fail on busy systems with the error EvtNext failed with error 1734: The array bounds are invalid.

ReadFromLast

Set this directive to control where the module begins reading events when NXLog Agent starts and at every ResubscribeInterval.

When TRUE, NXLog Agent only reads events logged after it subscribes to a provider or channel, unless SavePos is TRUE and a saved position for this log source exists in the cache file.

When FALSE, NXLog Agent will read all events from the log source, unless SavePos is TRUE and a saved position for this log source exists in the cache file.

The default is TRUE.

The following matrix shows the outcome of this directive in conjunction with the SavePos directive:

ReadFromLast SavePos Saved position Outcome

TRUE

TRUE

Yes

Reads events from the saved position.

TRUE

TRUE

No

Reads events that are logged after NXLog Agent is started.

TRUE

FALSE

Yes

Reads events that are logged after NXLog Agent is started.

TRUE

FALSE

No

Reads events that are logged after NXLog Agent is started.

FALSE

TRUE

Yes

Reads events from the saved position.

FALSE

TRUE

No

Reads all events.

FALSE

FALSE

Yes

Reads all events.

FALSE

FALSE

No

Reads all events.

If the NoCache directive is TRUE, it overrides the SavePos directive. In this case, the module behaves as if SavePos is FALSE.

RemoteAuthMethod

Set this directive to specify which authentication method the agent uses when connecting to a remote server.

The possible values are Default, Negotiate, Kerberos, and NTLM. If not specified, the agent uses Default, which maps to Negotiate.

RemoteDomain

Set this directive to define the domain of the user account used to authenticate when collecting logs from a remote server.

RemotePassword

Set this directive to provide the password used to authenticate when collecting logs from a remote server.

RemoteServer

Set this directive to collect events from a remote server, specifying the target system’s hostname. If not specified, the module collects events from the local system.

RemoteUser

Set this directive to provide the username used to authenticate when collecting logs from a remote server.

ResolveGUID

Set this directive to TRUE to resolve GUID values to their corresponding distinguished name. The scope of the resolution depends on the ResolvedIDOutput setting. The default is FALSE; the module does not resolve GUID values.

ResolveSID

Set this directive to TRUE to resolve SID values to user account names. The scope of the resolution depends on the ResolvedIDOutput setting. The default is FALSE; the module does not resolve SID values.

ResolvedIDOutput

Use this directive to control where SID and GUID values are resolved. It applies only when ResolveGUID or ResolveSID is set to TRUE. The default is FIELDS. The possible values are:

FIELDS

Resolves fields containing a GUID or SID value.

  • When ResolveGUID is TRUE, the module creates a new field containing the resolved distinguished name (DN). The new field uses the original field name with the DN suffix. If a field with that name already exists, the module preserves the existing value rather than overwriting it.

  • When ResolveSID is TRUE, the module creates a new field containing the resolved account name. The new field uses the original field name with the Name suffix. If a field with that name already exists, the module preserves the existing value rather than overwriting it.

BOTH

Resolves fields containing a GUID or SID value, as well as GUIDs and SIDs in the $Message field. GUIDs and SIDs must be visible in the event message when displayed in Windows Event Viewer for NXLog Agent to resolve them.

ResubscribeInterval

Use this directive to control how often the module attempts to resubscribe to providers and channels when TolerateQueryErrors is set to TRUE. This allows the agent to automatically retry unavailable sources without requiring a restart.

The value is specified in seconds. The default is 60 seconds, with a minimum of 10 and a maximum of 4,294,967,295 seconds (32-bit unsigned integer).

When NXLog Agent subscribes to a provider or channel, it determines which events to read according to the ReadFromLast setting. Unavailable providers are ignored until the next check.

SavePos

Set this directive to TRUE to save the position of the last processed event before NXLog Agent exits. On the next startup, the agent reads the saved position from the cache file and resumes from that point. Together with the ReadFromLast directive, this directive allows the agent to continue reading events from the saved position.

The default is TRUE; the position of the last read event is saved and will be read from the cache file on the next startup.

If the NoCache directive is TRUE, it overrides the SavePos directive. In this case, the module behaves as if SavePos is FALSE.

TolerateQueryErrors

Set this directive to TRUE to allow the module to start even if the query includes invalid event sources. This allows partial data collection when some sources are unavailable. The default is FALSE; the module fails to start if any specified source is invalid.

Fields

The following fields are used by im_msvistalog.

$raw_event (type: string)

The event data in key-value pairs.

$AccountName (type: string)

The username associated with the event.

$AccountType (type: string)

The Windows security principal type. The possible values are: User, Group, Domain, Alias, Well Known Group, Deleted Account, Invalid, Unknown, and Computer.

$ActivityID (type: string)

The globally unique identifier of the current activity. Equivalent to the EvtSystemActivityID Windows Event Log API system property.

$Category (type: string)

The event category name resolved from the $TaskValue field.

$Channel (type: string)

The event source channel. For example, Security or Application.

$Domain (type: string)

The domain name of the user.

$ERROR_EVT_UNRESOLVED (type: boolean)

This field is set to TRUE if the module fails to resolve the event message and the insertion strings are not present.

$EventID (type: integer)

The event ID specific to the event source. Equivalent to the EvtSystemEventID Windows Event Log API system property.

$EventTime (type: datetime)

Equivalent to the EvtSystemTimeCreated Windows Event Log API system property.

$EventType (type: string)

The severity of the event resolved from the $LevelValue. The possible values are: CRITICAL, ERROR, AUDIT_FAILURE, AUDIT_SUCCESS, INFO, WARNING, and VERBOSE.

$EventXML (type: string)

The raw event data in XML format. This field is available if the CaptureEventXML directive is TRUE.

$ExecutionProcessID (type: integer)

The process ID of the application or service that generated the event. Equivalent to the EvtSystemProcessID Windows Event Log API system property.

$Hostname (type: string)

Equivalent to the EvtSystemComputer Windows Event Log API system property.

$Keywords (type: string)

Equivalent to the EvtSystemKeywords Windows Event Log API system property.

$Level (type: string)

The string representation of $LevelValue.

$LevelValue (type: integer)

The event severity level. Equivalent to the EvtSystemLevel Windows Event Log API system property.

$Message (type: string)

The event message.

$Opcode (type: string)

The string representation of $OpcodeValue.

$OpcodeValue (type: integer)

The event operation code. Equivalent to the EvtSystemOpcode Windows Event Log API system property.

$ProviderGuid (type: string)

The globally unique identifier of the $SourceName.

$RecordNumber (type: integer)

The event record number.

$RelatedActivityID (type: string)

Equivalent to the EvtSystemRelatedActivityID Windows Event Log API system property.

$Severity (type: string)

The normalized event severity name. See $SeverityValue.

$SeverityValue (type: integer)

The normalized event severity number, mapped as follows:

Event Log Severity Normalized Severity

0/Audit Success

2/INFO

0/Audit Failure

4/ERROR

1/Critical

5/CRITICAL

2/Error

4/ERROR

3/Warning

3/WARNING

4/Information

2/INFO

5/Verbose

1/DEBUG

$SourceName (type: string)

The event source. Equivalent to the EvtSystemProviderName Windows Event Log API system property.

$TaskValue (type: integer)

The task number. Equivalent to the EvtSystemTask Windows Event Log API system property.

$ThreadID (type: integer)

The thread ID of the application or service that generated the event. Equivalent to the EvtSystemThreadID Windows Event Log API system property.

$UserID (type: string)

The Security Identifier (SID) of the $AccountName.

$Version (type: integer)

The event version number. Equivalent to the EvtSystemVersion Windows Event Log API system property.

Fields by providers

For the fields used by the providers, see the fields by providers list.

Examples

Find more examples in our Windows Event Log integration guide.

Example 1. Basic im_msvistalog configuration

The following is a basic configuration that collects events from the Application, Security, and System logs.

nxlog.conf
<Input windows_events>
    Module          im_msvistalog
    <QueryXML>
        <QueryList>
            <Query Id='0'>
                <Select Path='Application'>*</Select>
                <Select Path='Security'>*</Select>
                <Select Path='System'>*</Select>
            </Query>
        </QueryList>
    </QueryXML>
</Input>
Example 2. Retaining the original EventData and UserData XML

This configuration collects Windows events, extracts the original EventData and UserData XML, and converts the records to JSON format.

nxlog.conf
<Extension xml>
    Module           xm_xml
</Extension>

<Extension json>
    Module           xm_json
</Extension>

<Input windows_events>
    Module           im_msvistalog
    CaptureEventXML  TRUE (1)
    <QueryXML>
        <QueryList>
            <Query Id='0'>
                <Select Path='Application'>*</Select>
                <Select Path='Security'>*</Select>
                <Select Path='System'>*</Select>
            </Query>
        </QueryList>
    </QueryXML>
    <Exec>
        $EventData = extract_xml("/Event/EventData", $EventXML); (2)
        if $EventData == "" {
            delete($EventData);
        }

        $UserData = extract_xml("/Event/UserData", $EventXML);
        if $UserData == "" {
            delete($UserData);
        }

        delete($EventXML);
        to_json(); (3)
    </Exec>
</Input>
1 The CaptureEventXML directive is set to TRUE, storing the raw XML event data in the $EventXML field.
2 The extract_xml() function is provided by the XML extension. It returns the XML node extracted from the specified XPath query.
3 The to_json() procedure is provided by the JSON extension. It converts the event fields into JSON format and writes the result to the $raw_event core field.
Output sample
{
  "EventTime": "2026-02-20T13:11:52.780328+01:00",
  "Hostname": "PC1",
  "Keywords": "0x8080000000000000",
  "LevelValue": 4,
  "EventType": "INFO",
  "SeverityValue": 2,
  "Severity": "INFO",
  "EventID": 7040,
  "SourceName": "Service Control Manager",
  "ProviderGuid": "{555908D1-A6D7-4695-8E1E-26931D2012F4}",
  "Version": 0,
  "TaskValue": 0,
  "OpcodeValue": 0,
  "RecordNumber": 103372,
  "ExecutionProcessID": 1336,
  "ExecutionThreadID": 18852,
  "Channel": "System",
  "Domain": "EXAMPLE",
  "AccountName": "jdoe",
  "UserID": "S-1-5-21-3288775215-2077974584-1458381936-1001",
  "AccountType": "User",
  "Message": "The start type of the Print Spooler service was changed from auto start to demand start.",
  "Level": "Information",
  "param1": "Print Spooler",
  "param2": "auto start",
  "param3": "demand start",
  "param4": "Spooler",
  "EventReceivedTime": "2026-02-20T13:11:54.548165+01:00",
  "SourceModuleName": "windows_events",
  "SourceModuleType": "im_msvistalog",
  "EventData": "<EventData><Data Name=\"param1\">Print Spooler</Data><Data Name=\"param2\">auto start</Data><Data Name=\"param3\">demand start</Data><Data Name=\"param4\">Spooler</Data></EventData>"
}

Troubleshooting

Operator is unsupported by this implementation of the filter

Due to a limitation in the Windows Event Log API, queries with more than 22 clauses will fail, producing the following error message:

ERROR failed to subscribe to events with this module, the Query is invalid: This operator is unsupported by this implementation of the filter.; [error code: 15001]

The workaround for this limitation is to group clauses and/or split the filter across multiple queries. In the example below, the filter consists of 6 event IDs but is counted as 2.

Grouping clauses
<QueryXML>
    <QueryList>
        <Query Id="0">
            <Select Path="Security">*[System[(EventID=6416 or EventID=6424 or EventID=4732) or (EventID=1102 or EventID=4719 or EventID=4704)]]
            </Select>
        </Query>
    </QueryList>
</QueryXML>

Access denied to a channel

If the NXLog Agent service is running as a custom user, errors may be logged in the log file, such as:

WARNING [im_msvistalog|windows_evnts] failed to subscribe to msvistalog events,access denied [error code: 5]: Access is denied.

or

WARNING [im_msvistalog|windows_events] ignoring source as it cannot be subscribed to (error code: 5)

This occurs when the user account lacks permission to access the specified Windows Event Log channel. Refer to Access denied to a Windows Event Log channel for instructions on resolving these errors.