GrayLog 分布式日志管理平台完整指南
概述
GrayLog 是一个轻量级的分布式日志管理平台,是一个开源的日志聚合、分析、审计、展示和预警工具。在功能上来说,和 ELK 类似,但又比 ELK 要简单轻量许多。依靠着更加简洁、高效、部署使用简单的优势很快受到许多公司的青睐。

技术优势
GrayLog 相比 ELK Stack 的主要优势:
| 特性 | GrayLog | ELK Stack |
|---|---|---|
| 部署复杂度 | 低,一体化方案 | 高,需要协调多个组件 |
| 学习成本 | 低,UI 直观易用 | 高,需要了解多个组件 |
| 资源消耗 | 中等,优化良好 | 高,特别是 Logstash |
| 搜索语法 | 简单,类似 Google | 复杂,需要学习 DSL |
| 实时性 | 优秀,低延迟 | 良好,延迟稍高 |
| 扩展性 | 良好,支持集群 | 优秀,水平扩展强 |
核心特性
- 一体化方案: 安装方便,不像 ELK 有 3 个独立系统间的集成问题
- 原始日志采集: 采集原始日志,可以事后再添加字段,如
http_status_code、response_time等 - 灵活数据收集: 支持自定义 GELF 格式,Fluentd 和 Logstash 都有相应的输出插件
- 搜索结果高亮: 就像 Google 一样的搜索体验
- 简单搜索语法: 如
source:mongo AND response_time_ms:>5000,避免直接使用 Elasticsearch 的 JSON 语法 - 导出功能: 搜索条件可以导出为 Elasticsearch 的搜索 JSON 文本
应用场景
| 场景 | 描述 | 适用性 |
|---|---|---|
| 中小型企业 | 快速部署的日志分析平台 | ⭐⭐⭐⭐⭐ |
| 开发测试 | 开发和测试环境的日志监控 | ⭐⭐⭐⭐⭐ |
| 微服务架构 | 分布式应用的日志集中管理 | ⭐⭐⭐⭐ |
| 运维监控 | 系统和应用的实时监控 | ⭐⭐⭐⭐ |
| 故障排查 | 快速定位和分析问题 | ⭐⭐⭐⭐⭐ |
💡 官方网站: https://www.graylog.org/
环境准备
系统要求
| 组件 | 最低配置 | 推荐配置 | 说明 |
|---|---|---|---|
| CPU | 2 核心 | 4 核心以上 | GrayLog 服务器计算密集 |
| 内存 | 4GB | 8GB 以上 | Elasticsearch 需要较大内存 |
| 存储 | 50GB | 100GB 以上 SSD | 日志数据存储需求大 |
| 网络 | 100Mbps | 1Gbps | 大量日志数据传输 |
组件依赖
GrayLog 依赖以下组件:
- MongoDB: 存储配置元信息和配置数据(无需太多硬件资源)
- Elasticsearch: 存储日志数据(内存大以及更高的磁盘 I/O)
- GrayLog Server: 读取日志、展示日志(CPU 密集)
支持的操作系统
- Linux: CentOS 7+, Ubuntu 18.04+, RHEL 7+
- Windows: Windows Server 2016+
- Docker: 推荐使用容器化部署
- Kubernetes: 支持 K8s 集群部署
架构设计
GrayLog 工作流程

数据流向:
- 数据源 → GrayLog 输入 → 消息处理 → Elasticsearch 存储
- 用户 → GrayLog Web界面 → 搜索查询 → Elasticsearch
最小化部署架构

工作流程:
- 微服务中的 GrayLog 客户端发送日志到 GrayLog 服务端
- GrayLog 把日志信息格式化,存储到 Elasticsearch
- 客户端通过浏览器访问 GrayLog,GrayLog 访问 Elasticsearch
组件职责:
- MongoDB: 存储 GrayLog 配置信息,支持集群节点共享配置
- Elasticsearch: 存储日志数据,提供搜索和聚合能力
- GrayLog: 日志处理和 Web 界面
架构特点:
- ✅ 部署简单: 单节点快速启动
- ✅ 成本较低: 资源需求相对较小
- ❌ 单点故障: 无冗余,适合测试阶段
大型生产环境架构

