Below is an example Logback file that I’m using to achieve a similar function:
<?xml version="1.0" encoding="UTF-8"?>
<!-- For assistance related to logback-translator or configuration -->
<!-- files in general, please contact the logback user mailing list -->
<!-- at http://www.qos.ch/mailman/listinfo/logback-user -->
<!-- -->
<!-- For professional support please see -->
<!-- http://www.qos.ch/shop/products/professionalSupport -->
<!-- -->
<configuration debug="true">
<appender name="SysoutAppender" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>ignition %date{"yyyy-MM-dd HH:mm:ss.SSS",UTC}Z %level {%thread} [%logger] - %message%n</pattern>
</encoder>
</appender>
<appender name="rsyslog" class="ch.qos.logback.classic.net.SyslogAppender">
<syslogHost>rsyslog</syslogHost>
<port>514</port>
<facility>SYSLOG</facility>
<suffixPattern>ignition %date{"yyyy-MM-dd",UTC}T%date{"HH:mm:ss.SSS",UTC}Z %level {%thread} [%logger] - %message%ex{full}</suffixPattern>
<stackTracePattern> </stackTracePattern>
</appender>
<appender name="DB" class="com.inductiveautomation.logging.SQLiteAppender">
<dir>logs</dir>
<!--
Maintenance Settings
entryLimit: The maximum number of entries in the database. However, at any given time, there may be more than this number, due to how cleanup works.
maxEventsPerMaintenance: The number of event that can happen before a maintenance cycle occurs.
minTimeBetweenMaintenance: The minimum time (max frequency) between maintenance events. Takes precedent over max events.
vacuumFrequency: The number of maintenance cycles before a "vacuum" is performed, to recover disk space.
On disk, most log events are between 600-800 bytes.
<entryLimit>50000</entryLimit>
<maxEventsPerMaintenance>5000</maxEventsPerMaintenance>
<minTimeBetweenMaintenance>60000</minTimeBetweenMaintenance>
<vacuumFrequency>3</vacuumFrequency>
-->
</appender>
<appender name="SysoutAsync" class="ch.qos.logback.classic.AsyncAppender" queueSize="1000" discardingThreshold="0">
<appender-ref ref="SysoutAppender" />
</appender>
<appender name="rsyslogAsync" class="ch.qos.logback.classic.AsyncAppender" queueSize="1000" discardingThreshold="0">
<appender-ref ref="rsyslog" />
</appender>
<appender name="DBAsync" class="ch.qos.logback.classic.AsyncAppender" queueSize="100000" discardingThreshold="0">
<appender-ref ref="DB" />
</appender>
<root level="INFO">
<appender-ref ref="SysoutAsync"/>
<appender-ref ref="rsyslogAsync" />
<appender-ref ref="DBAsync"/>
</root>
</configuration>
In the example above I’m using rsyslog as a UDP syslog receiver and TCP syslog forwarder (to promtail). It looks like NXLog might be able to receive UDP syslog directly…
EDIT: you can ignore the SysoutAppender config above, I was just using that to debug the format before I got the rsyslog one working.