通过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
    #!/bin/bash

    # 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
    <?php
    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;">&nbsp;</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">&nbsp;</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;">&nbsp;</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
2
3
mkdir mailer
cd mailer
composer require "swiftmailer/swiftmailer:^6.0"

至此基本差不多了,剩下的就是在zabbix web页面上配置下了。