2021-02-27 13:40:40 +01:00
< ? php
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// MAILGRAPH
// =========
// Script that provides a Media Type for Zabbix that will add a graph to an e-mail that is sent out
// upon an alert message.
//
// ------------------------------------------------------------------------------------------------------
2024-12-30 11:26:28 +01:00
// Release 1 tested with Zabbix 5.4 and 6.0 LTS (history available on GitHub)
2021-12-16 13:46:18 +01:00
// ------------------------------------------------------------------------------------------------------
2023-06-30 08:48:59 +02:00
// Release 2 tested with Zabbix 5.4, 6.0 LTS and 6.4 - tested with latest Composer libraries
// ------------------------------------------------------------------------------------------------------
2021-12-16 13:46:18 +01:00
// 2.00 2021/12/16 - Mark Oudsen - itemId not always provisioned by Zabbix
// Several fixes on warning - several small bug fixes
2022-01-30 16:44:43 +01:00
// 2.01 2021/12/16 - Mark Oudsen - Screens are no longer available - reverting to using Dashboards now
// 2.02 2022/01/30 - Mark Oudsen - Added cleanup routine for old logs and images
2023-06-30 10:35:17 +02:00
// 2.10 2023/06/30 - Mark Oudsen - Refactored deprecated code - now compatible with Zabbix 6.0 LTS, 6.4
2023-07-01 13:26:29 +02:00
// 2.11 2023/07/01 - Mark Oudsen - Refactored Zabbix javascript - now capturing obvious errors
// Added ability to locate latest problems for testing purposes
2023-07-03 21:50:14 +02:00
// 2.12 2023/07/02 - Mark Oudsen - Replaced SwiftMailer with PHPMailer (based on AutoTLS)
// 2.13 2023/07/03 - Mark Oudsen - Bugfixes speciifally on links into Zabbix (missing context or info)
2023-07-10 14:32:47 +02:00
// 2.14 2023/07/10 - Mark Oudsen - Adding ability to set 'From' and 'ReplyTo' addresses in configuration
// Adding ACK_URL for utilization in the template to point to Ack page
2023-07-10 23:59:33 +02:00
// Small refactor on itemId variable processing (no longer mandatory)
// Additional logic added to random eventId to explain in case of issues
2023-07-15 00:51:55 +02:00
// Fixed missing flag for fetching web url related items
2023-08-16 14:18:08 +02:00
// 2.15 2023/08/16 - Mark Oudsen - Bugfix for Zabbix 5.4 where empty or zeroed variables are no longer
// passed by Zabbix (hence resulting in weird errors)
2023-08-16 22:50:00 +02:00
// 2.16 2023/08/16 - Mark Oudsen - Adding ability to use ACKNOWLEDGE messages in the mail message
2024-12-30 11:26:28 +01:00
// 2.17 2024/12/30 - Mark Oudsen - Fixed #47 mailData initializaton (wrong location) - BernardLinz
// Fixed #46 invalid GraphId on trigger tag - BernardLinz
// Fixed #44 config.json.template wrong var name - WMP
// Fixed #45 handling of international characters - Dima-online
// Tested with latest PHPMailer (6.9.3) and TWIG (3.11.3), PHP 7.4
// Tested with PHP 8.3, TWIG (3.18.0)
// ------------------------------------------------------------------------------------------------------
// Release 3 placeholder for Zabbix 7.0 LTS and 7.2
// ------------------------------------------------------------------------------------------------------
// v2.17 Testing on Zabbix 7.0 LTS (in progress), Zabbix 7.2 (in progress)
2021-02-27 13:40:40 +01:00
// ------------------------------------------------------------------------------------------------------
//
// (C) M.J.Oudsen, mark.oudsen@puzzl.nl
// MIT License
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2024-12-30 11:26:28 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Notes
// -----
// 1) mailGraph is following the environmental requirements from Zabbix, supporting PHP 7.4-8.3 ad per
// - https://www.zabbix.com/documentation/6.0/en/manual/installation/requirements
// - https://www.zabbix.com/documentation/6.4/en/manual/installation/requirements
//
// 2) TWIG 3.18.0 is available on PHP 8 only (seemless upgrade when using composer update)
//
// 3) Testing of composer libraries updates is limited to every 6 to 12 months
// - In case you encounter an issue, please raise an issue on GitHub
// https://github.com/moudsen/mailGraph/issues
//
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2023-07-02 14:54:00 +02:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Roadmap
// -------
// - Automatic setup and configuration of mailGraph
// - Automatic code updates (CLI triggered)
// - Add DASHBOARD facility (SCREEN was abandoned in Zabbix 5.4
// - Extract Graph API functionality to seperate code unit/object
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-02-27 13:40:40 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// MAIN SEQUENCE
// -------------
// 1) Fetch trigger, item, host, graph, event information via Zabbix API via CURL
2024-12-30 11:26:28 +01:00
// 2) Fetch Graph(s) associated to the item/trigger (if any) via Zabbix URL via CURL
// 3) Build and send mail message from template using PHPmailer//TWIG
2021-02-27 13:40:40 +01:00
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// CONSTANTS
2024-12-30 11:26:28 +01:00
$cVersion = 'v2.17' ;
2021-02-27 13:40:40 +01:00
$cCRLF = chr ( 10 ) . chr ( 13 );
$maskDateTime = 'Y-m-d H:i:s' ;
2023-07-02 14:54:00 +02:00
$maxGraphs = 8 ;
2021-02-27 13:40:40 +01:00
// DEBUG SETTINGS
2021-02-27 15:40:01 +01:00
// -- Should be FALSE for production level use
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
$cDebug = TRUE ; // Extended debug logging mode, switch to FALSE for production environment
2021-03-07 22:21:38 +01:00
$cDebugMail = FALSE ; // If TRUE, includes log in the mail message (html and plain text attachments)
$showLog = FALSE ; // Display the log - !!! only use in combination with CLI mode !!!
2021-02-27 13:40:40 +01:00
2021-12-16 13:46:18 +01:00
// Limit server level output errors
2021-10-06 11:15:17 +02:00
error_reporting ( E_ERROR | E_PARSE );
2021-02-27 13:40:40 +01:00
// INCLUDE REQUIRED LIBRARIES (Composer)
2021-02-27 15:40:01 +01:00
// (configure at same location as the script is running or load in your own central library)
2023-07-02 14:54:00 +02:00
// -- phpmailer/phpmailer https://github.com/PHPMailer/PHPMailer
2021-02-27 13:40:40 +01:00
// -- twig/twig https://twig.symfony.com/doc/3.x/templates.html
2021-03-01 19:51:11 +01:00
// Change only required if you decide to use a local/central library, otherwise leave as is
2021-02-27 15:40:01 +01:00
include ( getcwd () . '/vendor/autoload.php' );
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
use PHPMailer\PHPMailer\PHPMailer ;
use PHPMailer\PHPMailer\SMTP ;
use PHPMailer\PHPMailer\Exception ;
2021-02-27 13:40:40 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Fetch the HTML source of the given URL
// --- Redirects will be honored
// --- Enforces use of IPv4
// --- Caller must verify if the return string is JSON or ERROR
function postJSON ( $url , $data )
{
global $cCRLF ;
global $cVersion ;
global $cDebug ;
2021-03-12 16:23:47 +01:00
global $HTTPProxy ;
2021-02-27 13:40:40 +01:00
// Initialize Curl instance
_log ( '% postJSON: ' . $url );
2021-03-19 12:01:41 +01:00
if ( $cDebug ) { _log ( '> POST data: ' . json_encode ( maskOutputContent ( $data ))); }
2021-02-27 13:40:40 +01:00
$ch = curl_init ();
// Set options
2021-03-12 16:23:47 +01:00
if (( isset ( $HTTPProxy )) && ( $HTTPProxy != '' ))
{
2021-04-03 16:29:26 +02:00
if ( $cDebug ) { _log ( '% Using proxy: ' . $HTTPProxy ); }
2021-03-12 16:23:47 +01:00
curl_setopt ( $ch , CURLOPT_PROXY , $HTTPProxy );
}
2021-02-27 13:40:40 +01:00
curl_setopt ( $ch , CURLOPT_IPRESOLVE , CURL_IPRESOLVE_V4 );
curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , 20 );
2021-04-03 16:29:26 +02:00
curl_setopt ( $ch , CURLOPT_POST , TRUE );
curl_setopt ( $ch , CURLOPT_POSTFIELDS , json_encode ( $data ));
2021-02-27 13:40:40 +01:00
curl_setopt ( $ch , CURLOPT_URL , $url );
curl_setopt ( $ch , CURLOPT_HTTPHEADER , array ( 'Content-Type:application/json' ));
2021-04-03 16:29:26 +02:00
curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , TRUE );
curl_setopt ( $ch , CURLOPT_USERAGENT , 'Zabbix-mailGraph - ' . $cVersion );
2021-02-27 13:40:40 +01:00
// Execute Curl
$data = curl_exec ( $ch );
if ( $data === FALSE )
{
_log ( '! Failed: ' . curl_error ( $ch ));
2021-04-03 16:29:26 +02:00
$data = array ();
$data [] = 'An error occurred while retreiving the requested page.' ;
$data [] .= 'Requested page = ' . $url ;
$data [] .= 'Error = ' . curl_error ( $ch );
2021-02-27 13:40:40 +01:00
}
2021-03-07 22:21:38 +01:00
else
{
2021-02-27 13:40:40 +01:00
_log ( '> Received ' . strlen ( $data ) . ' bytes' );
2021-03-07 22:21:38 +01:00
$data = json_decode ( $data , TRUE );
}
2021-02-27 13:40:40 +01:00
// Close Curl
curl_close ( $ch );
// Return received response
return $data ;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Fetch the given Zabbix image
// --- Store with unique name
// --- Pass filename back to caller
2021-03-03 23:26:35 +01:00
function GraphImageById ( $graphid , $width = 400 , $height = 100 , $graphType = 0 , $showLegend = 0 , $period = '48h' )
2021-02-27 13:40:40 +01:00
{
global $z_server ;
global $z_user ;
global $z_pass ;
global $z_tmp_cookies ;
global $z_images_path ;
global $z_url_api ;
global $cVersion ;
2021-02-27 17:17:54 +01:00
global $cCRLF ;
2021-03-12 16:23:47 +01:00
global $HTTPProxy ;
2021-02-27 13:40:40 +01:00
// Unique names
$thisTime = time ();
// Relative web calls
$z_url_index = $z_server . " index.php " ;
2021-03-12 15:38:46 +01:00
switch ( $graphType )
{
// 0: Normal
// 1: Stacked
2021-03-12 15:41:48 +01:00
case 0 :
case 1 :
2021-03-12 15:38:46 +01:00
$z_url_graph = $z_server . " chart2.php " ;
break ;
// 2: Pie
// 3: Exploded
2021-03-12 15:41:48 +01:00
case 2 :
case 3 :
2021-03-12 15:38:46 +01:00
$z_url_graph = $z_server . " chart6.php " ;
break ;
2021-03-12 16:23:47 +01:00
default :
// Catch all ...
_log ( '% Graph type #' . $graphType . ' unknown; forcing "Normal"' );
$z_url_graph = $z_server . " chart2.php " ;
2021-03-12 15:38:46 +01:00
}
2021-03-02 23:17:03 +01:00
$z_url_fetch = $z_url_graph . " ?graphid= " . $graphid . " &width= " . $width . " &height= " . $height .
2021-03-03 23:26:35 +01:00
" &graphtype= " . $graphType . " &legend= " . $showLegend . " &profileIdx=web.graphs.filter " .
" &from=now- " . $period . " &to=now " ;
2021-02-27 13:40:40 +01:00
// Prepare POST login
$z_login_data = array ( 'name' => $z_user , 'password' => $z_pass , 'enter' => " Sign in " );
// Cookie and image names
$filename_cookie = $z_tmp_cookies . " zabbix_cookie_ " . $graphid . " . " . $thisTime . " .txt " ;
2021-03-10 19:57:42 +01:00
$filename = " zabbix_graph_ " . $graphid . " . " . $thisTime . " - " . $period . " .png " ;
2021-02-27 13:40:40 +01:00
$image_name = $z_images_path . $filename ;
// Configure CURL
_log ( '% GraphImageById: ' . $z_url_fetch );
$ch = curl_init ();
curl_setopt ( $ch , CURLOPT_URL , $z_url_index );
curl_setopt ( $ch , CURLOPT_HEADER , false );
curl_setopt ( $ch , CURLOPT_USERAGENT , 'Zabbix-mailGraph - ' . $cVersion );
2021-03-12 16:23:47 +01:00
if (( isset ( $HTTPProxy )) && ( $HTTPProxy != '' ))
{
_log ( '% Using proxy: ' . $HTTPProxy );
curl_setopt ( $ch , CURLOPT_PROXY , $HTTPProxy );
}
2021-02-27 13:40:40 +01:00
curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , true );
curl_setopt ( $ch , CURLOPT_BINARYTRANSFER , true );
curl_setopt ( $ch , CURLOPT_SSL_VERIFYPEER , false );
curl_setopt ( $ch , CURLOPT_POST , true );
curl_setopt ( $ch , CURLOPT_POSTFIELDS , $z_login_data );
curl_setopt ( $ch , CURLOPT_COOKIEJAR , $filename_cookie );
curl_setopt ( $ch , CURLOPT_COOKIEFILE , $filename_cookie );
// Login to Zabbix
2021-02-27 17:17:54 +01:00
$login = curl_exec ( $ch );
if ( $login != '' )
{
echo 'Error logging in to Zabbix!' . $cCRLF ;
die ;
}
2021-02-27 13:40:40 +01:00
// Get the graph
curl_setopt ( $ch , CURLOPT_URL , $z_url_fetch );
$output = curl_exec ( $ch );
2021-02-27 17:17:54 +01:00
2021-02-27 13:40:40 +01:00
curl_close ( $ch );
2023-07-02 14:54:00 +02:00
// Delete cookie (if exists)
if ( file_exists ( $filename_cookie ))
{
unlink ( $filename_cookie );
_log ( '- Removed cookie ' . $filename_cookie );
}
2021-02-27 13:40:40 +01:00
// Write file
$fp = fopen ( $image_name , 'w' );
fwrite ( $fp , $output );
fclose ( $fp );
// Return filename
_log ( '> Received ' . strlen ( $output ) . ' bytes' );
_log ( '> Saved to ' . $z_images_path . $filename );
return ( $filename );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Log information
$logging = array ();
function _log ( $information )
{
global $logging ;
global $maskDateTime ;
global $showLog ;
global $cCRLF ;
$logString = date ( $maskDateTime ) . ' : ' . $information ;
$logging [] = $logString ;
if ( $showLog ) { echo $logString . $cCRLF ; }
}
2021-03-20 14:06:08 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Catch PHP warnings/notices/errors
function catchPHPerrors ( $errno , $errstr , $errfile , $errline )
{
// --- Just log ...
_log ( '!! (' . $errno . ') "' . $errstr . '" at line #' . $errline . ' of "' . $errfile . '"' );
// --- We do not take care of any errors, etc.
return FALSE ;
}
set_error_handler ( " catchPHPerrors " );
2021-02-27 15:40:01 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Read configuration file
function readConfig ( $fileName )
{
global $cCRLF ;
if ( ! file_exists ( $fileName ))
{
echo 'Config file not found. (' . $fileName . ')' . $cCRLF ;
die ;
}
$content = file_get_contents ( $fileName );
$data = json_decode ( $content , TRUE );
if ( $data == NULL )
{
echo 'Invalid JSON format in config file?! (' . $fileName . ')' . $cCRLF ;
die ;
}
return ( $data );
}
2021-02-27 13:40:40 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// API request ID counter - for best practice / debug purposes only
$requestCounter = 0 ;
function nextRequestID ()
{
global $requestCounter ;
$requestCounter ++ ;
return ( $requestCounter );
}
2021-03-19 12:01:41 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Check the array for information we do not want to share in any logging
function maskOutputFields ( $info )
{
foreach ( $info as $aKey => $aValue )
{
switch ( $aKey )
{
case 'zabbix_user' :
case 'zabbix_user_pwd' :
case 'zabbix_api_user' :
case 'zabbix_api_pwd' :
$info [ $aKey ] = '<masked>' ;
break ;
}
}
return ( $info );
}
// Check the array if it contains information that should not be logged
function maskOutputContent ( $info )
{
global $config ;
foreach ( $info as $infoKey => $infoValue )
{
if ( is_array ( $infoValue )) { $info [ $infoKey ] = maskOutputContent ( $infoValue ); }
foreach ( $config as $aKey => $aValue )
{
switch ( $aKey )
{
case 'zabbix_user' :
case 'zabbix_user_pwd' :
case 'zabbix_api_user' :
case 'zabbix_api_pwd' :
if ( $aValue == $infoValue ) { $info [ $infoKey ] = '<masked>' ; };
break ;
}
}
}
return ( $info );
}
2022-01-30 16:44:43 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Cleanup 'path': remove files with 'ext' older than 'daysOld'
function cleanupDir ( $path , $ext , $daysOld )
{
_log ( '- Scanning "' . $path . '"' );
$files = glob ( $path . '/*' . $ext );
$now = time ();
$filesRemoved = 0 ;
$filesKept = 0 ;
foreach ( $files as $file )
{
if ( is_file ( $file ))
{
if ( $now - filemtime ( $file ) >= ( 60 * 60 * 24 * $daysOld ))
{
_log ( '> Removing "' . $file . '"' );
unlink ( $file );
$filesRemoved ++ ;
}
else
{
$filesKept ++ ;
}
}
}
_log ( ': Done. Cleaned up ' . $filesRemoved . ' file(s), kept ' . $filesKept . ' file(s)' );
}
2023-08-16 22:50:00 +02:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Zabbix translator functions
function zabbixTStoString ( $linuxTime )
{
return date ( " Y-m-d H:i:s " , $linuxTime );
}
function zabbixActionToString ( $actionMask )
{
$values = [];
if ( $actionMask & 1 ) { $values [] = " Close problem " ; }
if ( $actionMask & 2 ) { $values [] = " Acknowledge event " ; }
if ( $actionMask & 4 ) { $values [] = " Add message " ; }
if ( $actionMask & 8 ) { $values [] = " Change severity " ; }
if ( $actionMask & 16 ) { $values [] = " Unacknowledge event " ; }
if ( $actionMask & 32 ) { $values [] = " Suppress event " ; }
if ( $actionMask & 64 ) { $values [] = " Unsuppress event " ; }
if ( $actionMask & 128 ) { $values [] = " Change event rank to cause " ; }
if ( $actionMask & 256 ) { $values [] = " Change event rank to sympton " ; }
return implode ( " , " , $values );
}
function zabbixSeverityToString ( $severity )
{
switch ( $severity ) {
case 0 : return ( 'Not classified' );
case 1 : return ( 'Information' );
case 2 : return ( 'Warning' );
case 3 : return ( 'Average' );
case 4 : return ( 'High' );
case 5 : return ( 'Disaster' );
}
}
2021-02-27 13:40:40 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize ///////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-03-03 23:26:35 +01:00
// --- CONFIG DATA ---
2021-02-27 15:40:01 +01:00
// [CONFIGURE] Change only when you want to place your config file somewhere else ...
$config = readConfig ( getcwd () . '/config/config.json' );
2021-03-19 12:01:41 +01:00
_log ( '# Configuration taken from config.json' . $cCRLF .
json_encode ( maskOutputFields ( $config ), JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
2021-03-01 18:13:32 +01:00
2024-12-30 11:26:28 +01:00
// --- MAIL DATA ---
$mailData = array ();
2021-03-03 23:26:35 +01:00
// --- POST DATA ---
2021-02-27 15:40:01 +01:00
// Read POST data
2021-02-27 13:40:40 +01:00
$problemJSON = file_get_contents ( 'php://input' );
$problemData = json_decode ( $problemJSON , TRUE );
2021-03-03 23:26:35 +01:00
// --- CLI DATA ---
2021-03-12 16:23:47 +01:00
$HTTPProxy = '' ;
2021-02-27 15:40:01 +01:00
// Facilitate CLI based testing
2021-02-27 13:40:40 +01:00
if ( isset ( $argc ))
{
if (( $argc > 1 ) && ( $argv [ 1 ] == 'test' ))
{
2021-07-05 22:47:05 +02:00
// Switch on CLI log display
$showLog = TRUE ;
_log ( '<<< mailGraph ' . $cVersion . ' >>>' );
2021-02-27 15:40:01 +01:00
_log ( '# Invoked from CLI' );
2021-02-27 13:40:40 +01:00
2023-07-10 23:59:33 +02:00
// Assumes that config.json file has the correct information for MANDATORY information
2021-03-03 23:26:35 +01:00
2023-08-16 14:18:08 +02:00
// DEFAULTS
2023-07-10 23:59:33 +02:00
$problemData [ 'eventId' ] = 0 ;
2023-08-16 14:18:08 +02:00
$problemData [ 'duration' ] = 0 ;
2023-07-10 23:59:33 +02:00
2023-08-16 14:18:08 +02:00
// MANDATORY
2021-02-27 15:40:01 +01:00
$problemData [ 'recipient' ] = $config [ 'cli_recipient' ];
$problemData [ 'baseURL' ] = $config [ 'cli_baseURL' ];
2021-02-27 13:40:40 +01:00
2021-03-10 19:57:42 +01:00
// OPTIONAL
2023-07-10 23:59:33 +02:00
if ( isset ( $config [ 'cli_eventId' ])) { $problemData [ 'eventId' ] = $config [ 'cli_eventId' ]; }
2023-08-16 14:18:08 +02:00
if ( isset ( $config [ 'cli_duration' ])) { $problemData [ 'duration' ] = $config [ 'cli_duration' ]; }
2021-03-17 13:03:54 +01:00
if ( isset ( $config [ 'cli_subject' ])) { $problemData [ 'subject' ] = $config [ 'cli_subject' ]; }
if ( isset ( $config [ 'cli_period' ])) { $problemData [ 'period' ] = $config [ 'cli_period' ]; }
2021-03-10 19:57:42 +01:00
if ( isset ( $config [ 'cli_period_header' ])) { $problemData [ 'period_header' ] = $config [ 'cli_period_header' ]; }
if ( isset ( $config [ 'cli_periods' ])) { $problemData [ 'periods' ] = $config [ 'cli_periods' ]; }
if ( isset ( $config [ 'cli_periods_headers' ])) { $problemData [ 'periods_headers' ] = $config [ 'cli_periods_headers' ]; }
if ( isset ( $config [ 'cli_debug' ])) { $problemData [ 'debug' ] = $config [ 'cli_debug' ]; }
2021-03-12 16:23:47 +01:00
if ( isset ( $config [ 'cli_proxy' ])) { $problemData [ 'HTTPProxy' ] = $config [ 'cli_proxy' ]; }
2023-07-10 23:59:33 +02:00
// BACKWARDS COMPATIBILITY - obsolete from Zabbix 6.2 onwards
$problemData [ 'itemId' ] = 0 ;
if ( isset ( $config [ 'cli_itemId' ])) { $problemData [ 'itemId' ] = $config [ 'cli_itemId' ]; }
2021-02-27 13:40:40 +01:00
}
2022-01-30 16:44:43 +01:00
if (( $argc > 1 ) && ( $argv [ 1 ] == 'cleanup' ))
{
// Switch on CLI log display
$showLog = TRUE ;
// Check for configuration of retention period for images and logs
_log ( '<<< mailGraph ' . $cVersion . ' >>>' );
_log ( '# Invoked from CLI' );
// Set defaults
$retImages = 30 ;
$retLogs = 14 ;
// Check if configured settings
if ( isset ( $config [ 'retention_images' ])) { $retImages = intval ( $config [ 'retention_images' ]); }
if ( isset ( $config [ 'retention_logs' ])) { $retLogs = intval ( $config [ 'retention_logs' ]); }
_log ( 'Cleaning up IMAGES (' . $retImages . ' days) and LOGS (' . $retLogs . ' days)' );
cleanupDir ( getcwd () . '/images' , '.png' , $retImages );
cleanupDir ( getcwd () . '/log' , '.dump' , $retLogs );
exit ( 0 );
}
2021-02-27 13:40:40 +01:00
}
2021-03-20 14:06:08 +01:00
_log ( '# Data passed to MailGraph main routine and used for processing' .
$cCRLF . json_encode ( $problemData , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
2021-03-01 18:13:32 +01:00
2021-03-03 23:26:35 +01:00
// --- CHECK AND SET P_ VARIABLES ---
2023-08-16 14:18:08 +02:00
2021-03-05 11:57:01 +01:00
// FROM POST OR CLI DATA
2021-03-01 18:13:32 +01:00
2021-02-27 13:40:40 +01:00
if ( ! isset ( $problemData [ 'eventId' ])) { echo " Missing EVENT ID? \n " ; die ; }
$p_eventId = intval ( $problemData [ 'eventId' ]);
if ( ! isset ( $problemData [ 'recipient' ])) { echo " Missing RECIPIENT? \n " ; die ; }
2023-06-30 10:16:29 +02:00
$p_recipient = $problemData [ 'recipient' ];
2021-02-27 13:40:40 +01:00
2023-08-16 14:18:08 +02:00
$p_duration = 0 ;
if ( isset ( $problemData [ 'duration' ])) { $p_duration = intval ( $problemData [ 'duration' ]); }
2021-02-27 13:40:40 +01:00
if ( ! isset ( $problemData [ 'baseURL' ])) { echo " Missing URL? \n " ; die ; }
$p_URL = $problemData [ 'baseURL' ];
2021-03-02 23:17:03 +01:00
$p_subject = '{{ EVENT_SEVERITY }}: {{ EVENT_NAME|raw }}' ;
2021-02-28 21:31:46 +01:00
if ( isset ( $problemData [ 'subject' ])) { $p_subject = $problemData [ 'subject' ]; }
2021-02-27 13:40:40 +01:00
$p_graphWidth = 450 ;
if ( isset ( $problemData [ 'graphWidth' ])) { $p_graphWidth = intval ( $problemData [ 'graphWidth' ]); }
$p_graphHeight = 120 ;
if ( isset ( $problemData [ 'graphHeight' ])) { $p_graphHeight = intval ( $problemData [ 'graphHeight' ]); }
$p_showLegend = 0 ;
if ( isset ( $problemData [ 'showLegend' ])) { $p_showLegend = intval ( $problemData [ 'showLegend' ]); }
2021-03-03 23:26:35 +01:00
$p_period = '48h' ;
if ( isset ( $problemData [ 'period' ])) { $p_period = $problemData [ 'period' ]; }
2021-07-07 19:39:02 +02:00
if ( isset ( $problemData [ 'HTTPProxy' ])) { $HTTPProxy = $problemData [ 'HTTPProxy' ]; }
2021-03-12 16:23:47 +01:00
2021-03-05 11:57:01 +01:00
// DYNAMIC VARIABLES FROM ZABBIX
foreach ( $problemData as $aKey => $aValue )
{
if ( substr ( $aKey , 0 , 4 ) == 'info' ) { $mailData [ $aKey ] = $aValue ; }
}
2021-03-03 23:26:35 +01:00
// FROM CONFIG DATA
2021-03-01 18:13:32 +01:00
$p_smtp_server = 'localhost' ;
if ( isset ( $config [ 'smtp_server' ])) { $p_smtp_server = $config [ 'smtp_server' ]; }
$p_smtp_port = 25 ;
if ( isset ( $config [ 'smtp_port' ])) { $p_smtp_port = $config [ 'smtp_port' ]; }
2021-02-27 13:40:40 +01:00
2021-03-01 19:51:11 +01:00
$p_smtp_strict = 'yes' ;
if (( isset ( $config [ 'smtp_strict' ])) && ( $config [ 'smtp_strict' ] == 'no' )) { $p_smtp_strict = 'no' ; }
2021-03-24 12:27:44 +01:00
$p_smtp_username = '' ;
if ( isset ( $config [ 'smtp_username' ])) { $p_smtp_username = $config [ 'smtp_username' ]; }
$p_smtp_password = '' ;
if ( isset ( $config [ 'smtp_password' ])) { $p_smtp_password = $config [ 'smtp_password' ]; }
2023-07-10 10:09:39 +02:00
$p_smtp_from_address = '' ;
if ( isset ( $config [ 'smtp_from_address' ])) { $p_smtp_from_address = $config [ 'smtp_from_address' ]; }
$p_smtp_from_name = 'mailGraph' ;
if ( isset ( $config [ 'smtp_from_name' ])) { $p_smtp_from_name = $config [ 'smtp_from_name' ]; }
2023-07-10 14:32:47 +02:00
$p_smtp_reply_address = '' ;
if ( isset ( $config [ 'smtp_reply_address' ])) { $p_smtp_reply_address = $config [ 'smtp_reply_address' ]; }
$p_smtp_reply_name = 'mailGraph feedback' ;
if ( isset ( $config [ 'smtp_reply_name' ])) { $p_smtp_reply_name = $config [ 'smtp_reply_name' ]; }
2023-07-10 11:21:48 +02:00
// >>> Backwards compatibility but smtp_from_address is leading (<v2.14)
$mailFrom = '' ;
if ( isset ( $config [ 'mail_from' ])) { $mailFrom = $config [ 'mail_from' ]; }
if (( $p_smtp_from_address == '' ) && ( $mailFrom != '' ))
{
$p_smtp_from_address = $mailFrom ;
}
2021-03-01 20:22:42 +01:00
$p_graph_match = 'any' ;
if (( isset ( $config [ 'graph_match' ])) && ( $config [ 'graph_match' ] == 'exact' )) { $p_graph_match = 'exact' ; }
2021-03-03 23:26:35 +01:00
// --- GLOBAL CONFIGURATION ---
2021-02-27 13:40:40 +01:00
2021-02-27 15:40:01 +01:00
// Script related settings
$z_url = $config [ 'script_baseurl' ]; // Script URL location (for relative paths to images, templates, log, tmp)
2021-12-16 13:46:18 +01:00
$z_url_image = $z_url . 'images/' ; // Images URL (included in plain message text)
2021-02-27 13:40:40 +01:00
2021-12-16 13:46:18 +01:00
// Absolute path where to store the generated images - note: script does not take care of clearing out old images!
2021-02-27 15:40:01 +01:00
$z_path = getcwd () . '/' ; // Absolute base path on the filesystem for this url
2021-12-16 13:46:18 +01:00
$z_images_path = $z_path . 'images/' ;
$z_template_path = $z_path . 'templates/' ;
$z_tmp_cookies = $z_path . 'tmp/' ;
$z_log_path = $z_path . 'log/' ;
2021-02-27 13:40:40 +01:00
2023-08-17 06:39:34 -04:00
// If tmp, log, or images does not exist, create them
2023-07-15 00:51:55 +02:00
if ( ! is_dir ( $z_tmp_cookies ))
{
mkdir ( $z_tmp_cookies );
_log ( '+ created TMP directory "' . $z_tmp_cookies . '"' );
}
if ( ! is_dir ( $z_log_path ))
{
mkdir ( $z_log_path );
_log ( '+ created LOG directory "' . $z_log_path . '"' );
}
2023-08-17 06:39:34 -04:00
if ( ! is_dir ( $z_images_path ))
{
mkdir ( $z_images_path );
_log ( '+ created IMAGES directory "' . $z_images_path . '"' );
}
2021-02-27 13:40:40 +01:00
// Zabbix user (requires Super Admin access rights to access image generator script)
2021-02-27 15:40:01 +01:00
$z_user = $config [ 'zabbix_user' ];
$z_pass = $config [ 'zabbix_user_pwd' ];
2021-02-27 13:40:40 +01:00
// Zabbix API user (requires Super Admin access rights)
2023-06-30 08:48:59 +02:00
// --- Copy from Zabbix user and override when defined in configuration
2023-06-30 10:16:29 +02:00
// TODO: Check if information retreival can be done with less rigths
2023-06-30 08:48:59 +02:00
$z_api_user = $z_user ;
$z_api_pass = $z_pass ;
if ( isset ( $config [ 'zabbix_api_user' ]))
{
$z_api_user = $config [ 'zabbix_api_user' ];
}
if ( isset ( $config [ 'zabbix_api_pwd' ]))
{
$z_api_pass = $config [ 'zabbix_api_pwd' ];
}
2021-02-27 13:40:40 +01:00
// Derived variables - do not change!
$z_server = $p_URL ; // Zabbix server URL from config
$z_url_api = $z_server . " api_jsonrpc.php " ; // Zabbix API URL
2021-03-03 23:26:35 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Check accessibility of paths and template files //////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-02-27 13:40:40 +01:00
2021-12-16 13:46:18 +01:00
if ( ! is_writable ( $z_images_path )) { echo 'Image path inaccessible?' . $cCRLF ; die ; }
if ( ! is_writable ( $z_tmp_cookies )) { echo 'Cookies temporary path inaccessible?' . $cCRLF ; die ; }
if ( ! is_writable ( $z_log_path )) { echo 'Log path inaccessible?' . $cCRLF ; die ; }
2021-03-03 23:26:35 +01:00
if ( ! file_exists ( $z_template_path . 'html.template' )) { echo 'HTML template missing?' . $cCRLF ; die ; }
if ( ! file_exists ( $z_template_path . 'plain.template' )) { echo 'PLAIN template missing?' . $cCRLF ; die ; }
2021-02-27 13:40:40 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Fetch information via API ////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-02-28 21:31:46 +01:00
$mailData [ 'BASE_URL' ] = $p_URL ;
$mailData [ 'SUBJECT' ] = $p_subject ;
2021-02-27 13:40:40 +01:00
2021-03-17 13:03:54 +01:00
// -------------
2021-02-27 13:40:40 +01:00
// --- LOGIN ---
2021-03-17 13:03:54 +01:00
// -------------
2021-02-27 13:40:40 +01:00
_log ( '# LOGIN to Zabbix' );
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'user.login' ,
2023-06-30 08:48:59 +02:00
'params' => array ( 'username' => $z_api_user ,
2021-02-27 13:40:40 +01:00
'password' => $z_api_pass ),
'id' => nextRequestID (),
'auth' => null );
$result = postJSON ( $z_url_api , $request );
$token = '' ;
if ( isset ( $result [ 'result' ])) { $token = $result [ 'result' ]; }
2021-04-03 16:29:26 +02:00
if ( $token == '' )
{
2021-12-16 13:46:18 +01:00
echo 'Error logging in to Zabbix? (' . $z_url_api . '): ' . $cCRLF ;
2021-04-03 16:29:26 +02:00
echo var_dump ( $request ) . $cCRLF ;
echo var_dump ( $result ) . $cCRLF ;
die ;
}
2021-02-27 13:40:40 +01:00
_log ( '> Token = ' . $token );
2023-07-02 14:54:00 +02:00
// -----------------------
// --- LOG API VERSION ---
// -----------------------
_log ( '# Record Zabbix API version' );
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'apiinfo.version' ,
'params' => [],
'id' => nextRequestID ());
$result = postJSON ( $z_url_api , $request );
$apiVersion = $result [ 'result' ];
_log ( '> API version ' . $apiVersion );
2023-07-01 13:26:29 +02:00
// -----------------------------------
// --- IF NO EVENT ID FETCH LATEST ---
// -----------------------------------
if ( $p_eventId == " 0 " )
{
_log ( '# No event ID given, picking up random event from Zabbix' );
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'problem.get' ,
'params' => array ( 'output' => 'extend' ,
'recent' => 'true' ,
'limit' => 1 ),
'auth' => $token ,
'id' => nextRequestID ());
$thisProblems = postJSON ( $z_url_api , $request );
2023-07-10 23:59:33 +02:00
_log ( '> Problem data (recent)' . $cCRLF . json_encode ( $thisProblems , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
if ( ! isset ( $thisProblems [ 'result' ][ 0 ]))
{
_log ( '- No response data received. Retrying with less recent problems ... ' );
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'problem.get' ,
'params' => array ( 'output' => 'extend' ,
'recent' => 'false' ,
'limit' => 1 ),
'auth' => $token ,
'id' => nextRequestID ());
2023-07-01 13:26:29 +02:00
2023-07-10 23:59:33 +02:00
$thisProblems = postJSON ( $z_url_api , $request );
_log ( '> Problem data (not recent)' . $cCRLF . json_encode ( $thisProblems , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
if ( ! isset ( $thisProblems [ 'result' ][ 0 ]))
{
_log ( '! Cannot continue: mailGraph is unable to pick a random event via the Zabbix API. It is highly likely that no active problems exist? Please retry or determine and set an event ID manually and retry.' );
die ;
}
}
2023-07-01 13:26:29 +02:00
$p_eventId = $thisProblems [ 'result' ][ 0 ][ 'eventid' ];
_log ( '> Picked up random last event #' . $p_eventId );
}
2021-03-17 13:03:54 +01:00
// ------------------------------
// --- READ EVENT INFORMATION ---
// ------------------------------
_log ( '# Retreiving EVENT information' );
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'event.get' ,
'params' => array ( 'eventids' => $p_eventId ,
'output' => 'extend' ,
'selectRelatedObject' => 'extend' ,
2023-08-16 22:50:00 +02:00
'selectSuppressionData' => 'extend' ,
'select_acknowledges' => 'extend' ),
2021-03-17 13:03:54 +01:00
'auth' => $token ,
'id' => nextRequestID ());
$thisEvent = postJSON ( $z_url_api , $request );
_log ( '> Event data' . $cCRLF . json_encode ( $thisEvent , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
if ( ! isset ( $thisEvent [ 'result' ][ 0 ])) { echo '! No response data received?' . $cCRLF ; die ; }
$mailData [ 'EVENT_ID' ] = $thisEvent [ 'result' ][ 0 ][ 'eventid' ];
$mailData [ 'EVENT_NAME' ] = $thisEvent [ 'result' ][ 0 ][ 'name' ];
$mailData [ 'EVENT_OPDATA' ] = $thisEvent [ 'result' ][ 0 ][ 'opdata' ];
$mailData [ 'EVENT_SUPPRESSED' ] = $thisEvent [ 'result' ][ 0 ][ 'suppressed' ];
2021-03-19 12:01:41 +01:00
$mailData [ 'EVENT_VALUE' ] = $thisEvent [ 'result' ][ 0 ][ 'relatedObject' ][ 'value' ];
2021-03-17 13:03:54 +01:00
switch ( $mailData [ 'EVENT_VALUE' ])
{
case 0 : // Recovering
$mailData [ 'EVENT_SEVERITY' ] = 'Resolved' ;
$mailData [ 'EVENT_STATUS' ] = 'Recovered' ;
break ;
case 1 : // Triggered/Active
$_severity = array ( 'Not classified' , 'Information' , 'Warning' , 'Average' , 'High' , 'Disaster' );
$mailData [ 'EVENT_SEVERITY' ] = $_severity [ $thisEvent [ 'result' ][ 0 ][ 'severity' ]];
$mailData [ 'EVENT_STATUS' ] = 'Triggered/Active' ;
break ;
}
2023-08-16 22:50:00 +02:00
// --- Collect and attach acknowledge messages for this event
2024-12-30 11:26:28 +01:00
if ( sizeof ( $thisEvent [ 'result' ][ 0 ][ 'acknowledges' ] > 0 )) {
2023-08-16 22:50:00 +02:00
foreach ( $thisEvent [ 'result' ][ 0 ][ 'acknowledges' ] as $aCount => $anAck ) {
$mailData [ 'ACKNOWLEDGES' ][ $aCount ] = $anAck ;
$mailData [ 'ACKNOWLEDGES' ][ $aCount ][ '_clock' ] = zabbixTStoString ( $anAck [ 'clock' ]);
$mailData [ 'ACKNOWLEDGES' ][ $aCount ][ '_actions' ] = zabbixActionToString ( $anAck [ 'action' ]);
$mailData [ 'ACKNOWLEDGES' ][ $aCount ][ '_old_severity' ] = zabbixSeverityToString ( $anAck [ 'old_severity' ]);
$mailData [ 'ACKNOWLEDGES' ][ $aCount ][ '_new_severity' ] = zabbixSeverityToString ( $anAck [ 'new_severity' ]);
}
}
2021-03-17 13:03:54 +01:00
$p_triggerId = $thisEvent [ 'result' ][ 0 ][ 'relatedObject' ][ 'triggerid' ];
// ------------------------
2021-02-27 13:40:40 +01:00
// --- GET TRIGGER INFO ---
2021-03-17 13:03:54 +01:00
// ------------------------
2021-02-27 13:40:40 +01:00
_log ( '# Retrieve TRIGGER information' );
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'trigger.get' ,
'params' => array ( 'triggerids' => $p_triggerId ,
'output' => 'extend' ,
2021-03-04 14:29:35 +01:00
'selectFunctions' => 'extend' ,
2021-12-16 13:46:18 +01:00
'selectTags' => 'extend' ,
'expandComment' => 1 ,
'expandDescription' => 1 ,
2023-06-30 10:16:29 +02:00
'expandExpression' => 1 ),
2021-02-27 13:40:40 +01:00
'auth' => $token ,
'id' => nextRequestID ());
$thisTrigger = postJSON ( $z_url_api , $request );
_log ( '> Trigger data' . $cCRLF . json_encode ( $thisTrigger , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
2021-03-04 14:29:35 +01:00
if ( ! isset ( $thisTrigger [ 'result' ][ 0 ])) { echo '! No response data received?' . $cCRLF ; die ; }
2021-02-27 13:40:40 +01:00
$mailData [ 'TRIGGER_ID' ] = $thisTrigger [ 'result' ][ 0 ][ 'triggerid' ];
$mailData [ 'TRIGGER_DESCRIPTION' ] = $thisTrigger [ 'result' ][ 0 ][ 'description' ];
$mailData [ 'TRIGGER_COMMENTS' ] = $thisTrigger [ 'result' ][ 0 ][ 'comments' ];
2021-03-04 14:29:35 +01:00
// --- Custom settings?
$forceGraph = 0 ;
2021-03-20 14:06:08 +01:00
$triggerScreen = 0 ;
$triggerScreenPeriod = '' ;
$triggerScreenPeriodHeader = '' ;
2021-03-04 14:29:35 +01:00
foreach ( $thisTrigger [ 'result' ][ 0 ][ 'tags' ] as $aTag )
{
2021-03-05 11:57:01 +01:00
switch ( $aTag [ 'tag' ])
2021-03-04 14:29:35 +01:00
{
2021-03-05 11:57:01 +01:00
case 'mailGraph.period' :
2021-03-10 19:57:42 +01:00
$problemData [ 'period' ] = $aTag [ 'value' ];
_log ( '+ Graph display period override = ' . $problemData [ 'period' ]);
break ;
case 'mailGraph.period_header' :
$problemData [ 'period_header' ] = $aTag [ 'value' ];
_log ( '+ Graph display period header override = ' . $problemData [ 'period_header' ]);
break ;
case 'mailGraph.periods' :
$problemData [ 'periods' ] = $aTag [ 'value' ];
_log ( '+ Graph display periods override = ' . $problemData [ 'periods' ]);
break ;
case 'mailGraph.periods_headers' :
$problemData [ 'periods_headers' ] = $aTag [ 'value' ];
_log ( '+ Graph display periods headers override = ' . $problemData [ 'periods_headers' ]);
2021-03-05 11:57:01 +01:00
break ;
2021-03-04 14:29:35 +01:00
2021-03-05 11:57:01 +01:00
case 'mailGraph.graph' :
$forceGraph = intval ( $aTag [ 'value' ]);
_log ( '+ Graph ID to display = ' . $forceGraph );
break ;
case 'mailGraph.showLegend' :
$p_showLegend = intval ( $aTag [ 'value' ]);
_log ( '+ Graph display legend override = ' . $p_showLegend );
break ;
case 'mailGraph.graphWidth' :
$p_graphWidth = intval ( $aTag [ 'value' ]);
_log ( '+ Graph height override = ' . $$p_graphWidth );
break ;
case 'mailGraph.graphHeight' :
$p_graphHeight = intval ( $aTag [ 'value' ]);
_log ( '+ Graph height override = ' . $$p_graphHeight );
break ;
2021-03-10 19:57:42 +01:00
case 'mailGraph.debug' :
$problemData [ 'debug' ] = 1 ;
_log ( '+ Mail debug log enabled' );
break ;
2021-03-20 14:06:08 +01:00
case 'mailGraph.screen' :
$triggerScreen = intval ( $aTag [ 'value' ]);
_log ( '+ Trigger screen = ' . $triggerScreen );
break ;
case 'mailGraph.screenPeriod' :
$triggerScreenPeriod = $aTag [ 'value' ];
_log ( '+ Trigger screen period = ' . $triggerScreenPeriod );
break ;
case 'mailGraph.screenPeriodHeader' :
$triggerScreenPeriodHeader = $aTag [ 'value' ];
_log ( '+ Trigger screen header = ' . $triggerScreenPeriodHeader );
break ;
2021-03-04 14:29:35 +01:00
}
}
2023-07-10 23:59:33 +02:00
// If no specific itemId is requested take the first item found on the items list from the host
2021-12-16 13:46:18 +01:00
if ( ! isset ( $p_itemId ))
{
foreach ( $thisTrigger [ 'result' ][ 0 ][ 'functions' ] as $aFunction )
{
$p_itemId = $aFunction [ 'itemid' ];
_log ( '- Item ID taken from trigger (first) function = ' . $p_itemId );
break ;
}
}
2021-03-17 13:03:54 +01:00
// ---------------------
2021-02-27 13:40:40 +01:00
// --- GET ITEM INFO ---
2021-03-17 13:03:54 +01:00
// ---------------------
2021-02-27 13:40:40 +01:00
_log ( '# Retrieve ITEM information' );
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'item.get' ,
2021-03-17 13:03:54 +01:00
'params' => array ( 'itemids' => $p_itemId ,
2023-07-15 00:51:55 +02:00
'webitems' => 'true' ,
'output' => 'extend' ),
2021-02-27 13:40:40 +01:00
'auth' => $token ,
'id' => nextRequestID ());
$thisItem = postJSON ( $z_url_api , $request );
_log ( '> Item data' . $cCRLF . json_encode ( $thisItem , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
2021-03-04 14:29:35 +01:00
if ( ! isset ( $thisItem [ 'result' ][ 0 ])) { echo '! No response data received?' . $cCRLF ; die ; }
2021-02-27 13:40:40 +01:00
$mailData [ 'ITEM_ID' ] = $thisItem [ 'result' ][ 0 ][ 'itemid' ];
$mailData [ 'ITEM_KEY' ] = $thisItem [ 'result' ][ 0 ][ 'key_' ];
$mailData [ 'ITEM_NAME' ] = $thisItem [ 'result' ][ 0 ][ 'name' ];
$mailData [ 'ITEM_DESCRIPTION' ] = $thisItem [ 'result' ][ 0 ][ 'description' ];
$mailData [ 'ITEM_LASTVALUE' ] = $thisItem [ 'result' ][ 0 ][ 'lastvalue' ];
$mailData [ 'ITEM_PREVIOUSVALUE' ] = $thisItem [ 'result' ][ 0 ][ 'prevvalue' ];
// Catch elements that have a recordset definition returned as a value ...
if ( substr ( $mailData [ 'ITEM_LASTVALUE' ], 0 , 5 ) == '<?xml' ) { $mailData [ 'ITEM_LASTVALUE' ] = '[record]' ; }
if ( substr ( $mailData [ 'ITEM_PREVIOUSVALUE' ], 0 , 5 ) == '<?xml' ) { $mailData [ 'ITEM_PREVIOUSTVALUE' ] = '[record]' ; }
2021-03-05 11:57:01 +01:00
// Catch long elements
if ( strlen ( $mailData [ 'ITEM_LASTVALUE' ]) > 50 ) { $mailData [ 'ITEM_LASTVALUE' ] = substr ( $mailData [ 'ITEM_LASTVALUE' ], 0 , 50 ) . ' ...' ; }
if ( strlen ( $mailData [ 'ITEM_PREVIOUSVALUE' ]) > 50 ) { $mailData [ 'ITEM_PREVIOUSVALUE' ] = substr ( $mailData [ 'ITEM_PREVIOUSVALUE' ], 0 , 50 ) . ' ...' ; }
2021-03-17 13:03:54 +01:00
// ---------------------
2021-02-27 13:40:40 +01:00
// --- GET HOST INFO ---
2021-03-17 13:03:54 +01:00
// ---------------------
2021-02-27 13:40:40 +01:00
2021-02-28 21:31:46 +01:00
_log ( '# Retrieve HOST information' );
2021-02-27 13:40:40 +01:00
$hostId = $thisItem [ 'result' ][ 0 ][ 'hostid' ];
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'host.get' ,
'params' => array ( 'hostids' => $hostId ,
2021-03-20 14:06:08 +01:00
'output' => 'extend' ,
'selectTags' => 'extend' ),
2021-02-27 13:40:40 +01:00
'auth' => $token ,
'id' => nextRequestID ());
$thisHost = postJSON ( $z_url_api , $request );
_log ( '> Host data' . $cCRLF . json_encode ( $thisHost , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
2021-03-04 14:29:35 +01:00
if ( ! isset ( $thisHost [ 'result' ][ 0 ])) { echo '! No response data received?' . $cCRLF ; die ; }
2021-02-27 13:40:40 +01:00
$mailData [ 'HOST_ID' ] = $thisHost [ 'result' ][ 0 ][ 'hostid' ];
$mailData [ 'HOST_NAME' ] = $thisHost [ 'result' ][ 0 ][ 'name' ];
2021-12-16 13:46:18 +01:00
if ( isset ( $thisHost [ 'result' ][ 0 ][ 'error' ])) { $mailData [ 'HOST_ERROR' ] = $thisHost [ 'result' ][ 0 ][ 'error' ]; }
2021-02-27 13:40:40 +01:00
$mailData [ 'HOST_DESCRIPTION' ] = $thisHost [ 'result' ][ 0 ][ 'description' ];
2021-03-20 14:06:08 +01:00
// --- Custom settings?
$hostScreen = 0 ;
$hostScreenPeriod = '' ;
$hostScreenPeriodHeader = '' ;
foreach ( $thisHost [ 'result' ][ 0 ][ 'tags' ] as $aTag )
{
switch ( $aTag [ 'tag' ])
{
case 'mailGraph.screen' :
$hostScreen = intval ( $aTag [ 'value' ]);
_log ( '+ Host screen (from TAG) = ' . $hostScreen );
break ;
case 'mailGraph.screenPeriod' :
$hostScreenPeriod = $aTag [ 'value' ];
_log ( '+ Host screen period (from TAG) = ' . $hostScreenPeriod );
break ;
case 'mailGraph.screenPeriodHeader' :
$hostScreenPeriodHeader = $aTag [ 'value' ];
_log ( '+ Host screen period header (from TAG) = ' . $hostScreenPeriodHeader );
break ;
}
}
2021-02-28 21:31:46 +01:00
_log ( '# Retreive HOST macro information' );
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'usermacro.get' ,
'params' => array ( 'hostids' => $hostId ,
'output' => 'extend' ),
'auth' => $token ,
'id' => nextRequestID ());
$thisMacros = postJSON ( $z_url_api , $request );
_log ( '> Host macro data' . $cCRLF . json_encode ( $thisMacros , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
2021-03-20 14:06:08 +01:00
foreach ( $thisMacros [ 'result' ] as $aMacro )
{
switch ( $aMacro [ 'macro' ])
{
case 'mailGraph.screen' :
$hostScreen = intval ( $aMacro [ 'value' ]);
_log ( '+ Host screen (from MACRO) = ' . $hostScreen );
break ;
case 'mailGraph.screenPeriod' :
$hostScreenPeriod = $aMacro [ 'value' ];
_log ( '+ Host screen period (from MACRO) = ' . $hostScreenPeriod );
break ;
case 'mailGraph.screenPeriodHeader' :
$hostScreenPeriodHeader = $aMacro [ 'value' ];
_log ( '+ Host screen header (from MACRO) = ' . $hostScreenPeriodHeader );
break ;
}
}
// ------------------------------------------------------------------
// --- GET GRAPHS ASSOCIATED WITH THIS HOST AND THE TRIGGER ITEMS ---
// ------------------------------------------------------------------
2021-02-27 13:40:40 +01:00
2021-03-09 10:21:06 +01:00
_log ( '# Retrieve associated graphs to this HOST and the TRIGGER ITEMS' );
$searchItems = array ();
foreach ( $thisTrigger [ 'result' ][ 0 ][ 'functions' ] as $aFunction )
{
$searchItems [] = $aFunction [ 'itemid' ];
}
2021-02-27 13:40:40 +01:00
$keyName = $thisItem [ 'result' ][ 0 ][ 'key_' ];
$hostId = $thisItem [ 'result' ][ 0 ][ 'hostid' ];
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'graph.get' ,
2021-03-02 23:17:03 +01:00
'params' => array ( 'hostids' => $hostId ,
2021-03-09 10:21:06 +01:00
'itemids' => $searchItems ,
2021-03-02 23:17:03 +01:00
'expandName' => 1 ,
'selectGraphItems' => 'extend' ,
2021-02-27 13:40:40 +01:00
'output' => 'extend' ),
'auth' => $token ,
'id' => nextRequestID ());
2021-03-02 23:17:03 +01:00
$thisGraphs = postJSON ( $z_url_api , $request );
_log ( '> Graphs data' . $cCRLF . json_encode ( $thisGraphs , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
2021-02-27 13:40:40 +01:00
2021-03-04 14:29:35 +01:00
if ( $forceGraph > 0 )
{
2021-03-17 13:03:54 +01:00
// --------------------------------------------
2021-03-04 14:29:35 +01:00
// --- GET GRAPH ASSOCIATED WITH FORCEGRAPH ---
2021-03-17 13:03:54 +01:00
// --------------------------------------------
_log ( '# Retrieving FORCED graph information' );
2021-03-04 14:29:35 +01:00
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'graph.get' ,
'params' => array ( 'graphids' => $forceGraph ,
'expandName' => 1 ,
'output' => 'extend' ),
'auth' => $token ,
'id' => nextRequestID ());
$forceGraphInfo = postJSON ( $z_url_api , $request );
2021-03-20 14:06:08 +01:00
_log ( '> Forced graph data' . $cCRLF .
json_encode ( $forceGraphInfo , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
2021-03-04 14:29:35 +01:00
2021-03-09 10:21:06 +01:00
if ( ! isset ( $forceGraphInfo [ 'result' ][ 0 ]))
{
_log ( '! No data received for graph #' . $forceGraph . '; discarding forced graph information' );
$forceGraph = 0 ;
}
2021-03-04 14:29:35 +01:00
}
2021-03-17 13:03:54 +01:00
// --------------------------------------------------------
2021-03-02 23:17:03 +01:00
// --- FIND MATCHING GRAPH ITEMS WITH OUR TRIGGER ITEMS ---
2021-03-17 13:03:54 +01:00
// --------------------------------------------------------
2021-02-27 13:40:40 +01:00
2021-03-02 23:17:03 +01:00
_log ( '# Matching retreived graph information with our trigger items' );
2021-02-27 13:40:40 +01:00
2021-03-17 13:03:54 +01:00
// --- Look for graphs across all functions inside the item
2021-03-09 10:21:06 +01:00
2021-03-02 23:17:03 +01:00
$itemIds = array ();
2021-02-27 13:40:40 +01:00
2021-03-02 23:17:03 +01:00
foreach ( $thisTrigger [ 'result' ][ 0 ][ 'functions' ] as $aFunction )
2021-02-27 13:40:40 +01:00
{
2021-03-02 23:17:03 +01:00
$didFind = FALSE ;
2021-02-27 13:40:40 +01:00
2021-03-02 23:17:03 +01:00
foreach ( $itemIds as $anItem )
{
if ( $anItem == $aFunction [ 'itemid' ]) { $didFind = TRUE ; break ; }
}
if ( ! $didFind ) { $itemIds [] = $aFunction [ 'itemid' ]; }
}
$matchedGraphs = array ();
$otherGraphs = array ();
2021-02-27 13:40:40 +01:00
2021-03-02 23:17:03 +01:00
foreach ( $thisGraphs [ 'result' ] as $aGraph )
{
foreach ( $aGraph [ 'gitems' ] as $aGraphItem )
2021-02-27 13:40:40 +01:00
{
2021-03-02 23:17:03 +01:00
foreach ( $itemIds as $anItemId )
2021-02-27 13:40:40 +01:00
{
2021-03-02 23:17:03 +01:00
if ( $aGraphItem [ 'itemid' ] == $anItemId )
{
2021-03-19 12:01:41 +01:00
if ( $anItemId == $p_itemId )
2021-03-02 23:17:03 +01:00
{
_log ( '+ Graph #' . $aGraphItem [ 'graphid' ] . ' full match found (item #' . $aGraphItem [ 'itemid' ] . ')' );
$matchedGraphs [] = $aGraph ;
}
else
{
$otherGraphs [] = $aGraph ;
2023-06-30 10:16:29 +02:00
_log ( '~ Graph #' . $aGraphItem [ 'graphid' ] . ' partial match found (item #' . $aGraphItem [ 'itemid' ] . ')' );
2021-03-02 23:17:03 +01:00
}
}
2021-02-27 13:40:40 +01:00
}
}
}
2021-03-02 23:17:03 +01:00
_log ( '> Graphs found (matching/partial) = ' . sizeof ( $matchedGraphs ) . ' / ' . sizeof ( $otherGraphs ));
2021-02-27 13:40:40 +01:00
2021-03-20 14:06:08 +01:00
// ---------------------------------------------------------------------------
// --- FIND MATCHING GRAPH ITEMS WITH TRIGGER AND/OR HOST SCREEN REFERENCE ---
// ---------------------------------------------------------------------------
function _sort ( $a , $b )
{
if ( $a [ 'screen' ][ 'y' ] > $b [ 'screen' ][ 'y' ]) { return ( 1 ); }
if ( $a [ 'screen' ][ 'y' ] < $b [ 'screen' ][ 'y' ]) { return ( - 1 ); }
if ( $a [ 'screen' ][ 'x' ] > $b [ 'screen' ][ 'x' ]) { return ( 1 ); }
if ( $a [ 'screen' ][ 'x' ] < $b [ 'screen' ][ 'x' ]) { return ( - 1 ); }
return ( 0 );
}
function fetchGraphsFromScreen ( $screenId )
{
global $token ;
global $z_url_api ;
global $cCRLF ;
// --- Pick up the SCREEN ITEMS associated to the SCREEN
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'screen.get' ,
'params' => array ( 'screenids' => $screenId ,
'output' => 'extend' ,
'selectScreenItems' => 'extend' ),
'auth' => $token ,
'id' => nextRequestID ());
$screenGraphs = postJSON ( $z_url_api , $request );
_log ( '> Screen items data for screen #' . $screenId . $cCRLF . json_encode ( $screenGraphs , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
// --- Filter on specific type(s) and enrich the graph data
$result = array ();
foreach ( $screenGraphs [ 'result' ][ 0 ][ 'screenitems' ] as $anItem )
{
switch ( $anItem [ 'resourcetype' ])
{
case 0 : // Graph
$request = array ( 'jsonrpc' => '2.0' ,
'method' => 'graph.get' ,
'params' => array ( 'graphids' => $anItem [ 'resourceid' ],
'expandName' => 1 ,
'output' => 'extend' ),
'auth' => $token ,
'id' => nextRequestID ());
$screenGraph = postJSON ( $z_url_api , $request );
_log ( '+ Graph data for screen item #' . $anItem [ 'screenitemid' ] . $cCRLF .
json_encode ( $screenGraph , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK ));
$result [] = array ( 'screen' => $anItem , 'name' => $screenGraphs [ 'result' ][ 0 ][ 'name' ], 'graph' => $screenGraph [ 'result' ][ 0 ]);
break ;
}
}
// --- Sort the result according to SCREEN x,y position
usort ( $result , " _sort " );
// --- Done
return ( $result );
}
$triggerGraphs = array ();
if ( $triggerScreen > 0 )
{
_log ( '# Fetching graph information for TRIGGER for screen #' . $hostScreen );
$triggerGraphs = fetchGraphsFromScreen ( $triggerScreen );
_log ( '> Graphs found = ' . sizeof ( $triggerGraphs ));
}
2021-12-16 13:46:18 +01:00
$hostGraphs = array ();
2021-03-20 14:06:08 +01:00
if ( $hostScreen > 0 )
{
_log ( '# Fetching graph information for HOST for screen #' . $hostScreen );
$hostGraphs = fetchGraphsFromScreen ( $hostScreen );
_log ( '> Graphs found = ' . sizeof ( $hostGraphs ));
}
2021-02-27 13:40:40 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-03-20 14:06:08 +01:00
// Fetch Graph(s) ///////////////////////////////////////////////////////////////////////////////////////
2021-02-27 13:40:40 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-03-20 14:06:08 +01:00
// Determine number of periods for the ITEM graphs
2021-03-10 19:57:42 +01:00
$p_periods = array ();
$p_periods_headers = array ();
if ( isset ( $problemData [ 'periods' ]))
{
// Multiple periods mode selected
_log ( '# Multi period graph mode selected' );
$p_periods = explode ( ',' , $problemData [ 'periods' ]);
// If invalid, replace with single graph item
if ( sizeof ( $p_periods ) == 0 ) { $p_periods [] = $p_period ; }
// --- Determine headers
if ( isset ( $problemData [ 'periods_headers' ])) { $p_periods_headers = explode ( ',' , $problemData [ 'periods_headers' ]); }
// If no headers specified, simply copy the period information
if ( sizeof ( $p_periods_headers ) == 0 ) { $p_periods_headers = $p_periods ; }
}
else
{
// Single period mode selected
$p_periods [] = $p_period ;
if ( isset ( $problemData [ 'period_header' ]))
{
$p_periods_headers [] = $problemData [ 'period_header' ];
}
else
{
$p_periods_headers [] = $p_period ;
}
}
2023-07-02 14:54:00 +02:00
// Strip off any excessive elements from the end (protection of graph generation overload on system)
2021-03-20 14:06:08 +01:00
while ( sizeof ( $p_periods ) > $maxGraphs ) { array_pop ( $p_periods ); }
while ( sizeof ( $p_periods_headers ) > $maxGraphs ) { array_pop ( $p_periods_headers ); }
// Fetching of the ITEM graphs
2021-03-10 19:57:42 +01:00
$graphFiles = array ();
2021-02-27 13:40:40 +01:00
$graphURL = '' ;
2021-03-03 23:26:35 +01:00
// If we have any matching graph, make the embedding information available
2021-03-05 11:57:01 +01:00
if (( sizeof ( $matchedGraphs ) + sizeof ( $otherGraphs ) + $forceGraph ) > 0 )
2021-02-27 13:40:40 +01:00
{
2021-03-05 11:57:01 +01:00
if ( $forceGraph > 0 )
{
2024-12-30 11:26:28 +01:00
$theGraph = $forceGraphInfo [ 'result' ][ 0 ];
2021-03-05 11:57:01 +01:00
$theType = 'Forced' ;
}
else
2021-03-01 20:22:42 +01:00
{
2021-03-04 14:29:35 +01:00
if ( sizeof ( $matchedGraphs ) > 0 )
2021-03-01 20:22:42 +01:00
{
2021-03-05 11:57:01 +01:00
$theGraph = $matchedGraphs [ 0 ];
$theType = 'Matched' ;
2021-03-04 14:29:35 +01:00
}
else
{
2021-03-05 11:57:01 +01:00
if ( sizeof ( $otherGraphs ) > 0 )
2021-03-04 14:29:35 +01:00
{
2021-03-05 11:57:01 +01:00
$theGraph = $otherGraphs [ 0 ];
$theType = 'Other' ;
2021-03-04 14:29:35 +01:00
}
2021-03-01 20:22:42 +01:00
}
2021-03-04 14:29:35 +01:00
}
2021-03-05 11:57:01 +01:00
$mailData [ 'GRAPH_ID' ] = $theGraph [ 'graphid' ];
$mailData [ 'GRAPH_NAME' ] = $theGraph [ 'name' ];
$mailData [ 'GRAPH_MATCH' ] = $theType ;
_log ( '# Adding ' . strtoupper ( $theType ) . ' graph #' . $mailData [ 'GRAPH_ID' ]);
2021-03-10 19:57:42 +01:00
foreach ( $p_periods as $aKey => $aPeriod )
{
$graphFile = GraphImageById ( $mailData [ 'GRAPH_ID' ],
$p_graphWidth , $p_graphHeight ,
$theGraph [ 'graphtype' ],
$p_showLegend , $aPeriod );
2021-03-05 11:57:01 +01:00
2021-03-10 19:57:42 +01:00
$graphFiles [] = $graphFile ;
2021-03-20 14:06:08 +01:00
$mailData [ 'GRAPHS_I' ][ $aKey ][ 'PATH' ] = $z_images_path . $graphFile ;
2023-07-02 14:54:00 +02:00
$mailData [ 'GRAPHS_I' ][ $aKey ][ 'CID' ] = 'images/' . $graphFile ;
2021-03-20 14:06:08 +01:00
$mailData [ 'GRAPHS_I' ][ $aKey ][ 'URL' ] = $z_url_image . $graphFile ;
$mailData [ 'GRAPHS_I' ][ $aKey ][ 'HEADER' ] = $p_periods_headers [ $aKey ];
2021-03-10 19:57:42 +01:00
}
2021-03-05 11:57:01 +01:00
2021-03-07 22:21:38 +01:00
$mailData [ 'GRAPH_ZABBIXLINK' ] = $z_server . 'graphs.php?form=update&graphid=' . $mailData [ 'GRAPH_ID' ];
2021-02-27 13:40:40 +01:00
}
2021-03-20 14:06:08 +01:00
// Fetch graphs associated to TRIGGER or HOST screen references obtained earlier
function addGraphs ( $varName , $info , $period , $periodHeader )
{
global $p_graphWidth ;
global $p_graphHeight ;
global $p_showLegend ;
global $z_url_image ;
global $z_images_path ;
global $z_server ;
global $mailData ;
$files = array ();
foreach ( $info as $aKey => $anItem )
{
$graphFile = GraphImageById ( $anItem [ 'graph' ][ 'graphid' ],
$p_graphWidth , $p_graphHeight ,
$anItem [ 'graph' ][ 'graphtype' ],
$p_showLegend , $period );
$mailData [ 'GRAPHS_' . $varName ][ $aKey ][ 'URL' ] = $z_url_image . $graphFile ;
$mailData [ 'GRAPHS_' . $varName ][ $aKey ][ 'PATH' ] = $z_images_path . $graphFile ;
2023-07-02 14:54:00 +02:00
$mailData [ 'GRAPHS_' . $varName ][ $aKey ][ 'CID' ] = 'images/' . $graphFile ;
2021-03-20 14:06:08 +01:00
}
$mailData [ 'GRAPHS_' . $varName . '_LINK' ] = $z_server . 'screens.php?elementid=' . $info [ 0 ][ 'screen' ][ 'screenid' ];
$mailData [ 'GRAPHS_' . $varName . '_HEADER' ] = $info [ 0 ][ 'name' ];
$mailData [ 'GRAPHS_' . $varName . '_PERIODHEADER' ] = $periodHeader ;
}
if ( sizeof ( $triggerGraphs ) > 0 )
{
if ( $triggerScreenPeriod == '' )
{
$triggerScreenPeriod = $p_periods [ 0 ];
$triggerScreenPeriodHeader = $p_periods_headers [ 0 ];
}
if ( $triggerScreenPeriodHeader == '' ) { $triggerScreenPeriodHeader = $triggerScreenPeriod ; }
addGraphs ( 'T' , $triggerGraphs , $triggerScreenPeriod , $triggerScreenPeriodHeader );
$mailData [ 'TRIGGER_SCREEN' ] = $triggerScreen ;
}
if ( sizeof ( $hostGraphs ) > 0 )
{
if ( $hostScreenPeriod == '' )
{
$hostScreenPeriod = $p_periods [ 0 ];
$hostScreenPeriodHeader = $p_periods_headers [ 0 ];
}
if ( $hostScreenPeriodHeader == '' ) { $hostScreenPeriodHeader = $hostScreenPeriod ; }
addGraphs ( 'H' , $hostGraphs , $hostScreenPeriod , $hostScreenPeriodHeader );
$mailData [ 'HOST_SCREEN' ] = $hostScreen ;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-12-16 13:46:18 +01:00
// Prepare HTML LOG content /////////////////////////////////////////////////////////////////////////////
2021-03-20 14:06:08 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-02-27 13:40:40 +01:00
$mailData [ 'LOG_HTML' ] = implode ( '</br/>' , $logging );
$mailData [ 'LOG_HTML' ] = str_replace ( $cCRLF , '<br/>' , $mailData [ 'LOG_HTML' ]);
$mailData [ 'LOG_HTML' ] = str_replace ( '<br/>' , '<br/>' . $cCRLF , $mailData [ 'LOG_HTML' ]);
2023-07-15 00:51:55 +02:00
$mailData [ 'LOG_HTML' ] = '<html lang="en"><head><meta http-equiv=Content-Type content="text/html; charset=UTF-8"></head>' . $cCRLF .
'<style type="text/css">' . $cCRLF .
'body { font-family: courier, courier new, serif; font-size: 12px; }' . $cCRLF .
'</style>' . $cCRLF .
2021-02-27 13:40:40 +01:00
'<body>' . $cCRLF .
$mailData [ 'LOG_HTML' ] . $cCRLF .
'</body>' . $cCRLF .
'</html>' ;
2021-12-16 13:46:18 +01:00
// Prepare PLAIN LOG content
2021-02-27 13:40:40 +01:00
$mailData [ 'LOG_PLAIN' ] = implode ( chr ( 10 ), $logging );
2021-12-16 13:46:18 +01:00
// Prepare others
2021-02-27 13:40:40 +01:00
2023-07-03 21:50:14 +02:00
$mailData [ 'TRIGGER_URL' ] = $z_server . 'triggers.php?form=update&triggerid=' . $mailData [ 'TRIGGER_ID' ] . '&context=host' ;
$mailData [ 'ITEM_URL' ] = $z_server . 'items.php?form=update&hostid=' . $mailData [ 'HOST_ID' ] . '&itemid=' . $mailData [ 'ITEM_ID' ] . '&context=host' ;
2021-03-07 22:21:38 +01:00
$mailData [ 'HOST_URL' ] = $z_server . 'hosts.php?form=update&hostid=' . $mailData [ 'HOST_ID' ];
2023-07-10 14:32:47 +02:00
$mailData [ 'ACK_URL' ] = $z_server . 'zabbix.php?action=popup&popup_action=acknowledge.edit&eventids[]=' . $mailData [ 'EVENT_ID' ];
2021-03-07 22:21:38 +01:00
$mailData [ 'EVENTDETAILS_URL' ] = $z_server . 'tr_events.php?triggerid=' . $mailData [ 'TRIGGER_ID' ] . '&eventid=' . $mailData [ 'EVENT_ID' ];
2021-02-27 13:40:40 +01:00
2021-02-27 22:44:23 +01:00
$mailData [ 'EVENT_DURATION' ] = $p_duration ;
2023-07-03 21:50:14 +02:00
$mailData [ 'HOST_PROBLEMS_URL' ] = $z_server . 'zabbix.php?show=1&name=&inventory%5B0%5D%5Bfield%5D=type&inventory%5B0%5D%5Bvalue%5D=&evaltype=0&tags%5B0%5D%5Btag%5D=&tags%5B0%5D%5Boperator%5D=0&tags%5B0%5D%5Bvalue%5D=&show_tags=3&tag_name_format=0&tag_priority=&show_opdata=0&show_timeline=1&filter_name=&filter_show_counter=0&filter_custom_time=0&sort=clock&sortorder=DESC&age_state=0&show_suppressed=0&unacknowledged=0&compact_view=0&details=0&highlight_row=0&action=problem.view&hostids%5B%5D=' . $mailData [ 'HOST_ID' ];
2021-02-27 13:40:40 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Compose & Send Message ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2023-07-02 14:54:00 +02:00
_log ( '# Configuring Mailer' );
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
$mail = new PHPMailer ( true );
2021-03-07 22:21:38 +01:00
2023-07-02 14:54:00 +02:00
try
2021-03-01 18:36:28 +01:00
{
2024-12-30 11:26:28 +01:00
// If debugging is required change to '1'
2023-07-02 14:54:00 +02:00
$mail -> SMTPDebug = 0 ;
2021-03-01 19:51:11 +01:00
2024-12-30 11:26:28 +01:00
// Initialize for international characters
$mail -> CharSet = " UTF-8 " ;
$mail -> Encoding = " base64 " ;
// Inialize SMTP parameters
2023-07-02 14:54:00 +02:00
$mail -> isSMTP ();
$mail -> Host = $p_smtp_server ;
$mail -> Port = $p_smtp_port ;
// --- Authentication required?
if ( $p_smtp_username != " " )
2021-03-01 19:51:11 +01:00
{
2023-07-02 14:54:00 +02:00
$mail -> SMTPAuth = true ;
$mail -> Username = $p_smtp_username ;
$mail -> Password = $p_smtp_password ;
2021-03-01 19:51:11 +01:00
}
2023-07-02 14:54:00 +02:00
// --- Disable strict certificate checking?
if ( $p_smtp_strict == 'no' )
2021-03-01 20:22:42 +01:00
{
2023-07-02 14:54:00 +02:00
$mail -> SMTPOptions = [
'ssl' => [ 'verify_peer' => false , 'verify_peer_name' => false , 'allow_self_signed' => true ]
];
2021-03-01 19:51:11 +01:00
}
2021-03-24 12:27:44 +01:00
2023-07-10 10:09:39 +02:00
// --- Define from
2023-07-10 11:21:48 +02:00
$mail -> Sender = $p_smtp_from_address ;
$mail -> SetFrom ( $p_smtp_from_address , $p_smtp_from_name , FALSE );
2023-07-10 10:09:39 +02:00
2023-07-10 14:32:47 +02:00
// --- Define reply-to
if ( $p_smtp_reply_address != '' )
{
$mail -> clearReplyTos ();
$mail -> addReplyTo ( $p_smtp_reply_address , $p_smtp_reply_name );
}
2023-07-10 10:09:39 +02:00
// --- Add recipient
2023-07-02 14:54:00 +02:00
$mail -> addAddress ( $p_recipient );
2021-03-24 12:27:44 +01:00
2023-07-02 14:54:00 +02:00
// --- Prepare embedding of the graphs by attaching and generating "cid" (content-id) information
function embedGraphs ( $graphs , $varName , $type )
{
global $mail ;
global $mailData ;
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
foreach ( $graphs as $aKey => $anItem )
{
$mail -> AddEmbeddedImage ( $mailData [ 'GRAPHS_' . $varName ][ $aKey ][ 'PATH' ],
$mailData [ 'GRAPHS_' . $varName ][ $aKey ][ 'CID' ]);
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
// Add content-id marker to the identifier for ease of use in Twig
$mailData [ 'GRAPHS_' . $varName ][ $aKey ][ 'CID' ] = 'cid:' . $mailData [ 'GRAPHS_' . $varName ][ $aKey ][ 'CID' ];
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
_log ( '> Embedded graph image (' . $type . ') ' . $mailData [ 'GRAPHS_' . $varName ][ $aKey ][ 'URL' ]);
}
}
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
embedGraphs ( $graphFiles , 'I' , 'ITEM' );
embedGraphs ( $triggerGraphs , 'T' , 'TRIGGER' );
embedGraphs ( $hostGraphs , 'H' , 'HOST' );
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
// --- Render the content with TWIG for HTML, Plain text and the Subject of the message
$loader = new \Twig\Loader\ArrayLoader ([
'html' => file_get_contents ( $z_template_path . 'html.template' ),
'plain' => file_get_contents ( $z_template_path . 'plain.template' ),
'subject' => $mailData [ 'SUBJECT' ],
]);
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
$twig = new \Twig\Environment ( $loader );
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
$bodyHTML = $twig -> render ( 'html' , $mailData );
$bodyPlain = $twig -> render ( 'plain' , $mailData );
$mailSubject = $twig -> render ( 'subject' , $mailData );
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
// --- Attach debug log processing?
if (( $cDebugMail ) || ( isset ( $problemData [ 'debug' ])))
{
_log ( '# Attaching logs to mail message' );
2021-02-27 13:40:40 +01:00
2023-07-02 14:54:00 +02:00
$mail -> addStringAttachment ( $mailData [ 'LOG_HTML' ], 'log.html' );
$mail -> addStringAttachment ( $mailData [ 'LOG_PLAIN' ], 'log.txt' );
}
2021-03-10 19:57:42 +01:00
2023-07-02 14:54:00 +02:00
// ---Fill body and subject and mark as HTML while also supplying plain text option alternative
// Note: Not using PHPMailer option for automatic text/plain generation (by design)
$mail -> Body = $bodyHTML ;
$mail -> isHTML ( true );
$mail -> AltBody = $bodyPlain ;
$mail -> Subject = $mailSubject ;
2021-03-10 19:57:42 +01:00
2023-07-02 14:54:00 +02:00
// --- Send the message
if ( ! $mail -> send ())
2021-03-10 19:57:42 +01:00
{
2023-07-02 14:54:00 +02:00
_log ( " ! Failed to send mail message " );
echo " ! Failed to send mail message. Likely an issue with the recipient email address? " . $cCRLF ;
echo " + Mailer error: " . $mail -> ErrorInfo . $cCRLF ;
2021-03-10 19:57:42 +01:00
}
2021-03-20 14:06:08 +01:00
2023-07-02 14:54:00 +02:00
// --- Obtain message ID
$messageId = $mail -> getlastMessageID ();
_log ( '# Message ID = ' . $messageId );
2021-03-20 14:06:08 +01:00
2023-07-02 14:54:00 +02:00
// --- Return Event TAG information for Zabbix to store with Zabbix event
$response = array ( 'messageId' => $messageId );
echo json_encode ( $response ) . $cCRLF ;
} catch ( phpmailerException $e )
2021-02-27 13:40:40 +01:00
{
2023-07-02 14:54:00 +02:00
echo " ! Failed to send message " . $cCRLF ;
echo " ! phpMailer error message: " . $e -> getMessage () . $cCRLF ;
_log ( " ! phpMailer failed: " . $e -> getMessage ());
} catch ( Exception $e )
2023-07-01 13:26:29 +02:00
{
2023-07-02 14:54:00 +02:00
echo " ! Failed to send message " . $cCRLF ;
echo " ! Error message: " . $e -> getMessage () . $cCRLF ;
_log ( " ! Failed: " . $e -> getMessage ());
2023-07-01 13:26:29 +02:00
}
2021-02-27 13:40:40 +01:00
2021-03-24 12:27:44 +01:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Wrap up //////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-02-27 13:40:40 +01:00
// Store log?
2021-03-10 19:57:42 +01:00
if (( $cDebug ) || ( isset ( $problemData [ 'debug' ])))
2021-02-27 13:40:40 +01:00
{
2023-07-02 14:54:00 +02:00
// Prevent duplicate dump of log information
2021-02-27 13:40:40 +01:00
unset ( $mailData [ 'LOG_HTML' ]);
unset ( $mailData [ 'LOG_PLAIN' ]);
2023-07-02 14:54:00 +02:00
// Attach the collected information
2021-03-19 12:01:41 +01:00
$content = implode ( chr ( 10 ), $logging ) . $cCRLF . $cCRLF . '=== VALUES AVAILABLE FOR TWIG TEMPLATE ===' . $cCRLF . $cCRLF . json_encode ( $mailData , JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK );
2021-02-27 13:40:40 +01:00
$content = str_replace ( chr ( 13 ), '' , $content );
2023-07-02 14:54:00 +02:00
// Save to unique log file
2021-03-01 20:22:42 +01:00
$logName = 'log.' . $p_eventId . '.' . date ( 'YmdHis' ) . '.dump' ;
file_put_contents ( $z_log_path . $logName , $content );
2021-12-16 13:46:18 +01:00
_log ( '= Log stored to ' . $z_log_path . $logName );
2021-02-27 13:40:40 +01:00
}
2021-04-03 16:29:26 +02:00
?>