高可用特性:
- 客户访问和日志源面对的是前端的负载均衡器
- LB 通过 GrayLog REST API 负载管理 GrayLog 集群
- Elasticsearch 使用集群方案,多节点存储数据,达到备份冗余、负载的效应
- MongoDB 集群,具备自动的容错功能(auto-failover)和自动恢复(auto-recovery)的高可用
- 各组件方便伸缩扩展
Docker 快速部署
单节点部署(开发环境)
1. 部署 Elasticsearch
# 部署 Elasticsearch
docker run -d \
--name elasticsearch \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
-v es-data:/usr/share/elasticsearch/data \
-v es-plugins:/usr/share/elasticsearch/plugins \
--privileged \
-p 9200:9200 \
-p 9300:9300 \
--restart unless-stopped \
elasticsearch:7.17.5
# 验证 Elasticsearch
curl -X GET "localhost:9200/_cluster/health?pretty"
2. 部署 MongoDB
# 部署 MongoDB
docker run -d \
--name mongodb \
-p 27017:27017 \
--restart=always \
-v mongodb:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=graylog \
-e MONGO_INITDB_ROOT_PASSWORD=graylog123 \
mongo:4.4
# 验证 MongoDB
docker exec -it mongodb mongo --username graylog --password graylog123 --eval "db.adminCommand('ismaster')"
3. 部署 GrayLog
# 生成密码加密密钥和管理员密码
PASSWORD_SECRET=$(openssl rand -base64 64 | tr -d '\n')
ROOT_PASSWORD_SHA2=$(echo -n "admin" | sha256sum | cut -d' ' -f1)
# 部署 GrayLog
docker run -d \
--name graylog \
-p 9000:9000 \
-p 12201:12201/udp \
-p 1514:1514/udp \
-p 5555:5555/tcp \
-e GRAYLOG_HTTP_EXTERNAL_URI=http://localhost:9000/ \
-e GRAYLOG_ELASTICSEARCH_HOSTS=http://elasticsearch:9200/ \
-e GRAYLOG_ROOT_TIMEZONE="Asia/Shanghai" \
-e GRAYLOG_WEB_ENDPOINT_URI="http://localhost:9000/api" \
-e GRAYLOG_PASSWORD_SECRET="$PASSWORD_SECRET" \
-e GRAYLOG_ROOT_PASSWORD_SHA2="$ROOT_PASSWORD_SHA2" \
-e GRAYLOG_MONGODB_URI=mongodb://graylog:graylog123@mongodb:27017/graylog \
--link elasticsearch:elasticsearch \
--link mongodb:mongodb \
--restart unless-stopped \
graylog/graylog:4.3
# 检查运行状态
docker ps | grep graylog
4. Docker Compose 部署(推荐)
# docker-compose.yml
version: '3.8'
services:
elasticsearch:
image: elasticsearch:7.17.5
container_name: graylog-elasticsearch
environment:
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
- discovery.type=single-node
- xpack.security.enabled=false
ports:
- "9200:9200"
- "9300:9300"
volumes:
- es_data:/usr/share/elasticsearch/data
- es_logs:/usr/share/elasticsearch/logs
networks:
- graylog
restart: unless-stopped
mongodb:
image: mongo:4.4
container_name: graylog-mongodb
environment:
- MONGO_INITDB_ROOT_USERNAME=graylog
- MONGO_INITDB_ROOT_PASSWORD=graylog123
ports:
- "27017:27017"
volumes:
- mongodb_data:/data/db
networks:
- graylog
restart: unless-stopped
graylog:
image: graylog/graylog:4.3
container_name: graylog-server
environment:
# 基础配置
- GRAYLOG_HTTP_EXTERNAL_URI=http://localhost:9000/
- GRAYLOG_ELASTICSEARCH_HOSTS=http://elasticsearch:9200/
- GRAYLOG_MONGODB_URI=mongodb://graylog:graylog123@mongodb:27017/graylog
# 安全配置
- GRAYLOG_PASSWORD_SECRET=somepasswordpeppersomepasswordpeppersomepasswordpepper
- GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
# 时区和 API 配置
- GRAYLOG_ROOT_TIMEZONE=Asia/Shanghai
- GRAYLOG_WEB_ENDPOINT_URI=http://localhost:9000/api
# 性能优化
- GRAYLOG_PROCESSBUFFER_PROCESSORS=5
- GRAYLOG_OUTPUTBUFFER_PROCESSORS=3
- GRAYLOG_PROCESSOR_WAIT_STRATEGY=blocking
- GRAYLOG_RING_SIZE=65536
ports:
- "9000:9000" # Web 界面
- "12201:12201/udp" # GELF UDP
- "1514:1514/udp" # Syslog UDP
- "5555:5555/tcp" # Raw/Plaintext TCP
volumes:
- graylog_data:/usr/share/graylog/data
- graylog_journal:/usr/share/graylog/data/journal
networks:
- graylog
depends_on:
- elasticsearch
- mongodb
restart: unless-stopped
volumes:
es_data:
driver: local
es_logs:
driver: local
mongodb_data:
driver: local
graylog_data:
driver: local
graylog_journal:
driver: local
networks:
graylog:
driver: bridge
# 启动服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f graylog
5. 访问 GrayLog
访问地址: http://localhost:9000/
- 用户名:
admin - 密码:
admin

