#### RULES #### # Ensure message is a properly formatted UTF-8 sequence action(type="mmutf8fix" mode="utf-8") # Parse any CEE JSON messages action(type="mmjsonparse") {% if not rsyslog_forwarding or rsyslog_aggregator %} # Now that we have parsed out any CEE JSON data in log messages, we have a CEE # JSON tree with at least a "msg" field. We proceed with normalizing the data # to remove redundant pieces of information, and cleanup known bad data. # The mmjsonparse action above has made sure the $!msg is always populated # with $msg if initially unpopulated. if (strlen($!msg) > 0) then { set $.msg = $!msg; } else { if ($inputname == "impstats") then { set $.msg = "pstats"; } else { set $.msg = $msg; } } if (strlen($!MESSAGE) > 0) and ($!MESSAGE != $.msg) then { # Use the systemd message value when present. set $.msg = $!MESSAGE; } # Always pull msg out of the message properties so that it does not show up # again under the CEE property in ElasticSearch. unset $!msg; unset $!MESSAGE; if ($!_HOSTNAME == $hostname) then { unset $!_HOSTNAME; } if (strlen($!tags) > 0) then { set $.tags = $!tags; } # Always pull tags out of the message properties so that it does not show up # again under the CEE property in ElasticSearch. unset $!tags; # We'll attempt to normalize the PID value we have from the default rsyslog # properties with collected systemd properties below. set $.pid = $procid; set $.hostname = $hostname; set $.level = $syslogseverity-text; set $.rsyslog!appname = $app-name; set $.rsyslog!programname = $programname; # Copy browbeat json over then delete it from the json namespace if (strlen($!browbeat_json) > 0) then { set $.browbeat_json = $!browbeat_json; unset $!browbeat_json; } # Logs are fed into imfile as pure text strings with no level info # other than the default for that filestream, this parses the messages # to look for log level info that it can apply if ($.msg contains 'error') then { set $.level = 'error'; } if ($.msg contains 'ERROR') then { set $.level = 'error'; } if ($.msg contains 'warn') then { set $.level = 'notice'; } if ($.msg contains 'WARN') then { set $.level = 'notice'; } if ($.msg contains 'debug') then { set $.level = 'debug'; } if ($.msg contains 'DEBUG') then { set $.level = 'debug'; } # Now drop app-name if it is the same as programname, don't need to index # both, and if either or both are still blank, just drop them entirely. if ($app-name == $programname) then { unset $.rsyslog!appname; } if (strlen($.rsyslog!appname) == 0) then { unset $.rsyslog!appname; } if (strlen($.rsyslog!programname) == 0) then { unset $.rsyslog!programname; } # The facility is an rsyslog specific property defined to have a fixed set of # values. set $.rsyslog!facility = $syslogfacility-text; # The following four properties are pulled from the RFC 5424 message, when # available. If we don't have those kinds of messages, then the values are # "-", and in the case of app-name, it will have the same value as # programname. set $.rsyslog!protocol-version = $protocol-version; if (strlen($structured-data) > 0) and ($structured-data != "-") then { set $.rsyslog!structured-data = $structured-data; } if (strlen($msgid) > 0) and ($msgid != "-") then { set $.rsyslog!msgid = $msgid; } # The following four properities are derived by this instance of rsyslog (the # last instance to touch the message before being indexed into ElasticSearch), # and not sent across the wire. set $.rsyslog!fromhost-ip = $fromhost-ip; if ($fromhost != $hostname) and ($fromhost != $fromhost-ip) then { # We only report fromhost if it is different from hostname, and only if it # tells us something more that fromhost-ip. set $.rsyslog!fromhost = $fromhost; } template(name="timegeneratedrfc3339" type="string" string="%timegenerated:::date-rfc3339%") set $.rsyslog!timegenerated = exec_template("timegeneratedrfc3339"); set $.rsyslog!inputname = $inputname; if strlen($!_MACHINE_ID) > 0 then { # Pull out the systemd "user" and "trusted" journal fields. # See http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html # Pull out the systemd "user" journal fields... set $.systemd!t!MACHINE_ID = $!_MACHINE_ID; unset $!_MACHINE_ID; if strlen($!CODE_FILE) > 0 then { set $.systemd!u!CODE_FILE = $!CODE_FILE; } unset $!CODE_FILE; if strlen($!CODE_FUNCTION) > 0 then { set $.systemd!u!CODE_FUNCTION = $!CODE_FUNCTION; } unset $!CODE_FUNCTION; if strlen($!CODE_LINE) > 0 then { set $.systemd!u!CODE_LINE = $!CODE_LINE; } unset $!CODE_LINE; if strlen($!ERRNO) > 0 then { set $.systemd!u!ERRNO = $!ERRNO; } unset $!ERRNO; if strlen($!MESSAGE_ID) > 0 then { set $.systemd!u!MESSAGE_ID = $!MESSAGE_ID; } unset $!MESSAGE_ID; if strlen($!RESULT) > 0 then { set $.systemd!u!RESULT = $!RESULT; } unset $!RESULT; if strlen($!UNIT) > 0 then { set $.systemd!u!UNIT = $!UNIT; } unset $!UNIT; # NOTE We deal with $!MESSAGE separately above #set $.systemd!u!MESSAGE = $!MESSAGE; # NOTE WELL: we do not pull out MESSAGE, PRIORITY, SYSLOG_FACILITY, # SYSLOG_IDENTIFIER, or SYSLOG_PID, as imjournal either on the remote host # or on our local host has already done that for us using the values # appropriately for traditional rsyslog message properties. #unset $!MESSAGE; #set $.systemd!u!PRIORITY = $!PRIORITY; unset $!PRIORITY; #set $.systemd!u!SYSLOG_FACILITY = $!SYSLOG_FACILITY; unset $!SYSLOG_FACILITY; #set $.systemd!u!SYSLOG_IDENTIFIER = $!SYSLOG_IDENTIFIER; unset $!SYSLOG_IDENTIFIER; #set $.systemd!u!SYSLOG_PID = $!SYSLOG_PID; unset $!SYSLOG_PID; # Pull out the systemd "trusted" journal fields... if strlen($!_AUDIT_LOGINUID) > 0 then { set $.systemd!t!AUDIT_LOGINUID = $!_AUDIT_LOGINUID; } unset $!_AUDIT_LOGINUID; if strlen($!_AUDIT_SESSION) > 0 then { set $.systemd!t!AUDIT_SESSION = $!_AUDIT_SESSION; } unset $!_AUDIT_SESSION; if strlen($!_BOOT_ID) > 0 then { set $.systemd!t!BOOT_ID = $!_BOOT_ID; } unset $!_BOOT_ID; if strlen($!_CAP_EFFECTIVE) > 0 then { set $.systemd!t!CAP_EFFECTIVE = $!_CAP_EFFECTIVE; } unset $!_CAP_EFFECTIVE; if strlen($!_CMDLINE) > 0 then { set $.systemd!t!CMDLINE = $!_CMDLINE; } unset $!_CMDLINE; unset $!cmd; if strlen($!_COMM) > 0 then { set $.systemd!t!COMM = $!_COMM; } unset $!_COMM; unset $!appname; if strlen($!_EXE) > 0 then { set $.systemd!t!EXE = $!_EXE; } unset $!_EXE; unset $!exe; if strlen($!_GID) > 0 then { set $.systemd!t!GID = $!_GID; } unset $!_GID; unset $!gid; if strlen($!_HOSTNAME) > 0 then { set $.systemd!t!HOSTNAME = $!_HOSTNAME; } unset $!_HOSTNAME; if strlen($!pid) > 0 then { # The imjournal normalized _PID to pid in its message properties. set $.lclpid = $!pid; } else { if strlen($!_PID) > 0 then { set $.lclpid = $!_PID; } else { set $.lclpid = "-"; } } unset $!_PID; unset $!pid; if strlen($.lclpid) > 0 then { if ($.pid == "-") and ($.lclpid != "-") then { # We don't have a PID, so use the one we found in the systemd data. set $.pid = $.lclpid; } else { if ($.pid != $.lclpid) then { # We have a PID, but the systemd's PID is different, so be # sure to save it. set $.systemd!t!PID = $.lclpid; } } } if strlen($!_SELINUX_CONTEXT) > 0 then { set $.systemd!t!SELINUX_CONTEXT = $!_SELINUX_CONTEXT; } unset $!_SELINUX_CONTEXT; if strlen($!_SOURCE_REALTIME_TIMESTAMP) > 0 then { set $.systemd!t!SOURCE_REALTIME_TIMESTAMP = $!_SOURCE_REALTIME_TIMESTAMP; } unset $!_SOURCE_REALTIME_TIMESTAMP; if strlen($!_SYSTEMD_CGROUP) > 0 then { set $.systemd!t!SYSTEMD_CGROUP = $!_SYSTEMD_CGROUP; } unset $!_SYSTEMD_CGROUP; if strlen($!_SYSTEMD_OWNER_UID) > 0 then { set $.systemd!t!SYSTEMD_OWNER_UID = $!_SYSTEMD_OWNER_UID; } unset $!_SYSTEMD_OWNER_UID; if strlen($!_SYSTEMD_SESSION) > 0 then { set $.systemd!t!SYSTEMD_SESSION = $!_SYSTEMD_SESSION; } unset $!_SYSTEMD_SESSION; if strlen($!_SYSTEMD_SLICE) > 0 then { set $.systemd!t!SYSTEMD_SLICE = $!_SYSTEMD_SLICE; } unset $!_SYSTEMD_SLICE; if strlen($!_SYSTEMD_UNIT) > 0 then { set $.systemd!t!SYSTEMD_UNIT = $!_SYSTEMD_UNIT; } unset $!_SYSTEMD_UNIT; if strlen($!_SYSTEMD_USER_UNIT) > 0 then { set $.systemd!t!SYSTEMD_USER_UNIT = $!_SYSTEMD_USER_UNIT; } unset $!_SYSTEMD_USER_UNIT; if strlen($!_TRANSPORT) > 0 then { set $.systemd!t!TRANSPORT = $!_TRANSPORT; } unset $!_TRANSPORT; if strlen($!_UID) > 0 then { set $.systemd!t!UID = $!_UID; } unset $!_UID; unset $!uid; # Pull out the systemd "kernel" journal fields... if strlen($!_KERNEL_DEVICE) > 0 then { set $.systemd!k!KERNEL_DEVICE = $!_KERNEL_DEVICE; } unset $!_KERNEL_DEVICE; if strlen($!_KERNEL_SUBSYSTEM) > 0 then { set $.systemd!k!KERNEL_SUBSYSTEM = $!_KERNEL_SUBSYSTEM; } unset $!_KERNEL_SUBSYSTEM; if strlen($!_UDEV_SYSNAME) > 0 then { set $.systemd!k!UDEV_SYSNAME = $!_UDEV_SYSNAME; } unset $!_UDEV_SYSNAME; if strlen($!_UDEV_DEVNODE) > 0 then { set $.systemd!k!UDEV_DEVNODE = $!_UDEV_DEVNODE; } unset $!_UDEV_DEVNODE; if strlen($!_UDEV_DEVLINK) > 0 then { set $.systemd!k!UDEV_DEVLINK = $!_UDEV_DEVLINK; } unset $!_UDEV_DEVLINK; } else { # Because of how we have defined the template above, where the template # encodes the field name directly, we need to have an empty object for # $.systemd so that at least an empty set of braces ("{}") is emitted. # Without that, we don't have a valid JSON document to index. # # So to get that empty object whether or not we actually have systemd # data to normalize we need to create an object hierarchy and then remove # the leaf property. set $.systemd!foo = "bar"; unset $.systemd!foo; } {% else %} set $!browbeat_json = $.browbeat_json; {% endif %}