diff --git a/Dockerfile b/Dockerfile index 99184a6..25b69bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM centos:centos7 -MAINTAINER The BitScout Community +MAINTAINER The ViaQ Community EXPOSE 10514 @@ -7,12 +7,13 @@ ENV SYSLOG_LISTEN_PORT=10514 \ ES_HOST=bitscout-elasticsearch \ ES_PORT=9200 -RUN yum install -y rsyslog rsyslog-elasticsearch rsyslog-gssapi \ - rsyslog-mmjsonparse rsyslog-mmsnmptrapd && \ +RUN curl https://copr.fedorainfracloud.org/coprs/portante/rsyslog-8.17/repo/epel-7/portante-rsyslog-8.17-epel-7.repo > /etc/yum.repos.d/portante-rsyslog-v8.17-epel-7.repo && \ + yum install -y rsyslog rsyslog-elasticsearch rsyslog-gssapi \ + rsyslog-mmjsonparse && \ yum clean all -ADD rsyslog.conf /etc/rsyslog.conf -ADD rsyslog.d/* /etc/rsyslog.d/ +VOLUME /data + ADD run.sh /usr/sbin/ WORKDIR /var/lib/rsyslog diff --git a/README.md b/README.md index 32c3140..a80e244 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ # docker-rsyslog -BitScout rsyslog docker container - implements the aggregator/formatter +ViaQ rsyslog docker container - implements the aggregator/formatter + +## Environmental variables: +`ES_HOST` must be FQDN of ElasticSearch server. +`ES_PORT` must be the port on which the ElasticSearch server is listening. +`SYSLOG_LISTEN_PORT` the port this rsyslog instance is listening for. both TCP and UDP. + +## External rsyslog config +In order to add own rsyslog configuration file please add the configuration files to a local directory and map in to `/data` docker volume. +The following files are taken form the local directory: +`rsyslog.conf, rsyslog.d/*.conf` +In case `rsyslog.conf` exists, the default `rsyslog.d/*.conf` is removed and not used in the container. + +## Running: +docker run -d -p $syslog_listen_port:$syslog_listen_port/tcp -p $syslog_listen_port:$syslog_listen_port/udp -v $local_dir:/data -u $uid -e ES_HOST=$elasticsearchhost -e ES_PORT=$port -e SYSLOG_LISTEN_PORT=$syslog_listen_port -e NORMALIZER_NAME=container-rsyslog8.17 -e NORMALIZER_IP=$normalizer_ip -e LOGSTASH_PREFIX=v2016.03.10.0-viaq- --name $appname $image + diff --git a/build-image.sh b/build-image.sh index bf23aaa..1e759f4 100755 --- a/build-image.sh +++ b/build-image.sh @@ -1,7 +1,7 @@ #!/bin/sh set -ex -prefix=${PREFIX:-${1:-bitscout/}} +prefix=${PREFIX:-${1:-viaq/}} version=${VERSION:-${2:-latest}} docker build -t "${prefix}rsyslog:${version}" . diff --git a/rsyslog.conf b/rsyslog.conf index c5eefdf..2fae8e2 100644 --- a/rsyslog.conf +++ b/rsyslog.conf @@ -3,147 +3,46 @@ # For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html # If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html -#### MODULES #### - -# only using rsyslog in aggregator mode -#module(load="imjournal" StateFile="/var/lib/rsyslog/imjournal.state") - -# Provides UDP syslog reception -module(load="imudp") -input(type="imudp" port="%SYSLOG_LISTEN_PORT%") - -# Provides TCP syslog reception -module(load="imptcp") -input(type="imptcp" port="%SYSLOG_LISTEN_PORT%") - -# ElasticSearch output module -module(load="omelasticsearch") - -# Parsing CEE JSON messages -module(load="mmjsonparse") - -# Reformating SNMP trap messages module -module(load="mmsnmptrapd") - -# Ensures we have UTF-8 encoded payloads -#module(load="mmutf8fix") - - #### GLOBAL DIRECTIVES #### global( # Where to place auxiliary files workDirectory="/var/lib/rsyslog" # perf-dept: we want fully qualified domain names for common logging - preserveFQDN="on") + preserveFQDN="on" + # Try to avoid any message truncation + maxMessageSize="65536") -# main_queue not available in latest el7 rsyslog (7.4) only in 7.5 and later -# main_queue( -# # Beef up the internal message queue -# queue.size="131072" -# # 90% of QueueSize -# queue.discardmark="117964" -# # If we reach the discard mark, we'll throw out notice, info, and debug messages -# queue.discardseverity="5") +main_queue( + # 4 worker threads in the main queue + queue.workerthreads="4" + # Beaf up the internal message queue + queue.size="131072" + # 90% of QueueSize + queue.discardmark="117964" + # If we reach the discard mark, we'll throw out notice, info, and debug messages + queue.discardseverity="5") -# this is for index names to be like: bitscout-YYYY.MM.DD -# WARNING: any rsyslog collecting host MUST be running UTC -# if the proper index is to be chosen to hold the -# log entry. If you are running EDT, e.g., then -# the previous day's index will be chosen even -# though the UTC value is the current day, because -# the pattern logic does not convert "timereported" -# to a UTC value before pulling data out of it. -template(name="bitscout-index-pattern" type="list") { - constant(value="bitscout-") - property(name="timereported" dateFormat="rfc3339" position.from="1" position.to="4") - constant(value=".") - property(name="timereported" dateFormat="rfc3339" position.from="6" position.to="7") - constant(value=".") - property(name="timereported" dateFormat="rfc3339" position.from="9" position.to="10") - } -# this is for formatting our syslog data in JSON with @timestamp using a "hierarchical" metdata namespace -template(name="com-redhat-rsyslog-hier" - type="list") { - constant(value="{") - constant(value="\"@timestamp\":\"") property(name="timereported" dateFormat="rfc3339") - constant(value="\",\"@version\":\"2015.09.24-0") - constant(value="\",\"message\":\"") property(name="msg" format="json") - constant(value="\",\"hostname\":\"") property(name="hostname") - constant(value="\",\"level\":\"") property(name="syslogseverity-text") - constant(value="\",\"pid\":\"") property(name="procid") - constant(value="\",\"rsyslog\": {") - constant(value="\"facility\":\"") property(name="syslogfacility-text") - constant(value="\",\"programname\":\"") property(name="programname") - constant(value="\",\"fromhost\":\"") property(name="fromhost") - constant(value="\",\"fromhost-ip\":\"") property(name="fromhost-ip") - constant(value="\",\"timegenerated\":\"") property(name="timegenerated" dateFormat="rfc3339") - constant(value="\",\"protocol-version\":\"") property(name="protocol-version") - constant(value="\",\"structured-data\":\"") property(name="structured-data") - constant(value="\",\"app-name\":\"") property(name="app-name") - constant(value="\",\"msgid\":\"") property(name="msgid") - constant(value="\",\"inputname\":\"") property(name="inputname") - constant(value="\",\"_cee\":") property(name="$!all-json") - constant(value="} }") - } -# Use default timestamp format -$ActionFileDefaultTemplate RSYSLOG_FileFormat +# Include loading modules and basic formatting +$IncludeConfig /etc/rsyslog.d/00-load-modules-and-formatting.conf -# Include all config files in /etc/rsyslog.d/ -$IncludeConfig /etc/rsyslog.d/*.conf +# Include templates for destination index name and for data model +$IncludeConfig /etc/rsyslog.d/10-viaq-templates.conf -#### RULES #### +# Include Pipeline metadata information +$IncludeConfig /etc/rsyslog.d/20-viaq-pipeline-metadata.conf -# Ensure message is a properly formatted UTF-8 sequence -#action(type="mmutf8fix" mode="utf-8") +# Include top-level fields modifications +$IncludeConfig /etc/rsyslog.d/25-viaq-common.conf -# Reformat any SNMP trap messages (legacy format required) -*.* :mmsnmptrapd: +# Include fields in systemd section +$IncludeConfig /etc/rsyslog.d/30-viaq-systemd.conf -# Parse any CEE JSON messages -action(type="mmjsonparse") +# Include fields in rsyslog section +$IncludeConfig /etc/rsyslog.d/40-viaq-rsyslog-section.conf # Index into elasticsearch directly in a hierarchical metadata namespace -action( - type="omelasticsearch" - server="%ES_HOST%" - serverport="%ES_PORT%" - template="com-redhat-rsyslog-hier" - searchIndex="bitscout-index-pattern" - dynSearchIndex="on" - searchType="rsyslog" - bulkmode="on" - queue.type="linkedlist" - queue.size="5000" - queue.dequeuebatchsize="300" - action.resumeretrycount="-1") - -# Prevent local elasticsearch logs from flowing into other log files (they are -# already being logged to files). The local ElasticSearch instance is the -# "test" one, which has a "test-elasticsearch" tag, but we don't need to -# explicitly check for that since no logs from any elasticsearch instance need -# to be logged locally. -:programname, isequal, "elasticsearch" stop - -# Log anything (except mail) of level info or higher. -# Don't log private authentication messages! -*.info;mail.none;authpriv.none;cron.none /var/log/messages - -# The authpriv file has restricted access. -authpriv.* /var/log/secure - -# Log all the mail messages in one place. -mail.* -/var/log/maillog - -# Log cron stuff -cron.* /var/log/cron - -# Everybody gets emergency messages -*.emerg :omusrmsg:* +$IncludeConfig /etc/rsyslog.d/50-elasticsearch-output.conf -# Save news errors of level crit and higher in a special file. -uucp,news.crit /var/log/spooler -# Save boot messages also to boot.log -local7.* /var/log/boot.log diff --git a/rsyslog.d/00-bitscout-tags.conf b/rsyslog.d/00-bitscout-tags.conf deleted file mode 100644 index a872b08..0000000 --- a/rsyslog.d/00-bitscout-tags.conf +++ /dev/null @@ -1,3 +0,0 @@ -# A simple string of "tags" that system administrators can use to identify the -# various roles a system can take on, or categories to consider it under. -set $!tags = "BAGL,pbench-testing"; diff --git a/rsyslog.d/00-load-modules-and-formatting.conf b/rsyslog.d/00-load-modules-and-formatting.conf new file mode 100644 index 0000000..31b6963 --- /dev/null +++ b/rsyslog.d/00-load-modules-and-formatting.conf @@ -0,0 +1,30 @@ +#### MODULES #### + +# Emit internal rsyslog counters +module(load="impstats" format="cee" interval="60") + +# Provides UDP syslog reception +module(load="imudp") +input(type="imudp" port="%SYSLOG_LISTEN_PORT%") + +# Provides TCP syslog reception +module(load="imptcp") +input(type="imptcp" port="%SYSLOG_LISTEN_PORT%") + +# ElasticSearch output module +module(load="omelasticsearch") + +# Parsing CEE JSON messages +module(load="mmjsonparse") + +# Ensures we have UTF-8 encoded payloads +module(load="mmutf8fix") + +#### RULES #### + +# Ensure message is a properly formatted UTF-8 sequence +action(type="mmutf8fix" mode="utf-8") + +# Parse any CEE JSON messages +action(type="mmjsonparse") + diff --git a/rsyslog.d/10-viaq-templates.conf b/rsyslog.d/10-viaq-templates.conf new file mode 100644 index 0000000..87c9499 --- /dev/null +++ b/rsyslog.d/10-viaq-templates.conf @@ -0,0 +1,40 @@ +# Templates +# +# this is for index names to be like: logstash-YYYY.MM.DD +# WARNING: any rsyslog collecting host MUST be running UTC +# if the proper index is to be chosen to hold the +# log entry. If you are running EDT, e.g., then +# the previous day's index will be chosen even +# though the UTC value is the current day, because +# the pattern logic does not convert "timereported" +# to a UTC value before pulling data out of it. + + +template(name="viaq-index-pattern" type="list") { + constant(value="%LOGSTASH_PREFIX%") + property(name="timereported" dateFormat="rfc3339" position.from="1" position.to="4") + constant(value=".") + property(name="timereported" dateFormat="rfc3339" position.from="6" position.to="7") + constant(value=".") + property(name="timereported" dateFormat="rfc3339" position.from="9" position.to="10") + } + +# this is for formatting our syslog data in JSON with @timestamp using a "hierarchical" metdata namespace + +template(name="com-redhat-rsyslog-hier" + type="list") { + constant(value="{") + constant(value="\"@timestamp\":\"") property(name="timegenerated" dateFormat="rfc3339") + constant(value="\",\"message\":\"") property(name="$.msg" format="json") + constant(value="\",\"hostname\":\"") property(name="$.hostname") +# constant(value="\",\"ipaddr4\":\"") property(name="$.ipaddr4") + constant(value="\",\"level\":\"") property(name="$.level") + constant(value="\",\"pid\":\"") property(name="$.pid") + constant(value="\",\"tags\":\"") property(name="$.tags") + constant(value="\",\"service\":\"") property(name="$.service") + constant(value="\",\"CEE\":") property(name="$!all-json") + constant(value=",\"systemd\":") property(name="$.systemd") + constant(value=",\"rsyslog\":") property(name="$.rsyslog") + constant(value=",\"pipeline_metadata\":") property(name="$.pipeline_metadata") + constant(value="}\n") + } diff --git a/rsyslog.d/20-viaq-pipeline-metadata.conf b/rsyslog.d/20-viaq-pipeline-metadata.conf new file mode 100644 index 0000000..5ee7b09 --- /dev/null +++ b/rsyslog.d/20-viaq-pipeline-metadata.conf @@ -0,0 +1,17 @@ +# Pipeline metadata related fields + +# If there was some pipeline_metadata coming from the collector - we want to preserve it +if strlen($!pipeline_metadata) > 0 then { + set $.pipeline_metadata = $!pipeline_metadata; + unset $!pipeline_metadata; +} + +# Add information about the normalizer +template(name="timegeneratedrfc3339" type="string" string="%timegenerated:::date-rfc3339%") +set $.pipeline_metadata!normalizer!received_at = exec_template("timegeneratedrfc3339"); +set $.pipeline_metadata!normalizer!inputname = $inputname; +set $.pipeline_metadata!normalizer!ipaddr4 = "%NORMALIZER_IP%"; +set $.pipeline_metadata!normalizer!name = "%NORMALIZER_NAME%"; +set $.pipeline_metadata!version = "2016.03.10.0"; + + diff --git a/rsyslog.d/25-viaq-common.conf b/rsyslog.d/25-viaq-common.conf new file mode 100644 index 0000000..68c4aba --- /dev/null +++ b/rsyslog.d/25-viaq-common.conf @@ -0,0 +1,104 @@ +# Populating top-level fields + +# 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. + # original_raw_message saves the original unparsed $msg in case $!MESSAGE from journald is not equal to $!msg + set $.msg = $!MESSAGE; + set $.pipeline_metadata!normalizer!original_raw_message = $msg; +} + +# 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; +} +set $.hostname = $hostname; + +# If we don't have tags - we don't add new tags. +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. +# $procid is the PID according to syslog rfc's +# Since this rsyslog instance is running in the container it doesn't have any local input, everything is from imptcp/imudp +set $.pid = $procid; + +# $!pid and $!_PID might be coming from journald +if strlen($!pid) > 0 then { + # The imjournal normalized _PID to pid in its message properties. TODO: move PID to top level + set $.fwdpid = $!pid; +} else { + if strlen($!_PID) > 0 then { + set $.fwdpid = $!_PID; + } +} +unset $!_PID; +unset $!pid; + +if strlen($.fwdpid) > 0 then { + if ($.pid == "-") and ($.fwdpid != "-") then { + # We don't have a PID, so use the one we found in the systemd data. + set $.pid = $.fwdpid; + } else { + if ($.pid != $.fwdpid) then { + # We have a PID, but the systemd's PID is different, so be + # sure to save it. + set $.systemd!t!PID = $.fwdpid; + } + } +} + +set $.level = $syslogseverity-text; + +# if ipaddr4 was set by the collector we must preserve it. +if (strlen($!ipaddr4) > 0) then { + set $.ipaddr4 = $!ipaddr4; + unset $!ipaddr4; +} else if ($fromhost == $.hostname) then { + # iff fromhost == hostname we can set $.ipaddr4 as $.fromhost-ip + set $.ipaddr4 = $fromhost-ip; +} + +# 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 (strlen($programname) > 0) then { + set $.service = $programname; + } else if (strlen($app-name) > 0) then { + set $.service = $app-name; +} + +# if $.service == programname then we might need to save $app-name, if $.service == $app-name then it implies $.service == $programname OR $programname is empty +if ($.service != $app-name) then { + set $.rsyslog!appname=$app-name; +} +# If we unset, the output template will contain empty string +if (strlen($.service) == 0) then { + unset $.service; +} +if (strlen($.rsyslog!appname) == 0) then { + unset $.rsyslog!appname; +} diff --git a/rsyslog.d/30-viaq-systemd.conf b/rsyslog.d/30-viaq-systemd.conf new file mode 100644 index 0000000..c5a0e7c --- /dev/null +++ b/rsyslog.d/30-viaq-systemd.conf @@ -0,0 +1,166 @@ +# systemd section processing + +# pid normalization is in viaq-common + +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; + unset $!PRIORITY; + unset $!SYSLOG_FACILITY; + unset $!SYSLOG_IDENTIFIER; + 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($!_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; +} + + + + + + diff --git a/rsyslog.d/40-viaq-rsyslog-section.conf b/rsyslog.d/40-viaq-rsyslog-section.conf new file mode 100644 index 0000000..f6c73f8 --- /dev/null +++ b/rsyslog.d/40-viaq-rsyslog-section.conf @@ -0,0 +1,27 @@ +# Rsyslog section in ElasticSearch mapping + +# 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. +if ($fromhost-ip != $.ipaddr4) then { + 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; +} diff --git a/rsyslog.d/50-elasticsearch-output.conf b/rsyslog.d/50-elasticsearch-output.conf new file mode 100644 index 0000000..f57eb6a --- /dev/null +++ b/rsyslog.d/50-elasticsearch-output.conf @@ -0,0 +1,16 @@ + +# Index into elasticsearch directly in a hierarchical metadata namespace +action( + type="omelasticsearch" + server="%ES_HOST%" + serverport="%ES_PORT%" + template="com-redhat-rsyslog-hier" + searchIndex="viaq-index-pattern" + dynSearchIndex="on" + searchType="rsyslog" + bulkmode="on" + queue.type="linkedlist" + queue.size="5000" + queue.dequeuebatchsize="300" + action.resumeretrycount="-1") + diff --git a/run.sh b/run.sh index 768c197..3cf359f 100755 --- a/run.sh +++ b/run.sh @@ -3,14 +3,35 @@ set -e set -x -ES_HOST=${ES_HOST:-bitscout-elasticsearch} +ES_HOST=${ES_HOST:-viaq-elasticsearch} ES_PORT=${ES_PORT:-9200} SYSLOG_LISTEN_PORT=${SYSLOG_LISTEN_PORT:-10514} +DEBUG_RSYSLOG=${DEBUG_RSYSLOG:-false} +LOGSTASH_PREFIX=${LOGSTASH_PREFIX:-logstash-} +NORMALIZER_NAME=${NORMALIZER_NAME:-container-rsyslog8.17} +NORMALIZER_IP=${NORMALIZER_IP:-172.17.77.14} + +if [ "$DEBUG_RSYSLOG" = true ]; then + RSYSLOG_ARGS="-d -n" +else + RSYSLOG_ARGS="-n" +fi + +if [ -f "/data/rsyslog.conf" ]; then + cp /data/rsyslog.conf /etc/rsyslog.conf + rm /etc/rsyslog.d/*.conf + if [ -d "/data/rsyslog.d" ]; then + cp -R /data/rsyslog.d /etc/ + fi +fi for file in /etc/rsyslog.conf /etc/rsyslog.d/*.conf ; do if [ ! -f "$file" ] ; then continue ; fi sed -i -e "s/%ES_HOST%/$ES_HOST/g" -e "s/%ES_PORT%/$ES_PORT/g" \ -e "s/%SYSLOG_LISTEN_PORT%/$SYSLOG_LISTEN_PORT/g" \ + -e "s/%LOGSTASH_PREFIX%/$LOGSTASH_PREFIX/g" \ + -e "s/%NORMALIZER_NAME%/$NORMALIZER_NAME/g" -e "s/%NORMALIZER_IP%/$NORMALIZER_IP/g" \ "$file" done -/usr/sbin/rsyslogd -d -n +/usr/sbin/rsyslogd ${RSYSLOG_ARGS} +