点 闪电般的未来正在你所在城市的一场活动中到来。

在 Redis 发布中加入我们

通过 Syslog 向 Slack 发送 Redis 集群警报

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

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

本贴将介绍 Redis Enterprise 如何使用 syslog 服务记录事件和警报,并将说明如何执行以下操作:

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

为便于理解,我们说明一下:Redis Enterprise 管理着许多日志,默认情况下存储在/var/opt/redis/log目录中,但我们将重点关注Redis 文档中概述的 syslog 用法。希望在您读完本文时,您将了解如何执行以下操作:

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

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

了解配置

在所有节点上,您都将看到一个/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":"admin@demo.com","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"}

日志条目具有以下基本结构:
timestamp 严重程度 event_log  EventLog:{<任意顺序的关键值对列表>}

  • 时间戳
  • 事件的严重程度:信息、警告、错误、严重
  • 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定义了处理程序。默认配置使用“守护程序” “设施”

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

$ supervisorctl restart alert_mgr

什么是 syslog 设施?

Syslog 设备是一个配置条目,位于 /etc/rsyslog.conf 中,它根据消息的来源定义了 syslog 消息的写入位置。您可以在 syslog 维基百科页面找到有关设备的更多信息,包括可用设备的列表。

如上所述,默认情况下 Redis Enterprise 使用 daemon 设备,该设备用于记录系统守护程序。Syslog 还定义了 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) 的消息,其将为 infocritwarning,...
  • 当程序为 ‘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":"admin@demo.com","originator_uid":1,"time":1586281727,"throttled_event_count":1,"obj_uid":"18","type":"updated"}

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

配置完整集群

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

Redis 企业版集群现已配置为使用自定义 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 webhook

  1. 访问 https://apps.slack.com
  2. 创建或激活开发者帐户
  3. 搜索“传入 webhook”
  4. 创建一个新钩子

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

编写 Python 消息解析器

现在 Slack webhook 已经完成,让我们使用一个简单的 Python 脚本来追踪此文件,并检查新行是否来自 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])

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

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

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

此 Python 脚本非常简单,它原样发送消息。

日志是一项强大的工具,可捕获、组织、筛选各种位置的日志条目,并将其移至他处。在此发布中,我们配置了 Redis Enterprise 和日志以捕获自定义格式的集群事件和告警,并将这些条目发送至中央日志服务器。如果您想了解更多有关使用日志的信息,请转到官方网站RSylog 文档