CentOS下ELK基于ElastAlert实现日志的微信报警_writeback_index (1)

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

$ cd /app
$ git clone https://github.com/Yelp/elastalert.git


安装模块:



$ pip install “setuptools>=11.3”
$ python setup.py install


根据Elasticsearch的版本,您可能需要手动安装正确版本的elasticsearch-py。


Elasticsearch 5.0+:



$ pip install “elasticsearch>=5.0.0”


Elasticsearch 2.X:



$ pip install “elasticsearch<3.0.0”


## 3. 配置ElastAlert


配置config.yaml 文件



$ cp config.yaml.example config.yaml
$ cat config.yaml
rules_folder: example_rules
run_every:
seconds: 10
buffer_time:
minutes: 15
es_host: 10.1.144.208
es_port: 9201
#es_username: elastic
#es_password: 123456
writeback_index: elastalert_status
alert_time_limit:
days: 2


**rules\_folder**:ElastAlert从中加载规则配置文件的位置。它将尝试加载文件夹中的每个.yaml文件。没有任何有效规则,ElastAlert将无法启动。  
 **run\_every**: ElastAlert多久查询一次Elasticsearch的时间。  
 **buffer\_time**:查询窗口的大小,从运行每个查询的时间开始向后延伸。对于其中use\_count\_query或use\_terms\_query设置为true的规则,将忽略此值。  
 **es\_host**:是Elasticsearch群集的地址,ElastAlert将在其中存储有关其状态,查询运行,警报和错误的数据。  
 **es\_port**:es对应的端口。  
 **es\_username**: 可选的; 用于连接的basic-auth用户名es\_host。  
 **es\_password**: 可选的; 用于连接的basic-auth密码es\_host。  
 **es\_send\_get\_body\_as**: 可选的; 方法查询Elasticsearch - GET,POST或source。默认是GET  
 **writeback\_index**:ElastAlert将在其中存储数据的索引的名称。我们稍后将创建此索引。  
 **alert\_time\_limit**: 失败警报的重试窗口。


**创建elastalert-create-index索引**



$ elastalert-create-index
New index name (Default elastalert_status)
Name of existing index to copy (Default None)
New index elastalert_status created
Done!


## 三、使用微信报警


由于ElastAlert没有内置企业微信的报警方式,我们还需要使用一个开源插件elastalert-wechat-plugin来实现微信的报警,Github项目地址


## 1. 下载项目文件



$ cd elastalert
$ wget -P ~/elastalert/elastalert_modules/ wget https://raw.githubusercontent.com/anjia0532/elastalert-wechat-plugin/master/elastalert_modules/wechat_qiye_alert.py
$ touch ~/elastalert/elastalert_modules/init.py


## 2. 修改插件源码


由于这个插件是基于python2.x版本开发的,而ElastAlert的最新版本使用的是python3.6版本开发,所以需要改一些代码,以便正常运行,另外还添添加了转中文字符功能。  
 wechat\_qiye\_alert.py修改后如下:



#! /usr/bin/env python

-*- coding: utf-8 -*-

import json
import datetime
from elastalert.alerts import Alerter, BasicMatchString
from requests.exceptions import RequestException
from elastalert.util import elastalert_logger,EAException #感谢minminmsn分享
import requests
from elastalert_modules.MyEncoder import MyEncoder

‘’’
#################################################################

微信企业号推送消息

作者: AnJia anjia0532@gmail.com

作者博客: https://anjia.ml/

Github: https://github.com/anjia0532/elastalert-wechat-plugin

#################################################################
‘’’
class WeChatAlerter(Alerter):

#企业号id,secret,应用id必填

required_options = frozenset(['corp\_id','secret','agent\_id'])

def \_\_init\_\_(self, \*args):
    super(WeChatAlerter, self).\_\_init\_\_(\*args)
    self.corp_id = self.rule.get('corp\_id', '')     #企业号id
    self.secret = self.rule.get('secret', '')       #secret
    self.agent_id = self.rule.get('agent\_id', '')   #应用id

    self.party_id = self.rule.get('party\_id')       #部门id
    self.user_id = self.rule.get('user\_id', '')     #用户id,多人用 | 分割,全部用 @all
    self.tag_id = self.rule.get('tag\_id', '')       #标签id
    self.access_token = ''                          #微信身份令牌
    self.expires_in=datetime.datetime.now() - datetime.timedelta(seconds=60)

def create\_default\_title(self, matches):
    subject = 'ElastAlert: %s' % (self.rule['name'])
    return subject

def alert(self, matches):

    if not self.party_id and not self.user_id and not self.tag_id:
        elastalert_logger.warn("All touser & toparty & totag invalid")

    # 参考elastalert的写法
    # https://github.com/Yelp/elastalert/blob/master/elastalert/alerts.py#L236-L243
    body = self.create\_alert\_body(matches)

    #matches 是json格式
    #self.create\_alert\_body(matches)是String格式,详见 [create\_alert\_body 函数]( )

    # 微信企业号获取Token文档
    # http://qydev.weixin.qq.com/wiki/index.php?title=AccessToken
    self.get\_token()

    self.senddata(body)

    elastalert_logger.info("send message to %s" % (self.corp_id))

