广告位 · 页头(后台-模块管理-新建模块后替换此区域)

如何从零搭建Graylog日志聚合系统并高效分析海量日志?

把分散在各台服务器上的日志集中起来统一管理,是很多团队在业务增长过程中都必须解决的问题。Graylog 是一个开源的日志聚合系统,能够接收来自不同来源的日志,通过 Elasticsearch 建立索引,并提供强大的搜索、统计和告警功能。本文从实际部署出发,先梳理 Graylog 的架构和数据流向,然后在 Docker Compose 中把整套系统跑起来,最后演示怎么把日志接进去以及如何写出高效的查询和告警。

如何从零搭建Graylog日志聚合系统并高效分析海量日志?

Graylog核心组件与数据流

Graylog 本身并不存储日志数据,它负责接收、处理和转发日志,真正的索引和存储由 Elasticsearch 完成,而 Graylog 的元数据(如用户、输入配置、告警规则)则存放在 MongoDB 中。理解这三者之间的关系是部署和排错的前提。

一条日志从产生到可检索,大致经过这样的流程:日志源(例如 Linux 系统的 rsyslog、Java 应用通过 GELF 发送)先把日志发送到 Graylog 的 Input 端口;Graylog 接收后根据配置的 extractor 或 pipeline 对消息做解析和字段提取;处理后的消息被批量写入 Elasticsearch,Elasticsearch 为这些消息建立倒排索引,从而支持快速的全文检索和聚合分析。MongoDB 只在 Graylog 自身配置发生变化时才会读写,日志量再大也不会给它带来压力。

Graylog 的 Web 界面默认监听 9000 端口,提供搜索、仪表盘、告警管理等功能。它的搜索语法基于 Lucene 查询,并扩展了字段过滤器,例如通过 source:web01 限定来源节点,或者用 level:ERROR 筛选错误日志。理解了这套数据流,后面的部署和配置就会清晰很多。

基于Docker Compose的快速部署

对于演示环境或者中小规模生产环境,Docker Compose 是最省事的部署方式。下面给出一份可用的 docker-compose.yml,其中包含 MongoDB、Elasticsearch 和 Graylog 三个服务。需要提前准备好宿主机上的目录,并把环境变量中的密码改成自己的值。

version: '3'
services:
  mongo:
    image: mongo:4.4
    volumes:
      - mongo_data:/data/db
    networks:
      - graylog
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.10
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
    volumes:
      - es_data:/usr/share/elasticsearch/data
    networks:
      - graylog
  graylog:
    image: graylog/graylog:4.3
    environment:
      - GRAYLOG_PASSWORD_SECRET=somepasswordpepper1234567890
      - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      - GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:9000/
      - GRAYLOG_ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - GRAYLOG_MONGODB_URI=mongodb://mongo:27017/graylog
    depends_on:
      - mongo
      - elasticsearch
    ports:
      - "9000:9000"
      - "1514:1514/tcp"
      - "1514:1514/udp"
      - "12201:12201/tcp"
      - "12201:12201/udp"
    networks:
      - graylog
volumes:
  mongo_data:
  es_data:
networks:
  graylog:

上面配置中的 GRAYLOG_ROOT_PASSWORD_SHA2 是 root 用户登录密码的 SHA-256 值,可以通过命令 echo -n "你的密码" | sha256sum 生成。需要注意 GRAYLOG_PASSWORD_SECRET 必须不少于 16 个字符,否则 Graylog 会拒绝启动。端口方面,9000 是 Web 界面,1514 用于接收 Syslog 日志,12201 用于 GELF 格式日志。

启动前先创建挂载目录并赋权,否则 Elasticsearch 可能因为权限不足无法写入数据。执行 docker-compose up -d 后,用浏览器访问 http://127.0.0.1:9000,输入 admin 和刚才设置的密码即可看到 Graylog 界面。第一次启动需要等待 Elasticsearch 完成初始化,大约 1 到 2 分钟。

生产环境不建议直接用 Compose 单机部署,因为 Elasticsearch 需要集群来保证高可用。但作为入门和测试,这份配置足够完整,后续可以把 Elasticsearch 替换成外部集群,只在 Graylog 环境变量中修改连接地址。

