YAML Configuration Architecture#
YAML config is a thin translation front-end: yamlconf.c converts .yaml files into the same nvlst/cnfobj structures RainerScript produces, feeding them to the shared cnfDoObj() back-end.
Overview#
rsyslog’s YAML support is a first step toward a structured, operator-friendly
configuration format. The guiding principle was to minimise the change surface:
rather than building a parallel engine, runtime/yamlconf.c translates each YAML
block into the same intermediate representation (cnfobj + nvlst) that the
lex/bison RainerScript grammar already produces.
This confinement strategy means:
Parameter validation, type coercion, and error reporting reuse the existing
nvlstGetParams()layer — no duplication.Every module that works in RainerScript works identically in YAML.
Defects in the translation layer cannot silently corrupt the shared back-end.
The YAML-specific code is a single, self-contained file with no runtime presence after configuration loading completes.
This approach may be revisited if future requirements (richer error messages, schema validation, live reload) justify a deeper integration. Any such refactoring requires clear evidence of user benefit that outweighs the additional maintenance surface.
Processing Pipeline#
Legend: Yellow — input files/text. Blue — parsing stages. Red — intermediate representation. Green — shared rsyslog core back-end.
Key Structures#
``nvlst`` (runtime/conf.h) is an ordered linked list of (name, value)
pairs — rsyslog’s canonical intermediate representation for configuration
parameters. Both the RainerScript grammar and yamlconf.c produce nvlst
chains; nvlstGetParams() is format-agnostic.
``cnfobj`` wraps an nvlst with a type tag (CNFOBJ_GLOBAL,
CNFOBJ_ACTION, CNFOBJ_INPUT, etc.). One cnfobj is constructed per
top-level YAML block.
``cnfDoObj()`` (rsconf.c) receives a cnfobj, reads the type tag, and
calls the same module initialisation function that RainerScript would have called.
Ruleset Script Handling#
YAML offers three ways to express ruleset logic; all three end up in the same
RainerScript execution tree via cnfAddConfigBuffer():
``script:`` — raw RainerScript block, passed through verbatim.
``statements:`` — YAML-native
if / set / unset / call / foreachmaps;yamlconf.csynthesises them into a RainerScript string.``filter:`` + ``actions:`` — one-level shortcut; synthesised into an
if … then { … }fragment.
No separate interpreter exists. The lex/bison parser handles all ruleset logic.
Parity and Maintenance#
Because both formats share the back-end, parity is largely automatic:
New global parameters — no YAML change needed;
nvlstGetParams()picks them up automatically.New top-level statement types — requires a
parse_*function inyamlconf.cand an entry in the dispatch table.Renamed/removed parameters — update
yamlconf.cif it special-cases the name, and update the user docs for both formats.
See runtime/AGENTS.md: “Any change to config objects, statement types,
template modifiers, or global parameters must be reflected here as well as in
``grammar/``.”
See Also#
System Architecture — rsyslog microkernel architecture overview
Design Decisions — libyaml library choice rationale
The rsyslog config data model — rsyslog configuration object model
YAML Configuration Format — user-facing YAML reference
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.