You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
379 lines
14 KiB
379 lines
14 KiB
1 year ago
|
zabbix_export:
|
||
|
version: '7.0'
|
||
|
media_types:
|
||
|
-
|
||
|
name: Discord
|
||
|
type: WEBHOOK
|
||
|
parameters:
|
||
|
-
|
||
|
name: alert_message
|
||
|
value: '{ALERT.MESSAGE}'
|
||
|
-
|
||
|
name: alert_subject
|
||
|
value: '{ALERT.SUBJECT}'
|
||
|
-
|
||
|
name: discord_endpoint
|
||
|
value: '{ALERT.SENDTO}'
|
||
|
-
|
||
|
name: event_date
|
||
|
value: '{EVENT.DATE}'
|
||
|
-
|
||
|
name: event_id
|
||
|
value: '{EVENT.ID}'
|
||
|
-
|
||
|
name: event_name
|
||
|
value: '{EVENT.NAME}'
|
||
|
-
|
||
|
name: event_nseverity
|
||
|
value: '{EVENT.NSEVERITY}'
|
||
|
-
|
||
|
name: event_opdata
|
||
|
value: '{EVENT.OPDATA}'
|
||
|
-
|
||
|
name: event_recovery_date
|
||
|
value: '{EVENT.RECOVERY.DATE}'
|
||
|
-
|
||
|
name: event_recovery_time
|
||
|
value: '{EVENT.RECOVERY.TIME}'
|
||
|
-
|
||
|
name: event_severity
|
||
|
value: '{EVENT.SEVERITY}'
|
||
|
-
|
||
|
name: event_source
|
||
|
value: '{EVENT.SOURCE}'
|
||
|
-
|
||
|
name: event_tags
|
||
|
value: '{EVENT.TAGS}'
|
||
|
-
|
||
|
name: event_time
|
||
|
value: '{EVENT.TIME}'
|
||
|
-
|
||
|
name: event_update_action
|
||
|
value: '{EVENT.UPDATE.ACTION}'
|
||
|
-
|
||
|
name: event_update_date
|
||
|
value: '{EVENT.UPDATE.DATE}'
|
||
|
-
|
||
|
name: event_update_message
|
||
|
value: '{EVENT.UPDATE.MESSAGE}'
|
||
|
-
|
||
|
name: event_update_status
|
||
|
value: '{EVENT.UPDATE.STATUS}'
|
||
|
-
|
||
|
name: event_update_time
|
||
|
value: '{EVENT.UPDATE.TIME}'
|
||
|
-
|
||
|
name: event_update_user
|
||
|
value: '{USER.FULLNAME}'
|
||
|
-
|
||
|
name: event_value
|
||
|
value: '{EVENT.VALUE}'
|
||
|
-
|
||
|
name: host_ip
|
||
|
value: '{HOST.IP}'
|
||
|
-
|
||
|
name: host_name
|
||
|
value: '{HOST.NAME}'
|
||
|
-
|
||
|
name: trigger_description
|
||
|
value: '{TRIGGER.DESCRIPTION}'
|
||
|
-
|
||
|
name: trigger_id
|
||
|
value: '{TRIGGER.ID}'
|
||
|
-
|
||
|
name: use_default_message
|
||
|
value: 'false'
|
||
|
-
|
||
|
name: zabbix_url
|
||
|
value: '{$ZABBIX.URL}'
|
||
|
script: |
|
||
|
var SEVERITY_COLORS = [
|
||
|
'#97AAB3', // Not classified.
|
||
|
'#7499FF', // Information.
|
||
|
'#FFC859', // Warning.
|
||
|
'#FFA059', // Average.
|
||
|
'#E97659', // High.
|
||
|
'#E45959', // Disaster.
|
||
|
'#009900' // Resolved.
|
||
|
];
|
||
|
|
||
|
function stringTruncate(str, len) {
|
||
|
return str.length > len ? str.substring(0, len - 3) + '...' : str;
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
Zabbix.log(4, '[ Discord Webhook ] Executed with params: ' + value);
|
||
|
|
||
|
var params = JSON.parse(value);
|
||
|
|
||
|
if (!params.discord_endpoint) {
|
||
|
throw 'Cannot get discord_endpoint';
|
||
|
}
|
||
|
else {
|
||
|
params.discord_endpoint = params.discord_endpoint.replace('/api/', '/api/v7/') + '?wait=True';
|
||
|
}
|
||
|
|
||
|
params.zabbix_url = (params.zabbix_url.endsWith('/'))
|
||
|
? params.zabbix_url.slice(0, -1) : params.zabbix_url;
|
||
|
|
||
|
if ([0, 1, 2, 3, 4].indexOf(parseInt(params.event_source)) === -1) {
|
||
|
throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-4.';
|
||
|
}
|
||
|
|
||
|
// Set params to true for non trigger-based events.
|
||
|
if (params.event_source !== '0') {
|
||
|
params.use_default_message = 'true';
|
||
|
params.event_nseverity = '0';
|
||
|
}
|
||
|
|
||
|
// Check {EVENT.VALUE} for trigger-based and internal events.
|
||
|
if (params.event_value !== '0' && params.event_value !== '1'
|
||
|
&& (params.event_source === '0' || params.event_source === '3')) {
|
||
|
throw 'Incorrect "event_value" parameter given: "' + params.event_value + '".\nMust be 0 or 1.';
|
||
|
}
|
||
|
|
||
|
// Check {EVENT.UPDATE.STATUS} only for trigger-based events.
|
||
|
if (params.event_update_status !== '0' && params.event_update_status !== '1' && params.event_source === '0') {
|
||
|
throw 'Incorrect "event_update_status" parameter given: "' + params.event_update_status + '".\nMust be 0 or 1.';
|
||
|
}
|
||
|
|
||
|
if (params.event_value == 0) {
|
||
|
params.event_nseverity = '6';
|
||
|
}
|
||
|
|
||
|
if (!SEVERITY_COLORS[params.event_nseverity]) {
|
||
|
throw 'Incorrect "event_nseverity" parameter given: ' + params.event_nseverity + '\nMust be 0-5.';
|
||
|
}
|
||
|
|
||
|
var color = parseInt(SEVERITY_COLORS[params.event_nseverity].replace('#', ''), 16),
|
||
|
fields = [],
|
||
|
body = {
|
||
|
embeds: [
|
||
|
{
|
||
|
color: color || 0,
|
||
|
url: (params.event_source === '0')
|
||
|
? params.zabbix_url + '/tr_events.php?triggerid=' + params.trigger_id +
|
||
|
'&eventid=' + params.event_id
|
||
|
: params.zabbix_url
|
||
|
}
|
||
|
]
|
||
|
};
|
||
|
|
||
|
// Default message from {ALERT.MESSAGE}.
|
||
|
if (params.use_default_message.toLowerCase() == 'true') {
|
||
|
body.embeds[0].title = stringTruncate(params.alert_subject, 256);
|
||
|
body.embeds[0].description = stringTruncate(params.alert_message, 2048);
|
||
|
}
|
||
|
else {
|
||
|
fields.push(
|
||
|
{
|
||
|
name: 'Host',
|
||
|
value: params.host_name + ' [' + params.host_ip + ']'
|
||
|
}
|
||
|
);
|
||
|
|
||
|
// Resolved message.
|
||
|
if (params.event_value == 0 && params.event_update_status == 0) {
|
||
|
body.embeds[0].title = stringTruncate('OK: ' + params.event_name, 256);
|
||
|
fields.push(
|
||
|
{
|
||
|
name: 'Recovery time',
|
||
|
value: params.event_recovery_time + ' ' + params.event_recovery_date,
|
||
|
inline: 'True'
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// Problem message.
|
||
|
else if (params.event_value == 1 && params.event_update_status == 0) {
|
||
|
body.embeds[0].title = stringTruncate('PROBLEM: ' + params.event_name, 256);
|
||
|
fields.push(
|
||
|
{
|
||
|
name: 'Event time',
|
||
|
value: params.event_time + ' ' + params.event_date,
|
||
|
inline: 'True'
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// Update message.
|
||
|
else if (params.event_update_status == 1) {
|
||
|
body.embeds[0].title = stringTruncate('UPDATE: ' + params.event_name, 256);
|
||
|
body.embeds[0].description = params.event_update_user + ' ' + params.event_update_action + '.';
|
||
|
|
||
|
if (params.event_update_message) {
|
||
|
body.embeds[0].description += ' Comment:\n>>> ' + params.event_update_message;
|
||
|
}
|
||
|
|
||
|
body.embeds[0].description = stringTruncate(body.embeds[0].description, 2048);
|
||
|
|
||
|
fields.push(
|
||
|
{
|
||
|
name: 'Event update time',
|
||
|
value: params.event_update_time + ' ' + params.event_update_date,
|
||
|
inline: 'True'
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
fields.push(
|
||
|
{
|
||
|
name: 'Severity',
|
||
|
value: params.event_severity,
|
||
|
inline: 'True'
|
||
|
}
|
||
|
);
|
||
|
|
||
|
if (params.event_opdata) {
|
||
|
fields.push(
|
||
|
{
|
||
|
name: 'Operational data',
|
||
|
value: stringTruncate(params.event_opdata, 1024),
|
||
|
inline: 'True'
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (params.event_value == 1 && params.event_update_status == 0 && params.trigger_description) {
|
||
|
fields.push(
|
||
|
{
|
||
|
name: 'Trigger description',
|
||
|
value: stringTruncate(params.trigger_description, 1024)
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
body.embeds[0].footer = {
|
||
|
text: 'Event ID: ' + params.event_id
|
||
|
};
|
||
|
|
||
|
if (params.event_tags) {
|
||
|
body.embeds[0].footer.text += '\nEvent tags: ' + params.event_tags;
|
||
|
}
|
||
|
body.embeds[0].footer.text = stringTruncate(body.embeds[0].footer.text, 2048);
|
||
|
}
|
||
|
|
||
|
if (fields.length > 0) {
|
||
|
body.embeds[0].fields = fields;
|
||
|
}
|
||
|
|
||
|
var req = new HttpRequest();
|
||
|
|
||
|
if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
|
||
|
req.setProxy(params.HTTPProxy);
|
||
|
}
|
||
|
|
||
|
req.addHeader('Content-Type: application/json');
|
||
|
|
||
|
var resp = req.post(params.discord_endpoint, JSON.stringify(body)),
|
||
|
data = JSON.parse(resp);
|
||
|
|
||
|
Zabbix.log(4, '[ Discord Webhook ] JSON: ' + JSON.stringify(body));
|
||
|
Zabbix.log(4, '[ Discord Webhook ] Response: ' + resp);
|
||
|
|
||
|
if (data.id) {
|
||
|
return resp;
|
||
|
}
|
||
|
else {
|
||
|
var message = ((typeof data.message === 'string') ? data.message : 'Unknown error');
|
||
|
|
||
|
Zabbix.log(3, '[ Discord Webhook ] FAILED with response: ' + resp);
|
||
|
throw message + '. For more details check zabbix server log.';
|
||
|
}
|
||
|
}
|
||
|
catch (error) {
|
||
|
Zabbix.log(3, '[ Discord Webhook ] ERROR: ' + error);
|
||
|
throw 'Sending failed: ' + error;
|
||
|
}
|
||
|
message_templates:
|
||
|
-
|
||
|
event_source: TRIGGERS
|
||
|
operation_mode: PROBLEM
|
||
|
subject: '[{EVENT.STATUS}] {EVENT.NAME}'
|
||
|
message: |
|
||
|
Problem started at {EVENT.TIME} on {EVENT.DATE}
|
||
|
Problem name: {EVENT.NAME}
|
||
|
Host: {HOST.NAME}
|
||
|
Severity: {EVENT.SEVERITY}
|
||
|
Operational data: {EVENT.OPDATA}
|
||
|
Original problem ID: {EVENT.ID}
|
||
|
{TRIGGER.URL}
|
||
|
-
|
||
|
event_source: TRIGGERS
|
||
|
operation_mode: RECOVERY
|
||
|
subject: '[{EVENT.STATUS}] {EVENT.NAME}'
|
||
|
message: |
|
||
|
Problem has been resolved in {EVENT.DURATION} at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE}
|
||
|
Problem name: {EVENT.NAME}
|
||
|
Host: {HOST.NAME}
|
||
|
Severity: {EVENT.SEVERITY}
|
||
|
Original problem ID: {EVENT.ID}
|
||
|
{TRIGGER.URL}
|
||
|
-
|
||
|
event_source: TRIGGERS
|
||
|
operation_mode: UPDATE
|
||
|
subject: '[{EVENT.STATUS}] {EVENT.NAME}'
|
||
|
message: |
|
||
|
{USER.FULLNAME} {EVENT.UPDATE.ACTION} problem at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}.
|
||
|
{EVENT.UPDATE.MESSAGE}
|
||
|
|
||
|
Current problem status is {EVENT.STATUS}, acknowledged: {EVENT.ACK.STATUS}.
|
||
|
-
|
||
|
event_source: DISCOVERY
|
||
|
operation_mode: PROBLEM
|
||
|
subject: 'Discovery: {DISCOVERY.DEVICE.STATUS} {DISCOVERY.DEVICE.IPADDRESS}'
|
||
|
message: |
|
||
|
Discovery rule: {DISCOVERY.RULE.NAME}
|
||
|
|
||
|
Device IP: {DISCOVERY.DEVICE.IPADDRESS}
|
||
|
Device DNS: {DISCOVERY.DEVICE.DNS}
|
||
|
Device status: {DISCOVERY.DEVICE.STATUS}
|
||
|
Device uptime: {DISCOVERY.DEVICE.UPTIME}
|
||
|
|
||
|
Device service name: {DISCOVERY.SERVICE.NAME}
|
||
|
Device service port: {DISCOVERY.SERVICE.PORT}
|
||
|
Device service status: {DISCOVERY.SERVICE.STATUS}
|
||
|
Device service uptime: {DISCOVERY.SERVICE.UPTIME}
|
||
|
-
|
||
|
event_source: AUTOREGISTRATION
|
||
|
operation_mode: PROBLEM
|
||
|
subject: 'Autoregistration: {HOST.HOST}'
|
||
|
message: |
|
||
|
Host name: {HOST.HOST}
|
||
|
Host IP: {HOST.IP}
|
||
|
Agent port: {HOST.PORT}
|
||
|
-
|
||
|
event_source: SERVICE
|
||
|
operation_mode: PROBLEM
|
||
|
subject: 'Service "{SERVICE.NAME}" problem: {EVENT.NAME}'
|
||
|
message: |
|
||
|
Service problem started at {EVENT.TIME} on {EVENT.DATE}
|
||
|
Service problem name: {EVENT.NAME}
|
||
|
Service: {SERVICE.NAME}
|
||
|
Severity: {EVENT.SEVERITY}
|
||
|
Original problem ID: {EVENT.ID}
|
||
|
Service description: {SERVICE.DESCRIPTION}
|
||
|
|
||
|
{SERVICE.ROOTCAUSE}
|
||
|
-
|
||
|
event_source: SERVICE
|
||
|
operation_mode: RECOVERY
|
||
|
subject: 'Service "{SERVICE.NAME}" resolved in {EVENT.DURATION}: {EVENT.NAME}'
|
||
|
message: |
|
||
|
Service "{SERVICE.NAME}" has been resolved at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE}
|
||
|
Problem name: {EVENT.NAME}
|
||
|
Problem duration: {EVENT.DURATION}
|
||
|
Severity: {EVENT.SEVERITY}
|
||
|
Original problem ID: {EVENT.ID}
|
||
|
Service description: {SERVICE.DESCRIPTION}
|
||
|
-
|
||
|
event_source: SERVICE
|
||
|
operation_mode: UPDATE
|
||
|
subject: 'Changed "{SERVICE.NAME}" service status to {EVENT.UPDATE.SEVERITY} in {EVENT.AGE}'
|
||
|
message: |
|
||
|
Changed "{SERVICE.NAME}" service status to {EVENT.UPDATE.SEVERITY} at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}.
|
||
|
Current problem age is {EVENT.AGE}.
|
||
|
Service description: {SERVICE.DESCRIPTION}
|
||
|
|
||
|
{SERVICE.ROOTCAUSE}
|