登录成功后看到欢迎页面:

核心组件配置
GrayLog 服务器配置
主要配置参数说明
| 参数 | 说明 | 示例值 |
|---|---|---|
GRAYLOG_HTTP_EXTERNAL_URI | 对外开放的 IP 和端口信息 | http://localhost:9000/ |
GRAYLOG_ELASTICSEARCH_HOSTS | Elasticsearch 地址 | http://elasticsearch:9200/ |
GRAYLOG_WEB_ENDPOINT_URI | 对外开放的 API 地址 | http://localhost:9000/api |
GRAYLOG_PASSWORD_SECRET | 密码加密的秘钥 | 至少 64 位字符串 |
GRAYLOG_ROOT_PASSWORD_SHA2 | 管理员密码的 SHA2 哈希 | SHA256 哈希值 |
GRAYLOG_ROOT_TIMEZONE | 容器内时区 | Asia/Shanghai |
GRAYLOG_MONGODB_URI | MongoDB 连接信息 | mongodb://user:pass@host:27017/db |
端口配置
| 端口 | 协议 | 用途 |
|---|---|---|
9000 | HTTP | Web 界面和 API |
12201 | UDP | GELF UDP 协议日志接收 |
1514 | UDP | Syslog UDP 协议 |
5555 | TCP | Raw/Plaintext TCP |
输入配置 (Inputs)
1. 配置 GELF UDP 输入
- 进入
System→Inputs

- 选择
GELF UDP并点击Launch new input

- 配置参数并保存

主要配置参数:
- Title: 输入描述名称
- Port: 监听端口(默认 12201)
- Bind address: 绑定地址(0.0.0.0 表示监听所有接口)
- Receive buffer size: 接收缓冲区大小
2. 其他输入类型配置
Syslog UDP:
Title: Syslog UDP Input
Port: 1514
Bind address: 0.0.0.0
Raw/Plaintext TCP:
Title: Raw TCP Input
Port: 5555
Bind address: 0.0.0.0
Beats:
Title: Beats Input
Port: 5044
TLS: 启用或禁用加密
日志保留策略
日志量大时如果不限制存储,磁盘很快会被占满,查询也会变慢。GrayLog 通过 Index Set 控制索引的滚动和清理:进入 System → Indices,点击 Default index set 的 Edit。


**滚动策略(Rotation)**决定什么时候切换到新索引,三选一:
| 策略 | 触发条件 | 默认值 |
|---|---|---|
| Index Message Count | 单个索引的日志条数达到上限 | 20,000,000 条 |
| Index Size | 单个索引的大小达到上限 | 1 GB |
| Index Time | 单个索引覆盖的时间达到上限 | 1 天(P1D) |
**保留策略(Retention)**决定保留多少个旧索引,超出后按设置删除、关闭或归档最旧的索引。默认保留 20 个索引并删除多余的,所以实际可保留的日志量约等于”滚动阈值 × 保留索引数”。

