#!/bin/sh #--------------------------------------------------------------- # Project : Mandriva Linux # Module : rpm-helper # File : add-syslog # Version : 1 # Author : Herton Ronaldo Krzesinski # Created On : Tue Jul 19 23:24:48 2005 # Modified On : Sat Jul 30 22:25:00 2005 # Purpose : helper script for rpm scriptlets to add a # entry filter for software from package into # syslog (supported sysklogd and syslog-ng). #--------------------------------------------------------------- if [ $# -lt 3 ]; then echo "usage: $0 " 1>&2 exit 1 fi priority_order="debug info notice warn,warning err,error crit alert emerg,panic" # check range of level priority, example, an level mail.notice in # syslog.conf will filter and log notice or greater level of messages not_existing_entry() { if [ "$3" = "*" -o "$4" = "*" ]; then if sed "s/#.*$//g" /etc/syslog.conf | grep "$1" | grep -q "$2\.\*" || sed "s/#.*$//g" /etc/syslog.conf | grep "$1" | grep -q "$2\.=\*"; then return 1 fi lvl_start=`echo $priority_order | cut -d " " -f 1 | sed "s:,.*::"` num_levels=`echo $priority_order | wc -w` lvl_end=`echo $priority_order | cut -d " " -f $num_levels | sed "s:,.*::"` else lvl_start=$3 lvl_end=$4 fi local begin=0 for x in $priority_order; do if [[ "$begin" -eq 0 ]] && ! echo $x | grep -q "$lvl_start"; then continue fi begin=1 x=`echo $x | sed "s:,: :g"` for y in $x; do if sed "s/#.*$//g" /etc/syslog.conf | grep "$1" | grep -q "$2\.$y"; then return 1 fi if sed "s/#.*$//g" /etc/syslog.conf | grep "$1" | grep -q "$2\.=$y"; then return 1 fi done if echo $x | grep -q "$lvl_end"; then return 0 fi done } add_blank_line() { [ -n "`tail -n 1 $1`" ] && echo >> $1 || : } pkg=$1 # name of the package num=$2 # number of packages installed source=$3 # from where the log will come (log stream) # NOTE: source must be a unix-stream facility=$4 # subclass of log source, like kern, mail... level_begin=$5 # log level, eg.: info, notice, critical... level_end=$6 # if in a range, you especify level_end # like when you log from level debug # untill notice. if not in a range # you must specify level_end the same as # level_begin or leave level_end empty logfile=$7 # log file, like /var/log/messages # Don't readd entry on package updates if [ "$num" -ne 1 ]; then exit 0 fi # just ignore if it's default unix domain socket [ "$source" = "/dev/log" ] && source="" || : # if we only have level_end, assume that level_begin is the lowest # priority level order if [ -z "$level_begin" -a -n "$level_end" ]; then level_begin=`echo $priority_order | cut -d " " -f 1 | sed "s:,.*::"` fi # Do not use deprecated level names, set also label for syslog-ng levels for loglevel in $priority_order; do if echo $loglevel | grep -q "$level_begin"; then level_begin=`echo $loglevel | sed s:,.*::` break fi done if [ -n "$level_end" ]; then for loglevel in $priority_order; do if echo $loglevel | grep -q "$level_end"; then level_end=`echo $loglevel | sed s:,.*::` break fi done level_label=${level_begin}_${level_end} else level_label=$level_begin fi # Wildcards on begin or end means we want levels until a limit on either side # Just use wildcard if range of levels contains all levels if [ "$level_begin" = "debug" -a "$level_end" = "*" -o "$level_begin" = "*" -a "$level_end" = "emerg" ]; then level_begin="*" level_end="*" elif [ "$level_begin" = "*" -a "$level_end" != "*" ]; then level_begin="debug" elif [ "$level_begin" != "*" -a "$level_end" = "*" ]; then level_end="emerg" elif [ "$level_begin" = "debug" -a "$level_end" = "emerg" ]; then level_begin="*" level_end="*" fi # sysklogd handler if [ -f /etc/syslog.conf ]; then if [[ -n "$source" ]] && ! grep -q "$source" /etc/sysconfig/syslog; then . /etc/sysconfig/syslog SYSLOGD_OPTIONS="$SYSLOGD_OPTIONS -a $source" sed -i -e :a -e \ "s:SYSLOGD_OPTIONS=\"[^\"]*\":SYSLOGD_OPTIONS=\"$SYSLOGD_OPTIONS\":g;/SYSLOGD_OPTIONS/N;//ba" \ /etc/sysconfig/syslog fi # we first verify if there isn't already a log entry for the # logfile/facility/level provided, and then add the entry to # syslog.conf. Note that we must always remove comments, # otherwise commented lines are interpreted as active if not_existing_entry "$logfile" "$facility" "$level_begin" "$level_end"; then add_blank_line /etc/syslog.conf if [ "$level_begin" = "*" -a "$level_end" = "*" ]; then echo -e "$facility.*\t\t\t\t\t\t\t$logfile" >> /etc/syslog.conf elif [ -n "$level_begin" -a -n "$level_end" -a "$level_begin" != "$level_end" -a "$level_end" = "emerg" ]; then echo -e "$facility.$level_begin\t\t\t\t\t\t\t$logfile" >> /etc/syslog.conf elif [ -n "$level_begin" -a -n "$level_end" -a "$level_begin" != "$level_end" ]; then count=0 for loglevel in $priority_order; do if [[ "$count" -eq 0 ]] && ! echo "$loglevel" | grep -q "$level_begin"; then continue fi let count=count+1 current_level=`echo $loglevel | sed "s:,.*::"` if ! echo "$loglevel" | grep -q "$level_end"; then echo -n "$facility.=$current_level;" >> /etc/syslog.conf else echo -n "$facility.=$current_level " >> /etc/syslog.conf break fi done let count=8-count while [ "$count" -gt 0 ]; do echo -ne "\t" >> /etc/syslog.conf let count=count-1 done echo -n "$logfile" >> /etc/syslog.conf elif [ -n "$level_begin" ]; then echo -e "$facility.=$level_begin\t\t\t\t\t\t\t$logfile" >> /etc/syslog.conf fi fi [ -f "/etc/rc.d/init.d/syslog" ] && service syslog condrestart fi # syslog-ng handler if [ -f /etc/syslog-ng.conf ]; then config=`sed "s/#.*$//g" /etc/syslog-ng.conf` add_blank_line /etc/syslog-ng.conf if [ -z "$source" ]; then from=`echo $config | sed -n "s:\(.*source[[:space:]]\+\)\([[:alnum:]]\+\)\(.*/dev/log.*\):\2:p"` elif ! sed "s/#.*$//g" /etc/syslog-ng.conf | grep -q "$source"; then if [ -n "$facility" -o -n "$level_begin" -a -n "$logfile" ]; then echo "source $pkg { unix-stream (\"$source\"); };" >> /etc/syslog-ng.conf from=$pkg else from=`echo $config | sed -n "s:\(.*source[[:space:]]\+\)\([[:alnum:]]\+\)\(.*/dev/log.*\):\2:p"` fi else from=`echo $config | sed -n "s:\(.*source[[:space:]]\+\)\([[:alnum:]]\+\)\(.*$source.*\):\2:p"` fi if [ -n "$facility" -o -n "$level_begin" -a -n "$logfile" ]; then if ! sed "s/#.*$//g" /etc/syslog-ng.conf | grep -q "$logfile"; then echo "destination ${pkg}_${level_label} { file(\"$logfile\"); };" >> /etc/syslog-ng.conf dest=${pkg}_${level_label} else dest=`echo $config | sed -n "s:\(.*destination[[:space:]]\+\)\([[:alnum:]]\+\)\(.*$logfile.*\):\2:p"` fi if [ -n "$level_begin" -a -n "$level_end" -a "$level_begin" != "$level_end" ]; then level_str="$level_begin..$level_end" elif [ "$level_begin" = "*" -a "$level_end" = "*" ]; then level_str="debug..emerg" elif [ -n "$level_begin" ]; then level_str="$level_begin" fi if ! sed "s/#.*$//g" /etc/syslog-ng.conf | grep "$facility" | grep -q filter; then echo "filter f_${pkg}_${level_label} { facility($facility) and level($level_str); };" >> /etc/syslog-ng.conf filter=f_${pkg}_${level_label} else filter=`echo $config | sed -n "s:\(.*filter[[:space:]]\+\)\([[:alnum:]]\+\)\(.*$facility.*\):\2:p"` curfilt=`echo $config | sed -n "s:\(.*\)\(filter[[:space:]]\+$filter[^}]*};\)\(.*\):\2:gp"` has_level=0 levels=`echo $priority_order | sed -n "s:\($level_begin.*\):\1:p"` levels=`echo $levels | sed -n "s:\(.*$level_end\):\1:p"` for log_level in $levels; do if echo $curfilt | grep -q "$log_level"; then has_level=1 break fi done if [ "$has_level" -eq 0 ]; then echo "filter f_${pkg}_${level_label} { facility($facility) and level($level_str); };" >> /etc/syslog-ng.conf filter=f_${pkg}_${level_label} fi fi if [ -n "$from" -a -n "$dest" -a -n "$filter" ]; then if ! sed "s/#.*$//g" /etc/syslog-ng.conf | grep "$from" \ | grep "$dest" | grep "$filter" | grep -q "^[[:space:]]*log"; then echo "log { source($from); filter($filter); destination($dest); };" \ >> /etc/syslog-ng.conf fi fi elif [ -n "$source" ]; then if [ -n "$from" ]; then sed -i \ "/source/{ :a /}/! { N; ba }; s:\(source[[:space:]]*$from[[:space:]]*{.*\)\([[:space:]]\+}[[:space:]]*;\):\1 unix-stream (\"$source\"); };: }" \ /etc/syslog-ng.conf fi fi [ -f "/etc/rc.d/init.d/syslog-ng" ] && service syslog-ng condrestart fi exit 0