Sometimes you just need to receive all the logs from Windows hosts. There are a lot of ways to do this, but for me, using open source software on which I can rely is always preferable.

The schematic is the following: Windows machine ip: 192.168.1.100 (running NXLog) -> Linux machine ip: 192.168.1.1 (running rsyslog)

Lets begin with the easiest part, configuring rsyslog( /etc/rsyslog.conf ).

For that we can chose, to receive the events over TCP(more reliable but slower) or over UDP(less reliable but faster).

For UDP we need to add the following:

$ModLoad imudp.so #This loads the udp module
$UDPServerRun 514 #This defines the port where we can send the logs
$UDPServerAddress 192.168.1.1 #This defines the listening ip

For TCP we need to add the following:

$ModLoad imtcp.so #This loads the tcp module
$InputTCPServerRun 514 #This defines the port where we can send the logs
$InputTCPServerAddress 192.168.1.1 #This defines the listening ip

To organize our logs we can separate them by hostname and application (so we will have a folder for each host and a file for each application):

$template RemoteLogs,"/var/log/rsyslog/%HOSTNAME%/%PROGRAMNAME%.log" 
#Here we create a template on where to write the logs
*.* ?RemoteLogs #This specifies that we want to have all the logs written there
stop ~ #This will discard the event so it will only be processed by our template

On the rsyslog side we just need to restart the daemon and see if there are no errors.

Going to the Windows, after installing NXLog ( here we are using the community edition ) we need to change our config ( c:\Program Files (x86)\nxlog\conf\nxlog.conf ). We will need to create an input (from where we read the logs) an output (to where we write the logs) and a route (that defines how and what data we are sending).

Panic Soft
#NoFreeOnExit TRUE
define ROOT     C:\Program Files (x86)\nxlog
define CERTDIR  %ROOT%\cert
define CONFDIR  %ROOT%\conf
define LOGDIR   %ROOT%\data
define LOGFILE  %LOGDIR%\nxlog.log
LogFile %LOGFILE%
Moduledir %ROOT%\modules
CacheDir  %ROOT%\data
Pidfile   %ROOT%\data\nxlog.pid
SpoolDir  %ROOT%\data
<Extension _syslog>
    Module      xm_syslog
</Extension>
<Extension _charconv>
    Module      xm_charconv
    AutodetectCharsets iso8859-2, utf-8, utf-16, utf-32
</Extension>
<Extension _exec>
    Module      xm_exec
</Extension>
<Extension _fileop>
    Module      xm_fileop
    # Check the size of our log file hourly, rotate if larger than 5MB
    <Schedule>
        Every   1 hour
        Exec    if (file_exists('%LOGFILE%') and \
                   (file_size('%LOGFILE%') >= 5M)) \
                    file_cycle('%LOGFILE%', 8);
    </Schedule>
    # Rotate our log file every week on Sunday at midnight
    <Schedule>
        When    @weekly
        Exec    if file_exists('%LOGFILE%') file_cycle('%LOGFILE%', 8);
    </Schedule>
</Extension>

<Input in_app>
        Module im_msvistalog
        Query 
            <QueryList><Query Id="0">
            <Select Path="Application">*</Select>
            </Query></QueryList>
</Input>
<Input in_sys>
        Module im_msvistalog
        Query 
            <QueryList><Query Id="0">
            <Select Path="System">*</Select>
            </Query></QueryList>
</Input>
<Input in_sec>
        Module im_msvistalog
        Query 
            <QueryList><Query Id="0">
            <Select Path="Security">*</Select>
            </Query></QueryList>
</Input>

<Output out>
        Module om_tcp
        Host 192.168.1.1
        Port 514
        Exec to_syslog_bsd();
</Output>

<Route r1>
        Path    in_app => out
</Route>
<Route r2>
        Path    in_sys => out
</Route>
<Route r3>
        Path    in_sec => out
</Route>

Most of the file is self explanatory so we'l be just looking at what we added after the default config (those are: inputs, output and routes).

We have 3 different inputs, each one of them grabs their own log sources (Application, System and Security):

<Input in_app>
    Module im_msvistalog #Use the module to collect EventLog messages 
    Query
            <QueryList><Query Id="0">
            <Select Path="Application">*</Select>
            </Query></QueryList>
</Input>
<Input in_sys>
    Module im_msvistalog
    Query
            <QueryList><Query Id="0">
            <Select Path="System">*</Select>
            </Query></QueryList>
</Input>
<Input in_sec>
    Module im_msvistalog
    Query
            <QueryList><Query Id="0">
            <Select Path="Security">*</Select>
            </Query></QueryList>
</Input>

We have one output, that is our rsyslog server that is listening on 192.168.1.1 port 514:

<Output out>
        Module om_tcp#We are using tcp to connect to the rsyslog server
        Host 192.168.1.1
        Port 514
        Exec to_syslog_bsd();
</Output>

And in the end we need to show where to send the logs, as we want all the logs sent to the same server we point them all to it:

<Route r1>
        Path    in_app => out
</Route>
<Route r2>
        Path    in_sys => out
</Route>
<Route r3>
        Path    in_sec => out
</Route>

There is another method, a bit simpler configuration file can look like this(just the input, output and route part are present the initial part is ommited):

<Input win_log>
        Module im_msvistalog
</Input>
<Output out>
        Module om_udp
        Host 192.168.20.1
        Port 514
        Exec to_syslog_bsd();
</Output>
<Route r1>
        Path    win_log=> out
</Route>

But in this case we can get the following warnings:

WARNING Due to a limitation in the Windows EventLog subsystem, a query cannot contain more than 256 sources.

WARNING The following sources are omitted to avoid exceeding the limit in the generated query: ...

And that would not allow us to send all the logs.

For this to work we just need to restart the nxlog service and see the events flowing to our rsyslog.