From 8f2ec25cc26806c23dd9643313c3bcbdb4f5ce9b Mon Sep 17 00:00:00 2001 From: Anton Sherkhonov Date: Fri, 18 Mar 2016 17:29:36 +0000 Subject: [PATCH 1/4] Rename bitscout to viaq use Peter's copr repository for rsyslog 8.17, Use external config file outside of the container --- Dockerfile | 9 +++++---- README.md | 17 ++++++++++++++++- build-image.sh | 2 +- run.sh | 19 +++++++++++++++++-- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 99184a6..7deee42 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 \ +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 rsyslog-mmsnmptrapd && \ 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..0d92a76 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/udp -v $local_dir:/data -u $uid -e ES_HOST=$elasticsearchhost -e ES_PORT=$port -e SYSLOG_LISTEN_PORT=$syslog_listen_port --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/run.sh b/run.sh index 768c197..7b51b00 100755 --- a/run.sh +++ b/run.sh @@ -3,9 +3,24 @@ 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:-true} + +if [ "$DEBUG_RSYSLOG" = true ]; then + RSYSLOG_ARGS="-d -n" +else + RSYSLOG_ARGS="" +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 /data/rsyslog.d/*.conf /etc/rsyslog.d/*.conf + fi +fi for file in /etc/rsyslog.conf /etc/rsyslog.d/*.conf ; do if [ ! -f "$file" ] ; then continue ; fi @@ -13,4 +28,4 @@ for file in /etc/rsyslog.conf /etc/rsyslog.d/*.conf ; do -e "s/%SYSLOG_LISTEN_PORT%/$SYSLOG_LISTEN_PORT/g" \ "$file" done -/usr/sbin/rsyslogd -d -n +/usr/sbin/rsyslogd ${RSYSLOG_ARGS} From 5286015160e52e72bd9795dead53e72fe8e89fb6 Mon Sep 17 00:00:00 2001 From: Anton Sherkhonov Date: Mon, 28 Mar 2016 21:51:56 +0000 Subject: [PATCH 2/4] Split normalizer rsyslog in separate configs Apply new data model v2016.03.10.0 --- rsyslog.conf | 151 +++----------- rsyslog.d/00-bitscout-tags.conf | 3 - rsyslog.d/00-load-modules-and-formatting.conf | 39 ++++ rsyslog.d/10-viaq-templates.conf | 40 ++++ rsyslog.d/20-viaq-pipeline-metadata.conf | 22 ++ rsyslog.d/25-viaq-common.conf | 67 +++++++ rsyslog.d/30-viaq-systemd.conf | 188 ++++++++++++++++++ rsyslog.d/40-viaq-rsyslog-section.conf | 27 +++ rsyslog.d/50-elasticsearch-output.conf | 16 ++ run.sh | 6 +- 10 files changed, 428 insertions(+), 131 deletions(-) delete mode 100644 rsyslog.d/00-bitscout-tags.conf create mode 100644 rsyslog.d/00-load-modules-and-formatting.conf create mode 100644 rsyslog.d/10-viaq-templates.conf create mode 100644 rsyslog.d/20-viaq-pipeline-metadata.conf create mode 100644 rsyslog.d/25-viaq-common.conf create mode 100644 rsyslog.d/30-viaq-systemd.conf create mode 100644 rsyslog.d/40-viaq-rsyslog-section.conf create mode 100644 rsyslog.d/50-elasticsearch-output.conf diff --git a/rsyslog.conf b/rsyslog.conf index c5eefdf..4c14d36 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") - -# 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") - -# 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 all config files in /etc/rsyslog.d/ -$IncludeConfig /etc/rsyslog.d/*.conf + preserveFQDN="on" + # Try to avoid any message truncation + maxMessageSize="65536") -#### RULES #### +main_queue( + # 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") -# Ensure message is a properly formatted UTF-8 sequence -#action(type="mmutf8fix" mode="utf-8") -# Reformat any SNMP trap messages (legacy format required) -*.* :mmsnmptrapd: - -# Parse any CEE JSON messages -action(type="mmjsonparse") +#### MODULES #### -# 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") +# Include loading modules and basic formatting +$IncludeConfig /etc/rsyslog.d/00-load-modules-and-formatting.conf -# 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 +# Include templates for destination index name and for data model +$IncludeConfig /etc/rsyslog.d/10-viaq-templates.conf -# 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 +# Include Pipeline metadata information +$IncludeConfig /etc/rsyslog.d/20-viaq-pipeline-metadata.conf -# The authpriv file has restricted access. -authpriv.* /var/log/secure +# Include top-level fields modifications +$IncludeConfig /etc/rsyslog.d/25-viaq-common.conf -# Log all the mail messages in one place. -mail.* -/var/log/maillog +# Include fields in systemd section +$IncludeConfig /etc/rsyslog.d/30-viaq-systemd.conf -# Log cron stuff -cron.* /var/log/cron +# Include fields in rsyslog section +$IncludeConfig /etc/rsyslog.d/40-viaq-rsyslog-section.conf -# Everybody gets emergency messages -*.emerg :omusrmsg:* +# Index into elasticsearch directly in a hierarchical metadata namespace +$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..60e5f40 --- /dev/null +++ b/rsyslog.d/00-load-modules-and-formatting.conf @@ -0,0 +1,39 @@ +#### MODULES #### + +# Emit internal rsyslog counters +module(load="impstats" format="cee" interval="60") + +# Provides UDP syslog reception +module(load="imudp") +input(type="imudp" port="10514") + +# Provides TCP syslog reception +module(load="imptcp") +input(type="imptcp" port="10514") + +# 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") + + +# Use default timestamp format +$ActionFileDefaultTemplate RSYSLOG_FileFormat + +#### RULES #### + +# Ensure message is a properly formatted UTF-8 sequence +action(type="mmutf8fix" mode="utf-8") + +# Reformat any SNMP trap messages (legacy format required) +*.* :mmsnmptrapd: + +# 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..268b181 --- /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="v2016.03.10.0-viaq-") + 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..b231f5e --- /dev/null +++ b/rsyslog.d/20-viaq-pipeline-metadata.conf @@ -0,0 +1,22 @@ +# Pipeline metadata related fields + +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 = "172.17.77.14"; +set $.pipeline_metadata!normalizer!name = "container-rsyslog8.17"; +set $.pipeline_metadata!version = "2016.03.10.0"; + +if strlen($!pipeline_metadata!collector) > 0 then { + set $.pipeline_metadata!collector = $!pipeline_metadata!collector; + if strlen($!pipeline_metadata!original_raw_message) > 0 then { + set $.pipeline_metadata!original_raw_message = $!pipeline_metadata!original_raw_message; + } + unset $!pipeline_metadata; +} + +#if strlen($!pipeline_metadata!original_raw_message) > 0 then { +# set $.pipeline_metadata!original_raw_message = $!pipeline_metadata!original_raw_message; +# unset $!pipeline_metadata!original_raw_message; +#} + diff --git a/rsyslog.d/25-viaq-common.conf b/rsyslog.d/25-viaq-common.conf new file mode 100644 index 0000000..9336689 --- /dev/null +++ b/rsyslog.d/25-viaq-common.conf @@ -0,0 +1,67 @@ +# 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. + 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; +} else { + if ($inputname == 'imjournal') or ($inputname == "impstats") or ((($hostname == "localhost") or ($fromhost == "localhost")) and ($fromhost-ip == "127.0.0.1")) then { + # Local label for perf34 itself + set $.tags = "perf-dept rsyslog fluentd vos gunicorn jenkins test-elasticsearch"; + } +} +# 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 $.service = $app-name; +if (strlen($!ipaddr4) > 0) then { + set $.ipaddr4 = $!ipaddr4; + unset $!ipaddr4; +} + +# 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 { + set $.CEE!programname=$programname; +} +if (strlen($.service) == 0) then { + unset $.service; +} +if (strlen($.CEE!programname) == 0) then { + unset $.CEE!programname; +} diff --git a/rsyslog.d/30-viaq-systemd.conf b/rsyslog.d/30-viaq-systemd.conf new file mode 100644 index 0000000..47f9d30 --- /dev/null +++ b/rsyslog.d/30-viaq-systemd.conf @@ -0,0 +1,188 @@ +# systemd section processing + +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($!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; +} + + + + + + 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 7b51b00..db226d4 100755 --- a/run.sh +++ b/run.sh @@ -11,14 +11,16 @@ DEBUG_RSYSLOG=${DEBUG_RSYSLOG:-true} if [ "$DEBUG_RSYSLOG" = true ]; then RSYSLOG_ARGS="-d -n" else - RSYSLOG_ARGS="" + 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 /data/rsyslog.d/*.conf /etc/rsyslog.d/*.conf + for config in /data/rsyslog.d/*.conf; do + cp "$config" /etc/rsyslog.d/ + done fi fi From dc8a93b54e3fbf903a030dabff9f86b8604ec377 Mon Sep 17 00:00:00 2001 From: Anton Sherkhonov Date: Thu, 19 May 2016 18:59:04 +0000 Subject: [PATCH 3/4] fixed rsyslog config following discussion w/ peter --- rsyslog.conf | 2 - rsyslog.d/00-load-modules-and-formatting.conf | 15 +---- rsyslog.d/10-viaq-templates.conf | 2 +- rsyslog.d/20-viaq-pipeline-metadata.conf | 23 +++----- rsyslog.d/25-viaq-common.conf | 59 +++++++++++++++---- rsyslog.d/30-viaq-systemd.conf | 26 +------- run.sh | 10 +++- 7 files changed, 70 insertions(+), 67 deletions(-) diff --git a/rsyslog.conf b/rsyslog.conf index 4c14d36..1a521b3 100644 --- a/rsyslog.conf +++ b/rsyslog.conf @@ -22,8 +22,6 @@ main_queue( queue.discardseverity="5") -#### MODULES #### - # Include loading modules and basic formatting $IncludeConfig /etc/rsyslog.d/00-load-modules-and-formatting.conf diff --git a/rsyslog.d/00-load-modules-and-formatting.conf b/rsyslog.d/00-load-modules-and-formatting.conf index 60e5f40..31b6963 100644 --- a/rsyslog.d/00-load-modules-and-formatting.conf +++ b/rsyslog.d/00-load-modules-and-formatting.conf @@ -5,11 +5,11 @@ module(load="impstats" format="cee" interval="60") # Provides UDP syslog reception module(load="imudp") -input(type="imudp" port="10514") +input(type="imudp" port="%SYSLOG_LISTEN_PORT%") # Provides TCP syslog reception module(load="imptcp") -input(type="imptcp" port="10514") +input(type="imptcp" port="%SYSLOG_LISTEN_PORT%") # ElasticSearch output module module(load="omelasticsearch") @@ -17,23 +17,14 @@ 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") - -# Use default timestamp format -$ActionFileDefaultTemplate RSYSLOG_FileFormat - #### RULES #### # Ensure message is a properly formatted UTF-8 sequence action(type="mmutf8fix" mode="utf-8") -# Reformat any SNMP trap messages (legacy format required) -*.* :mmsnmptrapd: - # Parse any CEE JSON messages action(type="mmjsonparse") + diff --git a/rsyslog.d/10-viaq-templates.conf b/rsyslog.d/10-viaq-templates.conf index 268b181..87c9499 100644 --- a/rsyslog.d/10-viaq-templates.conf +++ b/rsyslog.d/10-viaq-templates.conf @@ -11,7 +11,7 @@ template(name="viaq-index-pattern" type="list") { - constant(value="v2016.03.10.0-viaq-") + 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") diff --git a/rsyslog.d/20-viaq-pipeline-metadata.conf b/rsyslog.d/20-viaq-pipeline-metadata.conf index b231f5e..5ee7b09 100644 --- a/rsyslog.d/20-viaq-pipeline-metadata.conf +++ b/rsyslog.d/20-viaq-pipeline-metadata.conf @@ -1,22 +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 = "172.17.77.14"; -set $.pipeline_metadata!normalizer!name = "container-rsyslog8.17"; +set $.pipeline_metadata!normalizer!ipaddr4 = "%NORMALIZER_IP%"; +set $.pipeline_metadata!normalizer!name = "%NORMALIZER_NAME%"; set $.pipeline_metadata!version = "2016.03.10.0"; -if strlen($!pipeline_metadata!collector) > 0 then { - set $.pipeline_metadata!collector = $!pipeline_metadata!collector; - if strlen($!pipeline_metadata!original_raw_message) > 0 then { - set $.pipeline_metadata!original_raw_message = $!pipeline_metadata!original_raw_message; - } - unset $!pipeline_metadata; -} - -#if strlen($!pipeline_metadata!original_raw_message) > 0 then { -# set $.pipeline_metadata!original_raw_message = $!pipeline_metadata!original_raw_message; -# unset $!pipeline_metadata!original_raw_message; -#} diff --git a/rsyslog.d/25-viaq-common.conf b/rsyslog.d/25-viaq-common.conf index 9336689..22c6ef3 100644 --- a/rsyslog.d/25-viaq-common.conf +++ b/rsyslog.d/25-viaq-common.conf @@ -18,7 +18,9 @@ if (strlen($!msg) > 0) then { } 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 @@ -29,14 +31,11 @@ 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; -} else { - if ($inputname == 'imjournal') or ($inputname == "impstats") or ((($hostname == "localhost") or ($fromhost == "localhost")) and ($fromhost-ip == "127.0.0.1")) then { - # Local label for perf34 itself - set $.tags = "perf-dept rsyslog fluentd vos gunicorn jenkins test-elasticsearch"; - } } # Always pull tags out of the message properties so that it does not show up # again under the CEE property in ElasticSearch. @@ -44,24 +43,62 @@ 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; -set $.hostname = $hostname; +# $!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; -set $.service = $app-name; + +# 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 ($app-name != $programname) then { - set $.CEE!programname=$programname; +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($.CEE!programname) == 0) then { - unset $.CEE!programname; +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 index 47f9d30..c5a0e7c 100644 --- a/rsyslog.d/30-viaq-systemd.conf +++ b/rsyslog.d/30-viaq-systemd.conf @@ -1,5 +1,7 @@ # 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 @@ -81,30 +83,6 @@ if strlen($!_MACHINE_ID) > 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; } diff --git a/run.sh b/run.sh index db226d4..0caba15 100755 --- a/run.sh +++ b/run.sh @@ -7,6 +7,9 @@ ES_HOST=${ES_HOST:-viaq-elasticsearch} ES_PORT=${ES_PORT:-9200} SYSLOG_LISTEN_PORT=${SYSLOG_LISTEN_PORT:-10514} DEBUG_RSYSLOG=${DEBUG_RSYSLOG:-true} +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" @@ -18,9 +21,7 @@ if [ -f "/data/rsyslog.conf" ]; then cp /data/rsyslog.conf /etc/rsyslog.conf rm /etc/rsyslog.d/*.conf if [ -d "/data/rsyslog.d" ]; then - for config in /data/rsyslog.d/*.conf; do - cp "$config" /etc/rsyslog.d/ - done + cp -R /data/rsyslog.d /etc/ fi fi @@ -28,6 +29,9 @@ 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 ${RSYSLOG_ARGS} + From 9a0ef2ac89e0833c232b01d50eeafefccb2d5ae8 Mon Sep 17 00:00:00 2001 From: Anton Sherkhonov Date: Thu, 19 May 2016 21:33:59 +0000 Subject: [PATCH 4/4] removed installing rsyslog-mmsnmptrapd. Added 4 worker threads in the main queue. fixed typo in the config, default to non-debug rsyslog --- Dockerfile | 2 +- README.md | 2 +- rsyslog.conf | 2 ++ rsyslog.d/25-viaq-common.conf | 2 +- run.sh | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7deee42..25b69bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ ENV SYSLOG_LISTEN_PORT=10514 \ 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 rsyslog-mmsnmptrapd && \ + rsyslog-mmjsonparse && \ yum clean all VOLUME /data diff --git a/README.md b/README.md index 0d92a76..a80e244 100644 --- a/README.md +++ b/README.md @@ -13,5 +13,5 @@ The following files are taken form the local directory: 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/udp -v $local_dir:/data -u $uid -e ES_HOST=$elasticsearchhost -e ES_PORT=$port -e SYSLOG_LISTEN_PORT=$syslog_listen_port --name $appname $image +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/rsyslog.conf b/rsyslog.conf index 1a521b3..2fae8e2 100644 --- a/rsyslog.conf +++ b/rsyslog.conf @@ -14,6 +14,8 @@ global( maxMessageSize="65536") main_queue( + # 4 worker threads in the main queue + queue.workerthreads="4" # Beaf up the internal message queue queue.size="131072" # 90% of QueueSize diff --git a/rsyslog.d/25-viaq-common.conf b/rsyslog.d/25-viaq-common.conf index 22c6ef3..68c4aba 100644 --- a/rsyslog.d/25-viaq-common.conf +++ b/rsyslog.d/25-viaq-common.conf @@ -80,7 +80,7 @@ if (strlen($!ipaddr4) > 0) then { unset $!ipaddr4; } else if ($fromhost == $.hostname) then { # iff fromhost == hostname we can set $.ipaddr4 as $.fromhost-ip - set $.ipaddr4 = $fromhost-ip + set $.ipaddr4 = $fromhost-ip; } # Now drop app-name if it is the same as programname, don't need to index diff --git a/run.sh b/run.sh index 0caba15..3cf359f 100755 --- a/run.sh +++ b/run.sh @@ -6,7 +6,7 @@ set -x ES_HOST=${ES_HOST:-viaq-elasticsearch} ES_PORT=${ES_PORT:-9200} SYSLOG_LISTEN_PORT=${SYSLOG_LISTEN_PORT:-10514} -DEBUG_RSYSLOG=${DEBUG_RSYSLOG:-true} +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}