├── rsyslog ├── files │ ├── listen.conf │ └── 50-default.conf ├── osfamilymap.yaml ├── defaults.yaml ├── map.jinja ├── init.sls └── templates │ └── rsyslog.conf.jinja ├── Dockerfile ├── LICENSE ├── README.rst └── pillar.example /rsyslog/files/listen.conf: -------------------------------------------------------------------------------- 1 | $SystemLogSocketName /run/systemd/journal/syslog 2 | -------------------------------------------------------------------------------- /rsyslog/osfamilymap.yaml: -------------------------------------------------------------------------------- 1 | RedHat: 2 | workdirectory: /var/spool/rsyslog 3 | FreeBSD: 4 | service: rsyslogd 5 | config: /usr/local/etc/rsyslog.conf 6 | custom_config_path: /usr/local/etc/rsyslog.d 7 | rungroup: wheel 8 | Gentoo: 9 | rungroup: adm 10 | package: app-admin/rsyslog -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM martinhoefling/salt-minion:debian 2 | MAINTAINER Martin Hoefling 3 | # push formula 4 | ADD rsyslog /srv/salt/rsyslog 5 | ADD pillar.example /srv/pillar/example.sls 6 | RUN echo "file_client: local" > /etc/salt/minion.d/local.conf 7 | RUN echo "base:" > /srv/pillar/top.sls 8 | RUN echo " '*':" >> /srv/pillar/top.sls 9 | RUN echo " - example" >> /srv/pillar/top.sls 10 | RUN salt-call --local state.sls rsyslog | tee log.txt && grep "Failed: 0" log.txt 11 | -------------------------------------------------------------------------------- /rsyslog/defaults.yaml: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=yaml 3 | rsyslog: 4 | package: rsyslog 5 | module_packages: 6 | gnutls: rsyslog-gnutls 7 | elasticsearch: rsyslog-elasticsearch 8 | gssapi: rsyslog-gssapi 9 | kafka: rsyslog-kafka 10 | mysql: rsyslog-mysql 11 | pgsql: rsyslog-pgsql 12 | relp: rsyslog-relp 13 | service: rsyslog 14 | runuser: root 15 | rungroup: root 16 | config: /etc/rsyslog.conf 17 | workdirectory: /var/spool/rsyslog 18 | custom_config_path: /etc/rsyslog.d 19 | exclusive: True 20 | stoplist: 21 | - syslogd 22 | custom_config_template: salt://rsyslog/templates/rsyslog.conf.jinja 23 | -------------------------------------------------------------------------------- /rsyslog/map.jinja: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # vim: ft=jinja 3 | 4 | {## Start with defaults from defaults.yaml ##} 5 | {% import_yaml "rsyslog/defaults.yaml" as defaults %} 6 | {% import_yaml "rsyslog/osfamilymap.yaml" as osfamilymap %} 7 | 8 | {## 9 | Setup variable using grains['os_family'] based logic, only add key:values here 10 | that differ from whats in defaults.yaml 11 | ##} 12 | {% set osfam = salt['grains.filter_by']( 13 | osfamilymap, 14 | grain='os_family' 15 | ) or {} %} 16 | 17 | 18 | {## Merge the flavor_map to the default settings ##} 19 | {% do salt['defaults.merge'](defaults['rsyslog'], osfam) %} 20 | 21 | 22 | {## Merge in salt:lookup pillar ##} 23 | {% set rsyslog = salt['pillar.get']( 24 | 'rsyslog', 25 | default=defaults.rsyslog, 26 | merge=True) 27 | %} 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Kenny Do 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | rsyslog-formula 2 | =============== 3 | 4 | Configures and starts rsyslog service. Currently the log file schema is based on the debian default. The formula allows 5 | control if rsyslog should listen for tcp / udp connections. Further ikml logging (kernel) logging can be disabled, e.g. for lxc containers. 6 | It supports both a client only (sending all logs to another machine) and a server side (receiving logs from mulitple other machines). 7 | 8 | It works on Redhat, Debian, FreeBSD, Suse and Arch OS families. 9 | 10 | In situations where there's already a default logger installed (e.g. a FreeBSD jail), an option exists to declare that rsyslog is the exclusive system logger. 11 | This provides a facility to add other loggers to a stoplist which helps, for example, to ensure that port 514 UDP is free for rsylog to use. 12 | 13 | .. note:: 14 | 15 | Contributions are welcome. 16 | 17 | Available states 18 | ================ 19 | 20 | .. contents:: 21 | :local: 22 | 23 | ``rsyslog`` 24 | ------------ 25 | 26 | Install and configure the ``rsyslog`` package and enable the service. See the `pillar.example` file for configuration. 27 | 28 | Changelog 29 | ================ 30 | April 2015: the default rules were moved from `rsyslog.conf` to `50-default.conf`. This file will be loaded if the `rsyslog:custom` pillar isnt set. However, if your `rsyslog:custom` specifies other files to include, you must add the `50-default.conf` as well! 31 | -------------------------------------------------------------------------------- /rsyslog/init.sls: -------------------------------------------------------------------------------- 1 | {% from "rsyslog/map.jinja" import rsyslog with context %} 2 | 3 | {% if rsyslog.exclusive %} 4 | {% for logger in rsyslog.stoplist %} 5 | stoplogger_{{logger}}: 6 | service.dead: 7 | - enable: False 8 | - name: {{ logger }} 9 | - require_in: 10 | - service: {{ rsyslog.service }} 11 | {% endfor %} 12 | {% endif %} 13 | 14 | rsyslog: 15 | pkg.installed: 16 | - name: {{ rsyslog.package }} 17 | file.managed: 18 | - name: {{ rsyslog.config }} 19 | - template: jinja 20 | - source: {{ rsyslog.custom_config_template }} 21 | - context: 22 | config: {{ rsyslog|json }} 23 | service.running: 24 | - enable: True 25 | - name: {{ rsyslog.service }} 26 | - require: 27 | - pkg: {{ rsyslog.package }} 28 | - watch: 29 | - file: {{ rsyslog.config }} 30 | 31 | workdirectory: 32 | file.directory: 33 | - name: {{ rsyslog.workdirectory }} 34 | - user: {{ rsyslog.runuser }} 35 | - group: {{ rsyslog.rungroup }} 36 | - mode: 755 37 | - makedirs: True 38 | 39 | {% for filename in salt['pillar.get']('rsyslog:custom', ["50-default.conf"]) %} 40 | {% set basename = filename.split('/')|last %} 41 | rsyslog_custom_{{basename}}: 42 | file.managed: 43 | - name: {{ rsyslog.custom_config_path }}/{{ basename|replace(".jinja", "") }} 44 | {% if basename != filename %} 45 | - source: {{ filename }} 46 | {% else %} 47 | - source: salt://rsyslog/files/{{ filename }} 48 | {% endif %} 49 | {% if filename.endswith('.jinja') %} 50 | - template: jinja 51 | {% endif %} 52 | - user: {{ rsyslog.runuser }} 53 | - group: {{ rsyslog.rungroup }} 54 | - dirmode: 755 55 | - makedirs: True 56 | - watch_in: 57 | - service: {{ rsyslog.service }} 58 | {% endfor %} 59 | 60 | {% if 'modules' in rsyslog %} 61 | {% for module in rsyslog.modules %} 62 | rsyslog-{{ module }}: 63 | pkg.installed: 64 | - name: {{ rsyslog.module_packages.get(module) }} 65 | {% endfor %} 66 | {% endif %} 67 | -------------------------------------------------------------------------------- /rsyslog/files/50-default.conf: -------------------------------------------------------------------------------- 1 | # Default rules for rsyslog. 2 | # 3 | # For more information see rsyslog.conf(5) and /etc/rsyslog.conf 4 | 5 | # 6 | # First some standard log files. Log by facility. 7 | # 8 | auth,authpriv.* /var/log/auth.log 9 | *.*;auth,authpriv.none -/var/log/syslog 10 | #cron.* /var/log/cron.log 11 | #daemon.* -/var/log/daemon.log 12 | kern.* -/var/log/kern.log 13 | #lpr.* -/var/log/lpr.log 14 | mail.* -/var/log/mail.log 15 | #user.* -/var/log/user.log 16 | 17 | # 18 | # Logging for the mail system. Split it up so that 19 | # it is easy to write scripts to parse these files. 20 | # 21 | #mail.info -/var/log/mail.info 22 | #mail.warn -/var/log/mail.warn 23 | mail.err /var/log/mail.err 24 | 25 | # 26 | # Logging for INN news system. 27 | # 28 | news.crit /var/log/news/news.crit 29 | news.err /var/log/news/news.err 30 | news.notice -/var/log/news/news.notice 31 | 32 | # 33 | # Some "catch-all" log files. 34 | # 35 | #*.=debug;\ 36 | # auth,authpriv.none;\ 37 | # news.none;mail.none -/var/log/debug 38 | #*.=info;*.=notice;*.=warn;\ 39 | # auth,authpriv.none;\ 40 | # cron,daemon.none;\ 41 | # mail,news.none -/var/log/messages 42 | 43 | # 44 | # Emergencies are sent to everybody logged in. 45 | # 46 | *.emerg :omusrmsg:* 47 | 48 | # 49 | # I like to have messages displayed on the console, but only on a virtual 50 | # console I usually leave idle. 51 | # 52 | #daemon,mail.*;\ 53 | # news.=crit;news.=err;news.=notice;\ 54 | # *.=debug;*.=info;\ 55 | # *.=notice;*.=warn /dev/tty8 56 | 57 | # The named pipe /dev/xconsole is for the `xconsole' utility. To use it, 58 | # you must invoke `xconsole' with the `-file' option: 59 | # 60 | # $ xconsole -file /dev/xconsole [...] 61 | # 62 | # NOTE: adjust the list below, or you'll go crazy if you have a reasonably 63 | # busy site.. 64 | # 65 | daemon.*;mail.*;\ 66 | news.err;\ 67 | *.=debug;*.=info;\ 68 | *.=notice;*.=warn |/dev/console 69 | -------------------------------------------------------------------------------- /pillar.example: -------------------------------------------------------------------------------- 1 | rsyslog: 2 | target: 192.168.100.1 # omit if you do not want to forward logs 3 | # NOTE: be careful using target and listen on 4 | # the same server, you can cause a loop 5 | targets: # If you want to use more than one target, 6 | - log1.example.com # you can specify targets as a list. 7 | - log2.example.com # The single 'target' directive takes precendence over this however. 8 | 9 | protocol: udp # protocol to use to send to target 10 | listentcp: true # omit to disable listening on tcp port 11 | listentcpprt: 10514 # specify tcp listen port ($InputTCPServerRun) 12 | listenudp: true # omit to disable listening on udp port 13 | impstats: false # impstats set to true to enable impstats 14 | impstatsinterval: 600 # impstats interval to gather stats 15 | impstatsseverity: 6 # The numerical syslog severity code to be used for generated messages. Default is 6(info) 16 | impstatsresetcounters: 'on' # When set to “on”, counters are automatically reset after they are emitted 17 | impstatslogsyslog: 'on' # This is a boolean setting specifying if data should be sent to the usual syslog stream 18 | impstatsformat: legacy # Impstats format. Legacy is default but other options can be used. 19 | impstatssyslogrule: 'syslog.=debug /var/log/rsyslog-stats' # Impstats log rule. 20 | imkllog: true # omit to log kernel messages 21 | imjournal: false # omit to log journal messages 22 | immark: false # enable/disable mark messages support 23 | markmessageperiod: 1200 # Specifies when mark messages are written (seconds) 24 | logbasepath: /mnt/logs # base path for logs to be saved to 25 | # also enables logging per host, per day 26 | fileowner: root # set the owner of the logfiles 27 | filegroup: root # set the group of the logfiles 28 | filemode: '0640' # mode for created log files 29 | dirmode: '0755' # mode for dirs created in log file paths 30 | template: 'RSYSLOG_FileFormat' # file default template 31 | 32 | custom: # Put custom config files in /etc/rsyslog.d/. 33 | - 001_custom1.conf # Files must be reachable from path `salt://rsyslog/` 34 | - salt://some_other/002_custom2.conf # Or with an absolute path. 35 | # The default is to include `salt://rsyslog/files/50-default.conf`. 36 | # If you change the custom conf dict, make sure to 37 | # include the 50-default.conf as well if needed. 38 | 39 | modules: # Install additional rsyslog module packages 40 | - gnutls # Currently supported are these modules, which are present in 41 | - elasticsearch # Debian and CentOS. 42 | - gssapi 43 | - kafka 44 | - mysql 45 | - pgsql 46 | - relp 47 | -------------------------------------------------------------------------------- /rsyslog/templates/rsyslog.conf.jinja: -------------------------------------------------------------------------------- 1 | # /etc/rsyslog.conf Configuration file for rsyslog. 2 | # 3 | # For more information see 4 | # /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html 5 | 6 | 7 | ################# 8 | #### MODULES #### 9 | ################# 10 | 11 | {% if config.impstats|default(false) -%} 12 | # Enable impstats.This module MUST be loaded right at the top of rsyslog.conf, otherwise stats may not get turned on in all places. 13 | module( 14 | load="impstats" 15 | interval="{{ config.impstatsinterval|default('600') }}" 16 | severity="{{ config.impstatsseverity|default('6') }}" 17 | resetCounters="{{ config.impstatsresetcounters|default('off') }}" 18 | log.syslog="{{ config.impstatslogsyslog|default('on') }}" 19 | format="{{ config.impstatsformat|default('legacy') }}" 20 | ) 21 | {% if config.impstatslogsyslog|default('off') == 'on' %} 22 | {{ config.impstatssyslogrule|default('syslog.=debug /var/log/rsyslog-stats') }} 23 | {%- endif %} 24 | {%- endif %} 25 | $ModLoad imuxsock # provides support for local system logging 26 | {% if config.imkllog|default(true) -%} 27 | $ModLoad imklog # provides kernel logging support (previously done by rklogd) 28 | {%- endif %} 29 | {% if config.imjournal|default(false) -%} 30 | $ModLoad imjournal # provides access to the systemd journal 31 | {%- endif %} 32 | {% if config.immark|default(false) -%} 33 | $ModLoad immark # provides --MARK-- message capability 34 | $MarkMessagePeriod {{ config.markmessageperiod|default('3600') }} 35 | {%- else %} 36 | #$ModLoad immark # provides --MARK-- message capability 37 | {%- endif %} 38 | 39 | {% if config.listenudp|default(false) -%} 40 | # provides UDP syslog reception 41 | $ModLoad imudp 42 | $UDPServerRun 514 43 | {%- endif %} 44 | 45 | {% if config.listentcp|default(false) -%} 46 | # provides TCP syslog reception 47 | $ModLoad imtcp 48 | $InputTCPServerRun {{ config.listentcpprt|default('514') }} 49 | {%- endif %} 50 | 51 | ########################### 52 | #### GLOBAL DIRECTIVES #### 53 | ########################### 54 | 55 | {% if config.imjournal|default(false) -%} 56 | # Where to place auxiliary files 57 | $WorkDirectory {{ config.get('workdirectory', '/var/spool/rsyslog') }} 58 | {%- endif %} 59 | 60 | # 61 | # Use traditional timestamp format. 62 | # To enable high precision timestamps, comment out the following line. 63 | # 64 | $ActionFileDefaultTemplate {{ config.get('template', 'RSYSLOG_TraditionalFileFormat') }} 65 | 66 | {% if config.repeated_msg_reduction|default(false) -%} 67 | # Filter duplicated messages 68 | $RepeatedMsgReduction {{config.get('repeated_msg_reduction', 'off') }} 69 | {%- endif %} 70 | 71 | # 72 | # Set the default permissions for all log files. 73 | # 74 | $FileOwner {{ config.get('fileowner', 'root') }} 75 | $FileGroup {{ config.get('filegroup', 'adm') }} 76 | $FileCreateMode {{ config.get('filemode', '0640') }} 77 | $DirCreateMode {{ config.get('dirmode', '0755') }} 78 | $Umask 0022 79 | {% if config.priv_drop_to_user|default(false) -%} 80 | $PrivDropToUser {{ config.get('priv_drop_to_user', config.get('fileowner', 'root'))}} 81 | {%- endif %} 82 | {% if config.priv_drop_to_group|default(false) -%} 83 | $PrivDropToGroup {{ config.get('priv_drop_to_group', config.get('filegroup', 'adm'))}} 84 | {%- endif %} 85 | 86 | # 87 | # Include all config files in /etc/rsyslog.d/ 88 | # 89 | $IncludeConfig /etc/rsyslog.d/*.conf 90 | 91 | {% if config.target|default(false) %} 92 | {% if config.protocol|default('udp') == 'tcp' %} 93 | *.* @@{{ config.target }} 94 | {% else %} 95 | *.* @{{ config.target }} 96 | {% endif %} 97 | {% else %} 98 | {% for target in config.get('targets', []) %} 99 | $ActionQueueType LinkedList 100 | $ActionQueueFileName {{ target }} 101 | $ActionResumeRetryCount -1 102 | $ActionQueueSaveOnShutdown on 103 | {% if config.protocol|default('udp') == 'tcp' %} 104 | *.* @@{{ target }} 105 | {% else %} 106 | *.* @{{ target }} 107 | {% endif %} 108 | {% endfor %} 109 | {% endif %} 110 | 111 | {% if config.logbasepath|default(false) %} 112 | $template DailyPerHostLogs,"{{ config.logbasepath }}/%HOSTNAME%-%FROMHOST-IP%/%$YEAR%/%$MONTH%/%$DAY%.log" 113 | *.* -?DailyPerHostLogs 114 | {% endif %} 115 | 116 | {% if config.imjournal|default(false) -%} 117 | # Turn off message reception via local log socket; 118 | # local messages are retrieved through imjournal now. 119 | $OmitLocalLogging on 120 | 121 | # File to store the position in the journal 122 | $IMJournalStateFile imjournal.state 123 | # If there is no saved state yet, don't read in the whole bulk of messages. 124 | # # This means some of the older messages won't be collected by rsyslog, 125 | # # but it also prevents a potential huge spike in resource utilization. 126 | # $IMJournalIgnorePreviousMessages on 127 | {%- endif %} 128 | --------------------------------------------------------------------------------