From 7af1adc734de72bfe5b7840242689c957b0d561d Mon Sep 17 00:00:00 2001
From: Ramon Novoa <rnovoa@artica.es>
Date: Thu, 17 Jan 2013 14:32:14 +0000
Subject: [PATCH] 2013-01-17  Ramon Novoa  <rnovoa@artica.es>

	* plugins/grep_log: Merged with grep_log_module.

	* plugins/grep_log_module: Added to repository grep plugin for log
	  modules.



git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7496 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
---
 pandora_agents/unix/ChangeLog               |   7 +
 pandora_agents/unix/plugins/grep_log        |  65 ++++-
 pandora_agents/unix/plugins/grep_log_module | 278 ++++++++++++++++++++
 3 files changed, 336 insertions(+), 14 deletions(-)
 create mode 100755 pandora_agents/unix/plugins/grep_log_module

diff --git a/pandora_agents/unix/ChangeLog b/pandora_agents/unix/ChangeLog
index a8b5800f86..545a75b364 100644
--- a/pandora_agents/unix/ChangeLog
+++ b/pandora_agents/unix/ChangeLog
@@ -1,3 +1,10 @@
+2013-01-17  Ramon Novoa  <rnovoa@artica.es>
+
+	* plugins/grep_log: Merged with grep_log_module.
+
+	* plugins/grep_log_module: Added to repository grep plugin for log
+	  modules.
+
 2013-01-11  Junichi Satoh  <junichi@rworks.jp>
 
 	* SunOS/make_solaris_package/make_solaris_package.sh: Updated
diff --git a/pandora_agents/unix/plugins/grep_log b/pandora_agents/unix/plugins/grep_log
index 2cf32474bd..9b02e2d4b9 100755
--- a/pandora_agents/unix/plugins/grep_log
+++ b/pandora_agents/unix/plugins/grep_log
@@ -23,6 +23,9 @@
 use strict;
 use File::Basename;
 
+# Output format (module or log_module).
+my $Output = 'module';
+
 # Be verbose
 my $Verbose = 0;
 
@@ -171,31 +174,62 @@ sub parse_log () {
 	# Go to starting position. 
 	seek(LOGFILE, $Idx_pos, 0);
 
-	print (stdout "<module>\n");
-	print (stdout "<name><![CDATA[" . $Module_name . "]]></name>\n");
-	print (stdout "<type><![CDATA[async_string]]></type>\n");
-	print (stdout "<datalist>\n");
-
 	# Parse log file
+	my @data;
 	while ($line = <LOGFILE>) {
 		if ($line =~ m/$Reg_exp/i) {
-			# Remove the trailing '\n'
-			chop($line);
-
-			print (stdout "<data><value><![CDATA[$line]]></value></data>\n");
+			push (@data, $line);
 		}
 	}
 
-	print (stdout "</datalist>\n");
-	print (stdout "</module>\n");
-
 	$Idx_pos = tell(LOGFILE);
 	close(LOGFILE);
 
 	# Save the index file
 	save_idx();
 
-	return;
+	return @data;
+}
+
+###############################################################################
+# SUB parse_log
+# Print log data to stdout.
+###############################################################################
+sub print_log (@) {
+	my @data = @_;
+
+	# No data
+	if ($#data < 0) {
+		return;
+	}
+	
+	# Log module
+	if ($Output eq 'log_module') {
+		my $output = "<log_module>\n";
+		$output .= "<source><![CDATA[" . $Module_name . "]]></source>\n";
+		$output .= "<data><![CDATA[";
+		foreach my $line (@data) {
+			$output .= $line;
+		}
+		$output .= "]]></data>";
+		$output .= "</log_module>\n";
+
+		print stdout $output;
+	}
+	# Regular module
+	else {
+		my $output = "<module>\n";
+		$output .= "<name><![CDATA[" . $Module_name . "]]></name>\n";
+		$output .= "<type><![CDATA[async_string]]></type>\n";
+		$output .= "<datalist>\n";
+		foreach my $line (@data) {
+			$output .= "<data><value><![CDATA[$line]]></value></data>\n";
+		}
+		$output .= "</datalist>\n";
+		$output .= "</module>\n";
+
+		print stdout $output;
+	}
 }
 
 ###############################################################################
