dot Redis 8 来了—而且是开源的

了解更多

使用 Syslog 将 Redis 集群告警发送到 Slack

在生产环境中运行时,系统会记录许多事件和警报,帮助管理员监控系统中发生的情况,并在需要响应问题时自动收到通知。例如

  • 当创建新数据库时,会记录一个事件,其中包含时间戳、用户和新数据库的名称——这使管理员能够检查配置,并在有问题时联系用户。
  • 当达到阈值(例如,特定百分比的内存消耗)时,会记录一个警报,提示管理员检查 Redis Enterprise 集群的运行状况。

本文将介绍 Redis Enterprise 如何使用 syslog 服务来记录事件和警报,并解释如何:

  • 配置 syslog
  • 将集群事件发送到集中式日志服务器
  • 将节点故障告警消息发送到 Slack

总的来说,Redis Enterprise 管理许多日志,默认情况下保存在 /var/opt/redis/log 目录中,但我们将重点介绍 Redis 文档中介绍的 syslog 的使用方法:Redis 文档。希望您在阅读完本文后,能够了解如何:

  • 配置 syslog 系统以将 Redis 事件和警报保存在 /var/log/redis.log 文件中
  • 将事件和警报发送到 syslog 远程服务器,如下图所示

在开始之前,您需要拥有一个 Redis Enterprise Software 集群,以及一个运行 syslog 服务器的 Linux 实例。(请注意,对于本文,我使用了 Redis Enterprise 5.4.14-28 的 3 节点集群,在 CentOS 7.x 上运行,以及另一个 Linux 实例来运行 syslog 服务器。)

了解配置

在所有节点上,您都会看到一个 /var/opt/redis/log 目录,Redis Enterprise 在其中写入所有日志。让我们重点关注 event_log。此文件由 Redis Enterprise 告警管理器服务管理,该服务根据集群和数据库告警的配置生成条目,并记录各种管理操作,例如数据库创建、配置和删除。

如果您打开 `/var/opt/redis/log/event_log.log` 文件,您将看到如下所示的条目:

2020-04-06 15:30:46,425 INFO event_log EventLog: {"originator_username":"Administrator","object":"bdb:7","extra":{"bdb_uid":"7","bdb_name":"db-002"},"object_type":"bdb","originator_email":"[email protected]","originator_uid":1,"time":1586187046,"throttled_event_count":1,"obj_uid":"7","type":"creation_request"}
2020-04-06 15:30:47,896 INFO event_log EventLog: {"originator_username":"system","object":"cluster","extra":{"bdb_uid":"7","bdb_name":"db-002"},"object_type":"cluster","originator_uid":0,"time":1586187047,"throttled_event_count":1,"obj_uid":null,"type":"bdb_created"}

2020-04-06 15:32:20,073 CRITICAL event_log EventLog: {"originator_username":"system","object":"node:2","object_type":"node","state":true,"originator_uid":0,"time":1586187140,"throttled_event_count":1,"obj_uid":"2","type":"failed"}

日志条目具有以下基本结构:
时间戳 严重性 event_log EventLog:{<任何顺序的键值对列表>}

  • 时间戳
  • 事件的严重性:INFO、WARNING、ERROR、CRITICAL
  • event_log­ EventLog 纯静态文本
  • {任何顺序的键值对列表} 描述特定事件的键值对列表。键值对可以以任何顺序出现。某些键值对始终显示,某些键值对根据特定事件显示。您可以在 Redis Enterprise 文档 中找到有关消息内容的更多信息。

这些事件在集群级别进行管理,因此只有集群的主节点才会特定时间写入 event_log 文件中的事件。让我们在集群上运行 `rladmin` 命令:

如您所见,node:1 是集群的主节点。这意味着 event_log 将在那里填充。如果主节点移动到另一个节点,事件将保存在新的主节点上。

这些日志由 Redis 集群日志记录基础设施管理。但是,Redis Enterprise 也使用 syslog。您将在 /var/log/messages 文件中找到相同的日志条目:

