通过Zabbix API在告警邮件中插入趋势图
告警邮件中嵌入趋势图是非常人性化的设计,只有有温度的告警邮件才会嵌入趋势图。。。
以下内容基于zabbix 3.0.2 测试有效,想必其它版本应该也问题不大。
话不多说,直接上代码:
邮件告警脚本
- cat mailAlarm.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# Description: 获取某一个监控项在某个时间段的graph
# Date:
# Author:
#=========================================
ALERT_SENDTO="$1"
ALERT_SUBJECT="$2"
ALERT_MESSAGE="$(echo -e "$3"|sed -e '$d' -e 's/$/<br\/>/g')"
ITEMID="$(echo -e "$3"|tail -n1|awk -F":" '{print $2}'|sed s/[[:space:]]//g)"
USERNAME="$4"
PASSWORD="$5"
STIME="$(date -d "1 hour ago" "+%Y%m%d%H%M%S")"
PERIOD=3600
WIDTH=800
#=========================================
ROOTPATH="$(cd $(dirname $0) && pwd)"
LOGFILE="${ROOTPATH}/logs/$(basename $0).log.$(date "+%Y-%m-%d")"
# 在zabbix-web根目录下创建一个graphs目录用来存放趋势图图片文件
GRAPH_DIR="/usr/local/zabbix-web/graphs"
COOKIE="${ROOTPATH}/.zabbixCookie.${USERNAME}"
CURL="/usr/bin/curl -s"
ZBX_URL="http://zabbix.server.url"
INDEX_URL="$ZBX_URL/index.php"
CHART_URL="$ZBX_URL/chart.php"
PNG_PATH="$GRAPH_DIR/$STIME.$PERIOD.${WIDTH}.$ITEMID.png"
function help()
{
cat << EOF
Usage:
sh $0 ALERT_SENDTO ALERT_SUBJECT ALERT_MESSAGE USERNAME PASSWORD
EOF
}
# 简单记一下日志
function writeLogs()
{
[ ! -d "$(dirname "${LOGFILE}")" ] && mkdir -p "$(dirname "${LOGFILE}")"
echo -e "$(date "+%Y-%m-%d %H:%M:%S")\t$1" >>"${LOGFILE}"
}
function check_integer()
{
local ret=`echo "$*" | sed 's/[0-9]//g'`
[ -n "$ret" ] && return 1
return 0
}
# 简单校验参数
function ParametersVerification()
{
[ -d "$GRAPH_DIR" ] || mkdir -p "$GRAPH_DIR"
check_integer "$ITEMID" || { echo "ERROR: Field 'ITEMID' is not integer."; exit 1;}
check_integer "$STIME" || { echo "ERROR: Field 'STIME' is not integer."; exit 1;}
check_integer "$PERIOD" || { echo "ERROR: Field 'PERIOD' is not integer."; exit 1;}
check_integer "$WIDTH" || { echo "ERROR: Field 'WIDTH' is not integer."; exit 1;}
[ $PERIOD -lt 3600 -o $PERIOD -gt 63072000 ] && { echo "ERROR: Incorrect value $PERIOD for PERIOD field: must be between 3600 and 63072000."; exit 1;}
# USERNAME、PASSWORD、ITEMID为必需参数
[ -z "$USERNAME" -o -z "$PASSWORD" -o -z "$ITEMID" ] && { echo "ERROR: Missing mandatory parameter."; help;}
# 如果没有传入STIME参数,STIME的值为当前时间减去PERIOD
[ "$STIME" == "" ] && STIME=`date -d "now -${PERIOD} second" +%Y%m%d%H%M%S`
}
# 关键步骤,获取cookie并写入文件
function getCookie()
{
/usr/bin/chattr -i ${COOKIE}
${CURL} -c ${COOKIE} -d "name=${USERNAME}&password=${PASSWORD}&autologin=1&enter=Sign+in" $INDEX_URL | egrep -o "(Login name or passwordis incorrect|Account is blocked.*seconds)"
# 如果登录失败则退出脚本,并清空cookie文件
[ ${PIPESTATUS[1]} -eq 0 ] && { echo >"$COOKIE"; exit 1;}
/usr/bin/chattr +i ${COOKIE}
}
# 获取趋势图文件
function getGraph()
{
# zabbix3.0-
#${CURL} -b ${COOKIE} -d "itemid=${ITEMID}&period=${PERIOD}&stime=${STIME}&width=${WIDTH}" $CHART_URL > "$PNG_PATH"
# zabbix3.0+
${CURL} -b ${COOKIE} -d "itemids%5B0%5D=${ITEMID}&period=${PERIOD}&stime=${STIME}&width=${WIDTH}" ${CHART_URL} > "${PNG_PATH}"
}
# 发送告警
function sendMessage()
{
/usr/bin/php ${ROOTPATH}/mailer/sendmail.php "${ALERT_SENDTO}" "${ALERT_SUBJECT}" "${ALERT_MESSAGE}" "$(basename ${PNG_PATH})" "${ITEMID}"
}
function main()
{
if [ ! -s "${COOKIE}" ];then
getCookie
fi
getGraph
if [ -s "${PNG_PATH}" ]; then
sendMessage
writeLogs "$(date "+%Y-%m-%d %H:%M:%S")\t send to ${ALERT_SENDTO}\t subject:${ALERT_SUBJECT}\t transmit status:$?"
else
writeLogs "$(date "+%Y-%m-%d %H:%M:%S")\t send to ${ALERT_SENDTO}\t subject:${ALERT_SUBJECT}\t transmit status:$? \t $PNG_PATH doesn't exist."
fi
}
[[ "$1" =~ "help" ]] && { help ; exit 0; }
main- 邮件告警脚本,同目录下创建一个mailer目录,mailer目录下存放swiftmailer源码
邮件模板及smtp服务
- cat mailer/sendmail.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
require_once ''. dirname(__FILE__) . '/vendor/autoload.php';
$sendto = $argv[1];
$subject = $argv[2];
$content = $argv[3];
$graphName = $argv[4];
$itemId = $argv[5];
// Create the Transport
$transport = (new Swift_SmtpTransport('smtp.xxxmail.com', 25))
->setUsername('AuthenticatedUser@xxxmail.com')
->setPassword('password')
;
// Create the Mailer using your created Transport
$mailer = new Swift_Mailer($transport);
// To use the ArrayLogger
#$logger = new Swift_Plugins_Loggers_ArrayLogger();
#$mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($logger));
// Or to use the Echo Logger
#$logger = new Swift_Plugins_Loggers_EchoLogger();
#$mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($logger));
// Create a message
$message = (new Swift_Message($subject))
->setFrom(['Admin@xxxmail.com' => 'Notice'])
->setTo([ $sendto => 'Swift Mailer']);
$message->setBody(
'
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <!-- So that mobile will display zoomed in -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- enable media queries for windows phone 8 -->
<meta name="format-detection" content="telephone=no"> <!-- disable auto telephone linking in iOS -->
<title>Two Columns to Rows (Simple)</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
table {
border-spacing: 0;
}
table td {
border-collapse: collapse;
}
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.ReadMsgBody {
width: 100%;
background-color: #ebebeb;
}
table {
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
-ms-interpolation-mode: bicubic;
}
.yshortcuts a {
border-bottom: none !important;
}
@media screen and (max-width: 599px) {
.force-row,
.container {
width: 100% !important;
max-width: 100% !important;
}
}
@media screen and (max-width: 400px) {
.container-padding {
padding-left: 12px !important;
padding-right: 12px !important;
}
}
.ios-footer a {
color: #aaaaaa !important;
text-decoration: underline;
}
</style>
</head>
<body style="margin:0; padding:0;" bgcolor="#F0F0F0" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
<!-- 100% background wrapper (grey background) -->
<table border="0" width="100%" height="100%" cellpadding="0" cellspacing="0" bgcolor="#F0F0F0">
<tr>
<td align="center" valign="top" bgcolor="#F0F0F0" style="background-color: #F0F0F0;">
<br>
<!-- 600px container (white background) -->
<table border="0" width="600" cellpadding="0" cellspacing="0" class="container" style="width:600px;max-width:600px">
<tr>
<td class="container-padding header" align="left" style="font-family:Helvetica, Arial, sans-serif;font-size:24px;font-weight:bold;padding-bottom:12px;color:#DF4726;padding-left:24px;padding-right:24px">
告警/恢复信息:
</td>
</tr>
<tr>
<td class="container-padding content" align="left" style="padding-left:24px;padding-right:24px;padding-top:12px;padding-bottom:12px;background-color:#ffffff">
<br>
<div class="title" style="font-family:Helvetica, Arial, sans-serif;font-size:18px;font-weight:600;color:#374550">
' . $subject . '
</div>
<div class="body-text" style="font-family:Helvetica, Arial, sans-serif;font-size:14px;line-height:20px;text-align:left;color:#333333">
<div class="hr" style="height:1px;border-bottom:1px solid #cccccc;clear: both;"> </div>
<br>
</div>
<div class="subtitle" style="font-family:Helvetica, Arial, sans-serif;font-size:16px;font-weight:600;color:#2469A0">
详细信息:
</div>
<br>
<div class="body-text" style="font-family:Helvetica, Arial, sans-serif;font-size:14px;line-height:20px;text-align:left;color:#333333">
<ol>
' . $content . '
</ol>
<div class="hr" style="height:1px;border-bottom:1px solid #cccccc"> </div>
<br>
<table width="264" border="0" cellpadding="0" cellspacing="0" align="left" class="force-row">
<tr>
<td class="col" valign="top" style="font-family:Helvetica, Arial, sans-serif;font-size:14px;line-height:20px;text-align:left;color:#333333;width:100%">
<strong>趋势图</strong>
<br><br>
<a href="http://zabbix.server.url/history.php?action=showgraph&itemids[]=' . $itemId . '">
<img src=http://zabbix.server.url/graphs/' . $graphName . ' /></a>
<br><br>
</td>
</tr>
</table>
<br><br>
<div class="hr" style="height:1px;border-bottom:1px solid #cccccc;clear: both;"> </div>
<br>
<br>
<em><small>Last updated: 08 April 2018</small></em>
</div>
<br>
</td>
</tr>
<tr>
<td class="container-padding footer-text" align="left" style="font-family:Helvetica, Arial, sans-serif;font-size:12px;line-height:16px;color:#aaaaaa;padding-left:24px;padding-right:24px">
<br><br>
Serviced provider: © 2018 XXX-INC.
<br><br>
You are receiving this email because you used our team\'s monitoring system. Update your <a href="#" style="color:#aaaaaa">alarm configuration</a> or <a href="#" style="color:#aaaaaa">to unsubscribe.</a>.
<br><br>
<strong>team@xxxmail.om</strong><br>
<span class="ios-footer">
department signature.<br>
team signature<br>
</span>
<a href="http://www.Your Company's Official network.com" style="color:#aaaaaa">www.Your Company's Official network.com</a><br>
<br><br>
</td>
</tr>
</table>
<!--/600px container -->
</td>
</tr>
</table>
<!--/100% background wrapper-->
</body>
</html>
','text/html'
);
// Send the message
$result = $mailer->send($message);
// Dump the log contents
// NOTE: The EchoLogger dumps in realtime so dump() does nothing for it
#echo $logger->dump();
swiftmailer安装
1 | mkdir mailer |
至此基本差不多了,剩下的就是在zabbix web页面上配置下了。