@@ -236,6 +270,9 @@ if (! -e $Idx_file) {
 load_idx();
 
 # Parse log file
-parse_log();
+my @data = parse_log();
+
+# Print output to stdout
+print_log (@data);
 
 exit 0;
diff --git a/pandora_agents/unix/plugins/grep_log_module b/pandora_agents/unix/plugins/grep_log_module
new file mode 100755
index 0000000000..78a7b1d9cd
--- /dev/null
+++ b/pandora_agents/unix/plugins/grep_log_module
@@ -0,0 +1,278 @@
+#!/usr/bin/perl
+###############################################################################
+#
+# Copyright (c) 2012  Ramon Novoa  <rnovoa@artica.es>
+# Copyright (c) 2012  Artica Soluciones Tecnologicas S.L.
+#
+# grep_log_module Perl script to search log files for a matching pattern. The
+#                 last searched position is saved in an index file so that
+#                 consecutive runs do not return the same results. The log file
+#                 inode number is also saved to detect log rotation.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.	
+#
+###############################################################################
+
+use strict;
+use File::Basename;
+
+# Output format (module or log_module).
+my $Output = 'log_module';
+
+# Be verbose
+my $Verbose = 0;
+
+# Index file storage directory, with a trailing '/'
+my $Idx_dir='/tmp/';
+
+# Log file
+my $Log_file = '';
+
+# Module name
+my $Module_name = "default_log";
+
+# Index file
+my $Idx_file = '';
+
+# Log file position index
+my $Idx_pos = 0;
+
+# Log file inode number
+my $Idx_ino = '';
+
+# Regular expression to be matched
+my $Reg_exp = '';
+
+###############################################################################
+# SUB error_msg
+# Print an error message and exit.
+###############################################################################
+sub error_msg ($) {
+	my $err_msg = $_[0];
+
+	if (! -z $err_msg) {
+		print(stderr "[error] $err_msg.\n");
+	}
+
+	exit 1;
+}
+
+###############################################################################
+# SUB print_help
+# Print a help message.
+###############################################################################
+sub print_help () {
+	print "Usage: $0 <log_file> <module_name> <pattern>\n";
+}
+
+###############################################################################
+# SUB log_msg
+# Print a log message.
+###############################################################################
+sub log_msg ($) {
+	my $log_msg = $_[0];
+
+	if (! -z $log_msg && $Verbose == 1) {
+		print(stdout "[log] $log_msg.\n");
+	}
+}
+
+###############################################################################
+# SUB load_idx
+# Load index file.
+###############################################################################
+sub load_idx () {
+	my $line;
+	my $current_ino;
+
+	log_msg("Loading index file $Idx_file");
+
+	open(IDXFILE, $Idx_file) || error_msg("Error opening file $Idx_file: " .
+	                                         $!);
+
+	# 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_msg("File changed, resetting index");
+
+		$Idx_pos = 0;
+		$Idx_ino = $current_ino;
+	}
+
+	return;
+}
+
+###############################################################################
+# SUB save_idx
+# Save index file.
+###############################################################################
+sub save_idx () {
+
+	log_msg("Saving index file $Idx_file");
+
+	open(IDXFILE, "> $Idx_file") || error_msg("Error opening file $Idx_file: "
+	                                          . $!);
+	print (IDXFILE $Idx_pos . " " . $Idx_ino);
+	close(IDXFILE);
+
+	return;
+}
+
+###############################################################################
+# SUB create_idx
+# Create index file.
+###############################################################################
+sub create_idx () {
+	my $first_line;
+
+	log_msg("Creating index file $Idx_file");
+
+	open(LOGFILE, $Log_file) || error_msg("Error opening file $Log_file: " .
+	                                     $!);
+
+	# 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];
+
+	# Save the index file
+	save_idx();
+
+	return;
+}
+
+###############################################################################
+# SUB parse_log
+# Parse log file starting from position $Idx_pos.
+###############################################################################
+sub parse_log () {
+	my $line;
+
+	log_msg("Parsing log file $Log_file");
+
+	# Open log file for reading
+	open(LOGFILE, $Log_file) || error_msg("Error opening file $Log_file: " .
+	                                     $!);
+
+	# Go to starting position. 
+	seek(LOGFILE, $Idx_pos, 0);
+
+	# Parse log file
+	my @data;
+	while ($line = <LOGFILE>) {
+		if ($line =~ m/$Reg_exp/i) {
+			push (@data, $line);
+		}
+	}
+
+	$Idx_pos = tell(LOGFILE);
+	close(LOGFILE);
+
+	# Save the index file
+	save_idx();
+
+	return @data;
+}
+
+###############################################################################
+# SUB parse_log
+# Print log data to stdout.
+###############################################################################
+sub print_log (@) {
+	my @data = @_;
+
+	# No data
+	if ($#data < 0) {
+		return;
+	}
+	
+	# Log module
+	if ($Output eq 'log_module') {
+		my $output = "<log_module>\n";
+		$output .= "<source><![CDATA[" . $Module_name . "]]></source>\n";
+		$output .= "<data><![CDATA[";
+		foreach my $line (@data) {
+			$output .= $line;
+		}
+		$output .= "]]></data>";
+		$output .= "</log_module>\n";
+
+		print stdout $output;
+	}
+	# Regular module
+	else {
+		my $output = "<module>\n";
+		$output .= "<name><![CDATA[" . $Module_name . "]]></name>\n";
+		$output .= "<type><![CDATA[async_string]]></type>\n";
+		$output .= "<datalist>\n";
+		foreach my $line (@data) {
+			$output .= "<data><value><![CDATA[$line]]></value></data>\n";
+		}
+		$output .= "</datalist>\n";
+		$output .= "</module>\n";
+
+		print stdout $output;
+	}
+}
+
+###############################################################################
+###############################################################################
+## Main
+###############################################################################
+###############################################################################
+
+# Check command line parameters
+if ($#ARGV != 2) {
+	print_help();
+	exit 1;
+}
+
+$Log_file = $ARGV[0];
+$Module_name = $ARGV[1];
+$Reg_exp = $ARGV[2];
+
+# Create index file storage directory
+if ( ! -d $Idx_dir) {
+	mkdir($Idx_dir) || error_msg("Error creating directory $Idx_dir: "
+	                             . $!);
+}
+
+# Check that log file exists
+if (! -e $Log_file) {
+	error_msg("File $Log_file does not exist");
+}
+
+# Create index file if it does not exist
+$Idx_file=$Idx_dir . $Module_name . "_" . basename($Log_file) . ".idx";
+if (! -e $Idx_file) {
+	create_idx();
+	exit 0;
+}
+
+# Load index file
+load_idx();
+
+# Parse log file
+my @data = parse_log();
+
+# Print output to stdout
+print_log (@data);
+
+exit 0;