Django的logging系统十分好用,使用file,mail_admins之类的handlers能够快捷地实现保存日志到文件,发送错误日志给管理员的功能。可是,若是能直接将应用的错误日志发送到手机上,实现即时告警,岂不是更好?html
首先须要注册一个企业微信帐号,地址是:
https://work.weixin.qq.com/we...python
**注意**:
注册过程若是是为企业使用要选择企业,而后上传企业的资质证实,若是是我的注册,选择团队,而后输入本身的身份证号便可完成注册.
而后进入企业应用页面,添加一个应用,添加完成后,进入应用页面:web
这里的agentid和secret须要留意, 后续的发送信息api须要它们。django
另外咱们还须要corpid,在个人企业-企业信息中能够找到。json
测试使用企业微信API发送消息:
企业微信API:发送消息c#
例子:api
#! /usr/bin/env python # -*- coding: utf-8 -*- import requests import json def get_token(): url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken' values = { 'corpid': '<YOUR CORPID>', 'corpsecret': '<YOUR SECRET>', } req = requests.post(url, params=values) data = json.loads(req.text) return data["access_token"] def send_msg(): url = ("https://qyapi.weixin.qq.com/cgi-bin/message/send" "?access_token={}").format(get_token()) values = { # "touser": "@all", "toparty": "2", "msgtype": "text", "agentid": "<YOUR AGENTID>", "text": { "content": u"报警测试,toparty: 2" }, } req = requests.post(url, json.dumps(values)) print(values, req) if __name__ == '__main__': send_msg()
其中toparty:2,意为向id为2的部门的全部成员发送消息。 使用touser:@all, 能够向全部人发送信息。
配置Django的logging系统
接下来咱们须要配置一下django的logging系统,来发送ERROR级别的log到企业微信。微信
个人思路是能够参照django自带的AdminEmailHandler写一个WechatAlarmHandler。
代码以下:运维
import logging import requests import json from copy import copy from django.core.cache import cache from django.views.debug import ExceptionReporter class WechatAlarmHandler(logging.Handler): """An exception log handler that sends log entries to wechat alarm bot. """ def __init__(self): logging.Handler.__init__(self) def emit(self, record): try: request = record.request subject = '%s (%s IP): %s' % ( record.levelname, ('internal' if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS # NOQA else 'EXTERNAL'), record.getMessage() ) except Exception: subject = '%s: %s' % ( record.levelname, record.getMessage() ) request = None subject = self.format_subject(subject) message = self.format(record) self.send_msg(subject, message) def send_msg(self, subject, message=None, *args, **kwargs): WechatAlarm().send_msg('{}\n\n{}'.format(subject, message)) def format_subject(self, subject): """ Escape CR and LF characters. """ return subject.replace('\n', '\\n').replace('\r', '\\r') class WechatAlarm: def __init__(self, corpid='<YOUR CORPID>', corpsecret='<YOUR SECRET>', agentid='<YOUR AGENTID>', partyid='<YOUR PARTYID>'): self.corpid = corpid self.partyid = partyid self.key = 'wechat_send_alarm_key' self.corpsecret = corpsecret self.agentid = agentid def get_token(self): token = cache.get(self.key) if token: return token else: url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken' values = { 'corpid': self.corpid, 'corpsecret': self.corpsecret, } req = requests.post(url, params=values) data = json.loads(req.text) cache.set(self.key, data["access_token"], 7200) return data["access_token"] def send_msg(self, content=None): url = ("https://qyapi.weixin.qq.com/cgi-bin/message/send" "?access_token={}").format(self.get_token()) values = { # "touser": "@all", "toparty": self.partyid, "msgtype": "text", "agentid": self.agentid, "text": { "content": content, }, } return requests.post(url, json.dumps(values))
再配置一下django的settings里的LOGGING:post
GGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '[%(asctime)s](%(levelname)s)<%(name)s.%(funcName)s>{%(process)d/%(thread)d} : %(message)s' }, 'simple': { 'format': '%(levelname)s %(message)s' }, }, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'handlers': { 'null': { 'level': 'DEBUG', 'class': 'django.utils.log.NullHandler', }, 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'filters': ['require_debug_false'], }, 'send_wechat': { 'level': 'ERROR', 'class': 'utils.log.WechatAlarmHandler', # your handler path }, 'file': { 'level': 'INFO', 'class': 'logging.handlers.TimedRotatingFileHandler', 'formatter': 'verbose', 'filename': webservice_logfile, 'when': 'D' }, }, 'loggers': { '': { 'handlers': ['file', 'mail_admins', 'send_wechat'], 'propagate': True, 'level': 'ERROR', }, 'django': { 'handlers': ['file', 'mail_admins'], 'propagate': True, 'level': 'ERROR', }, 'django.request': { 'handlers': ['file', 'mail_admins', ], 'level': 'ERROR', 'propagate': True, }, } }
即,在handler里增长了一个send_wechat, 在loggers里的handers里增长了send_wechat。
这样django的error log就会经过企业微信发送到手机了。