Elasticsearch 日志监控方案

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch 日志监控方案

现在大部分公司都会选择将应用、中间件、系统等日志存储在 Elasticsearch 中,如何发现日志中的异常数据并且及时告警通知就显得十分重要。本文将会介绍两种主流的日志监控方案,分别是 Yelp 公司开源的 ElastAlert 和 Elastic 官方的商业版功能 Watcher。

如下图所示,日志数据源是一台 Nginx 服务器,在该服务器上安装 Filebeat 收集 Nginx 日志并输出到 Elasticsearch,之后会分别演示用 ElastAlert 和 Watcher 两种方案监控日志并进行告警。image.png

部署 Nginx

安装依赖

yum install -y gcc gcc-c++ autoconf pcre pcre-devel make automake wget httpd-tools vim tree zlib-devel

下载安装包

wget http://nginx.org/download/nginx-1.14.0.tar.gz
tar -xzvf nginx-1.14.0.tar.gz

编译安装

cd nginx-1.14.0
./configure

配置 Nginx

编辑配置文件 /usr/local/nginx/conf/nginx.conf,在 Nginx 上配置一个静态网页服务。

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    server {
        listen  80;
        location / {
            root html;
        }
    }
}

启动 Nginx:

sbin/nginx

访问 Nginx:image.png

部署 Filebeat

下载并安装 Filebeat。

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.14.0-x86_64.rpm
sudo rpm -vi filebeat-7.14.0-x86_64.rpm

编辑 /etc/filebeat/filebeat.yml 配置文件,读取 Nginx 日志文件输出到 Elasticsearch 的 nginx 索引中,后缀是当前日期。

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /usr/local/nginx/logs/*.log
output.elasticsearch:
  hosts: ["192.168.1.8:9200"]
  index: "nginx-%{+yyyy.MM.dd}"
  #username: "elastic"
  #password: "changeme"
setup.ilm.enabled: false
setup.template.name: "nginx"
setup.template.pattern: "nginx-*"

启动 Filebeat:

systemctl start filebeat

ElastAlert

ElastAlert 是 Yelp 公司开源的一套用 Python 写的 Elasticsearch 告警框架,可以从 Elasticsearch 当中查询出匹配规则的数据进行告警。

ElastAlert 有以下特点:

  • 支持多种匹配规则(频率、阈值、数据变化、黑白名单、变化率等)。
  • 支持多种告警类型(邮件、HTTP POST、自定义脚本等)。
  • 支持用户自定义规则和告警类型。
  • 匹配项汇总报警,重复告警抑制,告警失败重试和过期。
  • 可用性强,状态信息保存到 Elasticsearch 的索引中。
  • 支持调试和审计。

部署 Elastalert

安装 Python

wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz
tar -zxvf Python-3.6.9.tgz
cd Python-3.6.9
./configure
make && make install

检查 Python 版本:

python3 -V

安装依赖

yum install gcc libffi-devel python3-devel openssl-devel -y
pip3 install -U pip
pip3 install "setuptools>=11.3"

安装 Elastalert

python3 install elastalert

配置 Elastalert

克隆代码到本地:

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

我们可以在 ElastAlert 源码文件的根目录下找到一个叫做 config.yaml.example 的文件,修改文件名为 config.yaml:

mv config.yaml.example  config.yaml

创建存放规则的目录。

mkdir rules
cd rules

编辑 config.yaml 文件,修改主配置:

#规则存放的目录
rules_folder: rules
#运行的频率
run_every:
  minutes: 1
#ElastAlert 将缓存最近一段时间的结果,以防某些日志源不是实时的
buffer_time:
  minutes: 45
#Elasticsearch 地址
es_host: 192.168.1.8
#Elasticsearch 端口
es_port: 9200
#Elasticsearch 用户名密码(可选)
#es_username: someusername
#es_password: somepassword
#ElastAlert 元数据存储索引
writeback_index: elastalert_status
#如果警报因某种原因失败,ElastAlert将重试发送警报,直到该时间段结束
alert_time_limit:
  days: 2

创建 rules/nginx.yaml 文件,编辑 rule:

规则内容为:在 1 分钟内如果查询 nginx-* 索引的 message 字段匹配 到 error 5 次就触发告警,往指定的 URL 发送一个 HTTP POST 请求。

# Alert when the rate of events exceeds a threshold
# (Required)
# Elasticsearch host
es_host: 192.168.1.8
# (Required)
# Elasticsearch port
es_port: 9200
# (OptionaL) Connect with SSL to elasticsearch
#use_ssl: True
# (Optional) basic-auth username and password for elasticsearch
#es_username: someusername
#es_password: somepassword
# (Required)
# Rule name, must be unique
name: nginx rule
# (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: nginx-*
# (Required, frequency specific)
# Alert when this many documents matching the query occur within a timeframe
num_events: 5
# (Required, frequency specific)
# num_events must occur within this amount of time to trigger an alert
timeframe:
  minutes: 1
# (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:
- term:
    message: "error"
# (Required)
# The alert is use when a match is found
alert:
- "post"
http_post_url: "https://webhook.site/2f64f4b3-8b43-488c-b2df-695136079e36"

https://webhook.site 网站提供了测试的 Webhook 接口,每个人的 URL 都是独立的,拷贝这个 URL 复制到 http_post_url 中。image.pngElastAlert 会把执行记录存放到一个索引中,可以方便我们审核和调试。使用以下命令创建这个索引的,默认情况下,索引名叫 elastalert_status。

root@ydt-net-es-node1:/software #elastalert-create-index
Enter Elasticsearch host: 192.168.1.8
Enter Elasticsearch port: 9200
Use SSL? t/f: f
#如果有认证输入用户名密码
Enter optional basic-auth username (or leave blank): 
Enter optional basic-auth password (or leave blank): 
Enter optional Elasticsearch URL prefix (prepends a string to the URL of every request): 
New index name? (Default elastalert_status) 
New alias name? (Default elastalert_alerts) 
Name of existing index to copy? (Default None) 
Elastic Version: 7.9.3
Reading Elastic 6 index mappings:
Reading index mapping 'es_mappings/6/silence.json'
Reading index mapping 'es_mappings/6/elastalert_status.json'
Reading index mapping 'es_mappings/6/elastalert.json'
Reading index mapping 'es_mappings/6/past_elastalert.json'
Reading index mapping 'es_mappings/6/elastalert_error.json'
New index elastalert_status created
Done!

发送 2 个请求,1 个是正确请求,1 个是错误请求。

> curl http://192.168.1.134 -I
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Mon, 16 Aug 2021 07:28:42 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 16 Jun 2021 02:46:13 GMT
Connection: keep-alive
ETag: "60c965f5-264"
Accept-Ranges: bytes
> curl http://192.168.1.134/xxxxxx -I
HTTP/1.1 404 Not Found
Server: nginx/1.14.2
Date: Mon, 16 Aug 2021 07:28:43 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive

在 Kibana 上可以看到 Nginx 的日志,错误请求会在 access.log 和 error.log 各写一次,因此这里看到 3 条记录。image.png运行 elastalert-test-rule 命令检验配置文件是否正确并且可以看到规则匹配的次数,elastalert-test-rule 命令并不会真正触发告警。

> elastalert-test-rule rules/nginx.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 nginx rule from 2021-08-16 15:28 CST to 2021-08-16 15:29 CST: 1 / 1 hits 
Would have written the following documents to writeback index (default is elastalert_status):
elastalert_status - {'rule_name': 'nginx rule', 'endtime': datetime.datetime(2021, 8, 16, 7, 29, 30, 422431, tzinfo=tzutc()), 'starttime': datetime.datetime(2021, 8, 16, 7, 28, 29, 822431, tzinfo=tzutc()), 'matches': 0, 'hits': 1, '@timestamp': datetime.datetime(2021, 8, 16, 7, 29, 30, 527080, tzinfo=tzutc()), 'time_taken': 0.02203655242919922}

1分钟内连续发送错误请求 5 次达到触发告警的阈值:

for i in {1..3};do curl http://192.168.1.134/xxxxxx -I;done

此时可以看到发送的告警格式。

> elastalert-test-rule rules/nginx.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 nginx rule from 2021-08-16 15:33 CST to 2021-08-16 15:34 CST: 5 / 5 hits
INFO:elastalert:Alert for nginx rule at 2021-08-16T07:34:26.230Z:
INFO:elastalert:nginx rule
At least 5 events occurred between 2021-08-16 15:33 CST and 2021-08-16 15:34 CST
@timestamp: 2021-08-16T07:34:26.230Z
_id: 0CDiTXsBCANUjLffFM2O
_index: nginx-2021.08.16
_type: _doc
agent: {
    "ephemeral_id": "4ee4bd89-cb8e-43fb-9331-476c229a5480",
    "hostname": "nginx-plus1",
    "id": "629442a8-34ab-40db-80a8-16e4fda8dec7",
    "name": "nginx-plus1",
    "type": "filebeat",
    "version": "7.14.0"
}
ecs: {
    "version": "1.10.0"
}
host: {
    "name": "nginx-plus1"
}
input: {
    "type": "log"
}
log: {
    "file": {
        "path": "/usr/local/nginx/logs/error.log"
    },
    "offset": 16944
}
message: 2021/08/16 15:34:22 [error] 4022#0: *40 open() "/usr/local/nginx/html/xxxxxx" failed (2: No such file or directory), client: 192.168.1.35, server: , request: "GET /xxxxxx HTTP/1.1", host: "192.168.1.134"
num_hits: 5
num_matches: 1
Would have written the following documents to writeback index (default is elastalert_status):
silence - {'exponent': 0, 'rule_name': 'nginx rule', '@timestamp': datetime.datetime(2021, 8, 16, 7, 34, 42, 866184, tzinfo=tzutc()), 'until': datetime.datetime(2021, 8, 16, 7, 35, 42, 866174, tzinfo=tzutc())}
elastalert_status - {'rule_name': 'nginx rule', 'endtime': datetime.datetime(2021, 8, 16, 7, 34, 42, 810992, tzinfo=tzutc()), 'starttime': datetime.datetime(2021, 8, 16, 7, 33, 42, 210992, tzinfo=tzutc()), 'matches': 1, 'hits': 5, '@timestamp': datetime.datetime(2021, 8, 16, 7, 34, 42, 868045, tzinfo=tzutc()), 'time_taken': 0.015259981155395508}

使用以下命令运行 elastalert,可以看到触发了告警:

> elastalert --verbose --rule rules/nginx.yaml
1 rules loaded
INFO:elastalert:Starting up
INFO:elastalert:Disabled rules are: []
INFO:elastalert:Sleeping for 59.999839 seconds
INFO:elastalert:Queried rule nginx rule from 2021-08-16 14:54 CST to 2021-08-16 15:39 CST: 7 / 7 hits
INFO:elastalert:HTTP Post alert sent.
INFO:elastalert:Ran nginx rule from 2021-08-16 14:54 CST to 2021-08-16 15:39 CST: 7 query hits (0 already seen), 1 matches, 1 alerts sent

访问 https://webhook.site 网站可以看到 ElastAlert 发送的 HTTP POST 请求。image.png查询 elastalert_status 索引可以看到 ElastAlert 的执行记录。

GET elastalert_status/_search
#返回结果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "elastalert_status",
        "_type" : "_doc",
        "_id" : "1SDmTXsBCANUjLff0M1Q",
        "_score" : 1.0,
        "_source" : {
          "match_body" : {
            "input" : {
              "type" : "log"
            },
            "agent" : {
              "hostname" : "nginx-plus1",
              "name" : "nginx-plus1",
              "id" : "629442a8-34ab-40db-80a8-16e4fda8dec7",
              "ephemeral_id" : "4ee4bd89-cb8e-43fb-9331-476c229a5480",
              "type" : "filebeat",
              "version" : "7.14.0"
            },
            "@timestamp" : "2021-08-16T07:34:26.230Z",
            "ecs" : {
              "version" : "1.10.0"
            },
            "log" : {
              "file" : {
                "path" : "/usr/local/nginx/logs/error.log"
              },
              "offset" : 16740
            },
            "host" : {
              "name" : "nginx-plus1"
            },
            "message" : "2021/08/16 15:34:22 [error] 4022#0: *39 open() \"/usr/local/nginx/html/xxxxxx\" failed (2: No such file or directory), client: 192.168.1.35, server: , request: \"GET /xxxxxx HTTP/1.1\", host: \"192.168.1.134\"",
            "_id" : "zyDiTXsBCANUjLffFM2O",
            "_index" : "nginx-2021.08.16",
            "_type" : "_doc",
            "num_hits" : 7,
            "num_matches" : 1
          },
          "rule_name" : "nginx rule",
          "alert_info" : {
            "type" : "http_post",
            "http_post_webhook_url" : [
              "https://webhook.site/2f64f4b3-8b43-488c-b2df-695136079e36"
            ]
          },
          "alert_sent" : true,
          "alert_time" : "2021-08-16T07:39:35.185929Z",
          "match_time" : "2021-08-16T07:34:26.230Z",
          "@timestamp" : "2021-08-16T07:39:37.418536Z"
        }
      }
    ]
  }
}

Watcher

Watcher 是 Elastic 官方提供的一个对日志数据监控和报警的功能,Watcher 属于收费功能,我们可以在 License Management 中开启 30 天的试用。image.pngWatcher 由以下 5 个部分组成:

  • trigger:定义 watcher 触发的时间或者周期。
  • input:定义数据的来源,可以是一个索引或者 HTTP 请求的结果等等。如果没有设置输入将为空。
  • condition:定义执行 action 触发的条件。如果没有设置默认总是触发 action。
  • transform(可选):修改 watcher 的 payload。
  • actions:定义执行的动作,例如 email,webhook,index,logging,slack 等等。

创建 1 个 Watcher:

  • trigger:每分钟运行一次。
  • input:通配符匹配 nginx-* 的索引,查询 message 字段中的 error 关键字,每次针对在过去5分钟内发生的事件来进行查询。
  • condition:如果在查询结果中,匹配到 1 次,就触发 action。
  • action:向指定 URL 发送一个 HTTP POST 请求。
PUT _watcher/watch/nginx-watcher
{
  "trigger": {
     "schedule" : {
      "interval" : "1m"
    }
  },
  "input": {
    "search": {
      "request": {
        "indices": [
          "nginx-*"
        ],
        "body": {
          "query": {
            "bool": {
              "must": {
                "match": {
                  "message": "error"
                }
              },
              "filter": {
                "range": {
                  "@timestamp": {
                    "from": "{{ctx.trigger.scheduled_time}}||-5m",
                    "to": "{{ctx.trigger.triggered_time}}"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "condition": {
    "compare": {
      "ctx.payload.hits.total": {
        "gt": 0
      }
    }
  },
  "actions": {
    "my_webhook": {
      "throttle_period": "2m",
      "webhook": {
        "method": "POST",
        "url": "https://webhook.site/2f64f4b3-8b43-488c-b2df-695136079e36",
        "body": "Number of Nginx Error: {{ctx.payload.hits.total}}"
      }
    }
  }
}

查看刚刚创建的 watcher:image.pngimage.pngimage.png

PUT _watcher/watch/nginx-watcher/_execute

参考资料

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
2月前
电子书阅读分享《Elasticsearch全观测技术解析与应用(构建日志、指标、APM统一观测平台)》
电子书阅读分享《Elasticsearch全观测技术解析与应用(构建日志、指标、APM统一观测平台)》
234 1
|
6月前
|
运维 安全 API
统一接入API赋能开发者:自动高效、灵活编排的云产品日志采集方案
随着企业对网络安全和数据安全防护水平要求的逐步提升,企业管理对企业生产运维过程中所产生的日志数据,在留存处理、权限隔离、跨境合规、数据汇总等方面提出了更高阶的需求。为了满足大客户及一些国际化客户安全合规、简单快速地接入日志、使用日志、操作日志,我们提出了一种新的解决方案——“云产品统一接入API”。统一接入API主要针对阿里云云产品日志类型,以API的方式提供企业或组织用户快速上手,编排灵活的日志采集方案。
|
2月前
|
JSON Prometheus Cloud Native
Grafana 系列 - 统一展示 -8-ElasticSearch 日志快速搜索仪表板
Grafana 系列 - 统一展示 -8-ElasticSearch 日志快速搜索仪表板
|
20天前
|
canal 消息中间件 关系型数据库
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
66 0
|
1月前
|
Web App开发 监控 应用服务中间件
全新架构!日志服务 SLS 自研免登录方案发布
全新架构!日志服务 SLS 自研免登录方案发布
87432 7
|
5月前
|
存储 缓存 前端开发
两种异步日志方案的介绍
两种异步日志方案的介绍
78 0
|
5月前
|
存储 数据可视化 搜索推荐
分布式系列教程(26) -分布式日志搜集工具Elasticsearch简介
分布式系列教程(26) -分布式日志搜集工具Elasticsearch简介
54 0
|
2月前
|
算法 搜索推荐 关系型数据库
Elasticsearch算分优化方案之rescore_query
Elasticsearch算分优化方案之rescore_query
27 0
|
2月前
|
消息中间件 设计模式 Java
spdlog中的异步日志方案
spdlog中的异步日志方案
219 2
|
7月前
|
存储 SQL 监控
一文解读如何落地企业级云上日志审计方案
近年来,随着云计算的广泛应用和企业上云的深度普及,许多企业或个人用户将各种日志托管在云上进行留存,从而进行查询、审计等操作。什么是日志审计?为什么要做日志审计?企业如何落地云上日志审计方案?带着这些问题出发,本文将以阿里云日志服务(SLS)旗下的日志审计服务为视角切入,带领读者从当今网络安全形势和法律法规要求出发,解读云计算背景下,如何构建、运行、实践一个标准的企业级云上审计方案,从而更好地保障企业或组织的云上资产、云上数据的安全,确保企业业务持续安全稳定地运行。

热门文章

最新文章