数据采集配置
Java 应用集成
1. 添加依赖
<dependency>
<groupId>biz.paluch.logging</groupId>
<artifactId>logstash-gelf</artifactId>
<version>1.15.0</version>
</dependency>
2. Logback 配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}.%method@%line - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 文件输出 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/application.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}.%method@%line - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- GrayLog GELF Appender -->
<appender name="GELF" class="biz.paluch.logging.gelf.logback.GelfLogbackAppender">
<!-- GrayLog 服务地址 -->
<host>udp:localhost</host>
<!-- GrayLog 服务端口 -->
<port>12201</port>
<version>1.1</version>
<!-- 当前服务名称 -->
<facility>my-application</facility>
<extractStackTrace>true</extractStackTrace>
<filterStackTrace>true</filterStackTrace>
<mdcProfiling>true</mdcProfiling>
<timestampPattern>yyyy-MM-dd HH:mm:ss,SSS</timestampPattern>
<maximumMessageSize>8192</maximumMessageSize>
<!-- 包含字段 -->
<includeFullMdc>true</includeFullMdc>
<!-- 静态字段 -->
<staticField>environment:production</staticField>
<staticField>service:user-service</staticField>
</appender>
<!-- 开发环境 -->
<springProfile name="dev">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="GELF"/>
</root>
</springProfile>
<!-- 生产环境 -->
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="GELF"/>
</root>
</springProfile>
</configuration>
3. Spring Boot 应用示例
@RestController
@Slf4j
public class UserController {
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
// 添加 MDC 上下文信息
MDC.put("userId", String.valueOf(id));
MDC.put("operation", "getUser");
try {
log.info("获取用户信息,用户ID: {}", id);
User user = userService.findById(id);
if (user == null) {
log.warn("用户不存在,用户ID: {}", id);
throw new UserNotFoundException("用户不存在");
}
log.info("成功获取用户信息: {}", user.getUsername());
return user;
} catch (Exception e) {
log.error("获取用户信息失败,用户ID: {}", id, e);
throw e;
} finally {
// 清理 MDC
MDC.clear();
}
}
}
Filebeat 集成
1. Filebeat 配置
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
fields:
service: nginx
environment: production
log_type: access
fields_under_root: true
- type: log
enabled: true
paths:
- /var/log/app/*.log
fields:
service: my-application
environment: production
log_type: application
multiline.pattern: '^\d{4}-\d{2}-\d{2}'
multiline.negate: true
multiline.match: after
# 输出到 GrayLog
output.logstash:
hosts: ["graylog:5044"]
# 或者直接输出到 GrayLog GELF
# output.gelf:
# hosts: ["graylog:12201"]
# 监控配置
monitoring.enabled: true
# 日志配置
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
Docker 容器日志采集
1. Docker 日志驱动配置
# 配置 Docker 使用 GELF 日志驱动
docker run -d \
--log-driver gelf \
--log-opt gelf-address=udp://localhost:12201 \
--log-opt tag="my-app" \
--log-opt gelf-compression-type=gzip \
--name my-application \
my-app:latest
2. Docker Compose 日志配置
version: '3.8'
services:
web:
image: nginx:latest
logging:
driver: gelf
options:
gelf-address: "udp://localhost:12201"
tag: "nginx"
gelf-compression-type: "gzip"
gelf-compression-level: "6"
labels: "service,environment"
labels:
service: "nginx"
environment: "production"
app:
image: my-app:latest
logging:
driver: gelf
options:
gelf-address: "udp://localhost:12201"
tag: "my-application"
gelf-compression-type: "gzip"
labels:
service: "my-application"
environment: "production"
搜索和分析
搜索语法
基础搜索
# 不指定字段,默认从 message 字段查询
error
# 输入两个关键字,关系为 OR
error exception
# 完整匹配(加引号)
"database connection failed"
# 指定字段查询
level:ERROR
source:nginx
service:user-service
# 数值范围查询
response_time_ms:>1000
http_status:[400 TO 599]
# 时间范围查询
timestamp:[2023-07-01 TO 2023-07-02]
高级搜索
# AND 操作
level:ERROR AND service:user-service
# OR 操作
level:(ERROR OR WARN)
service:(nginx OR apache)
# NOT 操作
NOT level:DEBUG
-source:test
# 通配符搜索
message:data*
source:web*server
# 正则表达式(需要启用)
message:/error|exception/i
# 字段存在性
_exists_:response_time
复合查询示例
# 查找特定服务的错误日志
service:user-service AND level:ERROR
# 查找响应时间超过 5 秒的请求
source:nginx AND response_time_ms:>5000
# 查找最近 1 小时的 HTTP 4xx 和 5xx 错误
timestamp:[now-1h TO now] AND http_status:[400 TO 599]
# 查找包含异常堆栈信息的日志
_exists_:full_message AND level:ERROR
# 查找特定用户的操作日志
user_id:12345 AND operation:(login OR logout)
消息详情分析

字段分析
标准字段:
timestamp: 日志时间戳message: 日志消息内容level: 日志级别(ERROR、WARN、INFO、DEBUG)source: 日志来源facility: 设施名称
自定义字段:
service: 服务名称environment: 环境标识user_id: 用户 IDrequest_id: 请求 IDresponse_time: 响应时间
字段操作
- 添加到搜索: 快速构建查询条件
- 显示统计: 查看字段值分布
- 创建图表: 基于字段创建可视化
- 设置告警: 基于字段值设置告警规则
可视化仪表盘
自定义展示字段

配置步骤:
- 在搜索结果页面,点击字段旁的配置图标
- 选择要显示的字段
- 调整字段显示顺序
- 保存配置
效果展示:

创建仪表盘
1. 创建新仪表盘

2. 配置仪表盘信息

基本信息:
- 标题: 仪表盘名称
- 描述: 仪表盘用途说明
- 共享设置: 设置访问权限
3. 添加小组件

小组件类型:
数值统计小组件
# 配置
标题: 错误日志统计
查询: level:ERROR
时间范围: 最近 24 小时
图表类型: 数字
趋势图小组件
# 配置
标题: 日志趋势
查询: *
时间范围: 最近 7 天
图表类型: 线图
间隔: 1 小时
饼图小组件
# 配置
标题: 日志级别分布
查询: *
字段: level
图表类型: 饼图
显示数量: 前 10 项
表格小组件
# 配置
标题: 服务错误统计
查询: level:ERROR
分组字段: service
排序: 计数降序
显示数量: 前 20 项
高级可视化配置
1. 堆叠面积图
# 配置多个查询
查询1: level:ERROR (红色)
查询2: level:WARN (橙色)
查询3: level:INFO (蓝色)
# 显示设置
堆叠模式: 启用
透明度: 70%
时间间隔: 5 分钟
2. 热力图
# 配置
查询: service:web AND response_time_ms:>0
X轴: 时间 (1小时间隔)
Y轴: 服务名称
颜色: 平均响应时间
3. 地理分布图
# 配置 (需要 IP 地址字段)
查询: _exists_:remote_addr
地理字段: remote_addr_geo
图层: 世界地图
聚合: 按国家统计
相关文章
监控与日志管理
- GrayLog SkyWalking 集成 - GrayLog 与 SkyWalking 联合部署
- SkyWalking 链路追踪 - APM 应用性能监控
- ELK Stack 分布式日志管理平台 - 完整的 ELK 技术栈对比
- ELK Stack 完整指南 - ELK Stack 分布式日志管理平台
容器化部署
- Docker 环境部署 - 容器化最佳实践
- Docker 容器引擎安装 - 容器环境搭建
- Docker 基本命令 - 容器操作指南
- Kubernetes 集群部署 - K8s 集群部署指南
数据库技术
- Elasticsearch 搜索引擎 - 搜索引擎技术详解
- MongoDB 文档数据库 - NoSQL 文档存储
- MySQL 关系型数据库 - 传统关系型数据库
- Redis 内存数据库 - 高性能缓存
中间件技术
- Kafka 消息队列 - 大数据日志管道
- RabbitMQ 消息队列 - 可靠消息传递
- Nacos 服务发现 - 微服务注册中心
总结
GrayLog 作为轻量级的分布式日志管理平台,为中小型企业和快速部署场景提供了优秀的日志分析解决方案:
🎯 核心优势
- 部署简单: 一体化解决方案,减少组件集成复杂度
- 使用便捷: 直观的 Web 界面和简单的搜索语法
- 性能优秀: 优化良好的资源使用和快速的搜索响应
- 扩展灵活: 支持集群部署和水平扩展
🛠️ 技术要点
- 快速部署: Docker 容器化部署,一键启动完整环境
- 数据采集: 多种输入方式,支持 GELF、Syslog、Beats 等
- 实时搜索: 强大的搜索功能和灵活的查询语法
- 可视化分析: 丰富的仪表盘和图表组件
- 告警监控: 实时告警和通知机制
🚀 应用场景
- 微服务监控: 分布式应用的日志集中管理
- 故障排查: 快速定位和分析系统问题
- 性能分析: 应用性能监控和瓶颈识别
- 安全审计: 安全日志分析和合规报告
📊 与 ELK 对比
| 特性 | GrayLog | ELK Stack |
|---|---|---|
| 学习难度 | 低 | 高 |
| 部署复杂度 | 简单 | 复杂 |
| 资源消耗 | 中等 | 较高 |
| 功能丰富度 | 中等 | 很高 |
| 社区生态 | 中等 | 丰富 |
💡 选择建议:
- 选择 GrayLog: 中小型团队、快速部署、简单易用
- 选择 ELK: 大型企业、复杂需求、深度定制