zoukankan      html  css  js  c++  java
  • 【原】elastalert 配置使用

    关于Elastalert使用

    1.安装

    参考链接:

    1. https://elastalert.readthedocs.io/en/latest/running_elastalert.html
    2. https://github.com/Yelp/elastalert
    3. https://marchal.tech/blog/2019/08/27/elastalert-enable-alert-only-in-specific-hour-range/
    4. https://github.com/0xSeb/elastalert_hour_range
    5. https://github.com/xuyaoqiang/elastalert-dingtalk-plugin

    运行环境要求:

    ​ Python 3.6

    1.1 基础环境

    本地环境为 centos7

    1.1.1 准备 yum 源

    阿里源的地址:https://developer.aliyun.com/mirror/

    1.备份旧的源

    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
    

    2.下载新的 CentOS-Base.repo 到 /etc/yum.repos.d/

    wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    

    或者

    curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    

    3.运行 yum makecache 生成缓存

    4.其他

    非阿里云ECS用户会出现 Couldn't resolve host 'mirrors.cloud.aliyuncs.com' 信息,不影响使用。用户也可自行修改相关配置: eg:

    sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
    

    1.1.2 安装 python3.6

    # 需要先安装阿里源
    yum -y install epel-release
    yum -y install python36 python36-devel python36-pip gcc gcc-c++
    

    1.2 安装elastalert

    使用 pip3 安装

    pip3 install elastalert
    

    或者

    $ git clone https://github.com/Yelp/elastalert.git
    $ cd elastalert
    $ pip install "setuptools>=11.3"
    $ python setup.py install
    

    根据 Elasticsearch 版本选择安装

    Elasticsearch 5.0+:

    $ pip3 install "elasticsearch>=5.0.0"
    

    Elasticsearch 2.X:

    $ pip3 install "elasticsearch<3.0.0"
    

    2.准备配置文件

    2.1 目录结构

    [root@liyongjian5179 ~]# tree elastalert
    elastalert
    ├── config.yaml
    ├── elastalert_modules
    │   ├── dingtalk_alert.py
    │   ├── hour_range_enhancement.py
    │   ├── __init__.py
    │   └── Readme.md
    ├── rules
    │   └── rule.yaml
    ├── smtp_auth.yaml
    └── start.sh
    

    2.2 配置文件 config.yaml

    可以直接下载示例文件:https://github.com/Yelp/elastalert/blob/master/config.yaml.example

    [root@liyongjian5179 elastalert]# cat config.yaml
    # This is the folder that contains the rule yaml files
    # Any .yaml file will be loaded as a rule
    rules_folder: rules
    
    # How often ElastAlert will query Elasticsearch
    # The unit can be anything from weeks to seconds
    run_every:
      minutes: 1
    
    # ElastAlert will buffer results from the most recent
    # period of time, in case some log sources are not in real time
    buffer_time:
      minutes: 15
    
    # The Elasticsearch hostname for metadata writeback
    # Note that every rule can have its own Elasticsearch host
    es_host: 192.168.100.129
    
    # The Elasticsearch port
    es_port: 9200
    
    # The AWS region to use. Set this when using AWS-managed elasticsearch
    #aws_region: us-east-1
    
    # The AWS profile to use. Use this if you are using an aws-cli profile.
    # See http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
    # for details
    #profile: test
    
    # Optional URL prefix for Elasticsearch
    #es_url_prefix: elasticsearch
    
    # Connect with TLS to Elasticsearch
    #use_ssl: True
    
    # Verify TLS certificates
    #verify_certs: True
    
    # GET request with body is the default option for Elasticsearch.
    # If it fails for some reason, you can pass 'GET', 'POST' or 'source'.
    # See http://elasticsearch-py.readthedocs.io/en/master/connection.html?highlight=send_get_body_as#transport
    # for details
    #es_send_get_body_as: GET
    
    # Option basic-auth username and password for Elasticsearch
    es_username: elastic
    es_password: XXXXXXXXXXXXXXXXXXXXX
    
    # Use SSL authentication with client certificates client_cert must be
    # a pem file containing both cert and key for client
    #verify_certs: True
    #ca_certs: /path/to/cacert.pem
    #client_cert: /path/to/client_cert.pem
    #client_key: /path/to/client_key.key
    
    # The index on es_host which is used for metadata storage
    # This can be a unmapped index, but it is recommended that you run
    # elastalert-create-index to set a mapping
    writeback_index: elastalert_status
    writeback_alias: elastalert_alerts
    
    # If an alert fails for some reason, ElastAlert will retry
    # sending the alert until this time period has elapsed
    alert_time_limit:
      days: 2
    
    # Custom logging configuration
    # If you want to setup your own logging configuration to log into
    # files as well or to Logstash and/or modify log levels, use
    # the configuration below and adjust to your needs.
    # Note: if you run ElastAlert with --verbose/--debug, the log level of
    # the "elastalert" logger is changed to INFO, if not already INFO/DEBUG.
    #logging:
    #  version: 1
    #  incremental: false
    #  disable_existing_loggers: false
    #  formatters:
    #    logline:
    #      format: '%(asctime)s %(levelname)+8s %(name)+20s %(message)s'
    #
    #    handlers:
    #      console:
    #        class: logging.StreamHandler
    #        formatter: logline
    #        level: DEBUG
    #        stream: ext://sys.stderr
    #
    #      file:
    #        class : logging.FileHandler
    #        formatter: logline
    #        level: DEBUG
    #        filename: elastalert.log
    #
    #    loggers:
    #      elastalert:
    #        level: WARN
    #        handlers: []
    #        propagate: true
    #
    #      elasticsearch:
    #        level: WARN
    #        handlers: []
    #        propagate: true
    #
    #      elasticsearch.trace:
    #        level: WARN
    #        handlers: []
    #        propagate: true
    #
    #      '':  # root logger
    #        level: WARN
    #          handlers:
    #            - console
    #            - file
    #        propagate: false
    

    2.3 添加控制警报时间段模块

    位置: 和启动的命令放一起,否则会找不到模块

    参考链接:https://marchal.tech/blog/2019/08/27/elastalert-enable-alert-only-in-specific-hour-range/

    原 github 地址:https://github.com/0xSeb/elastalert_hour_range

    详细使用见报警规则文件

    [root@liyongjian5179 elastalert]# mkdir elastalert_modules/
    [root@liyongjian5179 elastalert_modules]# cat __init__.py
    [root@liyongjian5179 elastalert_modules]# cat hour_range_enhancement.py
    #!/usr/bin/python3
    import dateutil.parser
    
    from elastalert.enhancements import BaseEnhancement
    from elastalert.enhancements import DropMatchException
    
    
    class HourRangeEnhancement(BaseEnhancement):
        def process(self, match):
            timestamp = None
            try:
                timestamp = dateutil.parser.parse(match['@timestamp']).time()
            except Exception:
                try:
                    timestamp = dateutil.parser.parse(match[self.rule['timestamp_field']]).time()
                except Exception:
                    pass
            if timestamp is not None:
                time_start = dateutil.parser.parse(self.rule['start_time']).time()
                time_end = dateutil.parser.parse(self.rule['end_time']).time()
                if(self.rule['drop_if'] == 'outside'):
                    if timestamp < time_start or timestamp > time_end:
                        raise DropMatchException()
                elif(self.rule['drop_if'] == 'inside'):
                    if timestamp >= time_start and timestamp <= time_end:
                        raise DropMatchException()
    

    2.4 报警规则 rule.yaml

    2.4.1 邮件报警

    [root@liyongjian5179 elastalert]# mkdir rules
    [root@liyongjian5179 elastalert]# cat ./rules/rule.yaml
    # Alert when the rate of events exceeds a threshold
    
    # (Optional)
    # Elasticsearch host
    es_host: 192.168.100.129
    
    # (Optional)
    # Elasticsearch port
    es_port: 9200
    
    # (OptionaL) Connect with SSL to Elasticsearch
    #use_ssl: True
    
    # (Optional) basic-auth username and password for Elasticsearch
    es_username: elastic
    es_password: XXXXXXXXXXXXXXXXXXXXX
    
    # (Required)
    # Rule name, must be unique
    name: "[lyj] upstream_status=200"
    
    # (Required)
    # Type of alert.
    # the frequency rule type alerts when num_events events occur with timeframe time
    type: frequency
    
    # (Required)
    # Index to search, wildcard supported
    index: filebeat-*
    
    # (Required, frequency specific)
    # Alert when this many documents matching the query occur within a timeframe
    num_events: 1
    
    # (Required, frequency specific)
    # num_events must occur within this amount of time to trigger an alert
    timeframe:
      #hours: 1
      minutes: 3
    
    # (Required)
    # A list of Elasticsearch filters used for find events
    # These filters are joined with AND and nested in a filtered query
    # For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html
    filter:
    - query:
        query_string:
          query: "upstream_status: 200"
          #query: "upstream_status: 200 AND upstream_http_custom_status: E*"
    
    # 24H mode
    # 如果没配置"elastalert.enhancements.TimeEnhancement",就是 UTC 时间
    start_time: "22:00"
    end_time: "06:00"
    # Drop match and cancel alert if (inside/outside) range
    # inside: 在上面的时间范围内
    # outside: 在上面的时间范围外
    drop_if: "inside"
    
    # 增加插件实现时间范围内报警
    match_enhancements:
      - "elastalert.enhancements.TimeEnhancement"  #时区
      - "elastalert_modules.hour_range_enhancement.HourRangeEnhancement"
    
    smtp_host: smtp.qq.com
    smtp_port: 465
    smtp_ssl: true
    smtp_auth_file: /root/elastalert/smtp_auth.yaml
    
    #回复给那个邮箱
    email_reply_to: 632712943@qq.com
    ##从哪个邮箱发送
    from_addr: 632712943@qq.com
    
    # (Required)
    # The alert is use when a match is found
    alert:
    - "email"
    
    # (required, email specific)
    # a list of email addresses to send alerts to
    email:
    - "liyongjian5179@163.com"
    
    alert_subject: "报警:发现接口错误,匹配到了{}条日志,匹配{}次"
    alert_subject_args:
      - num_hits
      - num_matches
    
    alert_text_type: alert_text_only
      ### Error frequency exceeds
    alert_text: |
      您好,submit 接口错误次数超限,请检查接口状态!
      > 截止发邮件前匹配到的请求数:{}
      > 截止发邮件前匹配到的次数:{}
      > 规则名称: {}
      > 接口: {}
      > timestamp: {}
    alert_text_args:
      - num_hits
      - num_matches
      - name
      - request
      - "@timestamp"
    
    # 5分钟内相同的报警不会重复发送
    realert:
      minutes: 5
    # 指数级扩大 realert 时间,中间如果有报警,
    # 则按照5>10>20>40>60不断增大报警时间到制定的最大时间,
    # 如果之后报警减少,则会慢慢恢复原始realert时间
    exponential_realert:
      hours: 1
    

    2.4.2 钉钉报警

    git clone https://github.com/xuyaoqiang/elastalert-dingtalk-plugin.git
    cd elastalert-dingtalk-plugin
    pip3 install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
    cp -r elastalert_modules/dingtalk_alert.py /root/elastalert/elastalert_modules/
    

    然后报警规则文件中添加

    alert:
    - "elastalert_modules.dingtalk_alert.DingTalkAlerter"
    #- "email"
    
    dingtalk_webhook: "https://oapi.dingtalk.com/robot/send?access_token=xxxxxxx"
    dingtalk_msgtype: "text"
    

    dingtalk_alert.py 文件内容如下

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    """
    @author: xuyaoqiang
    @contact: xuyaoqiang@gmail.com
    @date: 2017-09-14 17:35
    @version: 0.0.0
    @license:
    @copyright:
    
    """
    import json
    import requests
    from elastalert.alerts import Alerter, DateTimeEncoder
    from requests.exceptions import RequestException
    from elastalert.util import EAException
    
    
    class DingTalkAlerter(Alerter):
    
        required_options = frozenset(['dingtalk_webhook', 'dingtalk_msgtype'])
    
        def __init__(self, rule):
            super(DingTalkAlerter, self).__init__(rule)
            self.dingtalk_webhook_url = self.rule['dingtalk_webhook']
            self.dingtalk_msgtype = self.rule.get('dingtalk_msgtype', 'text')
            self.dingtalk_isAtAll = self.rule.get('dingtalk_isAtAll', False)
            self.digtalk_title = self.rule.get('dingtalk_title', '')
    
        def format_body(self, body):
            return body.encode('utf8')
    
        def alert(self, matches):
            headers = {
                "Content-Type": "application/json",
                "Accept": "application/json;charset=utf-8"
            }
            body = self.create_alert_body(matches)
            payload = {
                "msgtype": self.dingtalk_msgtype,
                "text": {
                    "content": body
                },
                "at": {
                    "isAtAll":False
                }
            }
            try:
                response = requests.post(self.dingtalk_webhook_url,
                            data=json.dumps(payload, cls=DateTimeEncoder),
                            headers=headers)
                response.raise_for_status()
            except RequestException as e:
                raise EAException("Error request to Dingtalk: {0}".format(str(e)))
    
        def get_info(self):
            return {
                "type": "dingtalk",
                "dingtalk_webhook": self.dingtalk_webhook_url
            }
            pass
    

    2.5 邮箱用户名密码文件 smtp_auth.yaml

    [root@liyongjian5179 elastalert]# cat smtp_auth.yaml
    user: "632712943@qq.com"
    password: "XXXX"
    

    2.6 创建索引

    elastalert-create-index
    

    2.7 启动脚本

    [root@liyongjian5179 elastalert]# cat start.sh
    #!/bin/bash
    
    >  ./nohup.out
    nohup elastalert --config config.yaml &
    # 详细输出
    # nohup elastalert --config config.yaml  --verbose &
    
    # 验证规则文件是否能正常匹配
    # elastalert-test-rule --config config.yaml ./rules/rule.yaml
    

    2.8 验证规则文件

    [root@liyongjian5179 elastalert]# elastalert-test-rule --config config.yaml ./rules/rule.yaml
    INFO:elastalert:Note: In debug mode, alerts will be logged to console but NOT actually sent.
                To send them but remain verbose, use --verbose instead.
    Didn't get any results.
    INFO:elastalert:Note: In debug mode, alerts will be logged to console but NOT actually sent.
                    To send them but remain verbose, use --verbose instead.
    1 rules loaded
    INFO:apscheduler.scheduler:Adding job tentatively -- it will be properly scheduled when the scheduler starts
    INFO:elastalert:Queried rule [lyj] upstream_status=200 from 2020-11-29 18:10 CST to 2020-11-29 18:13 CST: 0 / 0 hits
    
    Would have written the following documents to writeback index (default is elastalert_status):
    
    elastalert_status - {'rule_name': '[lyj] upstream_status=200', 'endtime': datetime.datetime(2020, 11, 29, 10, 13, 40, 204145, tzinfo=tzutc()), 'starttime': datetime.datetime(2020, 11, 29, 10, 10, 38, 404145, tzinfo=tzutc()), 'matches': 0, 'hits': 0, '@timestamp': datetime.datetime(2020, 11, 29, 10, 13, 40, 241449, tzinfo=tzutc()), 'time_taken': 0.009022235870361328}
    

    2.9 报警效果

    钉钉

    邮件

  • 相关阅读:
    spring AOP (使用AspectJ的注解方式 的aop实现) (6)
    spring aop的前奏,动态代理 (5)
    Python基础笔记系列九:变量、自定义函数以及局部变量和全局变量
    Python基础笔记系列八:字符串的运算和相关函数
    Python基础笔记系列六:字典
    Python基础笔记系列五:元组
    Python基础笔记系列四:工具的安装与配置
    Python基础笔记系列三:list列表
    Python基础笔记系列二:分支和循环
    Python基础笔记系列一:基本工具与表达式
  • 原文地址:https://www.cnblogs.com/liyongjian5179/p/14057554.html
Copyright © 2011-2022 走看看