Apr 8 05:32:20 ip-100-00-00-000 event_log[2015]: {"originator_username":"system","object":"node:2","object_type":"node","state":true,"originator_uid":0,"time":1586187140,"throttled_event_count":1,"obj_uid":"2","type":"failed"}

请注意,相同条目存在,主机名和进程名作为前缀

(ip-100-00-00-000 event_log[2015])

了解 Redis Enterprise 和 rsyslog 配置

现在让我们看看 Redis Enterprise 的配置,了解日志如何以及为何被 rsyslog 使用。Redis Enterprise 日志记录在 /opt/redis/config/logging.conf 文件中配置:

{
    "version": 1,
    "disable_existing_loggers": false,
    "formatters": {
        "standard": {
            "format": "%(asctime)s %(levelname)s %(name)s %(threadName)s: %(message)s"
        },
        "syslog": {
            "format": "%(name)s[%(process)d]: %(message)s"
        }
    },

    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "standard",
            "stream": "ext://sys.stdout"
        },
        "syslog": {
            "class": "logging.handlers.SysLogHandler",
            "formatter": "syslog",
            "facility": "daemon",
            "address": "/dev/log"
        }
    },

    "loggers": {
        "": {
            "level": "INFO"
        },
        "event_log": {
            "level": "INFO",
            "handlers": ["syslog"],
            "propagate": false
        }
    }
}

此文件包含本文中两个有趣的部分

loggers.event_log 定义了哪些处理程序用于记录事件

handlers.syslog 定义了处理程序。默认配置使用 “daemon” “facility”

请记住,如果您更改 /opt/redis/config/logging.conf,则在更新 Redis Enterprise 时它将被覆盖。在以下部分中,我将解释如何在不接触任何 Redis Enterprise 配置的情况下使用 syslog 控制日志记录。如果您确实更改了日志记录配置,则必须运行以下命令使其生效:

$ supervisorctl restart alert_mgr

什么是 syslog facility?

Syslog facility 是位于 /etc/rsyslog.conf 中的配置条目,它定义了 syslog 消息将写入的位置,基于消息的来源。您可以在 syslog Wikipedia 页面 中找到有关 facility 的更多信息,包括可用 facility 的列表。

如上所述,默认情况下,Redis Enterprise 使用 daemon facility,用于记录系统守护进程。Syslog 还定义了 facility local0local7,以便管理员配置自定义日志记录策略。

配置 syslog

现在我们准备好配置 syslog。让我们首先创建一个新的配置文件,其中包含 Redis 事件日志记录的所有特定信息。

创建如下所示的文件

/etc/rsyslog.d/redis.conf

并添加以下配置

template(name="RedisEventTemplate" type="string" string="%syslogseverity-text%:%pri-text%:%timegenerated%:%HOSTNAME%:%syslogtag%:%msg:::drop-last-lf% -- %syslogtag%  -- %programname% \n")

if $programname startswith 'event_log' then {
  action(type="omfile" file="/var/log/redis.log" template="RedisEventTemplate" )
}

通过此配置,syslog 服务将

  • 加载一个名为 RedisEventTemplate 的新模板,该模板记录具有优先级(syslogseverity-text)的消息,该优先级将为 info, crit, warning, …
  • 当程序为 ‘event_log’(Redis Enterprise 日志管理器)时,使用此模板写入文件 /var/log/redis.log

您可以在 syslog 文档 中了解有关模板语法的更多信息。

最后,重新启动 syslog

systemctl restart rsyslog

测试新配置

转到 Redis Enterprise Web 控制台并创建一个新数据库(或编辑现有数据库)。您应该看到一个新的 /var/log/redis.log 文件和您生成的事件。以下是一个日志条目的示例:

info:local5.info 17:48:47:ip-00-00-00-00:event_log[14176] ::{"originator_username":"Administrator","object":"bdb:18","extra":{"old_val":"dd2","new_val":"db01","attr":"name"},"object_type":"bdb","originator_email":"[email protected]","originator_uid":1,"time":1586281727,"throttled_event_count":1,"obj_uid":"18","type":"updated"}

