YAML Configuration Format

rsyslog supports configuration via YAML files as an alternative to RainerScript. The two formats are equivalent: every YAML configuration key maps directly to a RainerScript parameter of the same name, so all per-module documentation remains applicable unchanged.

Activation

rsyslog automatically selects the YAML loader whenever the configuration file name ends in .yaml or .yml. No special flag or directive is required:

rsyslogd -f /etc/rsyslog.yaml

The same detection applies to files pulled in via include() (from a RainerScript config) or the include: section of a YAML config. It is therefore valid to mix formats: a YAML main config may include .conf RainerScript fragments and vice versa.

Note

YAML configuration support requires rsyslog to have been compiled with libyaml (yaml-0.1). If libyaml is absent at build time the daemon will print an error and refuse to load a .yaml / .yml file. Install the libyaml-dev (Debian/Ubuntu) or libyaml-devel (RHEL/Fedora) package before compiling.

Schema Overview

A YAML config file is a single YAML mapping (dictionary) whose top-level keys correspond to rsyslog configuration object types:

version: 2          # optional, informational only

global:   { ... }
modules:  [ ... ]
inputs:   [ ... ]
templates: [ ... ]
rulesets: [ ... ]
mainqueue: { ... }
include:  [ ... ]
parsers:  [ ... ]
lookup_tables: [ ... ]
dyn_stats: [ ... ]
perctile_stats: [ ... ]   # note: spelt "perctile" — matches rsyslog internal naming
ratelimits: [ ... ]
timezones: [ ... ]

All section names are case-sensitive. Unknown top-level keys are logged as errors and ignored.

Singleton Sections

global and mainqueue are singleton sections: their value is a mapping of parameter names to values.

global:
  workdirectory: "/var/spool/rsyslog"
  maxmessagesize: 8192
  defaultnetstreamdriver: "gtls"
  privdrop.user.name: "syslog"
  privdrop.group.name: "syslog"

mainqueue:
  type: linkedlist
  size: 100000
  dequeuebatchsize: 1024

Parameter names are identical to their RainerScript counterparts (see global configuration parameters and queue parameters).

Sequence Sections

modules, inputs, templates, rulesets, parsers, lookup_tables, dyn_stats, perctile_stats, ratelimits, and timezones are sequences: each list element is a mapping that describes one object of that type.

modules

Each item must contain a load key (the module name). Additional keys supply module-level parameters:

modules:
  - load: imuxsock
  - load: imklog
  - load: imtcp
    threads: 2
  - load: imudp

inputs

Each item must contain a type key. All other keys are input instance parameters:

inputs:
  - type: imtcp
    port: "514"
    ruleset: main
  - type: imudp
    port: "514"
    ruleset: main
  - type: imfile
    file: "/var/log/app/*.log"
    tag: "applog"
    ruleset: main

templates

Four template types are supported:

String template — the most common type; a format string with %PROPERTY% placeholders:

templates:
  - name: myFormat
    type: string
    string: "%HOSTNAME% %syslogfacility-text%.%syslogseverity-text% %msg%\n"
  - name: filePerHost     # use with omfile dynafile: filePerHost
    type: string
    string: "/var/log/hosts/%HOSTNAME%.log"

Subtree template — serialises a JSON sub-tree of the message object:

templates:
  - name: jsonApp
    type: subtree
    subtree: "$!app"

List template — assembles output from an explicit sequence of property and constant items. Each element maps to a property() or constant() call; all parameters accepted by those RainerScript functions can be used:

templates:
  - name: listFmt
    type: list
    elements:
      - property:
          name: timestamp
          dateformat: rfc3339
      - constant:
          value: " "
      - property:
          name: hostname
      - constant:
          value: " "
      - property:
          name: msg
          droplastlf: "on"
      - constant:
          value: "\n"

Plugin template — delegates formatting to an external string-generator plugin (the type="plugin" form from RainerScript):

templates:
  - name: myPlugin
    type: plugin
    plugin: strgen_addprimary

rulesets

Ruleset items specify a name and may carry queue parameters. Rule logic is expressed in one of three ways:

  1. Structured shortcut (filter: + actions:) — for simple priority- or property-based routing without scripting. See Structured Filter Shortcut below.

  2. YAML-native statements (statements: key) — for conditional routing, if/then/else, call, call_indirect, foreach, stop, unset, variable assignment — without writing any RainerScript syntax. See YAML-Native Statements below. Recommended for most configs.

  3. Inline RainerScript (script: key) — escape hatch for complex metaprogramming or advanced RainerScript not covered by statements:. See Scripting below.

filter: + actions: example:

