Rsyslog: Rainerscript vs. Old-Style/Legacy Configuration

Please see Learning Rsyslog for the introduction and index to this series of blog posts about Rsyslog.

Syslog is a very old idea. Rsyslog is less old, but still has a 16 year history (forked from sysklogd in 2004).

About ten years ago(?), Rainer Gerhards (the author of Rsyslog) decided Rsyslog needed a more powerful way of handling logs, so he created "Rainerscript." According to the documentation: "RainerScript is a scripting language specifically designed and well-suited for processing network events and configuring event processors." This was fully implemented with version 6 (~2010 - I'm going based on Gerhards' statement of the version number, and on the Rsyslog git tags which are a bit shaky on the exact release date). But he didn't invalidate the old syntax, and has made no move to do so.

As examples of the two syntaxes, these two do more or less the same thing (these are only approximately correct and not guaranteed to work):

# Legacy format:
:syslogtag, startswith, "powerevents" /var/log/powerevents.log
# Approximately equivalent Rainerscript:
if ( $syslogtag contains "powerevents" )
then {
        type = "omfile"
        dirCreateMode = "0700"
        FileCreateMode = "0600"
        File = "/var/log/powerevents.log"

You might ask: "why would I use that second version when it's less concise and not even more readable?" And I suspect that's why he's never obsoleted the old format - and also presumably compatibility with other syslog variants. If all you need is basic logging, the legacy format is effective, concise, and easy. But it's not very flexible, whereas Rainerscript is. You'd use Rainerscript when you want to throw in a Template=power-events - templates offer a powerful way to rewrite the log message (and that's far from the only option Rainerscript offers). But learning Rainerscript is HARD: it's exceedingly difficult to find examples online. Gerhards and his company, Adiscon, have a strong presence on the internet and a huge amount of documentation relating to Rsyslog. Some of this documentation is legacy, some of it is Rainerscript - and some of it is a mix of both, because you can do that. Yes, you can mix legacy syntax with Rainerscript. This makes figuring out what will work nightmarish as there are not one, but two languages in which your Rsyslog configuration can be written, and you'll need to know both, and then you'll have to experiment to find out how you can mix the two because it's NOT obvious.

Which brings me to the single best page I've found for learning Rsyslog configuration:

Read this. Then read it slowly, three more times. Yes, it was originally in Russian and the translation isn't great, but it addresses many, many use-cases and talks about why and when you should use each of the languages and how you can mix them together. I'm still absorbing it, but it's the best intro to Rsyslog configuration I've ever seen (and I've spent two solid weeks searching for that holy grail). The problem is that Rainer Gerhards (the author of Rsyslog) has created technical documentation for a language, and has exhaustively detailed the options ... but hasn't assembled it into an introduction or any kind of practical use-cases. The only place I disagree with Selivan is on the choice of RELP over TCP for message delivery ... and I think their authority carries more weight than mine so maybe you should listen to them.

One sentence that happily stuck in my head (not just for its bad English) was "semicolon is forbidden somewhere, and strictly required in other places(second happes less often)." I remembered this, and when I found that every time I used the Rainerscript set ... command Rsyslog told me the line after it was bad syntax, I finally registered that Selivan always has a semicolon at the end of every set line ... You'll notice the examples above have no semicolons, this is an uncommon occurrence.

If you can avoid Rainerscript, do so. It's not that it's a bad language, but it's an extension that's hard to learn and complex, and for simple logging there's a far easier solution.