mirror of
https://github.com/moudsen/mailGraph
synced 2025-10-28 16:17:39 +01:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58668311ee | ||
|
|
9052b71562 | ||
|
|
74b6ee15c7 | ||
|
|
398637e582 | ||
|
|
9e40060cdd | ||
|
|
e85400b0de | ||
|
|
e05fcbfba7 | ||
|
|
66b504a66c | ||
|
|
bc0c83b544 | ||
|
|
17cdbea2bd | ||
|
|
fb51354649 | ||
|
|
78061964c4 | ||
|
|
1c9786c549 | ||
|
|
37b1ea7ea2 |
@@ -1,7 +1,10 @@
|
|||||||
## mailGraph (v1.22)
|
## mailGraph (v1.26)
|
||||||
Zabbix Media module and scripts for sending e-mail alerts with graphs.
|
Zabbix Media module and scripts for sending e-mail alerts with graphs.
|
||||||
|
|
||||||
**Please use the Wiki for information on how to install, configure and use MailGraph in Zabbix.**
|
**Please use the Wiki for information on how to install, configure and use MailGraph in Zabbix.**
|
||||||
|
|
||||||
|
## Upgrade notes
|
||||||
|
Per v1.25 and higher the template data provisioning and code has fundamentally changed. If you upgrade from an earlier version as v1.25, make sure you understand the changes in templates/html.template (now making use of arrays for lists of items).
|
||||||
|
|
||||||
## Example message
|
## Example message
|
||||||
[](images/Example-mail-message-v122.png)
|
[](images/Example-mail-message-v122.png)
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"script_baseurl": "https:\/\/domain.com\/",
|
"script_baseurl": "https:\/\/mydomain.com\/",
|
||||||
"cli_itemId": 0,
|
"cli_itemId": 0,
|
||||||
"cli_triggerId": 0,
|
"cli_triggerId": 0,
|
||||||
"cli_eventId": 0,
|
"cli_eventId": 0,
|
||||||
"cli_eventValue": 0,
|
|
||||||
"cli_duration": 0,
|
"cli_duration": 0,
|
||||||
"cli_recipient": "recipient@domain.com",
|
"cli_recipient": "recipient@mydomain.com",
|
||||||
"cli_subject": "[TEST] {{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}",
|
"cli_subject": "[TEST] {{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}",
|
||||||
"cli_baseURL": "https:\/\/domain.com\/zabbix\/",
|
"cli_baseURL": "https:\/\/mydomain.com\/zabbix\/",
|
||||||
"cli_period": "30m",
|
"cli_period": "30m",
|
||||||
"cli_period_header": "Last 30 minutes",
|
"cli_period_header": "Last 30 minutes",
|
||||||
"cli_debug": 1,
|
"cli_debug": 1,
|
||||||
|
"cli_proxy": "",
|
||||||
"zabbix_user": "alogicalusername",
|
"zabbix_user": "alogicalusername",
|
||||||
"zabbix_user_pwd": "astrongpassword",
|
"zabbix_user_pwd": "astrongpassword",
|
||||||
"zabbix_api_user": "alogicalusername",
|
"zabbix_api_user": "alogicalusername",
|
||||||
"zabbix_api_pwd": "astrongpassword",
|
"zabbix_api_pwd": "astrongpassword",
|
||||||
"mail_from": "sender@domain.com",
|
"mail_from": "sender@mydomain.com",
|
||||||
"subject": "{{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}",
|
"subject": "{{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}",
|
||||||
"smtp_server": "localhost",
|
"smtp_server": "localhost",
|
||||||
"smtp_port": 25,
|
"smtp_port": 25,
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"script_baseurl": "https:\/\/domain.com\/",
|
"script_baseurl": "https:\/\/mydomain.com\/",
|
||||||
"cli_itemId": 0,
|
"cli_itemId": 0,
|
||||||
"cli_triggerId": 0,
|
"cli_triggerId": 0,
|
||||||
"cli_eventId": 0,
|
"cli_eventId": 0,
|
||||||
"cli_eventValue": 0,
|
|
||||||
"cli_duration": 0,
|
"cli_duration": 0,
|
||||||
"cli_recipient": "recipient@domain.com",
|
"cli_recipient": "recipient@mydomain.com",
|
||||||
"cli_subject": "[TEST] {{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}",
|
"cli_subject": "[TEST] {{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}",
|
||||||
"cli_baseURL": "https:\/\/domain.com\/zabbix\/",
|
"cli_baseURL": "https:\/\/mydomain.com\/zabbix\/",
|
||||||
"cli_periods": "10m,4h,2d,7d",
|
"cli_periods": "10m,4h,2d,7d",
|
||||||
"cli_periods_headers": "Last 10 minutes,Last 4 hours,Last 2 days,Last 7 days",
|
"cli_periods_headers": "Last 10 minutes,Last 4 hours,Last 2 days,Last 7 days",
|
||||||
"cli_debug": 1,
|
"cli_debug": 1,
|
||||||
|
"cli_proxy": "",
|
||||||
"zabbix_user": "alogicalusername",
|
"zabbix_user": "alogicalusername",
|
||||||
"zabbix_user_pwd": "astrongpassword",
|
"zabbix_user_pwd": "astrongpassword",
|
||||||
"zabbix_api_user": "alogicalusername",
|
"zabbix_api_user": "alogicalusername",
|
||||||
"zabbix_api_pwd": "astrongpassword",
|
"zabbix_api_pwd": "astrongpassword",
|
||||||
"mail_from": "sender@domain.com",
|
"mail_from": "sender@mydomain.com",
|
||||||
"subject": "{{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}",
|
"subject": "{{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}",
|
||||||
"smtp_server": "localhost",
|
"smtp_server": "localhost",
|
||||||
"smtp_port": 25,
|
"smtp_port": 25,
|
||||||
|
|||||||
@@ -7,16 +7,17 @@ try {
|
|||||||
result = { tags: {} };
|
result = { tags: {} };
|
||||||
|
|
||||||
// Set HTTP proxy if required
|
// Set HTTP proxy if required
|
||||||
if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') { req.setProxy(params.HTTPProxy); }
|
if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
|
||||||
|
req.setProxy(params.HTTPProxy);
|
||||||
|
fields.HTTPProxy = params.HTTPProxy;
|
||||||
|
}
|
||||||
|
|
||||||
// Declare output type
|
// Declare output type
|
||||||
req.AddHeader('Content-Type: application/json');
|
req.AddHeader('Content-Type: application/json');
|
||||||
|
|
||||||
// Must have fields
|
// Must have fields
|
||||||
fields.itemId = params.itemId;
|
fields.itemId = params.itemId;
|
||||||
fields.triggerId = params.triggerId;
|
|
||||||
fields.eventId = params.eventId;
|
fields.eventId = params.eventId;
|
||||||
fields.eventValue = params.eventValue;
|
|
||||||
fields.recipient = params.recipient;
|
fields.recipient = params.recipient;
|
||||||
fields.baseURL = params.baseURL;
|
fields.baseURL = params.baseURL;
|
||||||
fields.duration = params.duration;
|
fields.duration = params.duration;
|
||||||
|
|||||||
239
mailGraph.php
239
mailGraph.php
@@ -28,6 +28,11 @@
|
|||||||
// 1.21 2021/03/09 - Mark Oudsen - Reverted graph.get code back to original code as it was not a bug but
|
// 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)!
|
// a wrongly typed requested (should be ARRAY, not comma separated)!
|
||||||
// 1.22 2021/03/10 - Mark Oudsen - Added ability to embed multiple periods (1-4) of the same graph
|
// 1.22 2021/03/10 - Mark Oudsen - Added ability to embed multiple periods (1-4) of the same graph
|
||||||
|
// 1.23 2021/03/12 - Mark Oudsen - Added graph support for 'Stacked', 'Pie' and 'Exploded'
|
||||||
|
// 1.24 2021/03/12 - Mark Oudsen - Added support for HTTP proxy
|
||||||
|
// 1.25 2021/03/16 - Mark Oudsen - Refactoring for optimized flow and relevant data retrieval
|
||||||
|
// 1.26 2021/03/19 - Mark Oudsen - Bugfixes after refactor (wrong itemId and incorrect eventValue)
|
||||||
|
// Suppressing Zabbix username-password in log
|
||||||
// ------------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// (C) M.J.Oudsen, mark.oudsen@puzzl.nl
|
// (C) M.J.Oudsen, mark.oudsen@puzzl.nl
|
||||||
@@ -50,7 +55,7 @@
|
|||||||
|
|
||||||
// CONSTANTS
|
// CONSTANTS
|
||||||
|
|
||||||
$cVersion = 'v1.22';
|
$cVersion = 'v1.26';
|
||||||
$cCRLF = chr(10).chr(13);
|
$cCRLF = chr(10).chr(13);
|
||||||
$maskDateTime = 'Y-m-d H:i:s';
|
$maskDateTime = 'Y-m-d H:i:s';
|
||||||
|
|
||||||
@@ -81,16 +86,23 @@
|
|||||||
global $cCRLF;
|
global $cCRLF;
|
||||||
global $cVersion;
|
global $cVersion;
|
||||||
global $cDebug;
|
global $cDebug;
|
||||||
|
global $HTTPProxy;
|
||||||
|
|
||||||
// Initialize Curl instance
|
// Initialize Curl instance
|
||||||
_log('% postJSON: '.$url);
|
_log('% postJSON: '.$url);
|
||||||
if ($cDebug) { _log('> POST data'.json_encode($data)); }
|
if ($cDebug) { _log('> POST data: '.json_encode(maskOutputContent($data))); }
|
||||||
|
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
|
|
||||||
// Set options
|
// Set options
|
||||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Zabbix-mailGraph - '.$cVersion);
|
curl_setopt($ch, CURLOPT_USERAGENT, 'Zabbix-mailGraph - '.$cVersion);
|
||||||
|
|
||||||
|
if ((isset($HTTPProxy)) && ($HTTPProxy!=''))
|
||||||
|
{
|
||||||
|
_log('% Using proxy: '.$HTTPProxy);
|
||||||
|
curl_setopt($ch, CURLOPT_PROXY, $HTTPProxy);
|
||||||
|
}
|
||||||
|
|
||||||
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
|
||||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
|
||||||
@@ -141,13 +153,36 @@
|
|||||||
global $z_url_api;
|
global $z_url_api;
|
||||||
global $cVersion;
|
global $cVersion;
|
||||||
global $cCRLF;
|
global $cCRLF;
|
||||||
|
global $HTTPProxy;
|
||||||
|
|
||||||
// Unique names
|
// Unique names
|
||||||
$thisTime = time();
|
$thisTime = time();
|
||||||
|
|
||||||
// Relative web calls
|
// Relative web calls
|
||||||
$z_url_index = $z_server ."index.php";
|
$z_url_index = $z_server ."index.php";
|
||||||
|
|
||||||
|
switch($graphType)
|
||||||
|
{
|
||||||
|
// 0: Normal
|
||||||
|
// 1: Stacked
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
$z_url_graph = $z_server ."chart2.php";
|
$z_url_graph = $z_server ."chart2.php";
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 2: Pie
|
||||||
|
// 3: Exploded
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
$z_url_graph = $z_server ."chart6.php";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Catch all ...
|
||||||
|
_log('% Graph type #'.$graphType.' unknown; forcing "Normal"');
|
||||||
|
$z_url_graph = $z_server ."chart2.php";
|
||||||
|
}
|
||||||
|
|
||||||
$z_url_fetch = $z_url_graph ."?graphid=" .$graphid ."&width=" .$width ."&height=" .$height .
|
$z_url_fetch = $z_url_graph ."?graphid=" .$graphid ."&width=" .$width ."&height=" .$height .
|
||||||
"&graphtype=".$graphType."&legend=".$showLegend."&profileIdx=web.graphs.filter".
|
"&graphtype=".$graphType."&legend=".$showLegend."&profileIdx=web.graphs.filter".
|
||||||
"&from=now-".$period."&to=now";
|
"&from=now-".$period."&to=now";
|
||||||
@@ -168,6 +203,12 @@
|
|||||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Zabbix-mailGraph - '.$cVersion);
|
curl_setopt($ch, CURLOPT_USERAGENT, 'Zabbix-mailGraph - '.$cVersion);
|
||||||
|
|
||||||
|
if ((isset($HTTPProxy)) && ($HTTPProxy!=''))
|
||||||
|
{
|
||||||
|
_log('% Using proxy: '.$HTTPProxy);
|
||||||
|
curl_setopt($ch, CURLOPT_PROXY, $HTTPProxy);
|
||||||
|
}
|
||||||
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
|
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
@@ -269,41 +310,51 @@
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Create easy to read duration
|
// Check the array for information we do not want to share in any logging
|
||||||
|
|
||||||
function getNiceDuration($durationInSeconds)
|
function maskOutputFields($info)
|
||||||
{
|
{
|
||||||
$duration = '';
|
foreach($info as $aKey=>$aValue)
|
||||||
|
|
||||||
$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';
|
switch($aKey)
|
||||||
if ($days!=1) { $duration .= 's'; }
|
{
|
||||||
|
case 'zabbix_user':
|
||||||
|
case 'zabbix_user_pwd':
|
||||||
|
case 'zabbix_api_user':
|
||||||
|
case 'zabbix_api_pwd':
|
||||||
|
$info[$aKey] = '<masked>';
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hours>0)
|
return($info);
|
||||||
{
|
|
||||||
$duration .= ' ' . $hours . ' hr';
|
|
||||||
if ($hours!=1) { $duration .= 's'; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($minutes>0)
|
// Check the array if it contains information that should not be logged
|
||||||
|
|
||||||
|
function maskOutputContent($info)
|
||||||
{
|
{
|
||||||
$duration .= ' ' . $minutes . ' min';
|
global $config;
|
||||||
if ($minutes!=1) { $duration .= 's'; }
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($seconds>=0) { $duration .= ' ' . $seconds . ' sec'; }
|
return($info);
|
||||||
if ($seconds!=1) { $duration .= 's'; }
|
|
||||||
|
|
||||||
return $duration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -315,7 +366,8 @@
|
|||||||
// [CONFIGURE] Change only when you want to place your config file somewhere else ...
|
// [CONFIGURE] Change only when you want to place your config file somewhere else ...
|
||||||
$config = readConfig(getcwd().'/config/config.json');
|
$config = readConfig(getcwd().'/config/config.json');
|
||||||
|
|
||||||
_log('# Configuration taken from config.json'.$cCRLF.json_encode($config,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK));
|
_log('# Configuration taken from config.json'.$cCRLF.
|
||||||
|
json_encode(maskOutputFields($config),JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK));
|
||||||
|
|
||||||
// --- POST DATA ---
|
// --- POST DATA ---
|
||||||
|
|
||||||
@@ -325,6 +377,8 @@
|
|||||||
|
|
||||||
// --- CLI DATA ---
|
// --- CLI DATA ---
|
||||||
|
|
||||||
|
$HTTPProxy = '';
|
||||||
|
|
||||||
// Facilitate CLI based testing
|
// Facilitate CLI based testing
|
||||||
if (isset($argc))
|
if (isset($argc))
|
||||||
{
|
{
|
||||||
@@ -336,20 +390,19 @@
|
|||||||
|
|
||||||
// MANDATORY
|
// MANDATORY
|
||||||
$problemData['itemId'] = $config['cli_itemId'];
|
$problemData['itemId'] = $config['cli_itemId'];
|
||||||
$problemData['triggerId'] = $config['cli_triggerId'];
|
|
||||||
$problemData['eventId'] = $config['cli_eventId'];
|
$problemData['eventId'] = $config['cli_eventId'];
|
||||||
$problemData['eventValue'] = $config['cli_eventValue'];
|
|
||||||
$problemData['recipient'] = $config['cli_recipient'];
|
$problemData['recipient'] = $config['cli_recipient'];
|
||||||
$problemData['baseURL'] = $config['cli_baseURL'];
|
$problemData['baseURL'] = $config['cli_baseURL'];
|
||||||
$problemData['duration'] = $config['cli_duration'];
|
$problemData['duration'] = $config['cli_duration'];
|
||||||
$problemData['subject'] = $config['cli_subject'];
|
|
||||||
$problemData['period'] = $config['cli_period'];
|
|
||||||
|
|
||||||
// OPTIONAL
|
// OPTIONAL
|
||||||
|
if (isset($config['cli_subject'])) { $problemData['subject'] = $config['cli_subject']; }
|
||||||
|
if (isset($config['cli_period'])) { $problemData['period'] = $config['cli_period']; }
|
||||||
if (isset($config['cli_period_header'])) { $problemData['period_header'] = $config['cli_period_header']; }
|
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'])) { $problemData['periods'] = $config['cli_periods']; }
|
||||||
if (isset($config['cli_periods_headers'])) { $problemData['periods_headers'] = $config['cli_periods_headers']; }
|
if (isset($config['cli_periods_headers'])) { $problemData['periods_headers'] = $config['cli_periods_headers']; }
|
||||||
if (isset($config['cli_debug'])) { $problemData['debug'] = $config['cli_debug']; }
|
if (isset($config['cli_debug'])) { $problemData['debug'] = $config['cli_debug']; }
|
||||||
|
if (isset($config['cli_proxy'])) { $problemData['HTTPProxy'] = $config['cli_proxy']; }
|
||||||
|
|
||||||
// Switch on CLI log display
|
// Switch on CLI log display
|
||||||
$showLog = TRUE;
|
$showLog = TRUE;
|
||||||
@@ -364,18 +417,12 @@
|
|||||||
if (!isset($problemData['itemId'])) { echo "Missing ITEM ID?\n"; die; }
|
if (!isset($problemData['itemId'])) { echo "Missing ITEM ID?\n"; die; }
|
||||||
$p_itemId = intval($problemData['itemId']);
|
$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; }
|
if (!isset($problemData['eventId'])) { echo "Missing EVENT ID?\n"; die; }
|
||||||
$p_eventId = intval($problemData['eventId']);
|
$p_eventId = intval($problemData['eventId']);
|
||||||
|
|
||||||
if (!isset($problemData['recipient'])) { echo "Missing RECIPIENT?\n"; die; }
|
if (!isset($problemData['recipient'])) { echo "Missing RECIPIENT?\n"; die; }
|
||||||
$p_recipient = $problemData['recipient'];
|
$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; }
|
if (!isset($problemData['duration'])) { echo "Missing DURATION?\n"; die; }
|
||||||
$p_duration = intval($problemData['duration']);
|
$p_duration = intval($problemData['duration']);
|
||||||
|
|
||||||
@@ -397,6 +444,8 @@
|
|||||||
$p_period = '48h';
|
$p_period = '48h';
|
||||||
if (isset($problemData['period'])) { $p_period = $problemData['period']; }
|
if (isset($problemData['period'])) { $p_period = $problemData['period']; }
|
||||||
|
|
||||||
|
if (isset($problemData['HTTPProxy'])) { $HTTPProxy = $problemData['HTTPPRoxy']; }
|
||||||
|
|
||||||
// DYNAMIC VARIABLES FROM ZABBIX
|
// DYNAMIC VARIABLES FROM ZABBIX
|
||||||
|
|
||||||
foreach($problemData as $aKey=>$aValue)
|
foreach($problemData as $aKey=>$aValue)
|
||||||
@@ -470,7 +519,9 @@
|
|||||||
$mailData['BASE_URL'] = $p_URL;
|
$mailData['BASE_URL'] = $p_URL;
|
||||||
$mailData['SUBJECT'] = $p_subject;
|
$mailData['SUBJECT'] = $p_subject;
|
||||||
|
|
||||||
|
// -------------
|
||||||
// --- LOGIN ---
|
// --- LOGIN ---
|
||||||
|
// -------------
|
||||||
|
|
||||||
_log('# LOGIN to Zabbix');
|
_log('# LOGIN to Zabbix');
|
||||||
|
|
||||||
@@ -490,7 +541,51 @@
|
|||||||
|
|
||||||
_log('> Token = '.$token);
|
_log('> Token = '.$token);
|
||||||
|
|
||||||
|
// ------------------------------
|
||||||
|
// --- READ EVENT INFORMATION ---
|
||||||
|
// ------------------------------
|
||||||
|
|
||||||
|
_log('# Retreiving EVENT information');
|
||||||
|
|
||||||
|
$request = array('jsonrpc'=>'2.0',
|
||||||
|
'method'=>'event.get',
|
||||||
|
'params'=>array('eventids'=>$p_eventId,
|
||||||
|
'output'=>'extend',
|
||||||
|
'selectRelatedObject'=>'extend',
|
||||||
|
'selectSuppressionData'=>'extend'),
|
||||||
|
'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'];
|
||||||
|
$mailData['EVENT_VALUE'] = $thisEvent['result'][0]['relatedObject']['value'];
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$p_triggerId = $thisEvent['result'][0]['relatedObject']['triggerid'];
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
// --- GET TRIGGER INFO ---
|
// --- GET TRIGGER INFO ---
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
_log('# Retrieve TRIGGER information');
|
_log('# Retrieve TRIGGER information');
|
||||||
|
|
||||||
@@ -570,15 +665,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
// --- GET ITEM INFO ---
|
// --- GET ITEM INFO ---
|
||||||
|
// ---------------------
|
||||||
|
|
||||||
_log('# Retrieve ITEM information');
|
_log('# Retrieve ITEM information');
|
||||||
|
|
||||||
$itemId = $thisTrigger['result'][0]['functions'][0]['itemid'];
|
|
||||||
|
|
||||||
$request = array('jsonrpc'=>'2.0',
|
$request = array('jsonrpc'=>'2.0',
|
||||||
'method'=>'item.get',
|
'method'=>'item.get',
|
||||||
'params'=>array('itemids'=>$itemId,
|
'params'=>array('itemids'=>$p_itemId,
|
||||||
'output'=>'extend'),
|
'output'=>'extend'),
|
||||||
'auth'=>$token,
|
'auth'=>$token,
|
||||||
'id'=>nextRequestID());
|
'id'=>nextRequestID());
|
||||||
@@ -603,7 +698,9 @@
|
|||||||
if (strlen($mailData['ITEM_LASTVALUE'])>50) { $mailData['ITEM_LASTVALUE'] = substr($mailData['ITEM_LASTVALUE'],0,50).' ...'; }
|
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).' ...'; }
|
if (strlen($mailData['ITEM_PREVIOUSVALUE'])>50) { $mailData['ITEM_PREVIOUSVALUE'] = substr($mailData['ITEM_PREVIOUSVALUE'],0,50).' ...'; }
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
// --- GET HOST INFO ---
|
// --- GET HOST INFO ---
|
||||||
|
// ---------------------
|
||||||
|
|
||||||
_log('# Retrieve HOST information');
|
_log('# Retrieve HOST information');
|
||||||
|
|
||||||
@@ -638,7 +735,9 @@
|
|||||||
$thisMacros = postJSON($z_url_api,$request);
|
$thisMacros = postJSON($z_url_api,$request);
|
||||||
_log('> Host macro data'.$cCRLF.json_encode($thisMacros,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK));
|
_log('> Host macro data'.$cCRLF.json_encode($thisMacros,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK));
|
||||||
|
|
||||||
|
// --------------------------------------------
|
||||||
// --- GET GRAPHS ASSOCIATED WITH THIS HOST ---
|
// --- GET GRAPHS ASSOCIATED WITH THIS HOST ---
|
||||||
|
// --------------------------------------------
|
||||||
|
|
||||||
_log('# Retrieve associated graphs to this HOST and the TRIGGER ITEMS');
|
_log('# Retrieve associated graphs to this HOST and the TRIGGER ITEMS');
|
||||||
|
|
||||||
@@ -667,9 +766,11 @@
|
|||||||
|
|
||||||
if ($forceGraph>0)
|
if ($forceGraph>0)
|
||||||
{
|
{
|
||||||
_log('# Retrieving FORCED graph information');
|
// --------------------------------------------
|
||||||
|
|
||||||
// --- GET GRAPH ASSOCIATED WITH FORCEGRAPH ---
|
// --- GET GRAPH ASSOCIATED WITH FORCEGRAPH ---
|
||||||
|
// --------------------------------------------
|
||||||
|
|
||||||
|
_log('# Retrieving FORCED graph information');
|
||||||
|
|
||||||
$request = array('jsonrpc'=>'2.0',
|
$request = array('jsonrpc'=>'2.0',
|
||||||
'method'=>'graph.get',
|
'method'=>'graph.get',
|
||||||
@@ -689,11 +790,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
// --- FIND MATCHING GRAPH ITEMS WITH OUR TRIGGER ITEMS ---
|
// --- FIND MATCHING GRAPH ITEMS WITH OUR TRIGGER ITEMS ---
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
_log('# Matching retreived graph information with our trigger items');
|
_log('# Matching retreived graph information with our trigger items');
|
||||||
|
|
||||||
// Look for graphs across all functions inside the item
|
// --- Look for graphs across all functions inside the item
|
||||||
|
|
||||||
$itemIds = array();
|
$itemIds = array();
|
||||||
|
|
||||||
@@ -720,7 +823,7 @@
|
|||||||
{
|
{
|
||||||
if ($aGraphItem['itemid']==$anItemId)
|
if ($aGraphItem['itemid']==$anItemId)
|
||||||
{
|
{
|
||||||
if ($anItemId=$itemId)
|
if ($anItemId==$p_itemId)
|
||||||
{
|
{
|
||||||
_log('+ Graph #'.$aGraphItem['graphid'].' full match found (item #'.$aGraphItem['itemid'].')');
|
_log('+ Graph #'.$aGraphItem['graphid'].' full match found (item #'.$aGraphItem['itemid'].')');
|
||||||
$matchedGraphs[] = $aGraph;
|
$matchedGraphs[] = $aGraph;
|
||||||
@@ -737,42 +840,6 @@
|
|||||||
|
|
||||||
_log('> Graphs found (matching/partial) = '.sizeof($matchedGraphs).' / '.sizeof($otherGraphs));
|
_log('> Graphs found (matching/partial) = '.sizeof($matchedGraphs).' / '.sizeof($otherGraphs));
|
||||||
|
|
||||||
// --- 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));
|
|
||||||
|
|
||||||
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_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 //////////////////////////////////////////////////////////////////////////////////////////
|
// Fetch Graph //////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -863,8 +930,8 @@
|
|||||||
|
|
||||||
$graphFiles[] = $graphFile;
|
$graphFiles[] = $graphFile;
|
||||||
|
|
||||||
$mailData['GRAPH_URL'.($aKey+1)] = $z_url_image . $graphFile;
|
$mailData['GRAPHS'][$aKey]['URL'] = $z_url_image . $graphFile;
|
||||||
$mailData['GRAPH_HEADER'.($aKey+1)] = $p_periods_headers[$aKey];
|
$mailData['GRAPHS'][$aKey]['HEADER'] = $p_periods_headers[$aKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
$mailData['GRAPH_ZABBIXLINK'] = $z_server.'graphs.php?form=update&graphid='.$mailData['GRAPH_ID'];
|
$mailData['GRAPH_ZABBIXLINK'] = $z_server.'graphs.php?form=update&graphid='.$mailData['GRAPH_ID'];
|
||||||
@@ -968,11 +1035,11 @@
|
|||||||
{
|
{
|
||||||
// Embed the image(s)
|
// Embed the image(s)
|
||||||
|
|
||||||
$graphReference = 1;
|
$graphReference = 0;
|
||||||
|
|
||||||
foreach($graphFiles as $graphFile)
|
foreach($graphFiles as $graphFile)
|
||||||
{
|
{
|
||||||
$mailData['GRAPH_CID'.$graphReference++] = $message->embed(Swift_Image::fromPath($z_images_path.$graphFile));
|
$mailData['GRAPHS'][$graphReference++]['CID'] = $message->embed(Swift_Image::fromPath($z_images_path.$graphFile));
|
||||||
_log('> Embedded graph image '.$z_images_path.$graphFile);
|
_log('> Embedded graph image '.$z_images_path.$graphFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1016,7 +1083,7 @@
|
|||||||
unset($mailData['LOG_HTML']);
|
unset($mailData['LOG_HTML']);
|
||||||
unset($mailData['LOG_PLAIN']);
|
unset($mailData['LOG_PLAIN']);
|
||||||
|
|
||||||
$content = implode(chr(10),$logging).$cCRLF.$cCRLF.'=== MAILDATA ==='.$cCRLF.$cCRLF.json_encode($mailData,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK);
|
$content = implode(chr(10),$logging).$cCRLF.$cCRLF.'=== VALUES AVAILABLE FOR TWIG TEMPLATE ==='.$cCRLF.$cCRLF.json_encode($mailData,JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK);
|
||||||
$content = str_replace(chr(13),'',$content);
|
$content = str_replace(chr(13),'',$content);
|
||||||
|
|
||||||
$logName = 'log.'.$p_eventId.'.'.date('YmdHis').'.dump';
|
$logName = 'log.'.$p_eventId.'.'.date('YmdHis').'.dump';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<zabbix_export>
|
<zabbix_export>
|
||||||
<version>5.0</version>
|
<version>5.0</version>
|
||||||
<date>2021-03-10T18:50:24Z</date>
|
<date>2021-03-17T12:55:43Z</date>
|
||||||
<media_types>
|
<media_types>
|
||||||
<media_type>
|
<media_type>
|
||||||
<name>MailGraph</name>
|
<name>MailGraph</name>
|
||||||
@@ -19,10 +19,6 @@
|
|||||||
<name>eventId</name>
|
<name>eventId</name>
|
||||||
<value>{EVENT.ID}</value>
|
<value>{EVENT.ID}</value>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter>
|
|
||||||
<name>eventValue</name>
|
|
||||||
<value>{EVENT.VALUE}</value>
|
|
||||||
</parameter>
|
|
||||||
<parameter>
|
<parameter>
|
||||||
<name>graphHeight</name>
|
<name>graphHeight</name>
|
||||||
<value>120</value>
|
<value>120</value>
|
||||||
@@ -35,6 +31,10 @@
|
|||||||
<name>HTTPProxy</name>
|
<name>HTTPProxy</name>
|
||||||
<value/>
|
<value/>
|
||||||
</parameter>
|
</parameter>
|
||||||
|
<parameter>
|
||||||
|
<name>infoTest</name>
|
||||||
|
<value>Test</value>
|
||||||
|
</parameter>
|
||||||
<parameter>
|
<parameter>
|
||||||
<name>itemId</name>
|
<name>itemId</name>
|
||||||
<value>{ITEM.ID}</value>
|
<value>{ITEM.ID}</value>
|
||||||
@@ -59,10 +59,6 @@
|
|||||||
<name>subject</name>
|
<name>subject</name>
|
||||||
<value>{{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}</value>
|
<value>{{ HOST_NAME|raw }}: ({{ EVENT_SEVERITY }}) {{ EVENT_NAME|raw }}</value>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter>
|
|
||||||
<name>triggerId</name>
|
|
||||||
<value>{TRIGGER.ID}</value>
|
|
||||||
</parameter>
|
|
||||||
<parameter>
|
<parameter>
|
||||||
<name>URL</name>
|
<name>URL</name>
|
||||||
<value>https://mydomain.com/mailGraph.php</value>
|
<value>https://mydomain.com/mailGraph.php</value>
|
||||||
@@ -77,16 +73,17 @@
|
|||||||
result = { tags: {} };
|
result = { tags: {} };
|
||||||
|
|
||||||
// Set HTTP proxy if required
|
// Set HTTP proxy if required
|
||||||
if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') { req.setProxy(params.HTTPProxy); }
|
if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
|
||||||
|
req.setProxy(params.HTTPProxy);
|
||||||
|
fields.HTTPProxy = params.HTTPProxy;
|
||||||
|
}
|
||||||
|
|
||||||
// Declare output type
|
// Declare output type
|
||||||
req.AddHeader('Content-Type: application/json');
|
req.AddHeader('Content-Type: application/json');
|
||||||
|
|
||||||
// Must have fields
|
// Must have fields
|
||||||
fields.itemId = params.itemId;
|
fields.itemId = params.itemId;
|
||||||
fields.triggerId = params.triggerId;
|
|
||||||
fields.eventId = params.eventId;
|
fields.eventId = params.eventId;
|
||||||
fields.eventValue = params.eventValue;
|
|
||||||
fields.recipient = params.recipient;
|
fields.recipient = params.recipient;
|
||||||
fields.baseURL = params.baseURL;
|
fields.baseURL = params.baseURL;
|
||||||
fields.duration = params.duration;
|
fields.duration = params.duration;
|
||||||
@@ -135,6 +132,8 @@ Customization:
|
|||||||
- "graphWidth" and "graphWidth" can be defined for the image size
|
- "graphWidth" and "graphWidth" can be defined for the image size
|
||||||
- "showLegend" can be defined to show or hide the legend of the graph
|
- "showLegend" can be defined to show or hide the legend of the graph
|
||||||
- "subject" can be defined for a customized subject for the mail message
|
- "subject" can be defined for a customized subject for the mail message
|
||||||
|
- "periods" and "periods_headers" can be defined for displaying multiple periods of the same graph, or
|
||||||
|
- "period" and "period_header" can be defined to display a single graph
|
||||||
|
|
||||||
The html.template and plain.template files can be adjusted (TWIG format).
|
The html.template and plain.template files can be adjusted (TWIG format).
|
||||||
|
|
||||||
|
|||||||
@@ -114,49 +114,16 @@
|
|||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if GRAPH_CID1|length > 0 %}
|
{% for aGraph in GRAPHS %}
|
||||||
<tr>
|
<tr>
|
||||||
<div align=justify>
|
<div align=justify>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<span class="graphHeader">{{ GRAPH_HEADER1 }}</span><br/>
|
<span class="graphHeader">{{ aGraph.HEADER }}</span><br/>
|
||||||
<img id="mainimage" border=0 style="width: 100%; max-width: 790px" alt="Zabbix Graph" src="{{ GRAPH_CID1 }}" />
|
<img id="mainimage" border=0 style="width: 100%; max-width: 790px" alt="Zabbix Graph" src="{{ aGraph.CID }}" />
|
||||||
</td>
|
</td>
|
||||||
</div>
|
</div>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
{% if GRAPH_CID2|length > 0 %}
|
|
||||||
<tr>
|
|
||||||
<div align=justify>
|
|
||||||
<td align="center">
|
|
||||||
<hr/>
|
|
||||||
<span class="graphHeader">{{ GRAPH_HEADER2 }}</span><br/>
|
|
||||||
<img id="mainimage" border=0 style="width: 100%; max-width: 790px" alt="Zabbix Graph" src="{{ GRAPH_CID2 }}" />
|
|
||||||
</td>
|
|
||||||
</div>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if GRAPH_CID3|length > 0 %}
|
|
||||||
<tr>
|
|
||||||
<div align=justify>
|
|
||||||
<td align="center">
|
|
||||||
<hr/>
|
|
||||||
<span class="graphHeader">{{ GRAPH_HEADER3 }}</span><br/>
|
|
||||||
<img id="mainimage" border=0 style="width: 100%; max-width: 790px" alt="Zabbix Graph" src="{{ GRAPH_CID3 }}" />
|
|
||||||
</td>
|
|
||||||
</div>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if GRAPH_CID4|length > 0 %}
|
|
||||||
<tr>
|
|
||||||
<div align=justify>
|
|
||||||
<td align="center">
|
|
||||||
<hr/>
|
|
||||||
<span class="graphHeader">{{ GRAPH_HEADER4 }}</span><br/>
|
|
||||||
<img id="mainimage" border=0 style="width: 100%; max-width: 790px" alt="Zabbix Graph" src="{{ GRAPH_CID4 }}" />
|
|
||||||
</td>
|
|
||||||
</div>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="links">
|
<td class="links">
|
||||||
<div align=center>
|
<div align=center>
|
||||||
|
|||||||
Reference in New Issue
Block a user