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.
|
|
|
|
//
|
|
|
|
// ------------------------------------------------------------------------------------------------------
|
|
|
|
// 1.00 2021/02/26 - Mark Oudsen - MVP version, ready for distribution
|
2021-02-27 15:40:01 +01:00
|
|
|
// 1.01 2021/02/27 - Mark Oudsen - Enhanced search for associated graphs to an item // bug fixes
|
|
|
|
// 1.10 2021/02/27 - Mark Oudsen - Moved all configuration outside code
|
2021-03-01 18:13:32 +01:00
|
|
|
// 1.11 2021/02/28 - Mark Oudsen - Bugfixes
|
2021-03-01 20:22:42 +01:00
|
|
|
// 1.12 2021/03/01 - Mark Oudsen - Bugfixes
|
|
|
|
// Adding mail server configuration via config.json
|
2021-03-01 18:36:28 +01:00
|
|
|
// 1.13 2021/03/01 - Mark Oudsen - Added smtp options to encrypt none,ssl,tls
|
2021-03-01 19:51:11 +01:00
|
|
|
// 1.14 2021/03/01 - Mark Oudsen - Added smtp strict certificates yes|no via config.json
|
2021-03-01 20:22:42 +01:00
|
|
|
// 1.15 2021/03/01 - Mark Oudsen - Revised relevant graph locator; allowing other item graphs if current
|
|
|
|
// item does not have a graph associated
|
2021-03-02 23:17:03 +01:00
|
|
|
// 1.16 2021/03/02 - Mark Oudsen - Found issue with graph.get not returning graphs to requested item ids
|
|
|
|
// Workaround programmed (fetch host graphs, search for certain itemids)
|
2021-03-03 23:26:35 +01:00
|
|
|
// 1.17 2021/03/02 - Mark Oudsen - Added ability to specify period of time displayed in the graph
|
2021-03-05 11:57:01 +01:00
|
|
|
// 1.18 2021/03/04 - Mark Oudsen - Added ability to specify Tags per trigger
|
|
|
|
// Shorten long "lastvalue" or "prevvalue"
|
|
|
|
// 1.19 2021/03/05 - Mark Oudsen - Added ability to pass Zabbix 'infoXXX' parameters for TWIG template
|
2021-03-07 22:21:38 +01:00
|
|
|
// 1.20 2021/03/07 - Mark Oudsen - Production level version - leaving BETA from here on ...
|
2021-03-09 10:21:06 +01:00
|
|
|
// 1.21 2021/03/09 - Mark Oudsen - Reverted graph.get code back to original code as it was not a bug but
|
|
|
|
// a wrongly typed requested (should be ARRAY, not comma separated)!
|
2021-02-27 13:40:40 +01:00
|
|
|
// ------------------------------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// (C) M.J.Oudsen, mark.oudsen@puzzl.nl
|
|
|
|
// MIT License
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// MAIN SEQUENCE
|
|
|
|
// -------------
|
|
|
|
// 1) Fetch trigger, item, host, graph, event information via Zabbix API via CURL
|
|
|
|
// 2) Fetch Graph associated to the item/trigger (if any) via Zabbix URL login via CURL
|
|
|
|
// 3) Build and send mail message from template using Swift/TWIG
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// CONSTANTS
|
|
|
|
|
2021-03-09 10:21:06 +01:00
|
|
|
$cVersion = 'v1.21';
|
2021-02-27 13:40:40 +01:00
|
|
|
$cCRLF = chr(10).chr(13);
|
|
|
|
$maskDateTime = 'Y-m-d H:i:s';
|
|
|
|
|
|
|
|
// 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
|
|
|
|
2021-03-07 22:21:38 +01:00
|
|
|
$cDebug = FALSE; // Extended debug logging mode
|
|
|
|
$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
|
|
|
|
|
|
|
// 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)
|
2021-02-27 13:40:40 +01:00
|
|
|
// -- swiftmailer/swiftmailer https://swiftmailer.symfony.com/docs/introduction.html
|
|
|
|
// -- 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
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
// Initialize Curl instance
|
|
|
|
_log('% postJSON: '.$url);
|
|
|
|
if ($cDebug) { _log('> POST data'.json_encode($data)); }
|
|
|
|
|
|
|
|
$ch = curl_init();
|
|
|
|
|
|
|
|
// Set options
|
|
|
|
curl_setopt($ch, CURLOPT_USERAGENT, 'Zabbix-mailGraph - '.$cVersion);
|
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
|
|
|
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
|
|
|
|
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
|
|
|
curl_setopt($ch, CURLOPT_POST, TRUE);
|
2021-03-07 22:21:38 +01:00
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS,
|
|
|
|
json_encode($data,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK));
|
2021-02-27 13:40:40 +01:00
|
|
|
|
|
|
|
// Execute Curl
|
|
|
|
$data = curl_exec($ch);
|
|
|
|
|
|
|
|
if ($data===FALSE)
|
|
|
|
{
|
|
|
|
_log('! Failed: '.curl_error($ch));
|
|
|
|
|
|
|
|
$data = 'An error occurred while retreiving the requested page.'.$cCRLF;
|
|
|
|
$data .= 'Requested page = '.$url.$cCRLF;
|
|
|
|
$data .= 'Error = '.curl_error($ch).$cCRLF;
|
|
|
|
}
|
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-02-27 13:40:40 +01:00
|
|
|
|
|
|
|
// Unique names
|
|
|
|
$thisTime = time();
|
|
|
|
|
|
|
|
// Relative web calls
|
|
|
|
$z_url_index = $z_server ."index.php";
|
|
|
|
$z_url_graph = $z_server ."chart2.php";
|
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";
|
|
|
|
$filename = "zabbix_graph_" .$graphid . "." . $thisTime . ".png";
|
|
|
|
$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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
// Delete cookie
|
|
|
|
unlink($filename_cookie);
|
|
|
|
|
|
|
|
// 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-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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Create easy to read duration
|
|
|
|
|
|
|
|
function getNiceDuration($durationInSeconds)
|
|
|
|
{
|
|
|
|
$duration = '';
|
|
|
|
|
|
|
|
$days = floor($durationInSeconds / 86400);
|
|
|
|
$durationInSeconds -= $days * 86400;
|
|
|
|
$hours = floor($durationInSeconds / 3600);
|
|
|
|
$durationInSeconds -= $hours * 3600;
|
|
|
|
$minutes = floor($durationInSeconds / 60);
|
|
|
|
$seconds = $durationInSeconds - $minutes * 60;
|
|
|
|
|
|
|
|
if ($days>0)
|
|
|
|
{
|
|
|
|
$duration .= $days . ' day';
|
|
|
|
if ($days!=1) { $duration .= 's'; }
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($hours>0)
|
|
|
|
{
|
|
|
|
$duration .= ' ' . $hours . ' hr';
|
|
|
|
if ($hours!=1) { $duration .= 's'; }
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($minutes>0)
|
|
|
|
{
|
|
|
|
$duration .= ' ' . $minutes . ' min';
|
|
|
|
if ($minutes!=1) { $duration .= 's'; }
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($seconds>=0) { $duration .= ' ' . $seconds . ' sec'; }
|
|
|
|
if ($seconds!=1) { $duration .= 's'; }
|
|
|
|
|
|
|
|
return $duration;
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 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-01 18:13:32 +01:00
|
|
|
_log('# Configuration taken from config.json'.$cCRLF.json_encode($config,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK));
|
|
|
|
|
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-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-02-27 15:40:01 +01:00
|
|
|
_log('# Invoked from CLI');
|
2021-02-27 13:40:40 +01:00
|
|
|
|
2021-02-27 15:40:01 +01:00
|
|
|
// Assumes that config.json file has the correct information
|
2021-03-03 23:26:35 +01:00
|
|
|
|
2021-02-27 15:40:01 +01:00
|
|
|
$problemData['itemId'] = $config['cli_itemId'];
|
|
|
|
$problemData['triggerId'] = $config['cli_triggerId'];
|
|
|
|
$problemData['eventId'] = $config['cli_eventId'];
|
|
|
|
$problemData['eventValue'] = $config['cli_eventValue'];
|
|
|
|
$problemData['recipient'] = $config['cli_recipient'];
|
|
|
|
$problemData['baseURL'] = $config['cli_baseURL'];
|
|
|
|
$problemData['duration'] = $config['cli_duration'];
|
2021-02-28 21:31:46 +01:00
|
|
|
$problemData['subject'] = $config['cli_subject'];
|
2021-03-03 23:26:35 +01:00
|
|
|
$problemData['period'] = $config['cli_period'];
|
2021-02-27 13:40:40 +01:00
|
|
|
|
|
|
|
// Switch on CLI log display
|
|
|
|
$showLog = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-01 18:13:32 +01:00
|
|
|
_log('# Data passed from Zabbix'.$cCRLF.json_encode($problemData,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK));
|
|
|
|
|
2021-03-03 23:26:35 +01:00
|
|
|
// --- CHECK AND SET P_ VARIABLES ---
|
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['itemId'])) { echo "Missing ITEM ID?\n"; die; }
|
|
|
|
$p_itemId = intval($problemData['itemId']);
|
|
|
|
|
|
|
|
if (!isset($problemData['triggerId'])) { echo "Missing TRIGGER ID?\n"; die; }
|
|
|
|
$p_triggerId = intval($problemData['triggerId']);
|
|
|
|
|
|
|
|
if (!isset($problemData['eventId'])) { echo "Missing EVENT ID?\n"; die; }
|
|
|
|
$p_eventId = intval($problemData['eventId']);
|
|
|
|
|
|
|
|
if (!isset($problemData['recipient'])) { echo "Missing RECIPIENT?\n"; die; }
|
|
|
|
$p_recipient = $problemData['recipient'];
|
|
|
|
|
|
|
|
if (!isset($problemData['eventValue'])) { echo "Missing EVENTVALUE?\n"; die; }
|
|
|
|
$p_eventValue = intval($problemData['eventValue']);
|
|
|
|
|
|
|
|
if (!isset($problemData['duration'])) { echo "Missing DURATION?\n"; die; }
|
2021-02-28 21:31:46 +01:00
|
|
|
$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-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 18:36:28 +01:00
|
|
|
$p_smtp_transport = 'none';
|
|
|
|
if ((isset($config['smtp_transport'])) && ($config['smtp_transport']=='tls')) { $p_smtp_transport = 'tls'; }
|
|
|
|
if ((isset($config['smtp_transport'])) && ($config['smtp_transport']=='ssl')) { $p_smtp_transport = 'ssl'; }
|
|
|
|
|
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-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)
|
|
|
|
$z_url_image = $z_url.'images/'; // Images URL (included in plain message text)
|
2021-02-27 13:40:40 +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-03-07 22:21:38 +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
|
|
|
|
|
|
|
// 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)
|
|
|
|
// TODO: Check if information retreival can be done with less rigths
|
2021-02-27 15:40:01 +01:00
|
|
|
$z_api_user = $config['zabbix_api_user'];
|
|
|
|
$z_api_pass = $config['zabbix_api_pwd'];
|
2021-02-27 13:40:40 +01:00
|
|
|
|
|
|
|
// Mail sender
|
2021-02-27 15:40:01 +01:00
|
|
|
$mailFrom = array($config['mail_from']=>'Zabbix Mailgraph');
|
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-03-03 23:26:35 +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; }
|
|
|
|
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 ////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
$mailData = array();
|
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
|
|
|
|
|
|
|
// --- LOGIN ---
|
|
|
|
|
|
|
|
_log('# LOGIN to Zabbix');
|
|
|
|
|
|
|
|
$request = array('jsonrpc'=>'2.0',
|
|
|
|
'method'=>'user.login',
|
|
|
|
'params'=>array('user'=>$z_api_user,
|
|
|
|
'password'=>$z_api_pass),
|
|
|
|
'id'=>nextRequestID(),
|
|
|
|
'auth'=>null);
|
|
|
|
|
|
|
|
$result = postJSON($z_url_api,$request);
|
|
|
|
|
|
|
|
$token = '';
|
|
|
|
if (isset($result['result'])) { $token = $result['result']; }
|
|
|
|
|
2021-02-27 15:40:01 +01:00
|
|
|
if ($token=='') { echo 'Error logging in to Zabbix? ('.$z_url_api.')'; die; }
|
2021-02-27 13:40:40 +01:00
|
|
|
|
|
|
|
_log('> Token = '.$token);
|
|
|
|
|
|
|
|
// --- GET TRIGGER INFO ---
|
|
|
|
|
|
|
|
_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',
|
|
|
|
'selectTags'=>'extend'),
|
2021-02-27 13:40:40 +01:00
|
|
|
'expandComment'=>1,
|
|
|
|
'expandDescription'=>1,
|
|
|
|
'expandExpression'=>1,
|
|
|
|
'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;
|
|
|
|
|
|
|
|
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':
|
|
|
|
$p_period = $aTag['value'];
|
|
|
|
_log('+ Graph display period override = '.$p_period);
|
|
|
|
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-04 14:29:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-27 13:40:40 +01:00
|
|
|
// --- GET ITEM INFO ---
|
|
|
|
|
|
|
|
_log('# Retrieve ITEM information');
|
|
|
|
|
|
|
|
$itemId = $thisTrigger['result'][0]['functions'][0]['itemid'];
|
|
|
|
|
|
|
|
$request = array('jsonrpc'=>'2.0',
|
|
|
|
'method'=>'item.get',
|
|
|
|
'params'=>array('itemids'=>$itemId,
|
|
|
|
'output'=>'extend'),
|
|
|
|
'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-02-27 13:40:40 +01:00
|
|
|
// --- GET HOST INFO ---
|
|
|
|
|
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,
|
|
|
|
'output'=>'extend'),
|
|
|
|
'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'];
|
|
|
|
$mailData['HOST_ERROR'] = $thisHost['result'][0]['error'];
|
|
|
|
$mailData['HOST_DESCRIPTION'] = $thisHost['result'][0]['description'];
|
|
|
|
|
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-02 23:17:03 +01:00
|
|
|
// --- GET GRAPHS ASSOCIATED WITH THIS HOST ---
|
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-09 10:21:06 +01:00
|
|
|
_log('# Retrieving FORCED graph information');
|
|
|
|
|
2021-03-04 14:29:35 +01:00
|
|
|
// --- GET GRAPH ASSOCIATED WITH FORCEGRAPH ---
|
|
|
|
|
|
|
|
$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);
|
|
|
|
_log('> Forced graph data'.$cCRLF.json_encode($forceGraphInfo,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK));
|
|
|
|
|
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-02 23:17:03 +01:00
|
|
|
// --- FIND MATCHING GRAPH ITEMS WITH OUR TRIGGER ITEMS ---
|
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-02 23:17:03 +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)
|
|
|
|
{
|
|
|
|
if ($anItemId=$itemId)
|
|
|
|
{
|
|
|
|
_log('+ Graph #'.$aGraphItem['graphid'].' full match found (item #'.$aGraphItem['itemid'].')');
|
|
|
|
$matchedGraphs[] = $aGraph;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$otherGraphs[] = $aGraph;
|
|
|
|
_log('~ Graph #'.$aGraphItem['graphid'].' partial match found (item #'.$aGraphItem['itemid'].')');
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
|
|
|
|
// --- READ EVENT INFORMATION ---
|
|
|
|
|
|
|
|
_log('# Retreiving EVENT information');
|
|
|
|
|
|
|
|
$request = array('jsonrpc'=>'2.0',
|
|
|
|
'method'=>'event.get',
|
|
|
|
'params'=>array('eventids'=>$p_eventId,
|
|
|
|
'output'=>'extend'),
|
|
|
|
'auth'=>$token,
|
|
|
|
'id'=>nextRequestID());
|
|
|
|
|
|
|
|
$thisEvent = postJSON($z_url_api,$request);
|
|
|
|
_log('> Event data'.$cCRLF.json_encode($thisEvent,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK));
|
|
|
|
|
2021-03-04 14:29:35 +01:00
|
|
|
if (!isset($thisEvent['result'][0])) { echo '! No response data received?'.$cCRLF; die; }
|
|
|
|
|
2021-02-27 13:40:40 +01:00
|
|
|
$mailData['EVENT_ID'] = $thisEvent['result'][0]['eventid'];
|
|
|
|
$mailData['EVENT_NAME'] = $thisEvent['result'][0]['name'];
|
|
|
|
$mailData['EVENT_OPDATA'] = $thisEvent['result'][0]['opdata'];
|
|
|
|
$mailData['EVENT_VALUE'] = $p_eventValue;
|
|
|
|
|
|
|
|
switch($p_eventValue)
|
|
|
|
{
|
|
|
|
case 0: // Recovering
|
|
|
|
$mailData['EVENT_SEVERITY'] = 'Resolved';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: // Triggered/Active
|
|
|
|
$_severity = array('Not classified','Information','Warning','Average','High','Disaster');
|
|
|
|
$mailData['EVENT_SEVERITY'] = $_severity[$thisEvent['result'][0]['severity']];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$_status = array('Recovered','Triggered/Active');
|
|
|
|
$mailData['EVENT_STATUS'] = $_status[$p_eventValue];
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Fetch Graph //////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
$graphFile = '';
|
|
|
|
$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)
|
|
|
|
{
|
|
|
|
$theGraph = $forceGraphInfo;
|
|
|
|
$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']);
|
|
|
|
|
|
|
|
$graphFile = GraphImageById($mailData['GRAPH_ID'],
|
|
|
|
$p_graphWidth,$p_graphHeight,
|
|
|
|
$theGraph['graphtype'],
|
|
|
|
$p_showLegend,$p_period);
|
|
|
|
|
|
|
|
_log('> Filename = '.$graphFile);
|
|
|
|
|
|
|
|
$mailData['GRAPH_URL'] = $z_url_image . $graphFile;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// Prepare HTML LOG content
|
|
|
|
|
|
|
|
$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']);
|
|
|
|
|
|
|
|
$mailData['LOG_HTML'] = '<html lang="en"><head><meta http-equiv=Content-Type content="text/html; charset=UTF-8">'.$cCRLF.
|
|
|
|
'<body>'.$cCRLF.
|
|
|
|
$mailData['LOG_HTML'].$cCRLF.
|
|
|
|
'</body>'.$cCRLF.
|
|
|
|
'</html>';
|
|
|
|
|
|
|
|
// Prepare PLAIN LOG content
|
|
|
|
|
|
|
|
$mailData['LOG_PLAIN'] = implode(chr(10),$logging);
|
|
|
|
|
|
|
|
// Prepare others
|
|
|
|
|
2021-03-07 22:21:38 +01:00
|
|
|
$mailData['TRIGGER_URL'] = $z_server.'triggers.php?form=update&triggerid='.$mailData['TRIGGER_ID'];
|
|
|
|
$mailData['ITEM_URL'] = $z_server.'items.php?form=update&hostid='.$mailData['HOST_ID'].'&itemid='.$mailData['ITEM_ID'];
|
|
|
|
$mailData['HOST_URL'] = $z_server.'hosts.php?form=update&hostid='.$mailData['HOST_ID'];
|
|
|
|
$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;
|
2021-02-27 13:40:40 +01:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Compose & Send Message ///////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
_log('# Setting up mailer');
|
|
|
|
|
2021-03-07 22:21:38 +01:00
|
|
|
// Do we need TLS or SSL?
|
|
|
|
|
2021-03-01 18:36:28 +01:00
|
|
|
if (($p_smtp_transport=='tls') || ($p_smtp_transport=='ssl'))
|
|
|
|
{
|
|
|
|
$transport = (new Swift_SmtpTransport($p_smtp_server, $p_smtp_port, $p_smtp_transport));
|
2021-03-01 19:51:11 +01:00
|
|
|
|
|
|
|
if ($p_smtp_strict=='no')
|
|
|
|
{
|
|
|
|
if ($transport instanceof \Swift_Transport_EsmtpTransport)
|
|
|
|
{
|
|
|
|
$transport->setStreamOptions([
|
|
|
|
'ssl' => ['allow_self_signed' => true,
|
|
|
|
'verify_peer' => false,
|
|
|
|
'verify_peer_name' => false]
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
2021-03-01 20:22:42 +01:00
|
|
|
else
|
|
|
|
{
|
2021-03-01 19:51:11 +01:00
|
|
|
if ($transport instanceof \Swift_Transport_EsmtpTransport)
|
|
|
|
{
|
|
|
|
$transport->setStreamOptions([
|
|
|
|
'ssl' => ['allow_self_signed' => false,
|
|
|
|
'verify_peer' => true,
|
|
|
|
'verify_peer_name' => true]
|
2021-03-01 20:22:42 +01:00
|
|
|
]);
|
2021-03-01 19:51:11 +01:00
|
|
|
}
|
|
|
|
}
|
2021-03-01 18:36:28 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$transport = (new Swift_SmtpTransport($p_smtp_server, $p_smtp_port));
|
|
|
|
}
|
|
|
|
|
2021-02-27 13:40:40 +01:00
|
|
|
$mailer = new Swift_Mailer($transport);
|
|
|
|
|
|
|
|
$message = (new Swift_Message());
|
|
|
|
|
|
|
|
// Fetch mailer ID from this message (no Swift function available for it ...)
|
|
|
|
// --- "Message-ID: <...id...@swift.generated>"
|
|
|
|
|
|
|
|
$content = $message->toString();
|
|
|
|
$lines = explode(chr(10),$content);
|
|
|
|
$firstLine = $lines[0];
|
|
|
|
$idParts = explode(' ',$firstLine);
|
|
|
|
$messageId = substr($idParts[1],1,-2);
|
|
|
|
|
|
|
|
_log('# Message ID = '.$messageId);
|
|
|
|
|
|
|
|
// Build parts for HTML and PLAIN
|
|
|
|
|
|
|
|
_log('# Processing templates');
|
|
|
|
_log('+ '.$z_template_path.'html.template');
|
|
|
|
_log('+ '.$z_template_path.'plain.template');
|
|
|
|
|
|
|
|
$loader = new \Twig\Loader\ArrayLoader([
|
|
|
|
'html' => file_get_contents($z_template_path.'html.template'),
|
|
|
|
'plain' => file_get_contents($z_template_path.'plain.template'),
|
2021-02-28 21:31:46 +01:00
|
|
|
'subject' => $mailData['SUBJECT'],
|
2021-02-27 13:40:40 +01:00
|
|
|
]);
|
|
|
|
|
|
|
|
$twig = new \Twig\Environment($loader);
|
|
|
|
|
|
|
|
if ($graphFile!='')
|
|
|
|
{
|
|
|
|
// Embed the image
|
|
|
|
$mailData['GRAPH_CID'] = $message->embed(Swift_Image::fromPath($z_images_path.$graphFile));
|
|
|
|
_log('> Embedded graph image '.$z_images_path.$graphFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
$bodyHTML = $twig->render('html', $mailData);
|
|
|
|
$bodyPlain = $twig->render('plain', $mailData);
|
|
|
|
$mailSubject = $twig->render('subject', $mailData);
|
|
|
|
|
|
|
|
// Prepare message
|
|
|
|
|
2021-02-28 21:31:46 +01:00
|
|
|
$message->setSubject($mailSubject)
|
2021-02-27 13:40:40 +01:00
|
|
|
->setFrom($mailFrom)
|
|
|
|
->setTo($p_recipient)
|
|
|
|
->setBody($bodyHTML, 'text/html')
|
|
|
|
->addPart($bodyPlain, 'text/plain');
|
|
|
|
|
|
|
|
if ($cDebugMail)
|
|
|
|
{
|
|
|
|
_log('# Attaching logs to mail message');
|
|
|
|
|
|
|
|
$attachLogHTML = new Swift_Attachment($mailData['LOG_HTML'], 'log.html', 'text/html');
|
|
|
|
$message->attach($attachLogHTML);
|
|
|
|
|
|
|
|
$attachLogPlain = new Swift_Attachment($mailData['LOG_PLAIN'], 'log.txt', '/text/plain');
|
|
|
|
$message->attach($attachLogPlain);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send message
|
|
|
|
|
|
|
|
$result = $mailer->send($message);
|
|
|
|
|
|
|
|
// Return TAG information
|
|
|
|
|
2021-02-27 17:17:54 +01:00
|
|
|
$response = array('messageId.mailGraph'=>$messageId);
|
2021-02-27 13:40:40 +01:00
|
|
|
echo json_encode($response).$cCRLF;
|
|
|
|
|
|
|
|
// Store log?
|
|
|
|
|
|
|
|
if ($cDebug)
|
|
|
|
{
|
|
|
|
unset($mailData['LOG_HTML']);
|
|
|
|
unset($mailData['LOG_PLAIN']);
|
|
|
|
|
|
|
|
$content = implode(chr(10),$logging).$cCRLF.$cCRLF.'=== MAILDATA ==='.$cCRLF.$cCRLF.json_encode($mailData,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK);
|
|
|
|
$content = str_replace(chr(13),'',$content);
|
|
|
|
|
2021-03-01 20:22:42 +01:00
|
|
|
$logName = 'log.'.$p_eventId.'.'.date('YmdHis').'.dump';
|
|
|
|
|
|
|
|
file_put_contents($z_log_path.$logName,$content);
|
|
|
|
_log('= Log stored to '.$z_log_path.$logName);
|
2021-02-27 13:40:40 +01:00
|
|
|
}
|
2021-03-07 22:21:38 +01:00
|
|
|
?>
|