Changelog for 7.2.6 (v7-stable)
Version 7.2.6 [v7-stable] 2013-03-05
- slightly improved config parser error messages when invalid escapes happen
- bugfix: include files got included in the wrong order
closes: http://bugzilla.adiscon.com/show_bug.cgi?id=411
This happens if an $IncludeConfig directive was done on multiple files (e.g. the distro default of $IncludeConfig /etc/rsyslog.d/*.conf). In that case, the order of include file processing is reversed, which could lead to all sorts of problems.
Thanks to Nathan Stratton Treadway for his great analysis of the problem, which made bug fixing really easy. - bugfix: omelasticsearch failed when authentication data was provided … at least in most cases it emitted an error message:
“snprintf failed when trying to build auth string”
Thanks to Joerg Heinemann for alerting us.
closes: http://bugzilla.adiscon.com/show_bug.cgi?id=404 - bugfix: some property-based filter were incorrectly parsed
This usually lead to a syntax error on startup and rsyslogd not actually starting up. The problem was the regex, which did not care for double quote characters to follow in the action part – unfortunately something that can frequently happen with v6+ format. An example:
:programname, isequal, “as” {action(type=”omfile” …) }
Here, the part
:programname, isequal, “as” {action(type=”omfile”
was treated as the property filter, and the rest as action part. Obviously, this did not work out. Unfortunately, such situations usually resulted in very hard to understand error messages.
Log normalization for different formats
In this article we want to show you a very functional use-case. We want to use rsyslog in conjunction with log normalization to bring login events from several different log sources together into a readable format and get rid of all the useless information which we don’t need. The log sources will be windows, linux and snare. All of them create log messages in a very different and often hard to read format. After bringing the information into a format that suits us well, we will finally write the essence of the log messages into a file. For this example we will also show two different output formats.
What do we need?
We need several things to be installed. In brackets we will show the version we used for this guide.
- rsyslog (7.3.6)
- liblognorm (0.3.5)
- libee (0.4.1)
- libestr (0.1.4)
These are the current versions at the date of this guide and need to be considered the minimum to be installed.
What do the logs look like?
The log messages come in different formats as already explained. We differentiate between 3 different formats.
1. Windows
The Adiscon products for Windows are able to send syslog messages directly in @cee/lumberjack format. That means, that the message consists of the default syslog header, which is followed by all the message properties being filled into the @cee representation format.
2. Linux
The log messages from Linux are in no specific format. Therefore we need to make some effort to get the data we want.
3. Snare
Snare logs are somewhat special again. They are somewhat like csv, but it uses tabs as a delimiter.
Installation
You should install libee, libestr and liblognorm before installing rsyslog. This is simply, because you won’t be able to install rsyslog the other way round. For rsyslog you need to know, that we will need several additional modules. These are:
- imtcp
- mmjsonparse
- mmnormalize
You configure should then look simliar to this:
./configure --prefix=/usr --enable-imtcp --enable-mmjsonparse --enable-mmnormalize
This will be sufficient, since we do not want to use any more extra or special features.
Please note: There are many ways to distribute rsyslog. But, make sure that the platform you build rsyslog on is the same platform as where it should be used. You cannot build rsyslog on CentOS and use it on Ubuntu. The differences between the platforms are just to big. The same applies to different versions of the same platform. When building on a older platform and using it on a newer version, this may work, but with restrictions. Whereas building on a newer version and using it on a older version will probably not work at all. So, if you build rsyslog from Source and want to use it on another machine, make sure the platform is the same.
The Configuration
The configuration is quite extensive. Thus we will show it in several parts. You can download the complete configuration here.
1. Rulebase
Before we begin with the rsyslog configuration, we will set up our rulebase for later. The rulebase is needed for mmnormalize and is a separate file. Our rulebase consists of two parts. The first part will handle the linux login messages and the second part is for the login messages sent by Snare. For more information about how to create a rulebase, visit this link.
# SSH and Sudo logins prefix=%rcvdat:date-rfc3164% %rcvdfrom:word% rule=: sudo: pam_unix(sudo:session): session %type:word% for user root by %user:char-to:(%(uid=%-:number%) rule=: sudo: pam_unix(sudo:session): session %type:word% for user %user:word% rule=: sshd[%-:number%]: pam_unix(sshd:session): session %type:word% for user %user:word% by (uid=%-:number%) rule=: sshd[%-:number%]: pam_unix(sshd:session): session %type:word% for user %user:word%
As you can see here, we have four rules. They are all lead by what is defined by the prefix. They represent the different log messages, but all variable parts that are needed for our final log will be put into properties. And in the case that some values might be different for each message, but not needed later, they will be parsed into a null property.
# Snare logins prefix= rule=:%rcvdat:date-rfc5424%#011%-:char-to:#%#011%-:char-to:#%#011%-:char-to:#%#011%-:char-to:#%#011%id:number%#011%-:char-to:#%#011%-:char-to:\%\%user:char-to:#%#011%-:char-to:#%#011%-:char-to:#%#011%rcvdfrom:char-to:#%#011%-:char-to:#%#011#011%-:char-to:#%#011%-:number%
The Snare format is way different than before. It is basically a tab delimited message format and rsyslog will by default replace all character codes into their ASCII values. Thus the message will look different and we have alle those character code replacements which are represented here as well. Most values from the Snare message are not needed and will be again filled into a null property. But the values we need, will be put into a real property, which we can use later.
2. Modules
In this first configuration step for the rsyslog configuration, we configure the modules that we will use.
module(load="imuxsock") module(load="imtcp") module(load="mmjsonparse") module(load="mmnormalize")
For this example we have basically four modules. Imuxsock will keep local logging activity, though we don’t really need it now. Imtcp will take care of syslog reception, so we can get the log messages via syslog from the various machines. Mmjsonparse and mmnormalize are message modification modules. The first will serve to parse messages in json format, the latter will parse messages according to a rulebase.
3. Inputs
Since we have three log sources, we will use three receivers.
input(type="imtcp" port="13514" Ruleset="windows") input(type="imtcp" port="13515" Ruleset="linux") input(type="imtcp" port="13516" Ruleset="snare")
As you can see, all three receivers are working on a different port and are directly bound to a ruleset. That way, there is no need to sort the messages per sender later with filters. The rulesets will be different for each receiver, since there are different needs of processing.
4. Templates
Now come the two format templates for the output.
template(name="csv" type="list") { property(name="$!usr!rcvdat" format="csv") constant(value=",") property(name="$!usr!rcvdfrom" format="csv") constant(value=",") property(name="$!usr!user" format="csv") constant(value=",") property(name="$!usr!type" format="csv") constant(value="\n") } template(name="cee" type="subtree" subtree="$!usr")
The first template is called csv. It will write our needed values in a comma-separated format. The second template is called cee. We can simply choose a subtree of values here which will automatically be put in @cee format. As you can see here, there is a huge difference concerning the effort needed for setting up the templates. In the end, the log messages look somewhat similar and will have the same values, but the format is different.
5. Rulesets
Now we get to the most interesting part. The rulesets. We will have three different rulesets which all serve their special purpose. As you will see later, we have 4 rulesets, indeed. But the forth ruleset holds the output and will be explained in step 6.
# Rulesets ruleset(name="windows") { action(type="mmjsonparse") if $parsesuccess == "OK" then { if $!id == "4634" then set $!usr!type = "logoff"; else if $!id == "4624" then set $!usr!type = "logon"; set $!usr!rcvdfrom = $!source; set $!usr!rcvdat = $timereported; set $!usr!user = $!TargetUserName; call output } }
The first ruleset will handle the log messages sent from Windows. Since they will be already sent in @cee-format, there is not much need for processing. First a action is called for all messages that run into this ruleset. Basically, the message will be parsed for their properties and values. If the message is successfully parsed (which only happens if the format is correct) then we go on and fill some user-defined variables in a special subtree of values. As you can see, it is checked whether the field “id” has a certain number and filles the variable $!usr!type with logoff or logon, which makes the final file more readable. After that we set a variable for the source system, timestamp of the log message and the user name that either logged on or off. Finally, we call our fourth ruleset for writing to disk.
ruleset(name="linux") { action(type="mmjsonparse") if $parsesuccess == "FAIL" then #/* only try normalization if non-lumberjack */ action(type="mmnormalize" rulebase="/etc/rulebase.rb" userawmsg="on") if $!user != "" then { if $!type == "opened" then set $!usr!type = "logon"; else if $!type == "closed" then set $!usr!type = "logoff"; set $!usr!rcvdfrom = $!rcvdfrom; set $!usr!rcvdat = $!rcvdat; set $!usr!user = $!user; call output } }
The second ruleset is for the linux log messages. Again we first check the log messages with mmjsonparse, but simply to verify that they are NOT in lumberjack format. If parsing the messages failed, which we want here, the log messages will be run through mmnormalize. This module uses the rulebase we created in the beginning and parses the messages according to this rulebase. If parsed successfully, processing continues. We check if the variable $!user isn’t empty. If that is the case, we set again our variables in the subtree and again we begin with the type of message (logon/logoff). Basically opened or closed would be sufficient enough for an experienced reader of logfiles, but we want to have all the log messages in the same format, thus this value will also be changed into logon and logoff. After that we alse set a variable for the source system, timestamp of the log message and the user name again. Finally, we call our fourth ruleset for writing to disk.
ruleset(name="snare") { action(type="mmjsonparse") if $parsesuccess == "FAIL" then #/* only try normalization if non-lumberjack */ action(type="mmnormalize" rulebase="/etc/rulebase.rb" userawmsg="on") if $!user != "" then { if $!id == "4634" then set $!usr!type = "logoff"; else if $!id == "4624" then set $!usr!type = "logon"; set $!usr!rcvdfrom = $!rcvdfrom; set $!usr!rcvdat = $!rcvdat; set $!usr!user = $!user; call output } }
The third ruleset is for the log messages from Snare. As with the linux messages, we check the messages if they are non-lumberjack by using mmjsonparse. And again we will use mmnormalize and the given rulebase to parse the messages. The rest is like for the linux messages. The only difference is, that we have basically Windows messages and need to use the Event ID to determine if the message represents a logon or a logoff. So you can consider this part as a combination from both rulesets. And of course finally, we call the ruleset for the output.
6. Output
As mentioned before, there is a fourth ruleset in the configuration, which just handles the output.
ruleset(name="outwriter") { action(type="omfile" file="/var/log/logfile.csv" template="csv") action(type="omfile" file="/var/log/logfile.cee" template="cee") }
This final ruleset provides us with our two outputs. They are both writing to disk. The only difference is, that they are using different templates as per the templates we defined earlier. So one file will hold the data in csv format whilst the other file holds the data in @cee format.
Final Thoughts
We have now our rsyslog configuration and our rulebase. The log messages will be parsed for the specific data we want from the different login log messages according to their specific format. And here is what the result might look like.
First in csv-format:
"Feb 5 14:19:00","win7fr","fr-win","logon" "Feb 5 14:19:00","win7fr","fr-win","logoff" "Jan 16 09:28:33","linuxvm","fr-lin","logon" "Jan 16 09:28:33","linuxvm","fr-lin","logoff"
And in @cee-format:
@cee: { "type": "logon", "rcvdfrom": "win7fr", "rcvdat": "Feb 5 14:19:00", "user": "fr-win" } @cee: { "type": "logoff", "rcvdfrom": "win7fr", "rcvdat": "Feb 5 14:19:00", "user": "fr-win" } @cee: { "type": "logon", "rcvdfrom": "linuxvm", "rcvdat": "Jan 16 09:28:33", "user": "fr-lin" } @cee: { "type": "logoff", "rcvdfrom": "linuxvm", "rcvdat": "Jan 16 09:28:33", "user": "fr-lin" }
So we now have two different formats, holding basically the same information. As you can see, we have now only the really necessary information of those log messages, namely the type of log message, the source system, the timestamp of this occurence and the user associated to this event.
Using MongoDB with rsyslog and LogAnalyzer
In this scenario we want to receive cee-formatted messages from a different system with rsyslog, store the messages with MongoDB and then display the stored messages with Adiscon LogAnalyzer. This is a very common use-case. Please read through the complete guide before starting.
We will split this guide in 3 main parts. These parts can consist of several steps.
- Setting up rsyslog
- Setting up MongoDB
- Setting up LogAnalyzer
This guide has been created with rsyslog 7.3.6 on ubuntu 12.04 LTS and Adiscon LogAnalyzer 3.6.3. All additional packages, services or applications where the latest version at that time.
Before you begin
Please note, there are many ways to distribute rsyslog. But, make sure that the platform you build rsyslog on is the same platform as where it should be used. You cannot build rsyslog on CentOS and use it on Ubuntu. The differences between the platforms are just to big. The same applies to different versions of the same platform. When building on a older platform and using it on a newer version, this may work, but with restrictions. Whereas building on a newer version and using it on a older version will probably not work at all. So, if you build rsyslog from Source and want to use it on another machine, make sure the platform is the same.
Step 1 – Setting up rsyslog
We need to setup rsyslog first. Not only do we need the core functionality, but several additional modules. For this case we want to receive the syslog messages via TCP, thus we need imtcp. For processing we need first mmjsonparse and ommongodb. Your configure should look like this.
./configure --prefix=/usr --enable-imtcp --enable-mmjsonparse --enable-ommongodb
The module mmjsonparse will be needed to verify and parse the @cee messages. Ommongodb will be used to write into the MongoDB. After the configure and installation, we can create our config. The config for our case looks like this:
module(load="imtcp") module(load="mmjsonparse") module(load="ommongodb")
input(type="imtcp" port="13514" Ruleset="mongodb")
template(name="mongodball" type="subtree" subtree="$!")
ruleset(name="mongodb") { action(type="mmjsonparse") if $parsesuccess == "OK" then { set $!time = $timestamp; set $!sys = $hostname; set $!procid = $syslogtag; set $!syslog_fac = $syslogfacility; set $!syslog_sever = $syslogpriority; set $!pid = $procid; action(type="ommongodb" server="127.0.0.1" db="logs" collection="syslog" template="mongodball") } }
As always, we first load the modules. The next part is the input. We need to receive tcp via imtcp. Please note, that we directly bind the input to a ruleset. The third part of the configuration is a template. We need it later when writing to MongoDB. Since we will automatically transform our @cee-message into json, we can use a subtree template. The template itself is basically the root of the subtree.
The last and most important part is the ruleset. Here all of our work is done. First, all messages are run through the mmjsonparse module. This will not only verify if we received a valid json message, but also transforms all the values into a json subtree. If the parsing was successful, we need to set several variables for the subtree. Information that is delivered in the syslog header will not be parsed into the subtree by mmjsonparse automatically. Thus we have to set subtree variables with the values of some default properties like timestamp, hostname and so on. After that we have basically all information from the complete syslog message in the subtree format. Finally a last action is needed. We need to write our log messages to MongoDB. In this example, MongoDB is installed on the same machine. We want to use the db “logs” and as collection we want to use “syslog”. And we use our subtree template to define the format that is written to MongoDB. Thus, all our parsed variables are stored separately. If we do not use this template, the @cee message gets written as it is into the msg field in MongoDB. But this is not what we want. We want all variables to be available separately.
That is basically it for rsyslog. You can now save the configuration and restart rsyslog. Though it won’t be able to be useful yet. We still need to install MongoDB.
Step 2 – Install MongoDB
Making a basic install for MongoDB is rather easy. Simply install the following packages:
mongodb mongodb-server php-pecl-mongo libmongo-client libglib2.0-dev
Please note, that package names may vary for different distributions.
After we have installed the packages, the MongoDB Server is already ready. By default, it is not secured by a user or password. Refer to the MongoDB manual for more information. Databases and collections (equivalent to tables) are created by rsyslog and do not need to be defined with the mongo shell. We will stick with the default setup to keep it simple.
Step 3 – Installing Adiscon LogAnalyzer
To run Adiscon LogAnalyzer, you need a webserver with PHP. The easiest way is to use apache2 and php5. To be able to access the MongoDB, we need to install an additional package. Run the following command
sudo pecl install mongo
You might need to install the package php-pear first, if it hasn’t been installed already with PHP.
After that, we need to put the following line into the file php.ini.
extension=mongo.so
Remember to restart your webserver after making changes to the php.ini. Without a lot of configuration, this should aready work.
We can now install Adiscon LogAnalyzer. Download the latest version from the Adiscon LogAnalyzer Download page and install it as it is described in the documentation.
The only difference we need to make is when setting up the log source in step 4.5. You need to set at least the following as shown in the screenshot:

Source Type: MongoDB Native Table Type: MongoDB Database Name: logs Database Tablename: syslog Database user: <clear this field>
The User and Password is of course needed, if you set it in your MongoDB setup.
After you have finished the installation of Adiscon LogAnalyzer, you should now be seeing the LogAnalyzer overview and the log messages in a table view (if you have already stored them in MongoDB). Now if you click on a specific message, you get to see the detail view of the log message.
Click on the picture for a bigger size
As you can see, you get a list of dynamic fields. These fields where already sent in @cee format from the original source and were parsed by rsyslog and mmjsonparse and finally they were automatically filled into the MongoDB.
With this setup, you are independent of a fixed database structure. Fields are inserted dynamically into the database as they are available and they are dynamically display by Adiscon LogAnalyzer as well.
Rsyslog Windows Agent 2.0 Released
Adiscon is proud to announce the 2.0 release of RSyslog Windows Agent.
This new major release adds full Continue reading “Rsyslog Windows Agent 2.0 Released”
How can I check the config?
We have often seen the case, that someone has rsyslog running and makes changes to the configuration. And usually, after making the changes, rsyslog gets restarted, but the changed config is invalid. rsyslog has a function to check the configuration for validity. This can be done very easily by invoking this command:
rsyslogd -N1
(Note that rsyslogd may not be in your search path – then it usually is found in /sbin/rsyslogd)
This tells rsyslog to do a config check. It does NOT run in regular mode, but just check configuration file correctness. This option is meant to verify a config file. To do so, run rsyslogd interactively in foreground, specifying -f <config-file> and -N level. The level argument modifies behaviour. Currently, 0 is the same as not specifying the -N option at all (so this makes limited sense) and 1 actually activates the code.
This configuration check will only check the configuration for integrity like syntax. Additionaly, the modules will be loaded to make sure that they work properly. On the downside, since the engine will not be loaded, errors with permissions or alike cannot be checked. These will occur only when running rsyslog normally.
The verdict for this option is, that it is quite useful for a first check if the changes were correct, without running the configuration in live mode. This might help to prevent that rsyslog gets restarted with a basically wrong configuration and thus rendering rsyslog useless, because it might not work or not work properly.
Modern syslogd Design (rsyslog)
In this (~5 minutes) Video Rainer Gerhards describes the core elements of a modern syslogd (like rsyslog) and how they enable the capability to evolve logging without loosing backwards compatibility. Continue reading “Modern syslogd Design (rsyslog)”
rsyslog 7.3.6 (v7-devel)
Download file name: rsyslog 7.3.6 (devel)
rsyslog 7.3.6 (devel)
sha256 hash: 1dd904459de0aaacf83d7d164caf419ba41fa6936a193e03ba57410b844d422b
Author: Rainer Gerhards (rgerhards@adiscon.com)
Version: 7.3.6 File size: 2.680 MB
rsyslog 7.3.6 (v7-devel) released
The 7.3.6 release contains a number of performance enhancements as well as some functional enhancements and bug fixes.
ChangeLog:
http://www.rsyslog.com/changelog-for-7-3-6-v7-devel/
Download:
http://www.rsyslog.com/rsyslog-7-3-6-v7-devel/
As always, feedback is appreciated.
Best regards,
Tim Eifler
Changelog for 7.3.6 (v7-devel)
Version 7.3.6 [devel] 2013-01-28
- greatly improved speed of large-array [N]EQ RainerScript comparisons
Thanks to David Lang for a related discussion that inspired the idea
to do this with a much simpler (yet sufficient) approach than orignally
planned for. - greatly improved speed of DNS cache for large cache sizes
- general performance improvements
- omfile: added stats counters for dynafile caches
- omfile: improved async writing, finally enabled full async write
also fixed a couple of smaller issues along that way - impstats: added ability to write stats records to local file
and avoid going through the syslog log stream. syslog logging can now
also be turned off (see doc for details). - bugfix: imklog issued wrong facility in error messages
…what could lead to problems in other parts of the code - fix compile problem in imklog
- added capability to output thread-id-to-function debug info
This is a useful debug aid, but nothing of concern for regular users.
How to use the Ubuntu repository
The Adiscon Ubuntu Repository has been setup to provide support for the latest rsyslog versions on Ubuntu 12 including support for necessary third party packages. Please note that the Ubuntu Repository is open for testing at the moment, and contains only the latest version for v7-devel. The new packages are based in the original and latest Ubuntu 12 rsyslog packages, so in most cases an simple sudo apt-get update && sudo apt-get upgrade will be enough to update rsyslog. Please note that these packages are currently experimental. Use at your own risk.
To use our repository, follow these steps:
Install our PGP Key into your apt system
sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com AEF0CF8E
Edit your /etc/apt/sources.list and add these lines to the end
# Adiscon repository
deb http://ubuntu.adiscon.com/v7-devel precise/ deb-src http://ubuntu.adiscon.com/v7-devel precise/
Once done perform these commands to update your apt cache and install the latest rsyslog version
sudo apt-get update && sudo apt-get upgrade
If you receive a message like this while upgrading follow these steps below:
The following packages have been kept back:
rsyslog
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.sudo apt-get install rsyslog
We highly appriciate any feedback or bug reports.
The newest information will be available on the Ubuntu Repository project page.