全部笔记All notes

GrayLog 分布式日志

阅读 11m 46s11m 46s read

GrayLog 分布式日志管理平台完整指南

概述

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

GrayLog架构图

技术优势

GrayLog 相比 ELK Stack 的主要优势:

特性GrayLogELK 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/


环境准备

系统要求

组件最低配置推荐配置说明
CPU2 核心4 核心以上GrayLog 服务器计算密集
内存4GB8GB 以上Elasticsearch 需要较大内存
存储50GB100GB 以上 SSD日志数据存储需求大
网络100Mbps1Gbps大量日志数据传输

组件依赖

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工作流程

数据流向:

  1. 数据源 → GrayLog 输入 → 消息处理 → Elasticsearch 存储
  2. 用户 → 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欢迎页面


核心组件配置

GrayLog 服务器配置

主要配置参数说明
参数说明示例值
GRAYLOG_HTTP_EXTERNAL_URI对外开放的 IP 和端口信息http://localhost:9000/
GRAYLOG_ELASTICSEARCH_HOSTSElasticsearch 地址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_URIMongoDB 连接信息mongodb://user:pass@host:27017/db
端口配置
端口协议用途
9000HTTPWeb 界面和 API
12201UDPGELF UDP 协议日志接收
1514UDPSyslog UDP 协议
5555TCPRaw/Plaintext TCP

输入配置 (Inputs)

1. 配置 GELF UDP 输入
  1. 进入 System → Inputs

Inputs配置

  1. 选择 GELF UDP 并点击 Launch new input

GELF UDP配置

  1. 配置参数并保存

输入参数配置

主要配置参数:

  • 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。

image-20240109145002566

38fba6a5b77842928d69838c6e366c62

**滚动策略(Rotation)**决定什么时候切换到新索引,三选一:

策略触发条件默认值
Index Message Count单个索引的日志条数达到上限20,000,000 条
Index Size单个索引的大小达到上限1 GB
Index Time单个索引覆盖的时间达到上限1 天(P1D)

**保留策略(Retention)**决定保留多少个旧索引,超出后按设置删除、关闭或归档最旧的索引。默认保留 20 个索引并删除多余的,所以实际可保留的日志量约等于”滚动阈值 × 保留索引数”。

2c6218061870d65547522aebf22335e3

数据采集配置

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: 用户 ID
  • request_id: 请求 ID
  • response_time: 响应时间
字段操作
  1. 添加到搜索: 快速构建查询条件
  2. 显示统计: 查看字段值分布
  3. 创建图表: 基于字段创建可视化
  4. 设置告警: 基于字段值设置告警规则

可视化仪表盘

自定义展示字段

字段配置

配置步骤:

  1. 在搜索结果页面,点击字段旁的配置图标
  2. 选择要显示的字段
  3. 调整字段显示顺序
  4. 保存配置

效果展示:

自定义字段效果

创建仪表盘

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 作为轻量级的分布式日志管理平台,为中小型企业和快速部署场景提供了优秀的日志分析解决方案:

🎯 核心优势

  • 部署简单: 一体化解决方案,减少组件集成复杂度
  • 使用便捷: 直观的 Web 界面和简单的搜索语法
  • 性能优秀: 优化良好的资源使用和快速的搜索响应
  • 扩展灵活: 支持集群部署和水平扩展

🛠️ 技术要点

  1. 快速部署: Docker 容器化部署,一键启动完整环境
  2. 数据采集: 多种输入方式,支持 GELF、Syslog、Beats 等
  3. 实时搜索: 强大的搜索功能和灵活的查询语法
  4. 可视化分析: 丰富的仪表盘和图表组件
  5. 告警监控: 实时告警和通知机制

🚀 应用场景

  • 微服务监控: 分布式应用的日志集中管理
  • 故障排查: 快速定位和分析系统问题
  • 性能分析: 应用性能监控和瓶颈识别
  • 安全审计: 安全日志分析和合规报告

📊 与 ELK 对比

特性GrayLogELK Stack
学习难度低高
部署复杂度简单复杂
资源消耗中等较高
功能丰富度中等很高
社区生态中等丰富

💡 选择建议:

  • 选择 GrayLog: 中小型团队、快速部署、简单易用
  • 选择 ELK: 大型企业、复杂需求、深度定制