rulesets:
  - name: main
    filter: "*.*"
    actions:
      - type: omfile
        file: "/var/log/syslog"

  - name: errors
    filter: "*.err"
    actions:
      - type: omfile
        file: "/var/log/errors.log"
      - type: omfwd
        target: "logserver.example.com"
        port: "514"
        protocol: "tcp"

  # Property filter — starts with ':'
  - name: tag_filter
    filter: ":syslogtag, startswith, \"myapp\""
    actions:
      - type: omfile
        file: "/var/log/myapp.log"

  # No filter — unconditional routing
  - name: archive
    actions:
      - type: omfile
        file: "/var/log/archive.log"

script: example (complex logic):

rulesets:
  - name: errors
    script: |
      if $syslogseverity <= 3 then {
        action(type="omfile" file="/var/log/errors.log")
      }
      stop

parsers

Custom parser chains (loaded via lmregdups, pmrfc3164, etc.). Each item must contain a name key and the parser-specific parameters:

parsers:
  - name: pmrfc3164.default
    force.tagEndingByColon: "on"

lookup_tables

In-memory lookup tables loaded from JSON files. The name and filename keys are required.

lookup_tables:
  - name: hostmap
    filename: "/etc/rsyslog.d/hostmap.json"
    reloadOnHUP: "on"

timezones

Named timezone definitions for use in template date formatting:

timezones:
  - id: "CET"
    offset: "+01:00"

dyn_stats, perctile_stats, ratelimits

These advanced sections follow the same key=value mapping pattern. Refer to the respective module documentation for available parameters. Example:

dyn_stats:
  - name: "msg_rate"
    resetsIntervals: 60

ratelimits:
  - name: "input_rl"
    interval: 5
    burst: 1000

Arrays

Parameters that accept a list of values are expressed as YAML sequences:

global:
  environment:
    - "TZ=UTC"
    - "LC_ALL=C"

Including Other Files

The include: section accepts a sequence of items. Each item must have a path key (which may contain shell globs) and an optional optional flag:

include:
  - path: "/etc/rsyslog.d/*.yaml"
    optional: "on"
  - path: "/etc/rsyslog.d/*.conf"
    optional: "on"
  - path: "/etc/rsyslog.d/tls.conf"

If optional is on (or yes or 1) a missing file or empty glob result is not an error. Files with a .yaml or .yml extension are loaded by the YAML loader; all other files are loaded by the RainerScript parser.

Note

Include ordering with mixed file types: within one include: list, .yaml files are always loaded before .conf files, regardless of their order in the list. This is an architectural constraint — YAML sub-files are processed immediately and recursively, while .conf files are deferred to the RainerScript flex-buffer stack. If strict ordering between .yaml and .conf fragments matters, use separate include: sections or consolidate to one file type. Multiple .conf entries within the same list ARE processed in document order.

Structured Filter Shortcut

For common routing patterns (match by severity or message property, then write to one or more outputs) you do not need any RainerScript. Use filter: and actions: directly on a ruleset:

filter:

Optional string. Two forms are recognised:

  • Priority filter — standard syslog selector syntax (e.g. *.info, kern.warn, auth,authpriv.*).

  • Property filter — starts with : (e.g. :msg, contains, "error").

If filter: is absent, all messages match (unconditional routing).

actions:

YAML sequence. Each item maps directly to a action() call; the type key names the output module and all remaining keys are module-specific parameters. Multiple actions are chained in order.

rulesets:
  # Route *.info to syslog; *.err also to a dedicated error file
  - name: main
    filter: "*.info"
    actions:
      - type: omfile
        file: "/var/log/syslog"

  - name: errors
    filter: "*.err"
    actions:
      - type: omfile
        file: "/var/log/errors.log"
      - type: omfwd
        target: "logserver.example.com"
        port: "514"
        protocol: "tcp"

  # Property filter
  - name: myapp
    filter: ":syslogtag, startswith, \"myapp\""
    actions:
      - type: omfile
        file: "/var/log/myapp.log"

Note

filter: and actions: are mutually exclusive with script: and statements:. If you need conditionals, loops, set, call, or stop, use statements: (recommended) or script: instead.

YAML-Native Statements

The statements: key is the recommended way to express conditional routing and control flow without writing raw RainerScript. Each item in the sequence is a YAML mapping that represents one statement. Only the filter expression inside if: remains as a RainerScript expression string — all structural elements and action parameters are expressed as YAML.

statements: is mutually exclusive with script:, filter:, and actions:.

If / action (single action shorthand)

rulesets:
  - name: main
    statements:
      - if: '$msg contains "error"'
        action:
          type: omfile
          file: "/var/log/errors.log"
        else:              # optional
          - stop: true

If / then / else (multiple statements per branch)

rulesets:
  - name: main
    statements:
      - if: '$syslogseverity <= 3'
        then:
          - type: omfile
            file: "/var/log/critical.log"
          - type: omfwd
            target: "logserver.example.com"
            port: "514"
            protocol: "tcp"
        else:
          - type: omfile
            file: "/var/log/messages"

Control flow: stop, continue, call

