mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
logmngr: fix severity and facility configuration issues
This commit is contained in:
parent
28c22277cd
commit
8001d9d14b
2 changed files with 179 additions and 143 deletions
|
|
@ -5,13 +5,13 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=logmngr
|
||||
PKG_VERSION:=1.1.2
|
||||
PKG_VERSION:=1.1.3
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/system/logmngr.git
|
||||
PKG_SOURCE_VERSION:=ad043d5d2e96c1b203a9c5b22ad6e6e1488ad8f2
|
||||
PKG_SOURCE_VERSION:=62441fdfe14a39bff8fff7c62307bd7b54d7240f
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -92,9 +92,6 @@ create_input_section() {
|
|||
# check if this source section has already been processed
|
||||
syslog_tag_already_processed "$tag" && return
|
||||
|
||||
# the input in our case is always syslog, hence, this section of the
|
||||
# fluent-bit.conf file has hardcoded values as well that do not depend
|
||||
# on any uci value
|
||||
append_conf "[INPUT]"
|
||||
append_conf " name syslog"
|
||||
append_conf " tag $tag"
|
||||
|
|
@ -102,147 +99,168 @@ create_input_section() {
|
|||
append_conf ""
|
||||
}
|
||||
|
||||
create_kmsg_input_section() {
|
||||
local tag="$1"
|
||||
populate_allowed_logs() {
|
||||
local facility_level sev_level
|
||||
local section="$1"
|
||||
|
||||
[ -z "$tag" ] && return
|
||||
[ -z "$section" ] && return
|
||||
|
||||
# check if this source section has already been processed
|
||||
kmsg_tag_already_processed "$tag" && return
|
||||
# reset
|
||||
match_pattern=""
|
||||
facilities=""
|
||||
all_facilities=0
|
||||
kern_facility=0
|
||||
severities=""
|
||||
sev_compare=1
|
||||
sev_action=0
|
||||
|
||||
if [ -c "/dev/kmsg" ]; then
|
||||
append_conf "[INPUT]"
|
||||
append_conf " name kmsg"
|
||||
append_conf " tag $tag"
|
||||
append_conf ""
|
||||
fi
|
||||
}
|
||||
# read config
|
||||
config_get match_pattern $section pattern_match
|
||||
|
||||
generate_facility_regex() {
|
||||
local facility_level=$1
|
||||
local pri=0
|
||||
|
||||
if [ "$facility_level" == "24" ]; then
|
||||
# value 24 means all facility level, which is as good as not
|
||||
# generating a filter section, so return
|
||||
return
|
||||
fi
|
||||
|
||||
# facility_level is a list value, hence, generate regex for
|
||||
# each value
|
||||
IFS=" "
|
||||
for val in $facility_level; do
|
||||
# as per rfc 5424 and 3164, pri in syslog msg is
|
||||
# facility*8+severity. Severity value can range from 0-7 hence
|
||||
# generate regex for each.
|
||||
for sval in 0 1 2 3 4 5 6 7; do
|
||||
pri=`expr $val \* 8 + $sval`
|
||||
append_conf " regex pri $pri"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
generate_severity_regex() {
|
||||
local sev_level="$1"
|
||||
local sev_compare="$2"
|
||||
local sev_action="$3"
|
||||
|
||||
local pri=0
|
||||
local param="exclude"
|
||||
|
||||
if [ "$sev_action" == "0" ]; then
|
||||
param="regex"
|
||||
fi
|
||||
|
||||
local fval=0
|
||||
if [ "$sev_compare" == "0" ]; then
|
||||
# generate regex for all facility values, with severity=sev_level
|
||||
while [ $fval -le 23 ] ; do
|
||||
pri=`expr $fval \* 8 + $sev_level`
|
||||
append_conf " $param pri $pri"
|
||||
fval=$((fval + 1))
|
||||
done
|
||||
elif [ "$sev_compare" == "1" ]; then
|
||||
# generate regex for all severity value greater than or equal to
|
||||
# sev_level. please, lower value have higher precedence, so sev_level
|
||||
# 0 which is emergency has higher precedence than error which is 3
|
||||
while [ $fval -le 23 ] ; do
|
||||
sval=0
|
||||
while [ $sev_level -ge $sval ]; do
|
||||
pri=`expr $fval \* 8 + $sval`
|
||||
append_conf " $param pri $pri"
|
||||
sval=$((sval + 1))
|
||||
done
|
||||
fval=$((fval + 1))
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
handle_filter_conf() {
|
||||
local section="$1" # config filter
|
||||
local filter_name="$2"
|
||||
local name
|
||||
|
||||
# no need to proceed if name of filter section is not one of the values
|
||||
# listed in option filter in config action section
|
||||
config_get name $section name
|
||||
if [ "$name" != "$filter_name" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# as per data model, at a time either facility_level or severity_level can
|
||||
# be specified along with pattern_match. hence, first process and generate
|
||||
# regex for pattern_match which is common in both condition. Next, we will
|
||||
# process facility_level and return if facility level is defined and not
|
||||
# process severity related params at all.
|
||||
|
||||
local pattern_match
|
||||
config_get pattern_match $section pattern_match
|
||||
if [ -n "$pattern_match" ]; then
|
||||
append_conf " regex $pattern_match"
|
||||
fi
|
||||
|
||||
local facility_level
|
||||
config_get facility_level $section facility_level
|
||||
|
||||
if [ -n "$facility_level" ]; then
|
||||
generate_facility_regex $facility_level
|
||||
# return from here since if facility_level is defined, then no
|
||||
# need to process severity_level
|
||||
return
|
||||
fi
|
||||
|
||||
local sev_level
|
||||
local sev_compare
|
||||
local sev_action
|
||||
config_get sev_level $section severity_level
|
||||
config_get sev_compare $section severity_compare 1
|
||||
config_get sev_action $section severity_action 0
|
||||
|
||||
if [ -n "$sev_level" ]; then
|
||||
# value 1 of severity compare corresponds to data model
|
||||
# and system default which is EqualorHigher
|
||||
config_get sev_compare $section severity_compare 1
|
||||
# value 0 of severity action corresponds to data model
|
||||
# and system default that is log
|
||||
config_get sev_action $section severity_action 0
|
||||
# normalize facilities
|
||||
if [ -n "$facility_level" ]; then
|
||||
for f in $facility_level; do
|
||||
if [ "$f" = "24" ]; then
|
||||
all_facilities=1
|
||||
# xargs is used to convert from new line separated numbers to space separated numbers
|
||||
facilities="$(seq 0 23 | xargs)"
|
||||
break
|
||||
fi
|
||||
|
||||
generate_severity_regex $sev_level $sev_compare $sev_action
|
||||
if [ "$f" = "0" ]; then
|
||||
kern_facility=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$all_facilities" -eq 0 ]; then
|
||||
facilities="$facility_level"
|
||||
fi
|
||||
else
|
||||
# default to "all facilities" when unset
|
||||
all_facilities=1
|
||||
facilities="$(seq 0 23 | xargs)"
|
||||
fi
|
||||
|
||||
# normalize severities
|
||||
case "$sev_level" in
|
||||
8) # all severities
|
||||
severities="$(seq 0 7 | xargs)"
|
||||
;;
|
||||
9) # none
|
||||
severities="none"
|
||||
;;
|
||||
"") # unset, treat as "all"
|
||||
severities="$(seq 0 7 | xargs)"
|
||||
;;
|
||||
*)
|
||||
if [ "$sev_compare" = "0" ]; then
|
||||
# equal
|
||||
severities="$sev_level"
|
||||
else
|
||||
# equl or higher
|
||||
severities="$(seq 0 $sev_level | xargs)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
create_filter_section() {
|
||||
local match_regex="$1"
|
||||
local pattern="$2"
|
||||
|
||||
[ -z "$match_regex" ] && return
|
||||
|
||||
append_conf "[FILTER]"
|
||||
append_conf " name grep"
|
||||
append_conf " match_regex $match_regex"
|
||||
append_conf " logical_op or" # handle multiple filters
|
||||
|
||||
# we need "logical_op or" only in non-pattern sections
|
||||
if [ "$pattern" = "0" ]; then
|
||||
append_conf " logical_op or" # handle multiple filters
|
||||
fi
|
||||
}
|
||||
|
||||
handle_filter_ref() {
|
||||
local filter_name="$1"
|
||||
config_foreach handle_filter_conf filter "$filter_name"
|
||||
create_kmsg_input_section() {
|
||||
local tag="$1"
|
||||
|
||||
[ -z "$tag" ] && return
|
||||
kmsg_tag_already_processed "$tag" && return
|
||||
|
||||
if [ -c "/dev/kmsg" ]; then
|
||||
append_conf "[INPUT]"
|
||||
append_conf " name kmsg"
|
||||
append_conf " tag $tag"
|
||||
|
||||
# check kern facility (0)
|
||||
if [ "$all_facilities" -eq 1 ] || [ "$kern_facility" -eq 1 ]; then
|
||||
if [ "$severities" != "none" ]; then
|
||||
# severity filtering
|
||||
# only EqualOrHigher is supported by Prio_Level
|
||||
# and only Log action is supported
|
||||
# so set Prio_Level = max severity
|
||||
if [ "$sev_action" = "0" ] && [ "$sev_compare" = "1" ]; then
|
||||
local max_sev=$(echo $severities | tr ' ' '\n' | sort -n | tail -1)
|
||||
append_conf " prio_level $max_sev"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
append_conf ""
|
||||
|
||||
# if severities is none, or
|
||||
# if kern facility has been excluded
|
||||
# then we need to stop kernel logs
|
||||
# sev_action and sev_compare is being checked because we don't want to work with rules that exclude logs
|
||||
if [ "$severities" = "none" ] || { [ "$kern_facility" -eq 0 ] && [ "$all_facilities" -eq 0 ] && [ "$sev_action" = "0" ] && [ "$sev_compare" = "1" ]; }; then
|
||||
# block all
|
||||
# create a filter section that matches on KM* tag
|
||||
# and excludes all messages
|
||||
create_filter_section "KM*" "0"
|
||||
append_conf " exclude message ^.*$"
|
||||
append_conf ""
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
generate_syslog_filter() {
|
||||
local param="regex"
|
||||
|
||||
[ "$sev_action" = "1" ] && param="exclude"
|
||||
|
||||
# start adding the fluent-bit filter section
|
||||
create_filter_section "SL*" "0"
|
||||
|
||||
if [ "$severities" = "none" ]; then
|
||||
append_conf " exclude pri ^.*$"
|
||||
return
|
||||
fi
|
||||
|
||||
for fval in $facilities; do
|
||||
for sval in $severities; do
|
||||
local pri=$((fval * 8 + sval))
|
||||
append_conf " $param pri ^${pri}$"
|
||||
done
|
||||
done
|
||||
|
||||
append_conf ""
|
||||
}
|
||||
|
||||
generate_pattern_filter() {
|
||||
local match_regex="$1"
|
||||
local match_pattern="$2"
|
||||
|
||||
[ -z "$match_regex" ] && return
|
||||
[ -z "$match_pattern" ] && return
|
||||
|
||||
# start adding the fluent-bit filter section
|
||||
create_filter_section "$match_regex" "1"
|
||||
append_conf " regex message $match_pattern"
|
||||
append_conf ""
|
||||
}
|
||||
|
||||
handle_log_file() {
|
||||
|
|
@ -275,6 +293,7 @@ handle_log_file() {
|
|||
append_conf " match_regex $match_regex"
|
||||
append_conf " file $file"
|
||||
|
||||
|
||||
if [ -n "$template" ]; then
|
||||
append_conf " format template"
|
||||
append_conf " template ${template}"
|
||||
|
|
@ -349,7 +368,7 @@ handle_log_remote() {
|
|||
resolve_source_section() {
|
||||
local src_section="$1"
|
||||
local linker="$2"
|
||||
local src_name syslog_en kernel_en source_tag_syslog source_tag_kmsg
|
||||
local src_name syslog_en kernel_en
|
||||
|
||||
config_get src_name "$src_section" name
|
||||
[ "$src_name" = "$linker" ] || return
|
||||
|
|
@ -364,13 +383,11 @@ resolve_source_section() {
|
|||
if [ "$syslog_en" = "1" ]; then
|
||||
source_tag_syslog="SL$src_name"
|
||||
create_input_section "$source_tag_syslog"
|
||||
action_tags="$source_tag_syslog $action_tags"
|
||||
fi
|
||||
|
||||
if [ "$kernel_en" = "1" ]; then
|
||||
source_tag_kmsg="KM$src_name"
|
||||
create_kmsg_input_section "$source_tag_kmsg"
|
||||
action_tags="$source_tag_kmsg $action_tags"
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
@ -406,10 +423,30 @@ build_match_regex() {
|
|||
echo "$regex"
|
||||
}
|
||||
|
||||
handle_filter_conf() {
|
||||
local section="$1" # config filter
|
||||
local filter_name="$2"
|
||||
local name
|
||||
|
||||
config_get name $section name
|
||||
[ "$name" = "$filter_name" ] || return
|
||||
|
||||
populate_allowed_logs "$filter_name"
|
||||
}
|
||||
|
||||
handle_action() {
|
||||
local tag_regex filter source_ref template_ref source_sec log_template
|
||||
local tag_regex filter source_ref template_ref source_sec log_template finst
|
||||
local action_section="$1"
|
||||
local action_tags=""
|
||||
local source_tag_syslog source_tag_kmsg
|
||||
|
||||
# shared variables set by populate_allowed_logs
|
||||
match_pattern=""
|
||||
facilities=""
|
||||
all_facilities=0
|
||||
kern_facility=0
|
||||
severities=""
|
||||
sev_compare=1
|
||||
sev_action=0
|
||||
|
||||
config_get action_name "$action_section" name
|
||||
config_get filter "$action_section" filter
|
||||
|
|
@ -419,27 +456,26 @@ handle_action() {
|
|||
[ -z "$action_name" ] && return
|
||||
[ -z "$source_ref" ] && return
|
||||
|
||||
# read filter section and populate relevant variables
|
||||
# these variables will be used by create_kmsg_input_section
|
||||
# generate_syslog_filter, and generate_pattern_filter functions
|
||||
if [ -n "$filter" ]; then
|
||||
for finst in $filter; do
|
||||
config_foreach handle_filter_conf filter "$finst"
|
||||
done
|
||||
fi
|
||||
|
||||
# Resolve referenced source sections
|
||||
for source_sec in $source_ref; do
|
||||
config_foreach resolve_source_section source "$source_sec"
|
||||
done
|
||||
|
||||
# build a regex that will match all the sources for this action
|
||||
tag_regex=$(build_match_regex "$action_tags")
|
||||
tag_regex=$(build_match_regex "$source_tag_syslog $source_tag_kmsg")
|
||||
|
||||
if [ -n "$filter" ]; then
|
||||
# the only fluentbit filter that is useful for the datamodel is
|
||||
# grep. Also, fluentbit does not seem to handle multiple instances
|
||||
# of FILTER of same kind. Hence, each filter section corresponding
|
||||
# to an action entry in the uci would translate for us into a set of
|
||||
# regex/exclude values instead of individual FILTER section per uci
|
||||
# section filter is a list, treat according
|
||||
create_filter_section "$tag_regex"
|
||||
|
||||
IFS=" "
|
||||
for finst in $filter; do
|
||||
handle_filter_ref $finst
|
||||
done
|
||||
generate_pattern_filter "$tag_regex" "$match_pattern"
|
||||
generate_syslog_filter
|
||||
fi
|
||||
|
||||
# get the template expression if any is present
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue