使用 ELK 构建智能日志监控与钉钉告警系统

引言

在当前微服务架构盛行的环境下,多个服务分布在不同的机器上,当出现问题时,逐一排查各个机器上的日志非常费时费力,且难以及时发现问题。而 ELK(Elasticsearch、Logstash、Kibana)作为一种成熟的日志管理解决方案,能够有效解决这些问题。本文将介绍如何搭建 ELK 系统,并结合钉钉实现智能告警,帮助及时发现和处理系统问题。

一、ELK 搭建与日志采集

1. Spring Boot 配置日志采集

我们使用 log4j2 + logback 配合 Logstash 进行日志采集,以下是 logback-logstash.xml 的配置:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <springProperty scope="context" name="appName" source="spring.application.name"/>
    <springProperty scope="context" name="logstash.host" source="log.logstash-host"/>
    <appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>${logstash.host}</destination>
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
            <customFields>{"spring.application.name":"${appName}"}</customFields>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="logstash"/>
    </root>
</configuration>

2. Logstash 配置

Logstash 的主要工作是将日志数据发送至 Elasticsearch,以下是 Logstash 的输入和输出配置:

bash 复制代码
input {
  tcp {
    mode => "server"
    host => "0.0.0.0"
    port => 4560
    codec => json_lines
  }
}

output {
  elasticsearch {
    hosts => ["http://192.168.0.0:9200"]
    index => "springboot-logstash-%{+YYYY.MM.dd}"
  }
  stdout { codec => rubydebug }
}

3. Elasticsearch 和 Kibana 的使用

在日志数据发送到 Elasticsearch 后,可以使用 Kibana 创建索引模式并查看日志。

  1. 打开 Kibana:在浏览器中访问 http://localhost:5601
  2. 创建索引模式:
    • 导航到 "Stack Management",选择 "Index Patterns"。
    • 点击 "Create index pattern",输入索引模式名称,例如 springboot-logstash-*,并完成创建。

二、ELK 配合钉钉的实时告警

ELK 搭建完成后,虽然可以查看日志,但无法及时发现错误。为了实现实时告警,可以结合钉钉机器人进行系统报警。

1. 使用 ElastAlert 实现钉钉告警

ElastAlert 是一个开源工具,能够检测 Elasticsearch 中的数据并生成告警。

安装和配置步骤:
  1. 安装 Python 环境:推荐使用 conda 安装,避免破坏系统自带工具。

  2. 安装 ElastAlert

    • 对于高版本的 Elasticsearch,可以使用 ElastAlert2,参考官网熟悉规则。
  3. 编写规则文件(rule)

    yaml 复制代码
    name: "Error Alert"
    schedule:
      interval:
        minutes: 2
    type: frequency
    index: "springboot-logstash-*"
    filter:
    - term:
        level.keyword: "ERROR"
    num_events: 1
    timeframe:
      minutes: 2
    realert:
      minutes: 5
    alert:
    - "command"
    command: ["/etc/elastalert/dingtalk_alert.sh","{message}","{stack_trace}"]
    alert_text: "ElastAlert Notification: An ERROR log was detected: {0}"
    alert_text_args:
    - "message"
  4. 编写钉钉通知脚本

#!/bin/bash 复制代码
#webhook URL
WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token="

# 原始 Kibana 链接
ORIGINAL_URL="http://36.139.142.158:5601/app/discover#/?_g=(time:(from:now-15m,to:now))&_a=(index:'logstash-*',query:(match_phrase:(level.keyword:'ERROR')))"

# 对 URL 进行编码
ENCODED_URL=$(python3 -c "import urllib.parse; print(urllib.parse.quote(\"${ORIGINAL_URL}\"))")

# 构造钉钉协议的链接
ACTION_URL="dingtalk://dingtalkclient/page/link?url=${ENCODED_URL}&pc_slide=false"

# 报警内容
STACK_INFO=$(echo "$2" | head -n 20 | sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/"/\\"/g')
MESSAGE=$(cat <<EOF
{
    "msgtype": "actionCard",
    "actionCard": {
        "title": "系统错误通知",
        "text": "### 系统出现错误\\n\\n请检查系统日志并尽快处理。\\n\\n- 错误描述:$1\\n- 时间:$(date +'%Y-%m-%d %H:%M:%S')\\n- 堆栈信息:${STACK_INFO}",
        "btnOrientation": "0",
        "btns": [
            {
                "title": "查看详细日志",
                "actionURL": "${ACTION_URL}"
            }
        ]
    }
}
EOF
)

# 打印日志
echo "发送消息内容:${MESSAGE}"

# 发送 POST 请求到钉钉
curl -X POST -H "Content-Type: application/json" -d "${MESSAGE}" "${WEBHOOK_URL}"

5.群内通知效果截图

三、总结

通过使用 ELK 构建日志收集系统,并结合钉钉机器人实现告警,可以极大提升系统的日志监控和问题发现能力。ElastAlert 提供了一种开源、低成本的告警方式,能够及时发现系统中的异常,帮助快速定位和解决问题。在选择告警方案时,可以根据企业的需求和预算来权衡不同方案的优缺点。

相关推荐
Daniel 大东15 分钟前
idea 解决缓存损坏问题
java·缓存·intellij-idea
wind瑞21 分钟前
IntelliJ IDEA插件开发-代码补全插件入门开发
java·ide·intellij-idea
HappyAcmen21 分钟前
IDEA部署AI代写插件
java·人工智能·intellij-idea
马剑威(威哥爱编程)27 分钟前
读写锁分离设计模式详解
java·设计模式·java-ee
鸽鸽程序猿28 分钟前
【算法】【优选算法】前缀和(上)
java·算法·前缀和
修道-032328 分钟前
【JAVA】二、设计模式之策略模式
java·设计模式·策略模式
九圣残炎34 分钟前
【从零开始的LeetCode-算法】2559. 统计范围内的元音字符串数
java·算法·leetcode
当归10241 小时前
若依项目-结构解读
java
hlsd#1 小时前
关于 SpringBoot 时间处理的总结
java·spring boot·后端
iiiiiankor1 小时前
C/C++内存管理 | new的机制 | 重载自己的operator new
java·c语言·c++