接入日志:Syslog与GELF两种方式

Graylog 支持多种日志输入类型,最常用的是 Syslog 和 GELF。Syslog 适合 Linux 系统日志和网络设备,GELF 则更适合应用自定义日志,因为它可以携带结构化的字段,避免后续再写正则解析。

先看 Syslog 接入。在 Graylog 的 Web 界面中,进入 System -> Inputs,选择 Syslog UDP,绑定到 0.0.0.0 端口 1514。然后修改 Linux 客户端的 rsyslog 配置,增加一行把日志转发到 Graylog 服务器:

# 在 /etc/rsyslog.conf 或 /etc/rsyslog.d/50-default.conf 中添加
*.* @graylog服务器IP:1514;RSYSLOG_SyslogProtocol23Format

这行配置使用 UDP 协议发送,@ 表示 UDP,@@ 表示 TCP。如果日志量大或者网络不稳定,建议改用 TCP,但需要把 Graylog 的 Input 也改成 Syslog TCP 并监听 1514。修改后重启 rsyslog 服务即可。接着在 Graylog 的 Search 页面就能看到来自该主机的日志。

对于应用日志,GELF 更加灵活。Graylog 已经内置了 GELF HTTP 和 GELF UDP 输入,默认端口都是 12201。以 Python 为例,可以安装 pygelf 库,几行代码就能把日志发过去:

import logging
from pygelf import GelfUdpHandler
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.addHandler(GelfUdpHandler(host='graylog服务器IP', port=12201))
logger.info('用户登录成功', extra={'user_id': 1024, 'source_ip': '10.0.0.8'})

这样发送的日志会带上 user_id 和 source_ip 两个自定义字段,后续查询时可以直接用 user_id:1024 过滤,比从原始文本里提取字段方便得多。Java 应用可以使用 logback-gelf,Node.js 可以使用 graylog2 库,原理类似。

接入过程中经常遇到端口不通的问题,可以先在 Graylog 服务器上用 telnet IP 1514 或者 nc -vz IP 12201 测试网络连通性。如果日志没有出现,检查 Input 是否处于 running 状态,以及客户端配置中的协议和端口是否与 Input 一致。

日志查询、告警与性能优化

日志进入 Elasticsearch 之后,Graylog 的搜索栏就可以直接使用 Lucene 语法。常用查询例如 source:web01 AND level:ERROR 查找某台机器的错误日志,或者 http_status:[500 TO 599] 查询 5xx 状态码。字段是否存在可以用 _exists_:user_id,时间范围则由右上角的时间选择器控制。

除了手动查询,Graylog 可以把保存的搜索条件转换为告警。进入 Alerts -> Event Definitions,新建一个事件定义,设置条件为 count() > 10 且时间窗口为 5 分钟,再配置通知方式(邮件、Slack 或 HTTP 回调)。这样当 5 分钟内匹配到超过 10 条指定错误日志时,Graylog 就会自动触发通知。告警规则要尽量精准,避免误报过多导致团队成员忽略告警。

性能优化方面,首先要控制 Elasticsearch 的索引分片数量。Graylog 默认按天创建索引,每个索引的分片数可以在 System -> Indices 中调整。对于每天日志量在几十 GB 以下的场景,主分片设置为 2 到 4 个即可,副本分片设为 1。如果日志量特别大,可以按小时创建索引,并缩短索引保留时间。另外,及时把不活跃的索引关闭或删除,能显著降低 Elasticsearch 内存占用。

另一个容易被忽略的优化点是消息字段的规范化。如果每条日志都携带十几个动态字段,会拖慢写入速度并占用大量内存。可以在 Graylog 的 Pipeline 中做字段清理,只保留真正需要检索的字段。搜索时尽量使用过滤(filter)而不是查询(query)上下文,这样能利用缓存减少计算。

Graylog 的实战价值在于把日志从“被动翻找”变成“主动检索和告警”。随着接入的日志源越来越多,统一的字段规范和索引策略会变得至关重要。建议在部署初期就制定好日志格式标准,比如规定 level、source、trace_id、user_id 等字段名称,后续做链路追踪和业务分析会更加顺畅。

广告位 · 文章底部(后台-模块管理替换此区域)