You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/misc/scripts/logging/fix-logs

156 lines
4.0 KiB

#!/usr/bin/perl -w
#
# Usage: fix-log [MODULE-NAME] < INFILE > OUTFILE
#
# Fixes logging macros and messages in the SER source file INFILE
# to match the recent updates in the logging API.
#
# Specify MODULE_NAME if INFILE source file is a part of a SER module.
#
# See doc/logging-api.txt for details.
#
# $Id$
#
# What *exactly* does this script do?
#
# - replaces LOG(L_*, ...) with the short macro corresponding to L_* level
#
# - replaces DEBUG() with DBG() macro
#
# - removes MODULE and the level string prefixes from FMT arguments of macros
# where FMT looks like "X:...", "X:Y:..." or "X:Y:Z:...", white spaces are
# ignored and preserved, string matching is case-insensitive
#
# In addition, if the level string found in FMT argument doesn't match the actual
# level of the macro, the macro level is fixed.
#
# Examples:
# ERR("ERROR:tm: blah\n") becomes ERR("blah\n")
# DBG("Debug: blah\n") becomes DBG("blah\n")
# LOG(L_ERR, "tm: INFO: blah\n") becomes INFO("blah\n")
#
# - removes 'MODULE_NAME ":' string from the beggining of FMT arguments of macros
# in module source files (a common special case)
#
# Example:
# LOG(L_ERR, MODULE_NAME ": tm:Info:blah\n") becomes INFO("blah\n")
#
# Map a text string to L_* log level macro
my %text2level = (
"BUG" => "L_CRIT",
"CRIT" => "L_CRIT",
"CRITICAL" => "L_CRIT",
"ALERT" => "L_ALERT",
"ERR" => "L_ERR",
"ERROR" => "L_ERR",
"WARN" => "L_WARN",
"WARNING" => "L_WARN",
"NOTICE" => "L_NOTICE",
"INFO" => "L_INFO",
"DBG" => "L_DBG",
"DEBUG" => "L_DBG",
);
#
short2level
# Strip the leading and trailing whitespaces and upper-case a text
sub norm {
my $text = ($_[0] || "");
$text =~ s/^\s*//;
$text =~ s/\s*$//;
uc($text);
}
my $module_name = norm($ARGV[0]);
sub fix_log_prefix {
my ($prefix, $level) = ($_[0], $_[1]);
# delete prefix if it contains module name
if ($module_name) {
if (!$text || (norm($text) eq $module_name)) {
return ("", $level);
}
}
# delete prefix if it contains text level
my $prefix_level = $text2level{norm($prefix)};
if ($prefix_level) {
$prefix = "";
# change level if does not match prefix level
if ($level =~ /^L_(DBG|INFO|NOTICE|WARN|ERR|CRIT|ALERT)$/ &&
$level ne $prefix_level) {
return ("", $prefix_level);
}
}
return ($prefix . ":", $level);
}
sub fix_log {
my $level = $_[0];
my $prefix1 = $_[1];
my $prefix2 = $_[2];
my $prefix3 = $_[3];
my $space = $_[4];
($prefix1, $level) = fix_log_prefix($prefix1, $level) if $prefix1;
($prefix2, $level) = fix_log_prefix($prefix2, $level) if $prefix2;
($prefix3, $level) = fix_log_prefix($prefix3, $level) if $prefix3;
my $prefix = $prefix1 . $prefix2 . $prefix3 . $space;
$prefix =~ s/^\s*//;
"LOG($level, \"$prefix";
}
while (<STDIN>) {
AGAIN:
# replace DEBUG() by DBG()
s/DEBUG\(/DBG\(/g;
# ...in case the statement spans more lines
if (/(DBG|INFO|NOTICE|WARN|ERR|BUG|ALERT)\(\s*$/ || /LOG\(([^,]*,)?\s*$/) {
$_ .= <STDIN>;
goto AGAIN;
}
# one common special case used in several modules
if ($module_name) {
s/LOG\(\s*([^,]+)\s*,\s*MODULE_NAME\s*"\s*:\s*/LOG($1, "/g;
s/(DBG|INFO|NOTICE|WARN|ERR|BUG|ALERT)\(\s*MODULE_NAME\s*"\s*:\s*/$1("/g;
}
# module name and level prefix removing magic, may change macro level
# if different one found in the message
$id='\s*[a-zA-Z0-9_]+\s*';
s/LOG\(\s*(([A-Z_]+)|[^,]+)\s*,\s*"($id):(($id):(($id):)?)?(\s*)/
fix_log($1, $3, $5, $7, $8);
/eg;
s/(DBG|INFO|NOTICE|WARN|ERR|BUG|ALERT)\(\s*"($id):(($id):(($id):)?)?(\s*)/
$1 = "CRIT" if $1 eq "BUG";
fix_log("L_$1", $2, $4, $6, $7);
/eg;
# prefer shorter static-level macros
s/LOG\(\s*L_(DBG|INFO|NOTICE|WARN|ERR|CRIT|ALERT)\s*,\s*/
$1 = "BUG" if $1 eq "CRIT";
"$1\(";
/eg;
print;
}