Syslog

parses /etc/syslog.conf

Author: Mathieu Arnold m.nosp@m.at@FreeB.nosp@m.SD.org

Summary
Syslogparses /etc/syslog.conf
ReferenceThis lens tries to keep as close as possible to `man 5 resolv.conf` where possible.
LicenceThis file is licensed under the BSD License.
Lens UsageTo be documented
Configuration filesThis lens applies to /etc/syslog.conf.
USEFUL PRIMITIVES
Comments and empty lines
empty
eol
sep_tab
sep_tab_opt
commentMap comments into “#comment” nodes Can’t use Util.comment as #+ and #! 
single characters macro
commaDeletes a comma and default to it
colonDeletes a colon and default to it
semicolonDeletes a semicolon and default to it
dotDeletes a dot and default to it
pipeDeletes a pipe and default to it
plusDeletes a plus and default to it
bangDeletes a bang and default to it
opt_hashdeletes an optional # sign
opt_plusdeletes an optional + sign
various macros
wordour version can’t start with [_.-] because it would mess up the grammar
comparisona comparison is an optional !
protocolmeans UDP means TCP
tokenalphanum or “*”
file_ra file begins with a / and get almost anything else after
loghost_rMatches a hostname, that is labels speparated by dots, labels can’t start or end with a “-”.
Function
label_opt_listUses Build.opt_list to generate a list of labels
label_opt_list_orEither label_opt_list matches something or it emits a single label with the “or” string.
LENSE DEFINITION
selector
facilitiesa list of facilities, separated by commas
selectora selector is a list of facilities, an optional comparison and a level
selectorsa list of selectors, separated by semicolons
action
filea file may start with a “-” meaning it does not gets sync’ed everytime
loghosta loghost is an @ sign followed by the hostname and a possible port
usersa list of users or a “*”
logprograma log program begins with a pipe
actionan action is either a file, a host, users, or a program
Entry
entryan entry contains selectors and an action
entriesentries are either comments/empty lines or entries
Program matching
programsa list of programs
programa program begins with an optional hash, a bang, and an optional + or -
Hostname maching
hostnamesa list of hostnames
hostnamea program begins with an optional hash, and a + or -
Top of the tree
lnsgeneric entries then programs or hostnames matching blocs
filterall you need is /etc/syslog.conf

Reference

This lens tries to keep as close as possible to `man 5 resolv.conf` where possible.  An online source being : http://www.freebsd.org/cgi/man.cgi?query=syslog.conf&sektion=5

Licence

This file is licensed under the BSD License.

Lens Usage

To be documented

Configuration files

This lens applies to /etc/syslog.conf.  See filter.

USEFUL PRIMITIVES

Comments and empty lines

empty

let empty = Util.empty

eol

let eol = Util.eol

sep_tab

let sep_tab = del /([ \t]+|[ \t]*\\\\\n[ \t]*)/ "\t"

sep_tab_opt

let sep_tab_opt = del /([ \t]*|[ \t]*\\\\\n[ \t]*)/ ""

comment

let comment_gen (space:regexp) (sto:regexp) = [ label "#comment" . del ("#" . space) "# " . store sto . eol ]

Map comments into “#comment” nodes Can’t use Util.comment as #+ and #! have a special meaning.  However, ‘# !’ and ‘# +’ have no special meaning so they should be allowed.

single characters macro

comma

let comma = sep_tab_opt . Util.del_str "," . sep_tab_opt

Deletes a comma and default to it

colon

let colon = sep_tab_opt . Util.del_str ":" . sep_tab_opt

Deletes a colon and default to it

semicolon

let semicolon = sep_tab_opt . Util.del_str ";" . sep_tab_opt

Deletes a semicolon and default to it

dot

let dot = Util.del_str "."

Deletes a dot and default to it

pipe

let pipe = Util.del_str "|"

Deletes a pipe and default to it

plus

let plus = Util.del_str "+"

Deletes a plus and default to it

bang

let bang = Util.del_str "!"

Deletes a bang and default to it

opt_hash

let opt_hash = del /#?/ ""

deletes an optional # sign

opt_plus

let opt_plus = del /\+?/ ""

deletes an optional + sign

various macros

word

let word = /[A-Za-z0-9][A-Za-z0-9_.-]*/

our version can’t start with [_.-] because it would mess up the grammar

comparison

let comparison = /(!|[<=>]+|![<=>]+)/

a comparison is an optional ! with optionaly some of [<=>]

protocol

let protocol = /@{1,2}/

means UDP means TCP

token

let token = /([A-Za-z0-9]+|\*)/

alphanum or “*”

file_r

let file_r = /\/[^ \t\n;]+/

a file begins with a / and get almost anything else after

loghost_r

let loghost_r = /[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*/ | "[" . Rx.ipv6 . "]"

Matches a hostname, that is labels speparated by dots, labels can’t start or end with a “-”.  maybe a bit too complicated for what it’s worth

Function

label_opt_list

let label_opt_list (l:string) (r:lens) (s:lens) = Build.opt_list [ label l . r ] s

Uses Build.opt_list to generate a list of labels

Parameters

l:stringthe label name
r:lensthe lens going after the label
s:lensthe separator lens passed to Build.opt_list

label_opt_list_or

let label_opt_list_or (l:string) (r:lens) (s:lens) (or:string) = ( label_opt_list l r s | [ label l . store or ] )

Either label_opt_list matches something or it emits a single label with the “or” string.

Parameters

l:stringthe label name
r:lensthe lens going after the label
s:lensthe separator lens passed to Build.opt_list
or:stringthe string used if the label_opt_list does not match anything

LENSE DEFINITION

selector

facilities

let facilities = label_opt_list "facility" (store token) comma

a list of facilities, separated by commas

selector

let selector = facilities . dot . [ label "comparison" . store comparison]? . [ label "level" . store token ]

a selector is a list of facilities, an optional comparison and a level

selectors

let selectors = label_opt_list "selector" selector semicolon

a list of selectors, separated by semicolons

action

file

let file = [ Build.xchgs "-" "no_sync" ]? . [ label "file" . store file_r ]

a file may start with a “-” meaning it does not gets sync’ed everytime

loghost

let loghost = [label "protocol" . store protocol] . [ label "hostname" . store loghost_r ] . (colon . [ label "port" . store /[0-9]+/ ] )?

a loghost is an @ sign followed by the hostname and a possible port

users

let users = label_opt_list_or "user" (store word) comma "*"

a list of users or a “*”

logprogram

let logprogram = pipe . [ label "program" . store /[^ \t\n][^\n]+[^ \t\n]/ ]

a log program begins with a pipe

action

let action = (file | loghost | users | logprogram)

an action is either a file, a host, users, or a program

Entry

entry

let entry = [ label "entry" . selectors . sep_tab . [ label "action" . action ] . eol ]

an entry contains selectors and an action

entries

let entries = (empty | comment | entry)*

entries are either comments/empty lines or entries

Program matching

programs

let programs = label_opt_list_or "program" (store word) comma "*"

a list of programs

program

let program = [ label "program" . opt_hash . bang . ( opt_plus | [ Build.xchgs "-" "reverse" ] ) . programs . eol . entries ]

a program begins with an optional hash, a bang, and an optional + or -

Hostname maching

hostnames

let hostnames = label_opt_list_or "hostname" (store Rx.word) comma "*"

a list of hostnames

hostname

let hostname = [ label "hostname" . opt_hash . ( plus | [ Build.xchgs "-" "reverse" ] ) . hostnames . eol . entries ]

a program begins with an optional hash, and a + or -

Top of the tree

lns

let lns = entries . ( program | hostname )*

generic entries then programs or hostnames matching blocs

filter

all you need is /etc/syslog.conf

let empty = Util.empty
let eol = Util.eol
let sep_tab = del /([ \t]+|[ \t]*\\\\\n[ \t]*)/ "\t"
let sep_tab_opt = del /([ \t]*|[ \t]*\\\\\n[ \t]*)/ ""
let comment_gen (space:regexp) (sto:regexp) = [ label "#comment" . del ("#" . space) "# " . store sto . eol ]
Map comments into “#comment” nodes Can’t use Util.comment as #+ and #! 
let comma = sep_tab_opt . Util.del_str "," . sep_tab_opt
Deletes a comma and default to it
let colon = sep_tab_opt . Util.del_str ":" . sep_tab_opt
Deletes a colon and default to it
let semicolon = sep_tab_opt . Util.del_str ";" . sep_tab_opt
Deletes a semicolon and default to it
let dot = Util.del_str "."
Deletes a dot and default to it
let pipe = Util.del_str "|"
Deletes a pipe and default to it
let plus = Util.del_str "+"
Deletes a plus and default to it
let bang = Util.del_str "!"
Deletes a bang and default to it
let opt_hash = del /#?/ ""
deletes an optional # sign
let opt_plus = del /\+?/ ""
deletes an optional + sign
let word = /[A-Za-z0-9][A-Za-z0-9_.-]*/
our version can’t start with [_.-] because it would mess up the grammar
let comparison = /(!|[<=>]+|![<=>]+)/
a comparison is an optional !
let protocol = /@{1,2}/
means UDP means TCP
let token = /([A-Za-z0-9]+|\*)/
alphanum or “*”
let file_r = /\/[^ \t\n;]+/
a file begins with a / and get almost anything else after
let loghost_r = /[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*/ | "[" . Rx.ipv6 . "]"
Matches a hostname, that is labels speparated by dots, labels can’t start or end with a “-”.
let label_opt_list (l:string) (r:lens) (s:lens) = Build.opt_list [ label l . r ] s
Uses Build.opt_list to generate a list of labels
let label_opt_list_or (l:string) (r:lens) (s:lens) (or:string) = ( label_opt_list l r s | [ label l . store or ] )
Either label_opt_list matches something or it emits a single label with the “or” string.
let facilities = label_opt_list "facility" (store token) comma
a list of facilities, separated by commas
let selector = facilities . dot . [ label "comparison" . store comparison]? . [ label "level" . store token ]
a selector is a list of facilities, an optional comparison and a level
let selectors = label_opt_list "selector" selector semicolon
a list of selectors, separated by semicolons
let file = [ Build.xchgs "-" "no_sync" ]? . [ label "file" . store file_r ]
a file may start with a “-” meaning it does not gets sync’ed everytime
let loghost = [label "protocol" . store protocol] . [ label "hostname" . store loghost_r ] . (colon . [ label "port" . store /[0-9]+/ ] )?
a loghost is an @ sign followed by the hostname and a possible port
let users = label_opt_list_or "user" (store word) comma "*"
a list of users or a “*”
let logprogram = pipe . [ label "program" . store /[^ \t\n][^\n]+[^ \t\n]/ ]
a log program begins with a pipe
let action = (file | loghost | users | logprogram)
an action is either a file, a host, users, or a program
let entry = [ label "entry" . selectors . sep_tab . [ label "action" . action ] . eol ]
an entry contains selectors and an action
let entries = (empty | comment | entry)*
entries are either comments/empty lines or entries
let programs = label_opt_list_or "program" (store word) comma "*"
a list of programs
let program = [ label "program" . opt_hash . bang . ( opt_plus | [ Build.xchgs "-" "reverse" ] ) . programs . eol . entries ]
a program begins with an optional hash, a bang, and an optional + or -
let hostnames = label_opt_list_or "hostname" (store Rx.word) comma "*"
a list of hostnames
let hostname = [ label "hostname" . opt_hash . ( plus | [ Build.xchgs "-" "reverse" ] ) . hostnames . eol . entries ]
a program begins with an optional hash, and a + or -
let lns = entries . ( program | hostname )*
generic entries then programs or hostnames matching blocs
all you need is /etc/syslog.conf
Close