- stop: true        # stop processing this message
- continue: true    # continue (no-op, rarely needed)
- call: other_rs    # call another ruleset by name

Variable assignment

- set:
    var: "$.nbr"
    expr: 'field($msg, 58, 2)'

Supported statement types

Type

YAML form

Action

{type: module, param: val, ...} — unconditional

If/action

{if: expr, action: {type: ..., ...}, else: [...]}

If/then

{if: expr, then: [...], else: [...]}

Stop

{stop: true}

Continue

{continue: true}

Call

{call: rulesetname}

Set

{set: {var: "$.x", expr: "rainerscript-expression"}}

Unset

{unset: "$.x"}

call_indirect

{call_indirect: "$.varname"}

foreach

{foreach: {var: "$.i", in: "$!arr", do: [...]}}

reload_lookup_table

{reload_lookup_table: {table: name, stub_value: val}}

foreach iterates over a JSON array. The do: value is a sequence of statement items using the same syntax as statements:. Example:

statements:
  - foreach:
      var: "$.item"
      in: "$!items"
      do:
        - type: omfile
          file: /var/log/items.log
          template: outfmt

Scripting

RainerScript filter expressions and statement types (if/then/else, set, unset, foreach, stop, call, legacy PRI-filters, property-filters, action()) are all available inside a script: block. The value is an ordinary YAML scalar (use a YAML block scalar for multi-line content):

rulesets:
  - name: main
    script: |
      # Route by severity
      if $syslogseverity <= 3 then {
        action(type="omfile" file="/var/log/critical.log")
        action(type="omfwd"  target="logserver.example.com" port="514"
                             protocol="tcp")
      }

      # Discard noisy debug messages
      if $syslogseverity == 7 then stop

      # Default sink
      action(type="omfile" file="/var/log/messages")

The script content is passed verbatim to the RainerScript lexer/parser, so anything that is valid RainerScript in a ruleset() {} body is valid here. Inline actions defined in the script: block do not need to be listed separately under an inputs: or actions: section.

Tip

For simple routing (one filter, one or more actions, no branching) use the filter: + actions: shortcut described in Structured Filter Shortcut. For conditional routing, variable assignments, call, foreach, stop, and reload_lookup_table use the statements: block described in YAML-Native Statements. Recommended for most configs. Reserve script: only for advanced RainerScript that cannot be expressed through statements:, such as complex nested legacy priority/property filters or inline call_direct patterns.

Complete Example

The following is a near-complete rsyslog YAML configuration equivalent to a typical /etc/rsyslog.conf:

version: 2

global:
  workdirectory: "/var/spool/rsyslog"
  maxmessagesize: 8192
  privdrop.user.name: "syslog"
  privdrop.group.name: "adm"

modules:
  - load: imuxsock
  - load: imklog
  - load: imtcp
    threads: 2

inputs:
  - type: imtcp
    port: "514"
    ruleset: main
  - type: imuxsock

templates:
  - name: fileFormat
    type: string
    string: "%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%\n"

mainqueue:
  type: linkedlist
  size: 100000

rulesets:
  - name: main
    filter: "auth,authpriv.*"
    actions:
      - type: omfile
        file: "/var/log/auth.log"

  - name: main_all
    filter: "*.*;auth,authpriv.none"
    actions:
      - type: omfile
        file: "/var/log/syslog"

  - name: kern
    filter: "kern.*"
    actions:
      - type: omfile
        file: "/var/log/kern.log"

  - name: emerg
    filter: "*.emerg"
    actions:
      - type: omusrmsg
        users: "*"

include:
  - path: "/etc/rsyslog.d/*.yaml"
    optional: "on"
  - path: "/etc/rsyslog.d/*.conf"
    optional: "on"

Relationship to RainerScript

YAML configuration is a thin front-end over the same internal machinery that RainerScript uses. In particular:

  • Parameter names are identical; all per-module parameter documentation applies without change.

  • Type coercion (integers, sizes, binary flags, UIDs, …) is performed by the same nvlstGetParams() layer after YAML parsing.

  • Unknown parameter names produce the same “unused parameter” error regardless of which format was used.

  • Template, ruleset, and lookup-table names are shared; a YAML-defined ruleset can be referenced from a RainerScript action().

Limitations (current implementation)

  • Nested YAML mappings inside parameter values are not supported. Use a YAML scalar or sequence.

  • filter: + actions: support one flat filter level. For nested if/then/else chains use statements: (recommended) or script:.

  • version: is accepted but not enforced; it is reserved for future schema evolution.

  • Within a single include: list, .yaml files are always processed before .conf files regardless of document order (see Including Other Files).

See Also


Support: rsyslog Assistant | GitHub Discussions | GitHub Issues: rsyslog source project

Contributing: Source & docs: rsyslog source project

© 2008–2026 Rainer Gerhards and others. Licensed under the Apache License 2.0.