def get\_token(self):

    #获取token是有次数限制的,本想本地缓存过期时间和token,但是elastalert每次调用都是一次性的,不能全局缓存
    if self.expires_in >= datetime.datetime.now() and self.access_token:
        return self.access_token

    #构建获取token的url
    get_token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s' %(self.corp_id,self.secret)

    try:
        response = requests.get(get_token_url)
        response.raise\_for\_status()
    except RequestException as e:
        raise EAException("get access\_token failed , stacktrace:%s" % e)
        #sys.exit("get access\_token failed, system exit")

    token_json = response.json()

    if 'access\_token' not in token_json :
        raise EAException("get access\_token failed , , the response is :%s" % response.text())
        #sys.exit("get access\_token failed, system exit")

    #获取access_token和expires_in
    self.access_token = token_json['access\_token']
    self.expires_in = datetime.datetime.now() + datetime.timedelta(seconds=token_json['expires\_in'])

    return self.access_token

def senddata(self, content):

    #如果需要原始json,需要传入matches

    # http://qydev.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E7%B1%BB%E5%9E%8B%E5%8F%8A%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F
    # 微信企业号有字符长度限制(2048),超长自动截断

    # 参考 http://blog.csdn.net/handsomekang/article/details/9397025
    #len utf8 3字节,gbk2 字节,ascii 1字节
    if len(content) > 512 :
        content = content[:512] + "..."

    # 微信发送消息文档
    # http://qydev.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E7%B1%BB%E5%9E%8B%E5%8F%8A%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F
    send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access\_token=%s' %( self.access_token)

    headers = {'content-type': 'application/json'}
  
    # 替换消息标题为中文,下面的字段为logstash切分的日志字段
    title_dict = { 

“At least”: “报警规则:At least”,

        "@timestamp": "报警时间",
        "\_index": "索引名称",
        "\_type": "索引类型",
        "ServerIP": "报警主机",
        "hostname": "报警机器",
        "message": "报警内容",
        "class": "报错类",
        "lineNum": "报错行"
       "num\_hits": "文档命中数",
       "num\_matches": "文档匹配数"
    }

    #print(f"type:{type(content)}")
    for k, v in title_dict.items():
        content = content.replace(k, v, 1 )

    # 最新微信企业号调整校验规则,tagid必须是string类型,如果是数字类型会报错,故而使用str()函数进行转换
    payload = {
        "touser": self.user_id and str(self.user_id) or '', #用户账户,建议使用tag
        "toparty": self.party_id and str(self.party_id) or '', #部门id,建议使用tag
        "totag": self.tag_id and str(self.tag_id) or '', #tag可以很灵活的控制发送群体细粒度。比较理想的推送应该是,在heartbeat或者其他elastic工具自定义字段,添加标签id。这边根据自定义的标签id,进行推送
        'msgtype': "text",
        "agentid": self.agent_id,
        "text":{
            "content": content.encode('UTF-8').decode("latin1") #避免中文字符发送失败
           },
        "safe":"0"
    }

    # set https proxy, if it was provided
    # 如果需要设置代理,可修改此参数并传入requests
    # proxies = {'https': self.pagerduty\_proxy} if self.pagerduty\_proxy else None
    try:
        #response = requests.post(send\_url, data=json.dumps(payload, ensure\_ascii=False), headers=headers)
        response = requests.post(send_url, data=json.dumps(payload, cls=MyEncoder, indent=4, ensure_ascii=False), headers=headers)
        response.raise\_for\_status()
    except RequestException as e:
        raise EAException("send message has error: %s" % e)

    elastalert_logger.info("send msg and response: %s" % response.text)


def get\_info(self):
    return {'type': 'WeChatAlerter'}

在同级目录下创建MyEncoder.py文件



#!/usr/bin/env python3

-*- coding: utf-8 -*-

import json

class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, bytes):
return str(obj, encoding=‘utf-8’)
return json.JSONEncoder.default(self, obj)


## 3. 申请企业微信账号


step 1: 访问网站 注册企业微信账号(不需要企业认证)。  
 step 2: 访问apps 创建第三方应用,点击创建应用按钮 -> 填写应用信息:  
 Step3: 创建部门,获取部门ID


## 4. 配置报警规则


配置规则文件



$ cd elastalert/example_rules/
$ cp example_frequency.yaml applog.yaml
$ cat sms-applog.yaml | grep -v ^#
name: 【日志报警】
use_strftine_index: true
type: frequency

index: applog-*
num_events: 1
timeframe:
minutes: 1
filter:

  • query:
    query_string:
    query: ‘“[ERROR]” NOT “发送邮件失败”’

alert:

  • “elastalert_modules.wechat_qiye_alert.WeChatAlerter”
    corp_id: wxdxxx40b4720f24
    secret: xa4pWq63sxxtaZzzEg8X860ZBIoOkToCbh_oNc
    agent_id: 1000002
    party_id: 2


> 
> index:要查询的索引的名称, ES中存在的索引。  
>  num\_events:此参数特定于frequency类型,并且是触发警报时的阈值。  
>  filter:用于过滤结果的Elasticsearch过滤器列表,这里的规则定义是除了包含“发送邮件失败”的错误日志,其他所有ERROR的日志都会触发报警。  
>  alert:定义报警方式,我们这里采用企业微信报警。  
>  corp\_id: 企业微信的接口认证信息
> 
> 
> 



![img](https://img-blog.csdnimg.cn/img_convert/e61db5c27f1035b7e60cad627ab0c846.png)
![img](https://img-blog.csdnimg.cn/img_convert/4612e24518327f872bd626ef2ec2ce64.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618631832)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

corp\_id: 企业微信的接口认证信息
> 
> 
> 



[外链图片转存中...(img-HV8Gb61T-1715734261975)]
[外链图片转存中...(img-P95HrdM8-1715734261976)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618631832)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值