#!/usr/bin/perl # Pandora FMS Agent Plugin for MongoDB # (c) Artica Soluciones Tecnologicas 2012 # v1.0, 18 Apr 2012 # ------------------------------------------------------------------------ use strict; use warnings; use Data::Dumper; use IO::Socket::INET; # OS and OS version my $OS = $^O; # Store original PATH my $ORIGINAL_PATH = $ENV{'PATH'}; # Load on Win32 only if ($OS eq "MSWin32"){ # Check dependencies eval 'local $SIG{__DIE__}; use Win32::OLE("in");'; if ($@) { print "Error loading Win32::Ole library. Cannot continue\n"; exit; } use constant wbemFlagReturnImmediately => 0x10; use constant wbemFlagForwardOnly => 0x20; } my %plugin_setup; # This stores plugin parameters my %mongo_resultset; # This stores mongo results my $archivo_cfg = $ARGV[0]; my $volume_items = 0; my $log_items = 0; my $process_items = 0; my $mongo_items = 0; my $stats_items = 0; my $OS_NAME = `uname -s`; my $hostname = `hostname | tr -d "\n"`; # FLUSH in each IO $| = 1; # ---------------------------------------------------------------------------- # This cleans DOS-like line and cleans ^M character. VERY Important when you process .conf edited from DOS # ---------------------------------------------------------------------------- sub parse_dosline ($){ my $str = $_[0]; $str =~ s/\r//g; return $str; } # ---------------------------------------------------------------------------- # Strips blank likes # ---------------------------------------------------------------------------- sub trim ($){ my $string = shift; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } # ---------------------------------------------------------------------------- # clean_blank # # This function return a string without blankspaces, given a simple text string # ---------------------------------------------------------------------------- sub clean_blank($){ my $input = $_[0]; $input =~ s/[\s\r\n]*//g; return $input; } # ---------------------------------------------------------------------------- # print_module # # This function return a pandora FMS valid module fiven name, type, value, description # ---------------------------------------------------------------------------- sub print_module ($$$$){ my $MODULE_NAME = $_[0]; my $MODULE_TYPE = $_[1]; my $MODULE_VALUE = $_[2]; my $MODULE_DESC = $_[3]; # If not a string type, remove all blank spaces! if ($MODULE_TYPE !~ m/string/){ $MODULE_VALUE = clean_blank($MODULE_VALUE); } print "\n"; print "\n"; print "$MODULE_TYPE\n"; print "\n"; print "\n"; print "\n"; } # ---------------------------------------------------------------------------- # load_mongostat_result # # Load temporal mongostat result file containing mongostat stats # ---------------------------------------------------------------------------- my $resultfile="/tmp/mongo_results.log"; my $resultfilestats="/tmp/mongo_resultstats.log"; sub load_mongo_result ($); sub load_mongo_result ($){ my $mongo_result = $_[0]; my $buffer_line; my @results; my $parametro =""; if (! open (CFG, "< $mongo_result")) { print "[ERROR] Error accessing mongo results $mongo_result: $!.\n"; exit 1; } while (){ $buffer_line = parse_dosline ($_); # Parse configuration file, this is specially difficult because can contain SQL code, with many things if ($buffer_line !~ /^\#/){ # begins with anything except # (for commenting) if ($buffer_line =~ m/(.+)\s(.*)/){ push @results, $buffer_line; } } } close (CFG); if ($mongo_result eq $resultfilestats) { foreach (@results){ $parametro = $_; $mongo_resultset{"checker"}->[$stats_items] = `echo "$parametro" | awk '{print \$15}' | tr -d "\n"`; my $checker = $mongo_resultset{"checker"}->[$stats_items]; if (!$checker) { $mongo_resultset{"dbinserts"}->[$stats_items] = `echo "$parametro" | awk '{print \$1}' | tr -d "\n"`; $mongo_resultset{"dbqueries"}->[$stats_items] = `echo "$parametro" | awk '{print \$2}' | tr -d "\n"`; $mongo_resultset{"dbupdates"}->[$stats_items] = `echo "$parametro" | awk '{print \$3}' | tr -d "\n"`; $mongo_resultset{"dbdeletes"}->[$stats_items] = `echo "$parametro" | awk '{print \$4}' | tr -d "\n"`; $mongo_resultset{"dbgetmores"}->[$stats_items] = `echo "$parametro" | awk '{print \$5}' | tr -d "\n"`; $mongo_resultset{"dbcommands"}->[$stats_items] = `echo "$parametro" | awk '{print \$6}' | tr -d "\n"`; $mongo_resultset{"dbpagefaults"}->[$stats_items] = `echo "$parametro" | awk '{print \$9}' | tr -d "\n"`; $mongo_resultset{"dbnetworktrafficinbits"}->[$stats_items] = `echo "$parametro" | awk '{print \$10}' | rev | cut -c2- | rev | tr -d "\n"`; $mongo_resultset{"dbnetworktrafficinbitunit"}->[$stats_items] = `echo "$parametro" | awk '{print \$10}' | rev | cut -c1 | tr -d "\n"`; $mongo_resultset{"dbnetworktrafficoutbits"}->[$stats_items] = `echo "$parametro" | awk '{print \$11}' | rev | cut -c2- | rev | tr -d "\n"`; $mongo_resultset{"dbnetworktrafficoutbitunit"}->[$stats_items] = `echo "$parametro" | awk '{print \$11}' | rev | cut -c1 | tr -d "\n"`; $mongo_resultset{"dbopenconnections"}->[$stats_items] = `echo "$parametro" | awk '{print \$12}' | tr -d "\n"`; } else { $mongo_resultset{"dbinserts"}->[$stats_items] = `echo "$parametro" | awk '{print \$1}' | tr -d "\n"`; $mongo_resultset{"dbqueries"}->[$stats_items] = `echo "$parametro" | awk '{print \$2}' | tr -d "\n"`; $mongo_resultset{"dbupdates"}->[$stats_items] = `echo "$parametro" | awk '{print \$3}' | tr -d "\n"`; $mongo_resultset{"dbdeletes"}->[$stats_items] = `echo "$parametro" | awk '{print \$4}' | tr -d "\n"`; $mongo_resultset{"dbgetmores"}->[$stats_items] = `echo "$parametro" | awk '{print \$5}' | tr -d "\n"`; $mongo_resultset{"dbcommands"}->[$stats_items] = `echo "$parametro" | awk '{print \$6}' | tr -d "\n"`; $mongo_resultset{"dbflushes"}->[$stats_items] = `echo "$parametro" | awk '{print \$7}' | tr -d "\n"`; $mongo_resultset{"dbpagefaults"}->[$stats_items] = `echo "$parametro" | awk '{print \$12}' | tr -d "\n"`; $mongo_resultset{"dblockpercent"}->[$stats_items] = `echo "$parametro" | awk '{print \$13}' | awk -F"\:" '{print \$2}' | tr -d "\%" | tr -d "\n"`; $mongo_resultset{"dbbttreepagemissedpercent"}->[$stats_items] = `echo "$parametro" | awk '{print \$14}' | tr -d "\%" | tr -d "\n"`; $mongo_resultset{"dbclientreadqueuelength"}->[$stats_items] = `echo "$parametro" | awk '{print \$15}' | awk -F"\|" '{print \$1}' | tr -d "\n"`; $mongo_resultset{"dbclientwritequeuelength"}->[$stats_items] = `echo "$parametro" | awk '{print \$15}' | awk -F"\|" '{print \$2}' | tr -d "\n"`; $mongo_resultset{"dbactivereadingclients"}->[$stats_items] = `echo "$parametro" | awk '{print \$16}' | awk -F"\|" '{print \$1}' | tr -d "\n"`; $mongo_resultset{"dbactivewritingclients"}->[$stats_items] = `echo "$parametro" | awk '{print \$16}' | awk -F"\|" '{print \$1}' | tr -d "\n"`; $mongo_resultset{"dbnetworktrafficinbits"}->[$stats_items] = `echo "$parametro" | awk '{print \$17}' | rev | cut -c2- | rev | tr -d "\n"`; $mongo_resultset{"dbnetworktrafficinbitunit"}->[$stats_items] = `echo "$parametro" | awk '{print \$17}' | rev | cut -c1 | tr -d "\n"`; $mongo_resultset{"dbnetworktrafficoutbits"}->[$stats_items] = `echo "$parametro" | awk '{print \$18}' | rev | cut -c2- | rev | tr -d "\n"`; $mongo_resultset{"dbnetworktrafficoutbitunit"}->[$stats_items] = `echo "$parametro" | awk '{print \$18}' | rev | cut -c1 | tr -d "\n"`; $mongo_resultset{"dbopenconnections"}->[$stats_items] = `echo "$parametro" | awk '{print \$19}' | tr -d "\n"`; } $stats_items++; } } } # ---------------------------------------------------------------------------- # load_external_setup # # Load external file containing configuration # ---------------------------------------------------------------------------- sub load_external_setup ($); # Declaration due a recursive call to itself on includes sub load_external_setup ($){ my $archivo_cfg = $_[0]; my $buffer_line; my @config_file; my $parametro = ""; # Collect items from config file and put in an array if (! open (CFG, "< $archivo_cfg")) { print "[ERROR] Error opening configuration file $archivo_cfg: $!.\n"; exit 1; } while (){ $buffer_line = parse_dosline ($_); # Parse configuration file, this is specially difficult because can contain SQL code, with many things if ($buffer_line !~ /^\#/){ # begins with anything except # (for commenting) if ($buffer_line =~ m/(.+)\s(.*)/){ push @config_file, $buffer_line; } } } close (CFG); # Some plugin setup default options $plugin_setup{"mongostat"}="mongostat"; $plugin_setup{"tmconfig"}="tmconfig"; $plugin_setup{"logparser"}="grep_log"; # $plugin_setup{"mongostat"} = ""; NOT USED ANYMORE foreach (@config_file){ $parametro = $_; if ($parametro =~ m/^instance\s(.*)/i) { $plugin_setup{"mongoinstance"}=$1; } if ($parametro =~ m/export PATH=(.*)/i) { $ENV{'PATH'} = $1; } if ($parametro =~ m/export LD_LIBRARY_PATH=(.*)/i) { $ENV{'LD_LIBRARY_PATH'} = $1; } if ($parametro =~ m/export MONGOCONFIG=(.*)/i) { $ENV{'MONGOCONFIG'} = $1; } if ($parametro =~ m/export NLSPATH=(.*)/i) { $ENV{'NLSPATH'} = $1; } if ($parametro =~ m/export MONGODIR=(.*)/i) { $ENV{'MONGODIR'} = $1; } if ($parametro =~ m/export APPDIR=(.*)/i) { $ENV{'APPDIR'} = $1; } if ($parametro =~ m/export LANG=(.*)/i) { $ENV{'LANG'} = $1; } if ($parametro =~ m/^include\s(.*)/i) { load_external_setup ($1); } if ($parametro =~ m/^logparser\s(.*)/i) { $plugin_setup{"logparser"}=$1; } # Log check if ($parametro =~ m/^log\s(.*)/i) { $plugin_setup{"log"}->[$log_items]=$1; $log_items++; } # Volume check if ($parametro =~ m/^volume\s(.*)/i) { $plugin_setup{"volume"}->[$volume_items]=$1; $volume_items++; } # Processcheck if ($parametro =~ m/^process\s(.*)/i) { $plugin_setup{"process"}->[$process_items]=$1; $process_items++; } # mongodb stats if ($parametro =~ m/^mongodb_stats\s(.*)/i) { $plugin_setup{"mongodb_stats"}->[$mongo_items]=$1; $mongo_items++; } } } # ---------------------------------------------------------------------------- # mongostat # # This function uses mongostat from Mongo to get information # Given Command (mongostat), check type and monitored object (optional) # ---------------------------------------------------------------------------- sub mongostat ($$$$$){ my $cmdname = $_[0]; my $checktype = $_[1]; my $objname = $_[2]; my $host = $_[3]; my $port = $_[4]; #Mongo instance my $mongoinstance = $plugin_setup{"mongoinstance"}; if (!defined $mongoinstance) { $mongoinstance = $hostname; } # Call to mongostat my $mongostat_call; if ($cmdname) { $mongostat_call = $cmdname; } else { $mongostat_call = $plugin_setup{"mongostat"}; } if ($checktype eq "check_dbstats") { $stats_items = 0; my $tmadmpqc_cmd = `$mongostat_call -n1 --host $host --port $port --all | tail -1 > "$resultfilestats"`; load_mongo_result ($resultfilestats); if ($stats_items > 0) { my $ax; my $cx; my $value = 0; my $novalue = 0; my $realchecker; my $dbinserts = 0; my $dbqueries = 0; my $dbupdates = 0; my $dbdeletes = 0; my $dbgetmores = 0; my $dbcommands = 0; my $dbflushes = 0; my $dbpagefaults = 0; my $dblockpercent = 0; my $dbbttreepagemissedpercent = 0; my $dbclientreadqueuelength = 0; my $dbclientwritequeuelength = 0; my $dbactivereadingclients = 0; my $dbactivewritingclients = 0; my $dbnetworktrafficinbits = 0; my $dbnetworktrafficinbitunit; my $dbnetworktrafficoutbits = 0; my $dbnetworktrafficoutbitunit; my $dbopenconnections = 0; for ($ax=0; $ax < $stats_items + 0; $ax++){ my $bx = $ax - 1; $realchecker = $mongo_resultset{"checker"}[$ax]; $dbinserts = $mongo_resultset{"dbinserts"}[$ax]; $dbqueries = $mongo_resultset{"dbqueries"}[$ax]; $dbupdates = $mongo_resultset{"dbupdates"}[$ax]; $dbdeletes = $mongo_resultset{"dbdeletes"}[$ax]; $dbgetmores = $mongo_resultset{"dbgetmores"}[$ax]; $dbcommands = $mongo_resultset{"dbcommands"}[$ax]; $dbflushes = $mongo_resultset{"dbflushes"}[$ax]; $dbpagefaults = $mongo_resultset{"dbpagefaults"}[$ax]; $dbbttreepagemissedpercent = $mongo_resultset{"dbbttreepagemissedpercent"}[$ax]; $dbclientreadqueuelength = $mongo_resultset{"dbclientreadqueuelength"}[$ax]; $dbclientwritequeuelength = $mongo_resultset{"dbclientwritequeuelength"}[$ax]; $dbactivereadingclients = $mongo_resultset{"dbactivereadingclients"}[$ax]; $dbactivewritingclients = $mongo_resultset{"dbactivewritingclients"}[$ax]; $dbnetworktrafficinbits = $mongo_resultset{"dbnetworktrafficinbits"}[$ax]; $dbnetworktrafficinbitunit = $mongo_resultset{"dbnetworktrafficinbitunit"}[$ax]; $dbnetworktrafficoutbits = $mongo_resultset{"dbnetworktrafficoutbits"}[$ax]; $dbnetworktrafficoutbitunit = $mongo_resultset{"dbnetworktrafficoutbitunit"}[$ax]; $dbopenconnections = $mongo_resultset{"dbopenconnections"}[$ax]; if ($dbnetworktrafficinbitunit eq "k") { $dbnetworktrafficinbits = $dbnetworktrafficinbits * 1024; } elsif ($dbnetworktrafficinbitunit eq "m") { $dbnetworktrafficinbits = $dbnetworktrafficinbits * 1024 * 1024; } elsif ($dbnetworktrafficinbitunit eq "g") { $dbnetworktrafficinbits = $dbnetworktrafficinbits * 1024 * 1024 * 1024; } elsif ($dbnetworktrafficinbitunit eq "t") { $dbnetworktrafficinbits = $dbnetworktrafficinbits * 1024 * 1024 * 1024 * 1024; } if ($dbnetworktrafficoutbitunit eq "k") { $dbnetworktrafficoutbits = $dbnetworktrafficoutbits * 1024; } elsif ($dbnetworktrafficoutbitunit eq "m") { $dbnetworktrafficoutbits = $dbnetworktrafficoutbits * 1024 * 1024; } elsif ($dbnetworktrafficoutbitunit eq "g") { $dbnetworktrafficoutbits = $dbnetworktrafficoutbits * 1024 * 1024 * 1024; } elsif ($dbnetworktrafficoutbitunit eq "t") { $dbnetworktrafficoutbits = $dbnetworktrafficoutbits * 1024 * 1024 * 1024 * 1024; } } if ($objname eq "") { print_module("MongoDB_Inserts_" . "$host" . ":" . "$port", "generic_data", $dbinserts, "DB Inserts per second for $host" . ":" . "$port"); print_module("MongoDB_Queries_" . "$host" . ":" . "$port", "generic_data", $dbqueries, "DB Queries per second for $host" . ":" . "$port"); print_module("MongoDB_Updates_" . "$host" . ":" . "$port", "generic_data", $dbupdates, "DB Updates per second for $host" . ":" . "$port"); print_module("MongoDB_Deletes_" . "$host" . ":" . "$port", "generic_data", $dbdeletes, "DB Deletes per second for $host" . ":" . "$port"); print_module("MongoDB_Getmores_" . "$host" . ":" . "$port", "generic_data", $dbgetmores, "DB Getmore operations per second for $host" . ":" . "$port"); print_module("MongoDB_Commands_" . "$host" . ":" . "$port", "generic_data", $dbcommands, "DB Command operations per second for $host" . ":" . "$port"); print_module("MongoDB_Flushes_" . "$host" . ":" . "$port", "generic_data", $dbflushes, "DB Fsync Flushes per second for $host" . ":" . "$port"); print_module("MongoDB_PageFaults_" . "$host" . ":" . "$port", "generic_data", $dbpagefaults, "DB Page faults per second for $host" . ":" . "$port"); print_module("MongoDB_IdxMiss_" . "$host" . ":" . "$port", "generic_data", $dbbttreepagemissedpercent, "DB bttree page missed percentage for $host" . ":" . "$port"); print_module("MongoDB_ClientReadQueueLength_" . "$host" . ":" . "$port", "generic_data", $dbclientreadqueuelength, "DB Client read queue length for $host" . ":" . "$port"); print_module("MongoDB_ClientWriteQueueLength_" . "$host" . ":" . "$port", "generic_data", $dbclientwritequeuelength, "DB Client write queue length for $host" . ":" . "$port"); print_module("MongoDB_ActiveClientsReading_" . "$host" . ":" . "$port", "generic_data", $dbactivereadingclients, "DB Active clients reading for $host" . ":" . "$port"); print_module("MongoDB_ActiveClientsWriting_" . "$host" . ":" . "$port", "generic_data", $dbactivewritingclients, "DB Active clients writing for $host" . ":" . "$port"); print_module("MongoDB_NetworkTrafficInBits_" . "$host" . ":" . "$port", "generic_data", $dbnetworktrafficinbits, "DB Network traffic in bits for $host" . ":" . "$port"); print_module("MongoDB_NetworkTrafficOutBits_" . "$host" . ":" . "$port", "generic_data", $dbnetworktrafficoutbits, "DB Network traffic out bits for $host" . ":" . "$port"); print_module("MongoDB_OpenConns_" . "$host" . ":" . "$port", "generic_data", $dbopenconnections, "DB Open connections for $host" . ":" . "$port"); } elsif ($objname eq "shardctrl") { print_module("MongoDB_Inserts_" . "$host" . ":" . "$port", "generic_data", $dbinserts, "DB Inserts per second for $host" . ":" . "$port"); print_module("MongoDB_Queries_" . "$host" . ":" . "$port", "generic_data", $dbqueries, "DB Queries per second for $host" . ":" . "$port"); print_module("MongoDB_Updates_" . "$host" . ":" . "$port", "generic_data", $dbupdates, "DB Updates per second for $host" . ":" . "$port"); print_module("MongoDB_Deletes_" . "$host" . ":" . "$port", "generic_data", $dbdeletes, "DB Deletes per second for $host" . ":" . "$port"); print_module("MongoDB_Getmores_" . "$host" . ":" . "$port", "generic_data", $dbgetmores, "DB Getmore operations per second for $host" . ":" . "$port"); print_module("MongoDB_Commands_" . "$host" . ":" . "$port", "generic_data", $dbcommands, "DB Command operations per second for $host" . ":" . "$port"); print_module("MongoDB_PageFaults_" . "$host" . ":" . "$port", "generic_data", $dbpagefaults, "DB Page faults per second for $host" . ":" . "$port"); print_module("MongoDB_NetworkTrafficInBits_" . "$host" . ":" . "$port", "generic_data", $dbnetworktrafficinbits, "DB Network traffic in bits for $host" . ":" . "$port"); print_module("MongoDB_NetworkTrafficOutBits_" . "$host" . ":" . "$port", "generic_data", $dbnetworktrafficoutbits, "DB Network traffic out bits for $host" . ":" . "$port"); print_module("MongoDB_OpenConns_" . "$host" . ":" . "$port", "generic_data", $dbopenconnections, "DB Open connections for $host" . ":" . "$port"); } } } } # ---------------------------------------------------------------------------- # alert_log # # Do a call to alertlog plugin and output the result # Receives logfile, and module name # ---------------------------------------------------------------------------- sub alert_log($$$){ my $alertlog = $_[0]; my $module_name = $_[1]; my $log_expression = $_[2]; my $plugin_call = ""; # Call to logparser if ($OS eq "MSWin32") { $plugin_call = $plugin_setup{"logparser"}. " $alertlog $module_name $log_expression"; } else { $plugin_call = $plugin_setup{"logparser"}. " $alertlog $module_name $log_expression 2> /dev/null"; } my $output = `$plugin_call`; if ($output ne ""){ print $output; } else { print_module($module_name, "async_string", "", "Alertlog for $alertlog ($log_expression)"); } } # ---------------------------------------------------------------------------- # spare_system_disk_win # # This function return % free disk on Windows, using WMI call # ---------------------------------------------------------------------------- sub spare_system_disk_win ($$){ my $name = $_[0]; my $volume = $_[1]; my $computer = "localhost"; my $objWMIService = Win32::OLE->GetObject("winmgmts:\\\\$computer\\root\\CIMV2") or return; my $colItems = $objWMIService->ExecQuery("SELECT * from CIM_LogicalDisk WHERE Name = '$volume'", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly); foreach my $objItem (in $colItems) { my $data = ($objItem->{"FreeSpace"} / $objItem->{"Size"}) * 100; print_module("Mongo_" . "$name" . "_Volume_" . "$volume", "generic_data", "$data", "Free disk on $volume (%)"); return; } } # ---------------------------------------------------------------------------- # spare_system_disk # # Check free space on volume # Receives volume name and instance # ---------------------------------------------------------------------------- sub spare_system_disk ($$) { my $name = $_[0]; my $vol = $_[1]; if ($vol eq ""){ return; } # This is a posix call, should be the same on all systems ! if ( $OS_NAME eq "SunOS\n" ) { my $output = `/usr/xpg4/bin/df -kP | grep "$vol\$" | awk '{ print \$5 }' | tr -d "%"`; my $disk_space = $output - 0; print_module("Mongo_" . "$name" . "_Volume_" . "$vol", "generic_data", $disk_space, "% of volume occupied on $vol (%)"); } else { my $output = `df -kP | grep "$vol\$" | awk '{ print \$5 }' | tr -d "%"`; my $disk_space = $output - 0; print_module("Mongo_" . "$name" . "_Volume_" . "$vol", "generic_data", $disk_space, "% of volume occupied on $vol (%)"); } } # ---------------------------------------------------------------------------- # process_status_unix # # Generates a pandora module about the running status of a given process # ---------------------------------------------------------------------------- sub process_status_unix ($$){ my $proc = $_[0]; my $proc_name = $_[1]; if ($proc eq ""){ return; } if ( $OS_NAME eq "SunOS\n" ) { my $data = trim (`/usr/ucb/ps -aguxwwww | grep "$proc" | grep -v grep | wc -l | awk '{print \$1}`); print_module("Mongo_" . "$proc_name" . "_Process_" . "$proc", "generic_proc", $data, "Status of process $proc"); } else { my $data = trim (`ps aux | grep "$proc" | grep -v grep | wc -l`); print_module("Mongo_" . "$proc_name" . "_Process_" . "$proc", "generic_proc", $data, "Status of process $proc"); } } # ---------------------------------------------------------------------------- # process_status_win # # Generates a pandora module about the running status of a given process # ---------------------------------------------------------------------------- sub process_status_win ($$){ my $proc = $_[0]; my $proc_name = $_[1]; if ($proc eq ""){ return; } my $computer = "localhost"; my $objWMIService = Win32::OLE->GetObject("winmgmts:\\\\$computer\\root\\CIMV2") or return; my $colItems = $objWMIService->ExecQuery("SELECT * FROM Win32_Process WHERE Caption = '$proc'", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly); foreach my $objItem (in $colItems) { if ($objItem->{"Caption"} eq $proc){ print_module("Mongo_" . "$proc_name" . "_Process_" . "$proc", "generic_proc", 1, "Status of process $proc"); return; } else { print_module("Mongo_" . "$proc_name" . "_Process_" . "$proc", "generic_proc", 0, "Status of process $proc"); return; } } # no matches, process is not running print_module("Mongo_" . "$proc_name" . "_Process_" . "$proc", "generic_proc", 0, "Status of process $proc"); } # ---------------------------------------------------------------------------- # process_mem_win # # Generates a Pandora FMS about memory usage of a given process "pepito.exe" # only works with EXACT names. # ---------------------------------------------------------------------------- sub process_mem_win ($$){ my $proc = $_[0]; my $proc_name = $_[1]; if ($proc eq ""){ return; } my $computer = "localhost"; my $objWMIService = Win32::OLE->GetObject("winmgmts:\\\\$computer\\root\\CIMV2") or return; my $colItems = $objWMIService->ExecQuery("SELECT * FROM Win32_Process WHERE Caption = '$proc'", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly); foreach my $objItem (in $colItems) { if ($objItem->{"Caption"} eq $proc){ print_module("Mongo_" . "$proc_name" . "_Proc_MEM_" . "$proc", "generic_data", $objItem->{"WorkingSetSize"}, "Memory in bytes of process $proc (B)"); } else { return; } } } # ---------------------------------------------------------------------------- # process_mem_unix # # Generates a Pandora FMS about memory usage of a given process # ---------------------------------------------------------------------------- sub process_mem_unix ($$){ my $vol = $_[0]; my $proc_name = $_[1]; if ($vol eq ""){ return; } if ( $OS_NAME eq "SunOS\n" ) { my $data = `/usr/ucb/ps -aguxwwww | grep "$vol" | grep -v grep | awk '{ print \$4 }'`; my @data2 = split ("\n", $data), my $tot = 0; foreach (@data2){ $tot = $tot + $_; } print_module("Mongo_" . "$proc_name" . "_Proc_MEM_" . "$vol", "generic_data", $tot, "Memory used (%) for process $vol (%)"); } else { my $data = `ps aux | grep "$vol" | grep -v grep | awk '{ print \$6 }'`; my @data2 = split ("\n", $data), my $tot = 0; foreach (@data2){ $tot = $tot + $_; } print_module("Mongo_" . "$proc_name" . "_Proc_MEM_" . "$vol", "generic_data", $tot, "Memory used (in bytes) for process $vol (%)"); } } # ---------------------------------------------------------------------------- # process_cpu_unix # # Generates a Pandora FMS about memory usage of a given process # ---------------------------------------------------------------------------- sub process_cpu_unix ($$) { my $vol = $_[0]; my $proc_name = $_[1]; if ($vol eq ""){ return; } if ( $OS_NAME eq "SunOS\n" ) { my $data = `/usr/ucb/ps -aguxwwww | grep "$vol" | grep -v grep | awk '{ print \$3 }'`; my @data2 = split ("\n", $data), my $tot = 0; foreach (@data2){ $tot = $tot + $_; } print_module("Mongo_" . "$proc_name" . "_Proc_CPU_" . "$vol", "generic_data", $tot, "CPU (%) used for process $vol (%)"); } else { my $data = `ps aux | grep "$vol" | grep -v grep | awk '{ print \$3 }'`; my @data2 = split ("\n", $data), my $tot = 0; foreach (@data2){ $tot = $tot + $_; } print_module("Mongo_" . "$proc_name" . "_Proc_CPU_" . "$vol", "generic_data", $tot, "CPU (%) used for process $vol (%)"); } } #-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # MAIN PROGRAM # ------------------------------------------------------------------------------- #-------------------------------------------------------------------------------- # Parse external configuration file # Load config file from command line if ($#ARGV == -1 ){ print "I need at least one parameter: Complete path to external configuration file \n"; exit; } # Check for file if ( ! -f $archivo_cfg ) { printf "\n [ERROR] Cannot open configuration file at $archivo_cfg. \n\n"; exit 1; } load_external_setup ($archivo_cfg); # Check for logparser, if not ready, skip all log check if ( ! -f $plugin_setup{"logparser"} ) { # Create a dummy check module with and advise warning if ($log_items > 0) { print_module("Error: Log parser not found", "async_string", 0, "Log parser not found, please check your configuration file and set it"); } $log_items =0; } # Check individual defined volumes if ($volume_items > 0){ my $ax; for ($ax=0; $ax < $volume_items; $ax++){ my ($name, $volume) = split (";",$plugin_setup{"volume"}[$ax]); if ($OS eq "MSWin32"){ spare_system_disk_win ($name, $volume); } else { spare_system_disk ($name, $volume); } } } # Check individual defined logs if ($log_items > 0){ my $ax; for ($ax=0; $ax < $log_items; $ax++){ my ($logfile, $name, $expression) = split (";",$plugin_setup{"log"}[$ax]); # Verify proper valid values here or skip if (!defined($logfile)){ next; } if (!defined($name)){ next; } if (!defined($expression)){ next; } alert_log ($logfile, $name, $expression); } } # Check individual defined process if ($process_items > 0){ my $ax; for ($ax=0; $ax < $process_items; $ax++){ my ($name, $process) = split (";",$plugin_setup{"process"}[$ax]); if ($OS eq "MSWin32") { process_status_win ($process, $name); process_mem_win ($process, $name); } else { process_status_unix ($process, $name); process_mem_unix ($process, $name); process_cpu_unix ($process, $name); } } } # Mongo stats if ($mongo_items > 0) { my $ax; for ($ax=0; $ax < $mongo_items; $ax++){ my ($cmdname, $checktype, $objname, $host, $port) = split (";",$plugin_setup{"mongodb_stats"}[$ax]); mongostat ($cmdname, $checktype, $objname, $host, $port); } }