在此示例中,日志条目的第一部分 (info) 是严重性,您以后可以使用它来捕获特定事件。

配置完整的集群

如前所述,您仅在一个节点(主节点)上配置 Redis Enterprise 和 syslog,因此您必须在集群中的每个节点上重复这些步骤。

Redis Enterprise 集群现在配置为使用自定义 syslog 配置来捕获事件和警报;现在可以使用 syslog 功能。

将集群中的所有节点发送到单个位置

常见的 syslog 用例是将所有日志聚合到单个位置进行处理。Syslog 提供了服务器功能来执行此操作,您只需在 syslog 配置中添加一个新操作即可通过网络发送消息。

要将所有消息发送到集中式日志服务器,请在 /etc/rsyslog.d/redis.conf 文件中添加一个新操作

template(name="RedisEventTemplate" type="string" string="%syslogseverity-text%:%pri-text%:%programname%:%timegenerated%:%HOSTNAME%:%syslogtag%:%msg:::drop-last-lf% \n")

if $programname startswith 'event_log' then {
  action(type="omfile" file="/var/log/redis.log" template="RedisEventTemplate" )
  action(type="omfwd" protocol="tcp" target="10.0.0.12" port="514" template="RedisEventTemplate" )
}

重新启动 syslog 服务

$ systemctl restart rsyslog

如果您从 Redis Enterprise 生成一个事件,例如通过编辑数据库,您应该在您指向的 syslog 服务器的 /var/log/messages 文件中看到一个新事件。

发送节点故障警报到 Slack

所有 Redis 集群事件都会被发送到一个集中的 syslog 服务器,并将这些事件写入 /var/log/messages 文件中。

现在,您可以使用此服务器来解析这些消息,并将它们与任何其他工具集成,例如 Splunk、Syslog Watcher 或 Datadog。 例如,一个简单而方便的流程是从日志文件中解析消息,并在满足特定模式时向 Slack 发送消息。 以下是如何做到这一点:

创建传入的 Slack Webhooks

  1. 转到 https://apps.slack.com
  2. 创建或激活开发者帐户
  3. 搜索“incoming webhooks”
  4. 创建一个新的 Hook

Slack 传入的 Webhook 是一个简单的 REST 端点,可用于向 Slack 发布消息。

编写 Python 消息解析器

现在 Slack Webhook 已经就位,让我们使用一个简单的 Python 脚本来 tail 这个文件,并检查新行是否来自 Redis event_log 并且包含字符串 failed 如果是,该脚本将使用简单的 Webhook 将消息推送到 Slack。

redis-alert.py 脚本 如下所示:

import time
import json
import requests
import re
import sys

# Read log
def tail(f):
    f.seek(0, 2)
    while True:
        line = f.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line

# Parse line and send message if match
def analyze_message(line, text):
    if re.search(r"\bevent_log\b", line) and  re.search(r"\b"+ text + r"\b", line):
        webhook_url = 'https://hooks.slack.com/services/YOUR_HOOK/URL/SLACK'
        slack_data = {'text': '"' + line + '"'}
        response = requests.post(
            webhook_url, data=json.dumps(slack_data),
            headers={'Content-Type': 'application/json'})

# Run the application
while True:
    print(sys.argv[1])
    auditlog = tail( open (sys.argv[1]) )
    for line in auditlog:
        analyze_message(line, sys.argv[2])

以下是 syslog 服务器上聚合所有 Redis 事件的脚本

$ python redis-alert.py /var/log/messages failed

要了解其工作原理,请生成一个节点故障,例如强制重启其中一个节点。 您应该在您的 Slack 频道中看到一条通知

这个 Python 脚本非常简单,它完全按照接收到的消息发送消息。

Syslog 是一个强大的工具,可以捕获、组织、过滤和移动各种位置的日志条目。 在这篇文章中,我们配置了 Redis Enterprise 和 syslog,以自定义格式捕获集群事件和警报,并将这些条目发送到中央 syslog 服务器。 如果您想了解更多关于使用 syslog 的信息,请访问官方 RSylog 文档