Modify log module

This commit is contained in:
felix.suarez 2023-10-04 14:00:29 -06:00
parent 0177d1906d
commit 3bd306fcf1
3 changed files with 214 additions and 205 deletions

View File

@ -54,7 +54,6 @@ if (!$@) {
use constant AGENT_VERSION => '4.0.1';
use constant AGENT_BUILD => '111213';
# Commands to retrieve total memory information in kB
use constant TOTALMEMORY_CMDS => {
linux => 'cat /proc/meminfo | grep MemTotal: | awk \'{ print $2 }\'',
@ -117,7 +116,6 @@ my $ConfDir = '';
# Pandora FMS agent configuration file
my $ConfFile = 'pandora_agent.conf';
# Broker agent configuration files
my @BrokerPid;
@ -264,7 +262,6 @@ sub valid_regexp ($) {
sub rmrf {
my $path = shift;
local *DIR;
if (-d $path) {
opendir (DIR, $path) || return;
while (defined (my $file_name = readdir(DIR))) {
@ -348,7 +345,6 @@ sub log_message ($$;$) {
}
}
}
################################################################################
# Add the given directory to the PATH.
################################################################################
@ -394,8 +390,6 @@ sub parse_conf_modules($) {
'max_warning' => undef,
'disabled' => undef,
'min_ff_event' => undef,
'filter' => undef,
'log_file' => undef,
'save' => '',
'conditions' => [],
'cron' => '',
@ -413,7 +407,7 @@ sub parse_conf_modules($) {
$module->{'description'} = $1;
} elsif ($line =~ /^\s*module_type\s+(\S+)\s*$/) {
$module->{'type'} = $1;
} elsif ($line =~ /^\s*module_precondition\s+(.*)$/) {
}elsif ($line =~ /^\s*module_precondition\s+(.*)$/) {
my $action = $1;
# Numeric comparison
@ -561,16 +555,6 @@ sub parse_conf_modules($) {
# Min ff event
} elsif ($line =~ /^\s*module_min_ff_event\s+(.*)\s*$/) {
$module->{'min_ff_event'} = $1;
# Log module file
} elsif ($line =~ /^\s*module_logfile\s+(.*)\s*$/) {
$module->{'filter'} = $1;
# Log module filter
} elsif ($line =~ /^\s*module_filter\s+(.*)\s*$/) {
$module->{'log_file'} = $1;
# Log module function
} elsif ($line =~ /^\s*module_logger\s+(.*)\s*$/) {
$module->{'func'} = \&module_logger;
$module->{'params'} = $1;
}
}
return;
@ -594,7 +578,6 @@ sub write_broker_conf($){
}
while (my $line = <CONF_FILE>){
# Skip broker definitions
if ($line =~ m/^\s*broker_agent/) {
next;
@ -1822,187 +1805,9 @@ sub exec_plugin ($) {
$Sem->down () if (defined ($Sem));
$Xml .= $output;
$Sem->up () if (defined ($Sem));
$ThreadSem->up () if (defined ($ThreadSem) && $Conf{'agent_threads'} > 1);
}
################################################################################
# Read the logs
################################################################################
sub module_logger ($) {
# Return: 0 If all was OK
# 1 If there is an error
my $status = grep_logs(
$module->{'name'},
$module->{'log_file'},
$module->{'filter'}
)
return ($status);
}
sub grep_logs {
my ($str_name, $str_file, $str_regex) = @_;
if(!$str_name){
log_message("module_logger", "Missing module name");
return;
}
if(!$str_file){
log_message("module_logger", "Missing file name");
return;
}
if(!$str_regex){
$str_regex = '\.\*'
}
my $idx_dir = '/tmp/';
my $idx_file = '';
my $idx_pos = 0;
my $idx_ino = '';
my $module_name = $str_name;
my $log_file = $str_file;
my $reg_exp = $str_regex;
# Check that log file exists
if (! -e $log_file) {
log_message("module_logger", "File $log_file does not exist");
return;
}
# Create index file storage directory
if (! -d $idx_dir) {
if (!mkdir($idx_dir)){
log_message("module_logger", "Error creating directory $idx_dir: " . $!);
return;
}
}
# Create index file if it does not exist
my $idx_file = $idx_dir.$module_name."_".basename($log_file).".idx";
if (! -e $idx_file) {
return if create_idx() == 1;
} else{
return if load_idx() == 1;
my $result = parse_log();
return if $result == 1;
return $result;
}
# Start the function definition
sub create_idx {
my $first_line;
log_message("module_logger", "Creating index file $idx_file");
if (!open(LOGFILE, $log_file)){
log_message("module_logger", "Error opening file $log_file: ".$!);
return 1;
}
# Go to EOF and save the position
seek(LOGFILE, 0, 2);
$idx_pos = tell(LOGFILE);
close(LOGFILE);
# Save the file inode number
$idx_ino = (stat($log_file))[1];
return 1 if save_idx() == 1;
return 0;
}
sub save_idx {
log_message("module_logger", "Saving index file $idx_file");
if (!open(IDXFILE, "> $idx_file")){
log_message("module_logger", "Error opening file $idx_file: ". $!);
return 1;
}
print (IDXFILE $idx_pos . " " . $idx_ino);
close(IDXFILE);
return 0;
}
sub load_idx {
my $line;
my $current_ino;
log_message("module_logger", "Loading index file $idx_file");
if (!open(IDXFILE, $idx_file)){
log_message("module_logger", "Error opening file $idx_file: " .$!);
return 1;
}
# Read position and date
$line = <IDXFILE>;
($idx_pos, $idx_ino) = split(' ', $line);
close(IDXFILE);
# Reset the file index if the file has changed
$current_ino = (stat($log_file))[1];
if ($current_ino != $idx_ino) {
log_message("module_logger", "File changed, resetting index");
$idx_pos = 0;
$idx_ino = $current_ino;
}
return 0;
}
sub parse_log {
my $result = "";
my $line;
log_message("module_logger", "Parsing log file $log_file");
# Open log file for reading
if (!open(LOGFILE, $log_file)){
log_message("module_logger", "Error opening file $log_file: " . $!);
return 1;
}
# Go to starting position.
seek(LOGFILE, $idx_pos, 0);
$result = $result . "<module>\n";
$result = $result . "<name><![CDATA[" . $module_name . "]]></name>\n";
$result = $result . "<type><![CDATA[async_string]]></type>\n";
$result = $result . "<datalist>\n";
# Parse log file
while ($line = <LOGFILE>) {
if ($line =~ m/$reg_exp/i) {
# Remove the trailing '\n'
chop($line);
$result = $result . "<data><value><![CDATA[$line]]></value></data>\n";
}
}
$result = $result . "</datalist>\n";
$result = $result . "</module>\n";
$idx_pos = tell(LOGFILE);
close(LOGFILE);
print($result);
# Save the index file
return 1 if save_idx() == 1;
return $result;
}
}
################################################################################
# TERM Handler
################################################################################
@ -2476,4 +2281,4 @@ This is released under the GNU Lesser General Public License.
Copyright (c) 2005-2023 Pandora FMS
=cut
=cut

View File

@ -317,12 +317,11 @@ module_plugin autodiscover --default
#module_absoluteinterval 7d
#module_end
# Logs extaction plugin
#module_begin
#module_name Syslog
#module_type log
#module_logfile /var/log/messages
#module_logger syslog
# module_filter uses REGEXP, optional, if not defined, it takes all lines.
#module_filter \.\*
# Logs extaction
#module_begin
#module_name Syslog
#module_description Logs extaction module
#module_type log
#module_regexp /var/log/logfile.log
#module_pattern .*
#module_end

View File

@ -1562,6 +1562,9 @@ sub parse_conf_modules($) {
} elsif ($line =~ /^\s*module_occupiedpercentdisk\s+(.*)$/) {
$module->{'func'} = \&module_occupiedpercentdisk;
$module->{'params'} = $1;
}elsif ($line =~ /^\s*module_regexp\s+(.*)$/) {
$module->{'func'} = \&module_logger;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*module_max\s+(.*)\s*$/) {
$module->{'max'} = $1;
} elsif ($line =~ /^\s*module_min\s+(.*)\s*$/) {
@ -1817,7 +1820,11 @@ sub parse_conf_modules($) {
# Macros
} elsif ($line =~ /^\s*module_macro(\S+)\s+(.*)\s*$/) {
$module->{'macros'}{$1} = $2;
# Regexp
}
elsif ($line =~ /^\s*module_pattern(\S+)\s+(.*)\s*$/) {
$module->{'filter'} = $1;
}
}
return;
}
@ -3860,6 +3867,203 @@ sub module_plugin ($) {
return ($output);
}
################################################################################
# Read the logs
################################################################################
sub module_logger ($) {
my $module = shift;
my $status = grep_logs(
$module->{'name'},
$module->{'params'},
$module->{'filter'}
);
print($status);
return ($status);
}
sub grep_logs {
my ($str_name, $str_file, $str_regex) = @_;
if(!$str_name){
log_message("module_logger", "Missing module name");
return;
}
if(!$str_file){
log_message("module_logger", "Missing file name");
return;
}
if(!$str_regex){
$str_regex = '.*';
}
my $idx_dir = '/tmp/';
my $idx_file = '';
my $idx_pos = 0;
my $idx_ino = '';
my $module_name = $str_name;
my $log_file = $str_file;
my $reg_exp = $str_regex;
# Check that log file exists
if (! -e $log_file) {
log_message("module_logger", "File $log_file does not exist");
return;
}
# Create index file storage directory
if (! -d $idx_dir) {
if (!mkdir($idx_dir)){
log_message("module_logger", "Error creating directory $idx_dir: " . $!);
return;
}
}
# Create index file if it does not exist
$idx_file = $idx_dir.$module_name."_".basename($log_file).".idx";
if (! -e $idx_file) {
return if create_idx(\$idx_pos, \$idx_ino, \$idx_file, \$log_file) == 1;
return ""
} else{
return if load_idx(\$idx_pos, \$idx_ino, \$idx_file) == 1;
my $result = parse_log(\$idx_pos, \$idx_ino, \$idx_file, \$log_file, \$module_name, \$reg_exp);
if (looks_like_number($result)) {
return if $result == 1;
}
return $result;
}
# Start the function definition
sub create_idx {
my ($idx_pos_ref, $idx_ino_ref, $idx_file_ref, $log_file_ref) = @_;
my $first_line;
log_message("module_logger", "Creating index file $$idx_file_ref");
if (!open(LOGFILE, $$log_file_ref)){
log_message("module_logger", "Error opening file $$log_file_ref: ".$!);
return 1;
}
# Go to EOF and save the position
seek(LOGFILE, 0, 2);
$$idx_pos_ref = tell(LOGFILE);
###################
close(LOGFILE);
# Save the file inode number
$$idx_ino_ref = (stat($$log_file_ref))[1];
return 1 if save_idx($idx_pos_ref, $idx_ino_ref, $idx_file_ref) == 1;
return 0;
}
sub save_idx {
my ($idx_pos_ref, $idx_ino_ref, $idx_file_ref) = @_;
log_message("module_logger", "Saving index file $$idx_file_ref");
if (!open(IDXFILE, "> $$idx_file_ref")){
log_message("module_logger", "Error opening file $$idx_file_ref: ". $!);
return 1;
}
print (IDXFILE $$idx_pos_ref . " " . $$idx_ino_ref);
close(IDXFILE);
return 0;
}
sub load_idx {
my ($idx_pos_ref, $idx_ino_ref, $idx_file_ref) = @_;
my $line;
my $current_ino;
log_message("module_logger", "Loading index file $$idx_file_ref");
if (!open(IDXFILE, $$idx_file_ref)){
log_message("module_logger", "Error opening file $$idx_file_ref: " .$!);
return 1;
}
# Read position and date
$line = <IDXFILE>;
($$idx_pos_ref, $$idx_ino_ref) = split(' ', $line);
close(IDXFILE);
print($$idx_pos_ref);
print($$idx_pos_ref);
# Reset the file index if the file has changed
$current_ino = (stat($$idx_file_ref))[1];
if ($current_ino != $$idx_ino_ref) {
log_message("module_logger", "File changed, resetting index");
$$idx_pos_ref = 0;
$$idx_ino_ref = $current_ino;
}
return 0;
}
sub parse_log {
my ($idx_pos_ref, $idx_ino_ref, $idx_file_ref, $log_file_ref, $module_name_ref, $reg_exp_ref) = @_;
my $result = "";
my $line;
log_message("module_logger", "Parsing log file $$log_file_ref");
# Open log file for reading
if (!open(LOGFILE, $$log_file_ref)){
log_message("module_logger", "Error opening file $$log_file_ref: " . $!);
return 1;
}
# Go to starting position.
seek(LOGFILE, $$idx_pos_ref, 0);
$result = $result . "<module>\n";
$result = $result . "<name><![CDATA[" . $$module_name_ref . "]]></name>\n";
$result = $result . "<type><![CDATA[async_string]]></type>\n";
$result = $result . "<datalist>\n";
# Parse log file
while ($line = <LOGFILE>) {
if ($line =~ m/$$reg_exp_ref/i) {
# Remove the trailing '\n'
chop($line);
$result = $result . "<data><value><![CDATA[$line]]></value></data>\n";
}
}
$result = $result . "</datalist>\n";
$result = $result . "</module>\n";
$$idx_pos_ref = tell(LOGFILE);
close(LOGFILE);
# Save the index file
return 1 if save_idx($idx_pos_ref, $idx_ino_ref, $idx_file_ref) == 1;
return $result;
}
}
################################################################################
# TERM Handler
################################################################################
@ -4030,6 +4234,7 @@ sub init_module ($) {
$module->{'module_ff_interval'} = undef;
$module->{'macros'} = {};
$module->{'alert_template'} = undef;
$module->{'filter'} = undef;
}
################################################################################