# this is an example based on early RainerScript ideas
# ( http://www.rsyslog.com/doc-rscript_abnf.html ), especially the
# idea that old-style and new style need to be used together.
# This example was created after lengthy discussion, which lead to
# the conclusion that any new format should be an evolution from the
# old style format. This in turn lead to heavy wrangling with a 
# somewhat decent grammar. It is not 100% sure I can actually create
# a grammer that supports all samples given below, but I am very
# optimistic (based on some "hardest first testing") that it is
# most probably possible.
# Note that this recommendation here does NOT try to specifically
# facilitate dropping privileges or on-HUP-config-reload, which are
# now considered secondary design goals over the config language 
# evolution (but will very probably benefit from a new config
# language implementation).
# My intent is, as far as possible, the use standard flex and bison
# to generate the grammer, both for ease of use/modifcation and
# reliability. Note that config parsing is a non-time critical
# and non-concurrent activity inside rsyslog.
# NOTE: even if this format seems acceptable, minor changes
# are most probably needed.
# rgerhards, 2010-06-30


################## A plain standard config as found on many systems ###############

# the config below would be read by the new config processor. Note that
# it accepts old syntayx as being perfectly valid with the new system. So a
# first config sample would be your own /etc/rsyslog.conf!


$EmitStartupMessages off
# we provide an additional syntax for true globals for complicated
# cases and consistency:
global(EmitStartupMessages="off")

$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imklog	# provides kernel logging support (previously done by rklogd)

# Note: inputs are implicitely started up as usual (at the discretion
# of the input module...)

$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

# an alternative syntax for $ModLoad and setting module params would be:
module(type="omfile" ActionFileDefaultTemplate="RSYSLOG_TraditionalFileFormat")

# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none                /var/log/messages

# The authpriv file has restricted access.
authpriv.*          /var/log/secure
# an alternative form would be 

# Log all the mail messages in one place and forward
mail.*               -/var/log/maillog
&                    @host.example.net
# an alternate syntax would be:
pri:mail.*	action(type="omfile" sync="no" file="/var/log/maillog")
		action(type="omfwd" protocol="udp" target="host.example.net")
#prop:msg,contains,"error" action(type="omusrmsg" user="*")


# Log cron stuff
cron.*              /var/log/cron

# Everybody gets emergency messages
*.emerg             *

# Save news errors of level crit and higher in a special file.
uucp,news.crit      /var/log/spooler

# Save boot messages also to boot.log
local7.*            /var/log/boot.log


### a forwarding rule could be specified WITHOUT scope:
# An on-disk queue is created for this action. If the remote host is
# down, messages are spooled to disk and sent when it is up again.
$WorkDirectory /var/spool/rsyslog # where to place spool files
$ActionQueueFileName fwdRule1 # unique name prefix for spool files
$ActionQueueMaxDiskSpace 1g   # 1gb space limit (use as much as possible)
$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
$ActionQueueType LinkedList   # run asynchronously
$ActionResumeRetryCount -1    # infinite retries if host is down
# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional
*.* @@remote-host:514

### or WITH scope (below is the same rule):
*.*	action(type="omfwd" protocol="tcp" target="remote-host" port="514"
	       rsyslog.WorkDirectory="/var/spool/rsyslog"
	       queue.FileName="fwdRule1"
	       queue.MaxDiskSpace="1g"
	       queue.SaveOnShutdown="on"
	       queue.Type="LinkedList"
	       action.RetryCount="-1")
# The scoped version IGNORES all globally set parameters. Note that
# there is only one level of scoping, as nesting of actions inside
# actions does not work (and seems to be pretty useless...)
#
#

################ NEW CONFIG #####################
# this is how the config would look like of ONLY
# new style statements were used:
#################################################
global(EmitStartupMessages="off")

module(type="omfile" ActionFileDefaultTemplate="RSYSLOG_TraditionalFileFormat")
module(type="imuxsock" /* type also is used as file name if no binray is given */)
module(type="imklog")
# we still have implicit module startup (no way around this)

# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
pri:*.info;mail.none;authpriv.none;cron.none
	        action(type="omfile" file="/var/log/messages")
# note that the action needs not to be on same line as the fitler!

# The authpriv file has restricted access.
pri:authpriv.*      action(type="omfile" file="/var/log/secure")
# an alternative form would be 

# Log all the mail messages in one place and forward
pri:mail.*	action(type="omfile" sync="no" file="/var/log/maillog")
		action(type="omfwd" protocol="udp" target="host.example.net")


# Log cron stuff
pri:cron.*              action(type="omfile" file="/var/log/cron")

# Everybody gets emergency messages
pri:*.emerg             *

# Save news errors of level crit and higher in a special file.
pri:uucp,news.crit      action(type="omfile" file="/var/log/spooler")

# Save boot messages also to boot.log
pri:local7.*            action(type="omfile" file="/var/log/boot.log")


### a forwarding rule with disk queue:
pri:*.*	action(type="omfwd" protocol="tcp" target="remote-host" port="514"
	       rsyslog.WorkDirectory="/var/spool/rsyslog"
	       queue.FileName="fwdRule1"
	       queue.MaxDiskSpace="1g"
	       queue.SaveOnShutdown="on"
	       queue.Type="LinkedList"
	       action.RetryCount="-1")


########################## NEW SAMPLE ###########################
# this time, we have a rather complicated config file.
# Note that the module syntax is slightly different. The decision
# for the actual format is pending and may be forced by 
# the need to go for a "good" grammar.
# Note that "newconfonly" is used to turn off old-style config
# statements to prevent the errors that can come with them.
#################################################################
global(emitstartupmessages="off" newconfonly="on")

module imtcp(binary="/unusual/path/to/binary/imudp")
module imuxsock
module ommail
module omfile(ActionFileDefaultTemplate="RSYSLOG_TraditionalFileFormat")

# start up inputs that do not auto-start:
input(type = "imtcp" listen="10515" input.ruleset="remote10515")
input(type = "imudp" listen="10515" input.ruleset="remote10515")

ruleset remote10514 {
	# we don't have any filters at all
	action(type="omfile" file="/var/log/catchall")
	action(use="dynfile")
}

ruleset testFromEMail {
	# if-then-else is optional, so if you do not like it, do not use it...
	if expr then {
		# the next action has samples of action-module specifc
		# parameters, queue parameters and generic action
		# parameters.
		action(type="omfile" file="/var/log/file2" sync="yes"
		       queue.mode="array" queue.size=5000
		       action.concurrency="norestriction")
	} else {
		if expr2 then
			action(type="omfile" file="/var/log/file3")
		else
			action(type="omfile" file="/var/log/file4")
	}
	# now we define some actions that need to be executed one after another
	# it is expected that this feature is very seldomly being used
	serial{
		action(type="omfile" file="/path/to/file1")
		action(type="omfile" file="/path/to/file2")
	}serial
}

ruleset singleaction action(type="omfile" file="/blah")

module smcustom
template strgenSample(strgen="smcustom")
template dynGen(format="/var/log/%fromhost%.log")

# this is a "stand-alone" action, to be used in more than one rule
define action dynfile(type="omfile", format="%msg%\n", filetemplate="dynGen")

# ruleset utilizing action predicates:
ruleset remote10515 {
	pri:mail.* action(type="omfile" file="/var/log/remote10514")
	pri:mail.* action(use="dynfile")
	prev       action(type="udpfwd" action.execonlyonce="5sec"
		          target="192.168.1.2" port="514")
	           action(type="udpfwd" target="192.168.1.3"
	                  action.previousfailed="on")
	           action(type="omfile" file="/var/log/catchall")
 	if $severity == 'error' and $msg contains 'Link 2' then
 		action(type="ommail" server="192.168.1.3"
 			    from="someone@example.net"
 			    to="ops@example.net"
 			    subject="###error \"detected\"###")
}

# ruleset remote10515 could be rewritten with if-then blocks as follows:
# [I (Rainer Gerhards) find this version somewhat easier to read, but
# that's probably a matter of personal taste...]
ruleset remote10515 {
	if pri("mail.*") then {
		action(type="omfile" file="/var/log/remote10514")
	        action(use="dynfile")
		action(type="udpfwd" action.execonlyonce="5sec"
		       target="192.168.1.2" port="514")
	}
	action(type="udpfwd" target="192.168.1.3" action.previousfailed="on")
	action(type="omfile" file="/var/log/catchall")
	if $severity == 'error' and $msg contains 'Link 2' then
		action(type="ommail" server="192.168.1.3"
			    from="someone@example.net"
			    to="ops@example.net"
			    subject="###error \"detected\"###")
}
