loganalyzer/src/classes/reports/report.syslog.syslogsummary.class.php
2010-01-08 14:16:17 +01:00

510 lines
17 KiB
PHP

<?php
/*
*********************************************************************
* -> www.phplogcon.org <- *
* ----------------------------------------------------------------- *
* Some constants *
* *
* Syslogsummary Report is a basic report for Syslog messages
*
* \version 1.0.0 Init Version
* *
* All directives are explained within this file *
*
* Copyright (C) 2008-2009 Adiscon GmbH.
*
* This file is part of phpLogCon.
*
* PhpLogCon 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, either version 3 of the License, or
* (at your option) any later version.
*
* PhpLogCon 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.
*
* You should have received a copy of the GNU General Public License
* along with phpLogCon. If not, see <http://www.gnu.org/licenses/>.
*
* A copy of the GPL can be found in the file "COPYING" in this
* distribution.
*********************************************************************
*/
// --- Avoid directly accessing this file!
if ( !defined('IN_PHPLOGCON') )
{
die('Hacking attempt');
exit;
}
// ---
// --- Basic Includes!
require_once($gl_root_path . 'classes/reports/report.class.php');
// ---
class Report_syslogsummary extends Report {
// Common Properties
public $_reportVersion = 1; // Internally Version of the ReportEngine
public $_reportID = "report.syslog.syslogsummary.class"; // ID for the report, needs to be unique!
public $_reportFileBasicName = "report.syslog.syslogsummary"; // Basic Filename for reportfiles
public $_reportTitle = "Syslog Summary Report"; // Display name for the report
public $_reportDescription = "This is a Syslog Summary Report";
public $_reportHelpArticle = "";
public $_reportNeedsInit = false; // True means that this report needs additional init stuff
public $_reportInitialized = false; // True means report is installed
// Advanced Report Options
private $_maxHosts = 20; // Threshold for maximum hosts to analyse!
private $_maxMsgsPerHost = 100; // Threshold for maximum amount of syslogmessages to analyse per host
private $_colorThreshold = 10; // Threshold for coloured display of Eventcounter
// Constructor
public function Report_syslogsummary() {
// $this->_logStreamConfigObj = $streamConfigObj;
// Fill fields we need for this report
$this->_arrProperties[] = SYSLOG_UID;
$this->_arrProperties[] = SYSLOG_DATE;
$this->_arrProperties[] = SYSLOG_HOST;
$this->_arrProperties[] = SYSLOG_MESSAGETYPE;
$this->_arrProperties[] = SYSLOG_FACILITY;
$this->_arrProperties[] = SYSLOG_SEVERITY;
$this->_arrProperties[] = SYSLOG_SYSLOGTAG;
$this->_arrProperties[] = SYSLOG_PROCESSID;
$this->_arrProperties[] = SYSLOG_MESSAGE;
$this->_arrProperties[] = MISC_CHECKSUM;
// Init Customfilters Array
$this->_arrCustomFilters['_maxHosts'] = array ( 'InternalID' => '_maxHosts',
'DisplayLangID' => 'ln_report_maxHosts_displayname',
'DescriptLangID'=> 'ln_report_maxHosts_description',
FILTER_TYPE => FILTER_TYPE_NUMBER,
'DefaultValue' => 20,
'MinValue' => 1,
/* 'MaxValue' => 0,*/
);
$this->_arrCustomFilters['_maxMsgsPerHost'] =
array ( 'InternalID' => '_maxMsgsPerHost',
'DisplayLangID' => 'ln_report_maxMsgsPerHost_displayname',
'DescriptLangID'=> 'ln_report_maxMsgsPerHost_description',
FILTER_TYPE => FILTER_TYPE_NUMBER,
'DefaultValue' => 100,
'MinValue' => 1,
/* 'MaxValue' => 0,*/
);
$this->_arrCustomFilters['_colorThreshold'] =
array ( 'InternalID' => '_colorThreshold',
'DisplayLangID' => 'ln_report_colorThreshold_displayname',
'DescriptLangID'=> 'ln_report_colorThreshold_description',
FILTER_TYPE => FILTER_TYPE_NUMBER,
'DefaultValue' => 10,
'MinValue' => 1,
/* 'MaxValue' => 0,*/
);
}
/**
* startDataProcessing, analysing data
*
* @param arrProperties array in: Properties wish list.
* @return integer Error stat
*/
public function startDataProcessing()
{
global $content, $severity_colors, $gl_starttime, $fields;
// Create Filter string, append filter for EventLog Type msgs!
$szFilters = $this->_filterString . " " . $fields[SYSLOG_MESSAGETYPE]['SearchField'] . ":=" . IUT_Syslog;
// Set Filter string
$this->_streamObj->SetFilter( $szFilters );
// Need to Open stream first!
$res = $this->_streamObj->Open( $this->_arrProperties, true );
if ( $res == SUCCESS )
{
// Set to common content variables
$this->SetCommonContentVariables();
// Set report specific content variables
$content["_colorThreshold"] = $this->_colorThreshold;
// --- Report logic starts here
$content["report_rendertime"] = "";
// Step 1: Gather Summaries
// Obtain data from the logstream!
$content["report_summary"] = $this->_streamObj->ConsolidateDataByField( SYSLOG_SEVERITY, 0, SYSLOG_SEVERITY, SORTING_ORDER_DESC, null, false );
// TimeStats
$nowtime = microtime_float();
$content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s, ";
// If data is valid, we have an array!
if ( is_array($content["report_summary"]) && count($content["report_summary"]) > 0 )
{
// Count Total Events
$iTotalEvents = 0;
foreach ($content["report_summary"] as &$tmpReportData )
{
$tmpReportData['DisplayName'] = GetSeverityDisplayName( $tmpReportData[SYSLOG_SEVERITY] );
$tmpReportData['bgcolor'] = $this->GetSeverityBGColor( $tmpReportData[SYSLOG_SEVERITY] ); // $severity_colors[ $tmpReportData[SYSLOG_SEVERITY] ];
$iTotalEvents += $tmpReportData['ItemCount'];
}
// Prepent Item with totalevents count
$totalItem['DisplayName'] = "Total Events";
$totalItem['bgcolor'] = "#999999";
$totalItem['ItemCount'] = $iTotalEvents;
// Prepent to array
array_unshift( $content["report_summary"], $totalItem );
}
else
return ERROR_REPORT_NODATA;
// Get List of hosts
$content["report_computers"] = $this->_streamObj->ConsolidateItemListByField( SYSLOG_HOST, $this->_maxHosts, SYSLOG_HOST, SORTING_ORDER_DESC );
// TimeStats
$nowtime = microtime_float();
$content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s, ";
if ( is_array($content["report_computers"]) && count($content["report_computers"]) > 0 )
{
// Create plain hosts list for Consolidate function
foreach ( $content["report_computers"] as $tmpComputer )
$arrHosts[] = $tmpComputer[SYSLOG_HOST];
}
else
return ERROR_REPORT_NODATA;
// This function will consolidate the Events based per Host!
$this->ConsolidateSyslogmessagesPerHost($arrHosts);
// TimeStats
$nowtime = microtime_float();
$content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s ";
// ---
}
else
return $ret;
// Return success!
return SUCCESS;
}
/**
* InitReport, empty
*
*/
public function InitReport()
{
// Nothing todo
return SUCCESS;
}
/**
* RemoveReport, empty
*
*/
public function RemoveReport()
{
// Nothing todo
return SUCCESS;
}
/**
* validateLicense, check license code
*
*/
public function validateLicense()
{
// This is a free report!
return SUCCESS;
}
/**
* Init advanced settings from _customFilters string
*/
public function InitAdvancedSettings()
{
// Parse and Split _customFilters
if ( strlen($this->_customFilters) > 0 )
{
// First of all split by comma
$tmpFilterValues = explode( ",", $this->_customFilters );
//Loop through mappings
foreach ($tmpFilterValues as &$myFilterValue )
{
// Split subvalues
$tmpArray = explode( "=>", $myFilterValue );
// Set into temporary array
$tmpfilterid = trim($tmpArray[0]);
// Set advanced property
if ( isset($this->_arrCustomFilters[$tmpfilterid]) )
{
// Copy New value first!
$szNewVal = trim($tmpArray[1]);
// Negated logic
if (
$this->_arrCustomFilters[$tmpfilterid][FILTER_TYPE] == FILTER_TYPE_NUMBER &&
!(isset($this->_arrCustomFilters[$tmpfilterid]['MinValue']) && intval($szNewVal) < $this->_arrCustomFilters[$tmpfilterid]['MinValue']) &&
!(isset($this->_arrCustomFilters[$tmpfilterid]['MaxValue']) && intval($szNewVal) >= $this->_arrCustomFilters[$tmpfilterid]['MaxValue'])
)
{
if ( $tmpfilterid == '_maxHosts' )
$this->_maxHosts = intval($szNewVal);
else if ( $tmpfilterid == '_maxMsgsPerHost' )
$this->_maxMsgsPerHost = intval($szNewVal);
else if ( $tmpfilterid == '_colorThreshold' )
$this->_colorThreshold = intval($szNewVal);
}
else
{
// Write to debuglog
OutputDebugMessage("Failed setting advanced report option property '" . $tmpfilterid . "', value not in value range!", DEBUG_ERROR);
}
}
}
}
}
// --- Private functions...
/**
* Helper function to consolidate syslogmessages
*/
private function ConsolidateSyslogmessagesPerHost( $arrHosts )
{
global $content, $gl_starttime;
// Now open the stream for data processing
$res = $this->_streamObj->Open( $this->_arrProperties, true );
if ( $res == SUCCESS )
{
// Set reading direction
// $this->_streamObj->SetReadDirection( EnumReadDirection::Backward );
// Init uid helper
$uID = UID_UNKNOWN;
// Set position to BEGIN of FILE
$this->_streamObj->Sseek($uID, EnumSeek::BOS, 0);
// Start reading data
$ret = $this->_streamObj->Read($uID, $logArray);
// TimeStats
$nowtime = microtime_float();
$content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s ";
// Found first data record
if ( $ret == SUCCESS )
{
do
{
// Check if Event from host is in our hosts array
if ( in_array($logArray[SYSLOG_HOST], $arrHosts) )
{
// Set Host Item Basics if not set yet
if ( !isset($content["report_consdata"][ $logArray[SYSLOG_HOST] ][SYSLOG_HOST]) )
{
$content["report_consdata"][ $logArray[SYSLOG_HOST] ][SYSLOG_HOST] = $logArray[SYSLOG_HOST];
}
// Calc checksum
if ( !isset($logArray[MISC_CHECKSUM]) || $logArray[MISC_CHECKSUM] == 0 )
{
// Calc crc32 from message, we use this as index
$logArray[MISC_CHECKSUM] = crc32( $logArray[SYSLOG_MESSAGE] );
$strChecksum = $logArray[MISC_CHECKSUM];
// TODO, save calculated Checksum into DB!
}
// Check if entry exists in result array
if ( isset($content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ]) )
{
// Increment counter and set First/Last Event date
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ]['ItemCount']++;
// Set FirstEvent date if necessary!
if ( $logArray[SYSLOG_DATE][EVTIME_TIMESTAMP] < $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ]['FirstOccurrence_Date'][EVTIME_TIMESTAMP] )
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ]['FirstOccurrence_Date'] = $logArray[SYSLOG_DATE];
// Set LastEvent date if necessary!
if ( $logArray[SYSLOG_DATE][EVTIME_TIMESTAMP] > $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ]['LastOccurrence_Date'][EVTIME_TIMESTAMP] )
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ]['LastOccurrence_Date'] = $logArray[SYSLOG_DATE];
}
else
{
// Set Basic data entries
if (isset( $content['filter_facility_list'][$logArray[SYSLOG_FACILITY]] ))
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ][SYSLOG_FACILITY] = $logArray[SYSLOG_FACILITY];
else
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ][SYSLOG_FACILITY] = SYSLOG_NOTICE; // Set default in this case
if (isset( $content['filter_severity_list'][$logArray[SYSLOG_SEVERITY]] ))
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ][SYSLOG_SEVERITY] = $logArray[SYSLOG_SEVERITY];
else
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ][SYSLOG_SEVERITY] = SYSLOG_LOCAL0; // Set default in this case
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ][SYSLOG_SYSLOGTAG] = $logArray[SYSLOG_SYSLOGTAG];
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ][SYSLOG_MESSAGE] = $logArray[SYSLOG_MESSAGE];
// Set Counter and First/Last Event date
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ]['ItemCount'] = 1;
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ]['FirstOccurrence_Date'] = $logArray[SYSLOG_DATE];
$content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_msgs'][ $strChecksum ]['LastOccurrence_Date'] = $logArray[SYSLOG_DATE];
}
}
// Get next data record
$ret = $this->_streamObj->ReadNext($uID, $logArray);
} while ( $ret == SUCCESS );
// TimeStats
$nowtime = microtime_float();
$content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s ";
// Start Postprocessing
foreach( $content["report_consdata"] as &$tmpConsolidatedComputer )
{
// First use callback function to sort array
uasort($tmpConsolidatedComputer['cons_msgs'], "MultiSortArrayByItemCountDesc");
// Remove entries according to _maxMsgsPerHost
if ( count($tmpConsolidatedComputer['cons_msgs']) > $this->_maxMsgsPerHost )
{
$iDropCount = 0;
do
{
array_pop($tmpConsolidatedComputer['cons_msgs']);
$iDropCount++;
} while ( count($tmpConsolidatedComputer['cons_msgs']) > $this->_maxMsgsPerHost );
// Append a dummy entry which shows count of all other events
if ( $iDropCount > 0 )
{
$lastEntry[SYSLOG_SEVERITY] = SYSLOG_NOTICE;
$lastEntry[SYSLOG_FACILITY] = SYSLOG_LOCAL0;
$lastEntry[SYSLOG_SYSLOGTAG] = $content['LN_GEN_ALL_OTHER_EVENTS'];
$lastEntry[SYSLOG_MESSAGE] = $content['LN_GEN_ALL_OTHER_EVENTS'];
$lastEntry['ItemCount'] = $iDropCount;
$lastEntry['FirstOccurrence_Date'] = "-";
$lastEntry['LastOccurrence_Date'] = "-";
$tmpConsolidatedComputer['cons_msgs'][] = $lastEntry;
}
}
// TimeStats
$nowtime = microtime_float();
$content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s ";
// PostProcess Events!
foreach( $tmpConsolidatedComputer["cons_msgs"] as &$tmpMyEvent )
{
$tmpMyEvent['FirstOccurrence_Date_Formatted'] = GetFormatedDate( $tmpMyEvent['FirstOccurrence_Date'] );
$tmpMyEvent['LastOccurrence_Date_Formatted'] = GetFormatedDate( $tmpMyEvent['LastOccurrence_Date'] );
$tmpMyEvent['syslogseverity_text'] = $this->GetSeverityDisplayName($tmpMyEvent['syslogseverity']); //$content['filter_severity_list'][ $tmpMyEvent['syslogseverity'] ]["DisplayName"];
$tmpMyEvent['syslogfacility_text'] = $this->GetFacilityDisplayName($tmpMyEvent['syslogfacility']); //$content['filter_facility_list'][ $tmpMyEvent['syslogfacility'] ]["DisplayName"];
$tmpMyEvent['syslogseverity_bgcolor'] = $this->GetSeverityBGColor($tmpMyEvent['syslogseverity']);
$tmpMyEvent['syslogfacility_bgcolor'] = $this->GetSeverityBGColor($tmpMyEvent['syslogfacility']);
}
}
}
else
return $ret;
}
// Work done!
return SUCCESS;
}
/*
* Helper function to convert a facility string into a facility number
*/
private function GetFacilityDisplayName($nFacility)
{
global $content;
if ( isset($nFacility) && is_numeric($nFacility) )
{
foreach ( $content['filter_facility_list'] as $myfacility )
{
// check if valid!
if ( $myfacility['ID'] == $nFacility )
return $myfacility['DisplayName'];
}
}
// If we reach this point, facility is not valid
return $content['LN_GEN_UNKNOWN'];
}
/*
* Helper function to convert a severity string into a severity number
*/
private function GetSeverityDisplayName($nSeverity)
{
global $content;
if ( isset($nSeverity) && is_numeric($nSeverity) )
{
foreach ( $content['filter_severity_list'] as $myseverity )
{
// check if valid!
if ( $myseverity['ID'] == $nSeverity )
return $myseverity['DisplayName'];
}
}
// If we reach this point, severity is not valid
return $content['LN_GEN_UNKNOWN'];
}
/*
* Helper function to obtain Severity background color
*/
private function GetSeverityBGColor( $nSeverity )
{
global $severity_colors;
if ( isset( $severity_colors[$nSeverity] ) )
return $severity_colors[$nSeverity];
else
return $severity_colors[SYSLOG_INFO]; //Default
}
/*
* Helper function to obtain Severity background color
*/
private function GetFacilityBGColor( $nFacility )
{
global $facility_colors;
if ( isset( $facility_colors[$nFacility] ) )
return $facility_colors[$nFacility];
else
return $facility_colors[SYSLOG_LOCAL0]; //Default
}
//---
}
?>