├── .fuse_hidden000012f500000001
├── .idea
├── encodings.xml
├── misc.xml
├── modules.xml
├── weixin.iml
└── workspace.xml
├── QQ20170425141712.png
├── README.md
├── Screenshot_2017-01-10-18-06-11.png
├── Screenshot_2017-01-10-18-07-06.png
├── conf
├── BLog.py
├── INIFILES.py
├── __init__.py
└── file_util.py
├── config.ini
├── get_pic.py
├── ghostdriver.log
├── problem.xml
├── recover.xml
├── requests
├── Pillow-4.0.0-cp27-cp27m-manylinux1_x86_64.whl
├── fontconfig-2.10.95-10.el7.x86_64.rpm
├── freetype-2.4.11-12.el7.x86_64.rpm
├── phantomjs-2.1.1-linux-x86_64.tar.bz2
├── requests-2.12.4-py2.py3-none-any.whl
├── requests-2.12.4.tar.gz
└── selenium-3.0.2.tar.gz
├── requirements.txt
├── test_xml.py
├── weixin.jpg
├── weixin.py
└── weixin_bak.py
/.fuse_hidden000012f500000001:
--------------------------------------------------------------------------------
1 | [INFO - 2017-01-09T18:46:22.534Z] GhostDriver - Main - running on port 50482
2 | [INFO - 2017-01-09T18:46:23.441Z] Session [eb1f97d0-d69b-11e6-90a5-dbb5d5b2099d] - page.settings - {"XSSAuditingEnabled":false,"javascriptCanCloseWindows":true,"javascriptCanOpenWindows":true,"javascriptEnabled":true,"loadImages":true,"localToRemoteUrlAccessEnabled":false,"userAgent":"Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1","webSecurityEnabled":true}
3 | [INFO - 2017-01-09T18:46:23.441Z] Session [eb1f97d0-d69b-11e6-90a5-dbb5d5b2099d] - page.customHeaders: - {}
4 | [INFO - 2017-01-09T18:46:23.441Z] Session [eb1f97d0-d69b-11e6-90a5-dbb5d5b2099d] - Session.negotiatedCapabilities - {"browserName":"phantomjs","version":"2.1.1","driverName":"ghostdriver","driverVersion":"1.2.0","platform":"linux-unknown-64bit","javascriptEnabled":true,"takesScreenshot":true,"handlesAlerts":false,"databaseEnabled":false,"locationContextEnabled":false,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"cssSelectorsEnabled":true,"webStorageEnabled":false,"rotatable":false,"acceptSslCerts":false,"nativeEvents":true,"proxy":{"proxyType":"direct"}}
5 | [INFO - 2017-01-09T18:46:23.441Z] SessionManagerReqHand - _postNewSessionCommand - New Session Created: eb1f97d0-d69b-11e6-90a5-dbb5d5b2099d
6 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/weixin.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
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 | 1483953404466
39 |
40 | 1483953404466
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/QQ20170425141712.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/QQ20170425141712.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ZABBIX可以实现短信、邮件、微信等各种报警,这三种基本大家都很熟悉, 现在基于微信写py,之前写了个无图的,感觉微信色彩不丰富,再加个有图的,说可以实现微信报警,苍老师的话牢记心头:Life is short,you need python!
2 |
3 | [TOC]
4 | ### 1 微信配置(与无图版一样)
5 | 微信公众号官网:https://qy.weixin.qq.com/
6 | 我们主要获取四个参数:部门id,应用ID和CorpID和CorpSecret
7 | #### 1.1 注册安装
8 | 注册微信企业号,安装手机微信略过
9 | ##### 1.1.1 部门设置
10 | 在通信录管理里面设置部门,如下图,我们这里设置的运维部,这个部门id要记住,在ZABBIX里面要配置这个名称,然后把你需要发送告警的人员添加到这个部门里面
11 | ##### 1.1.2 应用设置
12 | 点击左侧“应用中心”,新建消息型应用,应用名称为“服务器报警”,“应用可见范围”,添加刚刚新建的子部门(运维部),点击“服务器报警”,记录应用ID
13 | ##### 1.1.3 权限管理
14 | 点击左侧“设置”,权限管理,新建普通管理组,名称填写“服务器报警组”。点击修改“通讯录权限”,勾选管理,点击修改“应用权限”,勾选刚刚创建的“服务器报警”,点击刚刚创建的“服务器报警组”,记录左侧的CorpID与CorpSecret
15 | ### 2 程序配置
16 | 代码托管到github:https://github.com/bluetom520/zabbix-weixin-picture
17 | 下载
18 | ```
19 | git clone https://github.com/bluetom520/zabbix-weixin-picture.git
20 | ```
21 | 依赖包
22 | ```
23 | image==1.5.5
24 | lxml==3.5.0
25 | selenium==3.0.2
26 | ```
27 | 安装phantomjs
28 | ```
29 | tar -jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2
30 | mv phantomjs-2.1.1-linux-x86_64 /usr/local/phantomjs-2.1.1
31 | ```
32 | 程序部署
33 | ```
34 | cp zabbix-weixin-picture/* /usr/lib/zabbix/alertscripts/
35 | cd /usr/lib/zabbix/alertscripts/
36 | chown -R zabbix:zabbix pic
37 | chown -R zabbix:zabbix weixin.py
38 | chmod o+x weixin.py
39 | chown -R zabbix:zabbix config.ini
40 | chmod o+w config.ini
41 | ```
42 | 修改config.ini,把上节获得的三个参数填入,web 设置为zabbix服务器主页,是点击报警信息后跳转的页面,设置的监控数据的最新出图。
43 | ```
44 | [wei]
45 | corpid = wx3317042c8bcf7551
46 | corpsecret = m0VqePgfDsTbVoFlGSx5-JOCbE5p43rf5G-GC2CqN4Wq2Ce0OJQkgo0JnXMqKypv
47 | agentid = 2
48 | toparty =
49 | web = http://192.168.1.199/zabbix/
50 | ```
51 | ### 3 ZABBIX配置
52 | #### 3.1 报警媒介类型
53 | 到管理-》报警媒介类型配置我们的微信
54 | 
55 | #### 3.2 配置用户
56 | 到管理-》用户-》报警媒介-》添加,注意填写收件人为我们之前设置的运维部id 2
57 | 
58 | #### 3.3 动作设置
59 | 到配置-》动作-》创建动作(触发器)
60 | - 动作
61 | 
62 |
63 | - 条件
64 | 
65 | - 操作
66 | 
67 |
68 | ### 4 效果展现
69 | 故障图
70 | 
71 | 恢复图
72 | 
73 |
74 | ### 5 docker环境修改
75 | > * 参照无图版
76 |
77 |
78 | ### 如果你觉得微信报警对你有帮助, 可以对作者进行小额捐款(微信)
79 |
80 | 
81 |
82 |
--------------------------------------------------------------------------------
/Screenshot_2017-01-10-18-06-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/Screenshot_2017-01-10-18-06-11.png
--------------------------------------------------------------------------------
/Screenshot_2017-01-10-18-07-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/Screenshot_2017-01-10-18-07-06.png
--------------------------------------------------------------------------------
/conf/BLog.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | # __author__ = 'bluetom'
4 |
5 | import sys
6 | import logging
7 | from logging.handlers import RotatingFileHandler
8 | import os
9 |
10 | #{{{class ColoredFormatter
11 | class ColoredFormatter(logging.Formatter):
12 | '''A colorful formatter.'''
13 |
14 | def __init__(self, fmt = None, datefmt = None):
15 | logging.Formatter.__init__(self, fmt, datefmt)
16 | # Color escape string
17 | COLOR_RED='\033[1;31m'
18 | COLOR_GREEN='\033[1;32m'
19 | COLOR_YELLOW='\033[1;33m'
20 | COLOR_BLUE='\033[1;34m'
21 | COLOR_PURPLE='\033[1;35m'
22 | COLOR_CYAN='\033[1;36m'
23 | COLOR_GRAY='\033[1;37m'
24 | COLOR_WHITE='\033[1;38m'
25 | COLOR_RESET='\033[1;0m'
26 |
27 | # Define log color
28 | self.LOG_COLORS = {
29 | 'DEBUG': '%s',
30 | 'INFO': COLOR_GREEN + '%s' + COLOR_RESET,
31 | 'WARNING': COLOR_YELLOW + '%s' + COLOR_RESET,
32 | 'ERROR': COLOR_RED + '%s' + COLOR_RESET,
33 | 'CRITICAL': COLOR_RED + '%s' + COLOR_RESET,
34 | 'EXCEPTION': COLOR_RED + '%s' + COLOR_RESET,
35 | }
36 |
37 | def format(self, record):
38 | level_name = record.levelname
39 | msg = logging.Formatter.format(self, record)
40 |
41 | return self.LOG_COLORS.get(level_name, '%s') % msg
42 | #}}}
43 | #{{{class Log
44 | class Log(object):
45 |
46 | '''
47 | log
48 | '''
49 | def __init__(self, filename, level="debug", logid="qiueer", mbs=20, count=10, is_console=True):
50 | '''
51 | mbs: how many MB
52 | count: the count of remain
53 | '''
54 | try:
55 | self._level = level
56 | #print "init,level:",level,"\t","get_map_level:",self._level
57 | self._filename = filename
58 | self._logid = logid
59 |
60 | self._logger = logging.getLogger(self._logid)
61 | file_path = os.path.split(self._filename)[0]
62 | if not os.path.exists(file_path):
63 | os.makedirs(file_path)
64 |
65 | if not len(self._logger.handlers):
66 | self._logger.setLevel(self.get_map_level(self._level))
67 |
68 | fmt = '[%(asctime)s] %(levelname)s\n%(message)s'
69 | datefmt = '%Y-%m-%d %H:%M:%S'
70 | formatter = logging.Formatter(fmt, datefmt)
71 |
72 | maxBytes = int(mbs) * 1024 * 1024
73 | file_handler = RotatingFileHandler(self._filename, mode='a',maxBytes=maxBytes,backupCount=count)
74 | self._logger.setLevel(self.get_map_level(self._level))
75 | file_handler.setFormatter(formatter)
76 | self._logger.addHandler(file_handler)
77 |
78 | if is_console == True:
79 | stream_handler = logging.StreamHandler(sys.stderr)
80 | console_formatter = ColoredFormatter(fmt, datefmt)
81 | stream_handler.setFormatter(console_formatter)
82 | self._logger.addHandler(stream_handler)
83 |
84 | except Exception as expt:
85 | print expt
86 |
87 | def tolog(self, msg, level=None):
88 | try:
89 | level = level if level else self._level
90 | level = str(level).lower()
91 | level = self.get_map_level(level)
92 | if level == logging.DEBUG:
93 | self._logger.debug(msg)
94 | if level == logging.INFO:
95 | self._logger.info(msg)
96 | if level == logging.WARN:
97 | self._logger.warn(msg)
98 | if level == logging.ERROR:
99 | self._logger.error(msg)
100 | if level == logging.CRITICAL:
101 | self._logger.critical(msg)
102 | except Exception as expt:
103 | print expt
104 |
105 | def debug(self,msg):
106 | self.tolog(msg, level="debug")
107 |
108 | def info(self,msg):
109 | self.tolog(msg, level="info")
110 |
111 | def warn(self,msg):
112 | self.tolog(msg, level="warn")
113 |
114 | def error(self,msg):
115 | self.tolog(msg, level="error")
116 |
117 | def critical(self,msg):
118 | self.tolog(msg, level="critical")
119 |
120 | def get_map_level(self,level="debug"):
121 | level = str(level).lower()
122 | #print "get_map_level:",level
123 | if level == "debug":
124 | return logging.DEBUG
125 | if level == "info":
126 | return logging.INFO
127 | if level == "warn":
128 | return logging.WARN
129 | if level == "error":
130 | return logging.ERROR
131 | if level == "critical":
132 | return logging.CRITICAL
133 | #}}}
134 | if __name__ == "__main__":
135 | from BLog import Log
136 | debug=False
137 | logpath = "/tmp/test.log"
138 | logger = Log(logpath,level="warn",is_console=True, mbs=5, count=5)
139 |
140 |
141 | logstr="helloworld"
142 | logger.error(logstr)
143 | logger.info(logstr)
144 | logger.warn(logstr)
145 |
--------------------------------------------------------------------------------
/conf/INIFILES.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | # __author__ = 'TT'
4 | import sys,os,time
5 | import ConfigParser
6 |
7 |
8 | class Config:
9 | def __init__(self, path):
10 | self.path = path
11 | self.cf = ConfigParser.ConfigParser()
12 | self.cf.read(self.path)
13 |
14 | def get(self, field, key):
15 | result = ""
16 | try:
17 | result = self.cf.get(field, key)
18 | except:
19 | result = ""
20 | return result
21 |
22 | def set(self, field, key, value):
23 | try:
24 | self.cf.set(field, key, value)
25 | self.cf.write(open(self.path,'w'))
26 | except:
27 | return False
28 | return True
29 |
30 |
31 | def read_config(config_file_path, field, key):
32 | cf = ConfigParser.ConfigParser()
33 | try:
34 | cf.read(config_file_path)
35 | result = cf.get(field, key)
36 | except:
37 | sys.exit(1)
38 | return result
39 |
40 |
41 | def write_config(config_file_path, field, key, value):
42 | cf = ConfigParser.ConfigParser()
43 | try:
44 | cf.read(config_file_path)
45 | cf.set(field, key, value)
46 | cf.write(open(config_file_path,'w'))
47 | except:
48 | sys.exit(1)
49 | return True
50 |
51 | if __name__ == "__main__":
52 | config_file_path = 'config.ini'
53 | print read_config(config_file_path, 'baseconf', "host")
54 |
55 | write_config(config_file_path, 'baseconf', "host", '192.168.0.101')
56 |
57 | print read_config(config_file_path, 'baseconf', "host")
--------------------------------------------------------------------------------
/conf/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | # __author__ = 'bluetom'
--------------------------------------------------------------------------------
/conf/file_util.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | # __author__ = 'bluetom'
4 |
5 | """Package for operations.
6 | """
7 |
8 | import os
9 | if __name__ == '__main__':
10 | import sys
11 | root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
12 | sys.path.insert(0, root_path)
13 |
14 | import re
15 | import shlex
16 |
17 | import subprocess
18 | import sys
19 | import linecache
20 | reload(sys)
21 | sys.setdefaultencoding('utf8')
22 |
23 | # 需要修改,配置文件位置
24 | CONFIG_CFG = '/etc/zabbix/zabbix_agentd.conf'
25 |
26 | #{{{loadconfig
27 |
28 |
29 | def loadconfig(cfgfile=None, detail=False):
30 | """Read config file and parse config item to dict.
31 | """
32 | if not cfgfile:
33 | cfgfile = CONFIG_CFG
34 |
35 | settings = {}
36 | with open(cfgfile) as f:
37 | for line_i, line in enumerate(f):
38 | # line_i[行号],line[每行内容]
39 |
40 | # 删除空白符(包括'\n', '\r', '\t', ' ')
41 | line = line.strip()
42 |
43 | # 跳过空行和注释('# '开头的)
44 | if not line or line.startswith('# '):
45 | continue
46 |
47 | # detect if it's commented
48 | if line.startswith('#'):
49 | line = line.strip('#')
50 | commented = True
51 | if not detail:
52 | continue
53 | else:
54 | commented = False
55 |
56 | # 将行以第一个'='分割
57 | #########################################
58 | fs = re.split('=', line, 1)
59 | if len(fs) != 2:
60 | continue
61 |
62 | item = fs[0].strip()
63 | value = fs[1].strip()
64 |
65 | if settings.has_key(item):
66 | if detail:
67 | count = settings[item]['count'] + 1
68 | if not commented:
69 | settings[item] = detail and {
70 | 'file': cfgfile,
71 | 'line': line_i,
72 | 'value': value,
73 | 'commented': commented,
74 | } or value
75 | else:
76 | count = 1
77 | settings[item] = detail and {
78 | 'file': cfgfile,
79 | 'line': line_i,
80 | 'value': fs[1].strip(),
81 | 'commented': commented,
82 | } or value
83 | if detail:
84 | settings[item]['count'] = count
85 |
86 | return settings
87 |
88 | #}}}
89 | #{{{cfg_get
90 |
91 |
92 | def cfg_get(item, detail=False, config=None):
93 | """Get value of a config item.
94 | """
95 | if not config:
96 | config = loadconfig(detail=detail)
97 | if config.has_key(item):
98 | return config[item]
99 | else:
100 | return None
101 | #}}}
102 | #{{{cfg_set
103 |
104 |
105 | def cfg_set(item, value, commented=False, config=None):
106 | """Set value of a config item.
107 | 如果可以获取到key,则对key后的item进行修改
108 | 如果获取不到key,则直接在配置文件后进行追加一行
109 | """
110 | cfgfile = CONFIG_CFG
111 | v = cfg_get(item, detail=True, config=config)
112 | # print v
113 |
114 | if v:
115 | # detect if value change
116 | if v['commented'] == commented and v['value'] == value:
117 | return True
118 |
119 | # empty value should be commented
120 | # 如果有key,但是传的value值为空,会将此行进行注释
121 | if value == '':
122 | commented = True
123 |
124 | # replace item in line
125 | lines = []
126 | with open(v['file']) as f:
127 | for line_i, line in enumerate(f):
128 | if line_i == v['line']:
129 | # 对没注释的行进行操作
130 | if not v['commented']:
131 | # 检测是否需要注释
132 | if commented:
133 | if v['count'] > 1:
134 | # delete this line, just ignore it
135 | pass
136 | else:
137 | # comment this line
138 | #########################################
139 | # lines.append('#%s=%s\n' % (item, value))
140 | lines.append('#%s\n' % (line,))
141 | else:
142 | #########################################
143 | lines.append('%s=%s\n' % (item, value))
144 | else:
145 | if commented:
146 | # do not allow change comment value
147 | lines.append(line)
148 | pass
149 | else:
150 | # append a new line after comment line
151 | # lines.append(line)
152 | #########################################
153 | lines.append('%s=%s\n' % (item, value))
154 | else:
155 | lines.append(line)
156 | with open(v['file'], 'w') as f:
157 | f.write(''.join(lines))
158 | else:
159 | # append to the end of file
160 | with open(v['file'], 'a') as f:
161 | f.write('\n%s%s = %s\n' % (commented and '#' or '', item, value))
162 |
163 | return True
164 | #}}}
165 | if __name__ == '__main__':
166 | # import pprint
167 | # pp = pprint.PrettyPrinter(indent=4)
168 | # loadconfig()
169 | # pp.pprint(loadconfig())
170 | print cfg_get('Hostname') #有#号的不显示
171 | # print cfg_get('Subsystem', detail=True) #detail显示细节
172 | # print cfg_set('Subsystem','') #直接注释
173 | # print cfg_set('Subsystem', '44444333') #设置值
174 | # # print cfg_set('Subsystem', 'sftp\t/usr/libexec/openssh/sftp-server',commented=False)
175 | # print cfg_get('Subsystem', detail=True) #detail显示细节
176 |
177 |
--------------------------------------------------------------------------------
/config.ini:
--------------------------------------------------------------------------------
1 | [wei]
2 | corpid = wx3317042c8bcf7555
3 | corpsecret = z4RWpYBw3dzZYExmhmENw9vZ2UTDZQahIycjla55u9v2QdScQBjYTz0fTJ30RAqx
4 | agentid = 5
5 | toparty =
6 | web = http://192.168.1.199/zabbix/
7 | author = 懒懒的天空
8 | [zabbix]
9 | user = Admin
10 | passwd = 123456
11 |
--------------------------------------------------------------------------------
/get_pic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | # __author__ = 'bluetom'
4 |
5 | import sys
6 | import time
7 | import datetime
8 | from selenium import webdriver
9 | from conf.INIFILES import read_config
10 | from conf.BLog import Log
11 | import os
12 |
13 |
14 | def get_item_pic(url, user, passwd, itemid):
15 | try:
16 | driver = webdriver.PhantomJS("/usr/local/phantomjs-2.1.1/bin/phantomjs")
17 | driver.get(url)
18 | driver.set_window_size(640, 480)
19 | path = "/usr/lib/zabbix/alertscripts/pic"
20 | # path = "/tmp/pic"
21 | if not os.path.exists(path):
22 | os.makedirs(path)
23 | driver.find_element_by_id("name").send_keys(user) #输入用户名
24 | driver.find_element_by_id("password").send_keys(passwd) #输入用户名
25 | driver.find_element_by_id("enter").click()
26 | item_url = url + "history.php?action=showgraph&fullscreen=1&itemids[]=" + itemid
27 | driver.get(item_url)
28 | temp_name = itemid + "_" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + ".png"
29 | time.sleep(0.5)
30 | driver.save_screenshot(temp_name)
31 | driver.close()
32 | driver.quit()
33 | return temp_name
34 | # shutil.move(temp_name, backpath)
35 | # im = Image.open(temp_name)
36 | # im = im.crop((0, 0, 640, 480))
37 | # im.save(temp_name)
38 | except Exception, e:
39 | senderr = str(e)
40 | sendstatus = False
41 |
42 | def getpic(item_id):
43 | try:
44 | global sendstatus
45 | global senderr
46 | start = time.time()
47 | config_file_path = get_path()
48 | user = read_config(config_file_path, 'zabbix', "user")
49 | passwd = read_config(config_file_path, 'zabbix', "passwd")
50 | url = read_config(config_file_path, 'wei', "web")
51 | path = get_item_pic(url, user=user, passwd=passwd, itemid=item_id)
52 | sendstatus = True
53 | except Exception, e:
54 | senderr = str(e)
55 | sendstatus = False
56 | # logwrite(sendstatus, path)
57 | return path
58 |
59 |
60 | def logwrite(sendstatus, content):
61 | logpath = '/var/log/zabbix/weixin'
62 | # logpath = "log"
63 | if not sendstatus:
64 | content = senderr
65 | t = datetime.datetime.now()
66 | daytime = t.strftime('%Y-%m-%d')
67 | daylogfile = logpath+'/'+str(daytime)+'.log'
68 | logger = Log(daylogfile, level="info", is_console=False, mbs=5, count=5)
69 | os.system('chown zabbix.zabbix {0}'.format(daylogfile))
70 | logger.info(content)
71 |
72 |
73 | def get_path():
74 | path = os.path.dirname(os.path.abspath(sys.argv[0]))
75 | config_path = path + '/config.ini'
76 | return config_path
77 |
78 |
79 | if __name__ == "__main__":
80 | print getpic('24099')
81 |
82 |
83 |
--------------------------------------------------------------------------------
/ghostdriver.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/ghostdriver.log
--------------------------------------------------------------------------------
/problem.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | <告警主机>{HOST.NAME}告警主机>
4 | <告警地址>{HOST.IP}告警地址>
5 | <告警时间>{EVENT.DATE} {EVENT.TIME}告警时间>
6 | <告警等级>{TRIGGER.SEVERITY}告警等级>
7 | <告警信息>{TRIGGER.NAME}告警信息>
8 | <监控项目>{ITEM.NAME}监控项目>
9 | <当前状态>{TRIGGER.STATUS}当前状态>
10 | <持续时间>{EVENT.AGE}持续时间>
11 | <事件ID>{EVENT.ID}事件ID>
12 | <监控取值>{ITEM.LASTVALUE}监控取值>
13 | <监控ID>{ITEM.ID}监控ID>
14 |
--------------------------------------------------------------------------------
/recover.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | <告警主机>{HOST.NAME}告警主机>
4 | <告警地址>{HOST.IP}告警地址>
5 | <告警时间>{EVENT.DATE} {EVENT.TIME}告警时间>
6 | <恢复时间>{EVENT.RECOVERY.DATE} {EVENT.RECOVERY.TIME}恢复时间>
7 | <告警等级>{TRIGGER.SEVERITY}告警等级>
8 | <告警信息>{TRIGGER.NAME}告警信息>
9 | <监控项目>{ITEM.NAME}监控项目>
10 | <当前状态>{TRIGGER.STATUS}当前状态>
11 | <持续时间>{EVENT.AGE}持续时间>
12 | <事件ID>{EVENT.ID}事件ID>
13 | <监控取值>{ITEM.LASTVALUE}监控取值>
14 | <监控ID>{ITEM.ID}监控ID>
15 |
--------------------------------------------------------------------------------
/requests/Pillow-4.0.0-cp27-cp27m-manylinux1_x86_64.whl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/requests/Pillow-4.0.0-cp27-cp27m-manylinux1_x86_64.whl
--------------------------------------------------------------------------------
/requests/fontconfig-2.10.95-10.el7.x86_64.rpm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/requests/fontconfig-2.10.95-10.el7.x86_64.rpm
--------------------------------------------------------------------------------
/requests/freetype-2.4.11-12.el7.x86_64.rpm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/requests/freetype-2.4.11-12.el7.x86_64.rpm
--------------------------------------------------------------------------------
/requests/phantomjs-2.1.1-linux-x86_64.tar.bz2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/requests/phantomjs-2.1.1-linux-x86_64.tar.bz2
--------------------------------------------------------------------------------
/requests/requests-2.12.4-py2.py3-none-any.whl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/requests/requests-2.12.4-py2.py3-none-any.whl
--------------------------------------------------------------------------------
/requests/requests-2.12.4.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/requests/requests-2.12.4.tar.gz
--------------------------------------------------------------------------------
/requests/selenium-3.0.2.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/requests/selenium-3.0.2.tar.gz
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | image==1.5.5
2 | lxml==3.5.0
3 | selenium==3.0.2
4 |
--------------------------------------------------------------------------------
/test_xml.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | # __author__ = 'bluetom'
4 |
5 | from lxml import etree
6 | xml_file = etree.parse('problem.xml')
7 | root_node = xml_file.getroot()
8 | a = root_node.find(u"告警等级").text
9 | print a
10 |
11 | root2 = etree.fromstring(open('problem.xml').read())
12 | print root2.xpath(u"告警等级")[0].text
13 | print root2.xpath(u"监控项目")[0].text
14 | print root2.xpath(u"告警等级")[0].text
--------------------------------------------------------------------------------
/weixin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluetom520/zabbix-weixin-picture/3a826ba16c77d22f43fa4e87d010e720bcdf8067/weixin.jpg
--------------------------------------------------------------------------------
/weixin.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | # __author__ = '懒懒的天空'
4 |
5 | import requests
6 | import sys
7 | import json
8 | import time
9 | import Image
10 | from conf.INIFILES import read_config, write_config
11 | from selenium import webdriver
12 | import os
13 | import datetime
14 | from conf.BLog import Log
15 | from get_pic import getpic
16 | import re
17 | from lxml import etree
18 | reload(sys)
19 | sys.setdefaultencoding('utf-8')
20 |
21 |
22 | class WeiXin(object):
23 | def __init__(self, corpid, corpsecret): # 初始化的时候需要获取corpid和corpsecret,需要从管理后台获取
24 | self.__params = {
25 | 'corpid': corpid,
26 | 'corpsecret': corpsecret
27 | }
28 |
29 | self.url_get_token = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
30 | self.url_send = 'https://qyapi.weixin.qq.com/cgi-bin/message/send'
31 | self.url_uploadimg = 'https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg'
32 | self.img_url = 'https://qyapi.weixin.qq.com/cgi-bin/media/upload'
33 |
34 | self.__token = self.__get_token()
35 | self.__token_params = {
36 | 'access_token': self.__token
37 | }
38 |
39 | def __raise_error(self, res):
40 | raise Exception('error code: %s,error message: %s' % (res.json()['errcode'], res.json()['errmsg']))
41 | global senderr
42 | global sendstatus
43 | sendstatus = False
44 | senderr = 'error code: %s,error message: %s' % (res.json()['errcode'], res.json()['errmsg'])
45 |
46 | def __get_token(self):
47 | # print self.url_get_token
48 | headers = {'content-type': 'application/json'}
49 | res = requests.get(self.url_get_token, headers=headers, params=self.__params)
50 |
51 | try:
52 | return res.json()['access_token']
53 | except:
54 | self.__raise_error(res.content)
55 |
56 |
57 | def send_message(self, agentid, messages, userid='', toparty=''):
58 | payload = {
59 | 'touser': userid,
60 | 'toparty': toparty,
61 | 'agentid': agentid,
62 | "msgtype": "news",
63 | "news": messages
64 | }
65 | headers = {'content-type': 'application/json'}
66 | data = json.dumps(payload, ensure_ascii=False).encode('utf-8')
67 | params = self.__token_params
68 | res = requests.post(self.url_send, headers=headers, params=params, data=data)
69 | try:
70 | return res.json()
71 | except:
72 | self.__raise_error(res)
73 |
74 | def send_message_mediaid(self, agentid, messages, userid='', toparty=''):
75 | payload = {
76 | 'touser': userid,
77 | 'toparty': toparty,
78 | 'agentid': agentid,
79 | "msgtype": "mpnews",
80 | "mpnews": messages
81 | }
82 | headers = {'content-type': 'application/json'}
83 | data = json.dumps(payload, ensure_ascii=False).encode('utf-8')
84 | params = self.__token_params
85 | res = requests.post(self.url_send, headers=headers, params=params, data=data)
86 | try:
87 | return res.json()
88 | except:
89 | self.__raise_error(res)
90 |
91 | def get_media_ID(self, path):
92 | try:
93 | params = self.__token_params
94 | params['type'] = "image"
95 | data = {'media': open(path, 'rb')}
96 | r = requests.post(url=self.img_url, params=params, files=data)
97 | dict = r.json()
98 | return dict['media_id']
99 | except:
100 | self.__raise_error(r)
101 |
102 | def get_imaging(self, path):
103 | try:
104 | params = self.__token_params
105 | data = {'media': open(path, 'rb')}
106 | r = requests.post(url=self.url_uploadimg, params=params, files=data)
107 | dict = r.json()
108 | return dict['url']
109 | except:
110 | self.__raise_error(r)
111 |
112 | def get_image(self, path):
113 | try:
114 | params = self.__token_params
115 | headers = {'content-type': 'application/json'}
116 | data = {'type': "image", 'media': open(path, 'rb')}
117 | r = requests.post(url=self.img_url, params=params, headers=headers, files=data)
118 | dict = r.json()
119 | return dict['url']
120 | except:
121 | self.__raise_error(r)
122 |
123 | def main(send_to, subject, content):
124 | try:
125 | global sendstatus
126 | global senderr
127 | data = ''
128 | messages = {}
129 | body = {}
130 | config_file_path = get_path()
131 | CorpID = read_config(config_file_path, 'wei', "CorpID")
132 | CorpSecret = read_config(config_file_path, 'wei', "CorpSecret")
133 | agentid = read_config(config_file_path, 'wei', "agentid")
134 | web = read_config(config_file_path, 'wei', "web")
135 | author = read_config(config_file_path, 'wei', "author")
136 | # content = json.loads(content)
137 | messages["message_url"] = web
138 | root = etree.fromstring(content)
139 | itemid = root.xpath(u"监控ID")[0].text
140 | itemvalue = root.xpath(u"监控取值")[0].text
141 | s = re.match(r'^[0-9\.]+(\s\w{0,3})?$', itemvalue)
142 | # s = re.match(r'^[0-9\.]+$', itemvalue.split(' ')[0])
143 | if s:
144 | body["content_source_url"] = web + "history.php?action=showgraph&itemids[]=" + itemid
145 | else:
146 | body["content_source_url"] = web + "history.php?action=showvalues&itemids[]=" + itemid
147 | warn_message = ''
148 | if root.xpath(u"当前状态")[0].text == 'PROBLEM':
149 | body["title"] = "服务器故障"
150 | warn_message += subject + '\n'
151 | warn_message += '详情:\n'
152 | warn_message += '告警等级:' + root.xpath(u"告警等级")[0].text + '\n'
153 | warn_message += '告警时间:' + root.xpath(u"告警时间")[0].text + '\n'
154 | warn_message += '告警地址:' + root.xpath(u"告警地址")[0].text + '\n'
155 | warn_message += '持续时间:' + root.xpath(u"持续时间")[0].text + '\n'
156 | warn_message += '监控项目:' + root.xpath(u"监控项目")[0].text + '\n'
157 | warn_message += root.xpath(u"告警主机")[0].text + '故障(' + root.xpath(u"事件ID")[0].text+ ')'
158 | else:
159 | body["title"] = "服务器恢复"
160 | warn_message += subject + '\n'
161 | warn_message += '详情:\n'
162 | warn_message += '告警等级:' + root.xpath(u"告警等级")[0].text + '\n'
163 | warn_message += '恢复时间:' + root.xpath(u"恢复时间")[0].text + '\n'
164 | warn_message += '告警地址:' + root.xpath(u"告警地址")[0].text + '\n'
165 | warn_message += '持续时间:' + root.xpath(u"持续时间")[0].text + '\n'
166 | warn_message += '监控项目:' + root.xpath(u"监控项目")[0].text + '\n'
167 | warn_message += root.xpath(u"告警主机")[0].text + '恢复(' + root.xpath(u"事件ID")[0].text+ ')'
168 | body['digest'] = warn_message
169 | warn_message = ''
170 | if root.xpath(u"当前状态")[0].text == 'PROBLEM':
171 | body["title"] = "服务器故障"
172 | warn_message += '
'+subject + '
' + '\n'
173 | warn_message += ''+'详情:' + '
' + '\n'
174 | warn_message += ''+'告警等级:' + root.xpath(u"告警等级")[0].text + '
' + '\n'
175 | warn_message += ''+'告警时间:' + root.xpath(u"告警时间")[0].text + '
'+ '\n'
176 | warn_message += ''+'告警地址:' + root.xpath(u"告警地址")[0].text + '
'+ '\n'
177 | warn_message += ''+'持续时间:' + root.xpath(u"持续时间")[0].text + '
'+ '\n'
178 | warn_message += ''+'监控项目:' + root.xpath(u"监控项目")[0].text + '
'+ '\n'
179 | warn_message += ''+root.xpath(u"告警主机")[0].text + '故障(' + root.xpath(u"事件ID")[0].text+ ')'+'
'
180 | else:
181 | body["title"] = "服务器恢复"
182 | warn_message += ''+subject + '
' + '\n'
183 | warn_message += ''+'详情:' + '
' + '\n'
184 | warn_message += ''+'告警等级:' + root.xpath(u"告警等级")[0].text + '
' + '\n'
185 | warn_message += ''+'恢复时间:' + root.xpath(u"恢复时间")[0].text + '
'+ '\n'
186 | warn_message += ''+'告警地址:' + root.xpath(u"告警地址")[0].text + '
'+ '\n'
187 | warn_message += ''+'持续时间:' + root.xpath(u"持续时间")[0].text + '
'+ '\n'
188 | warn_message += ''+'监控项目:' + root.xpath(u"监控项目")[0].text + '
'+ '\n'
189 | warn_message += ''+root.xpath(u"告警主机")[0].text + '恢复(' + root.xpath(u"事件ID")[0].text+ ')'+'
'
190 | body['content'] = warn_message
191 | body['author'] = author
192 | wx = WeiXin(CorpID, CorpSecret)
193 | pic_path = getpic(itemid, s)
194 | picurl = wx.get_media_ID(pic_path)
195 | body['thumb_media_id'] = picurl
196 | data = []
197 | data.append(body)
198 | messages['articles'] = data
199 | data = wx.send_message_mediaid(toparty=send_to, agentid=agentid, messages=messages)
200 | sendstatus = True
201 | except Exception, e:
202 | senderr = str(e)
203 | sendstatus = False
204 | logwrite(sendstatus, data)
205 |
206 |
207 | def get_path():
208 | path = os.path.dirname(os.path.abspath(sys.argv[0]))
209 | config_path = path + '/config.ini'
210 | return config_path
211 |
212 |
213 | def logwrite(sendstatus, content):
214 | logpath = '/var/log/zabbix/weixin'
215 | if not sendstatus:
216 | content = senderr
217 | t = datetime.datetime.now()
218 | daytime = t.strftime('%Y-%m-%d')
219 | daylogfile = logpath+'/'+str(daytime)+'.log'
220 | logger = Log(daylogfile, level="info", is_console=False, mbs=5, count=5)
221 | os.system('chown zabbix.zabbix {0}'.format(daylogfile))
222 | logger.info(content)
223 |
224 |
225 | def get_item_pic(url, user, passwd, itemid, flag):
226 | try:
227 | driver = webdriver.PhantomJS("/usr/local/phantomjs-2.1.1/bin/phantomjs",service_log_path=os.path.devnull)
228 | # driver = webdriver.PhantomJS(executable_path='/usr/local/phantomjs-2.1.1/bin/phantomjs', service_log_path='/var/log/ghostdriver.log', service_args=["--webdriver-loglevel=NONE"])
229 | driver.get(url)
230 | driver.set_window_size(640, 480)
231 | picpath = "/usr/lib/zabbix/alertscripts/pic"
232 | driver.find_element_by_id("name").send_keys(user) #输入用户名
233 | driver.find_element_by_id("password").send_keys(passwd) #输入用户名
234 | driver.find_element_by_id("enter").click()
235 | if flag:
236 | item_url = url + "history.php?action=showgraph&fullscreen=1&itemids[]=" + itemid
237 | else:
238 | item_url = url + "history.php?action=showvalues&fullscreen=1&itemids[]=" + itemid
239 | driver.get(item_url)
240 | temp_name = picpath+"/"+itemid + "_" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + ".png"
241 | # logwrite(True, temp_name)
242 | time.sleep(0.5)
243 | driver.save_screenshot(temp_name)
244 | driver.close()
245 | driver.quit()
246 | # shutil.move(temp_name, backpath)
247 | if not flag:
248 | im = Image.open(temp_name)
249 | im = im.crop((0, 0, 640, 480))
250 | im.save(temp_name)
251 | return temp_name
252 | except Exception, e:
253 | global senderr
254 | senderr = str(e)
255 | global sendstatus
256 | sendstatus = False
257 | logwrite(sendstatus, e)
258 |
259 |
260 | def getpic(item_id, s):
261 | try:
262 | config_file_path = get_path()
263 | user = read_config(config_file_path, 'zabbix', "user")
264 | passwd = read_config(config_file_path, 'zabbix', "passwd")
265 | url = read_config(config_file_path, 'wei', "web")
266 | ppath = get_item_pic(url, user=user, passwd=passwd, itemid=item_id, flag=s)
267 | global sendstatus
268 | sendstatus = True
269 | return ppath
270 | except Exception, e:
271 | global senderr
272 | senderr = str(e)
273 | sendstatus = False
274 | logwrite(sendstatus, e)
275 |
276 |
277 | if __name__ == "__main__":
278 | if len(sys.argv) > 1:
279 | send_to = sys.argv[1]
280 | subject = sys.argv[2]
281 | content = sys.argv[3]
282 | logwrite(True, content)
283 | main(send_to, subject, content)
284 |
285 |
286 |
--------------------------------------------------------------------------------
/weixin_bak.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | # __author__ = '懒懒的天空'
4 |
5 | import requests
6 | import sys
7 | import json
8 | import time
9 | import Image
10 | from conf.INIFILES import read_config, write_config
11 | from selenium import webdriver
12 | import os
13 | import datetime
14 | from conf.BLog import Log
15 | from get_pic import getpic
16 | import re
17 |
18 | reload(sys)
19 | sys.setdefaultencoding('utf-8')
20 |
21 |
22 | class WeiXin(object):
23 | def __init__(self, corpid, corpsecret): # 初始化的时候需要获取corpid和corpsecret,需要从管理后台获取
24 | self.__params = {
25 | 'corpid': corpid,
26 | 'corpsecret': corpsecret
27 | }
28 |
29 | self.url_get_token = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
30 | self.url_send = 'https://qyapi.weixin.qq.com/cgi-bin/message/send'
31 | self.url_uploadimg = 'https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg'
32 | self.img_url = 'https://qyapi.weixin.qq.com/cgi-bin/media/upload'
33 |
34 | self.__token = self.__get_token()
35 | self.__token_params = {
36 | 'access_token': self.__token
37 | }
38 |
39 | def __raise_error(self, res):
40 | raise Exception('error code: %s,error message: %s' % (res.json()['errcode'], res.json()['errmsg']))
41 | global senderr
42 | global sendstatus
43 | sendstatus = False
44 | senderr = 'error code: %s,error message: %s' % (res.json()['errcode'], res.json()['errmsg'])
45 |
46 | def __get_token(self):
47 | # print self.url_get_token
48 | headers = {'content-type': 'application/json'}
49 | res = requests.get(self.url_get_token, headers=headers, params=self.__params)
50 |
51 | try:
52 | return res.json()['access_token']
53 | except:
54 | self.__raise_error(res.content)
55 |
56 |
57 | def send_message(self, agentid, messages, userid='', toparty=''):
58 | payload = {
59 | 'touser': userid,
60 | 'toparty': toparty,
61 | 'agentid': agentid,
62 | "msgtype": "news",
63 | "news": messages
64 | }
65 | headers = {'content-type': 'application/json'}
66 | data = json.dumps(payload, ensure_ascii=False).encode('utf-8')
67 | params = self.__token_params
68 | res = requests.post(self.url_send, headers=headers, params=params, data=data)
69 | try:
70 | return res.json()
71 | except:
72 | self.__raise_error(res)
73 |
74 | def get_media_ID(self, path):
75 | params = self.__token_params
76 | params['type'] = 'image\r\n'
77 | data = {'media': open(path, 'rb')}
78 | r = requests.post(url=self.img_url, params=params, files=data)
79 | dict = r.json()
80 | return dict['media_id']
81 |
82 | def get_imaging(self, path):
83 | params = self.__token_params
84 | data = {'media': open(path, 'rb')}
85 | r = requests.post(url=self.url_uploadimg, params=params, files=data)
86 | dict = r.json()
87 | return dict['url']
88 |
89 |
90 | def main(send_to, subject, content, value):
91 | try:
92 | global sendstatus
93 | global senderr
94 | data = ''
95 | messages = {}
96 | body = {}
97 | config_file_path = get_path()
98 | CorpID = read_config(config_file_path, 'wei', "CorpID")
99 | CorpSecret = read_config(config_file_path, 'wei', "CorpSecret")
100 | agentid = read_config(config_file_path, 'wei', "agentid")
101 | web = read_config(config_file_path, 'wei', "web")
102 | content = json.loads(content)
103 | messages["message_url"] = web
104 | itemid = content[u'监控ID']
105 | itemvalue = value
106 | s = re.match(r'^[0-9\.]+$', itemvalue)
107 | if s:
108 | body["url"] = web + "history.php?action=showgraph&itemids[]=" + itemid
109 | else:
110 | body["url"] = web + "history.php?action=showvalues&itemids[]=" + itemid
111 | warn_message = ''
112 | if content[u'当前状态'] == 'PROBLEM':
113 | body["title"] = "服务器故障"
114 | warn_message += subject + '\n'
115 | warn_message += '详情:\n'
116 | warn_message += '告警等级:'+ content[u'告警等级'] + '\n'
117 | warn_message += '告警时间:'+ content[u'告警时间'] + '\n'
118 | warn_message += '告警地址:'+ content[u'告警地址'] + '\n'
119 | warn_message += '持续时间:'+ content[u'持续时间'] + '\n'
120 | warn_message += '监控项目:'+ content[u'监控项目'] + '\n'
121 | warn_message += content[u'告警主机'] + '故障(' + content[u'事件ID']+ ')'
122 | else:
123 | body["title"] = "服务器恢复"
124 | warn_message += subject + '\n'
125 | warn_message += '详情:\n'
126 | warn_message += '告警等级:'+ content[u'告警等级'] + '\n'
127 | warn_message += '恢复时间:'+ content[u'恢复时间'] + '\n'
128 | warn_message += '告警地址:'+ content[u'告警地址'] + '\n'
129 | warn_message += '持续时间:'+ content[u'持续时间'] + '\n'
130 | warn_message += '监控项目:'+ content[u'监控项目'] + '\n'
131 | warn_message += content[u'告警主机'] + '恢复(' + content[u'事件ID']+ ')'
132 | body["title"] = "服务器故障"
133 | body['description'] = warn_message
134 | wx = WeiXin(CorpID, CorpSecret)
135 | pic_path = getpic(itemid,s)
136 | picurl = wx.get_imaging(pic_path)
137 | body['picurl'] = picurl
138 | data = []
139 | data.append(body)
140 | messages['articles'] = data
141 | data = wx.send_message(toparty=send_to, agentid=agentid, messages=messages)
142 | sendstatus = True
143 | except Exception, e:
144 | senderr = str(e)
145 | sendstatus = False
146 | logwrite(sendstatus, data)
147 |
148 |
149 | def get_path():
150 | path = os.path.dirname(os.path.abspath(sys.argv[0]))
151 | config_path = path + '/config.ini'
152 | return config_path
153 |
154 |
155 | def logwrite(sendstatus, content):
156 | logpath = '/var/log/zabbix/weixin'
157 | if not sendstatus:
158 | content = senderr
159 | t = datetime.datetime.now()
160 | daytime = t.strftime('%Y-%m-%d')
161 | daylogfile = logpath+'/'+str(daytime)+'.log'
162 | logger = Log(daylogfile, level="info", is_console=False, mbs=5, count=5)
163 | os.system('chown zabbix.zabbix {0}'.format(daylogfile))
164 | logger.info(content)
165 |
166 |
167 | def get_item_pic(url, user, passwd, itemid, flag):
168 | try:
169 | driver = webdriver.PhantomJS("/usr/local/phantomjs-2.1.1/bin/phantomjs",service_log_path=os.path.devnull)
170 | # driver = webdriver.PhantomJS(executable_path='/usr/local/phantomjs-2.1.1/bin/phantomjs', service_log_path='/var/log/ghostdriver.log', service_args=["--webdriver-loglevel=NONE"])
171 | driver.get(url)
172 | driver.set_window_size(640, 480)
173 | picpath = "/usr/lib/zabbix/alertscripts/pic"
174 | driver.find_element_by_id("name").send_keys(user) #输入用户名
175 | driver.find_element_by_id("password").send_keys(passwd) #输入用户名
176 | driver.find_element_by_id("enter").click()
177 | if flag:
178 | item_url = url + "history.php?action=showgraph&fullscreen=1&itemids[]=" + itemid
179 | else:
180 | item_url = url + "history.php?action=showvalues&fullscreen=1&itemids[]=" + itemid
181 | driver.get(item_url)
182 | temp_name = picpath+"/"+itemid + "_" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + ".png"
183 | time.sleep(0.5)
184 | driver.save_screenshot(temp_name)
185 | driver.close()
186 | driver.quit()
187 | # shutil.move(temp_name, backpath)
188 | if flag:
189 | im = Image.open(temp_name)
190 | im = im.crop((0, 0, 640, 480))
191 | im.save(temp_name)
192 | return temp_name
193 | except Exception, e:
194 | global senderr
195 | senderr = str(e)
196 | global sendstatus
197 | sendstatus = False
198 | logwrite(sendstatus, e)
199 |
200 |
201 | def getpic(item_id, s):
202 | try:
203 | config_file_path = get_path()
204 | user = read_config(config_file_path, 'zabbix', "user")
205 | passwd = read_config(config_file_path, 'zabbix', "passwd")
206 | url = read_config(config_file_path, 'wei', "web")
207 | ppath = get_item_pic(url, user=user, passwd=passwd, itemid=item_id, flag=s)
208 | global sendstatus
209 | sendstatus = True
210 | return ppath
211 | except Exception, e:
212 | global senderr
213 | senderr = str(e)
214 | sendstatus = False
215 | logwrite(sendstatus, e)
216 |
217 |
218 | if __name__ == "__main__":
219 | if len(sys.argv) > 1:
220 | send_to = sys.argv[1]
221 | subject = sys.argv[2]
222 | content = sys.argv[3]
223 | itemvalue = sys.argv[4]
224 | logwrite(True, content)
225 | main(send_to, subject, content, itemvalue)
226 |
227 |
228 |
--------------------------------------------------------------------------------