Posted in

Go图书管理系统日志体系搭建(Zap+Loki+Grafana):实现借阅行为毫秒级溯源与异常操作实时告警

第一章:Go图书管理系统日志体系设计全景概览

日志是图书管理系统可观测性的基石,它不仅承载错误追踪与审计需求,更支撑性能分析、用户行为回溯与系统健康评估。在Go语言生态中,日志体系需兼顾结构化、可扩展性与低侵入性,避免阻塞主线程或拖累高并发借阅请求处理。

核心设计原则

  • 结构化优先:统一采用JSON格式输出,字段包含timestamp、level、service、trace_id、span_id、operation(如book.search)、status_code及业务上下文(如isbn: "978-7-02-014567-8");
  • 分级采集策略:DEBUG日志仅在开发/测试环境启用;INFO记录关键业务流转(如“用户U123借阅《三体》成功”);WARN标记异常但可恢复场景(如缓存未命中);ERROR必须附带堆栈与上下文快照;
  • 异步非阻塞写入:通过zap.Logger搭配zapcore.NewCore与zapcore.Lock封装的os.File,结合zapcore.AddSync实现日志缓冲与批量刷盘。

日志采集与路由配置

使用uber-go/zap构建多输出通道:

// 初始化带分级路由的日志器
core := zapcore.NewCore(
  zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
  zapcore.NewMultiWriteSyncer(
    zapcore.AddSync(os.Stdout),                    // 控制台(仅DEBUG/INFO)
    zapcore.AddSync(zapcore.Lock(os.Stderr)),     // 文件(全级别,含ERROR)
  ),
  zap.InfoLevel, // 默认级别,由环境变量动态覆盖
)
logger := zap.New(core).Named("book-system")

关键日志场景示例

场景 触发条件 示例字段片段
图书借阅成功 HTTP 201响应 "operation":"borrow.create","user_id":"U789","book_isbn":"978-7-02-014567-8"
数据库连接超时 sql.Open返回timeout error "error":"dial tcp 10.0.1.5:5432: i/o timeout","component":"postgres"
JWT鉴权失败 token.Valid == false "auth_method":"bearer","reason":"expired_token"

日志生命周期涵盖生成、序列化、传输(本地文件+ELK集成)、归档(按日切割,保留30天)与告警联动(ERROR频次>5/min触发PagerDuty)。所有日志字段均遵循OpenTelemetry语义约定,确保与后续链路追踪系统无缝对齐。

第二章:Zap日志框架深度集成与高性能实践

2.1 Zap核心架构解析与零分配日志写入原理

Zap 的高性能源于其结构化日志抽象层 + 零堆分配编码器双引擎设计。核心由 Logger、Core 和 Encoder 三组件协同驱动,其中 Core 负责日志生命周期管理,Encoder(如 jsonEncoder)直接操作预分配 []byte 缓冲区,规避 fmt/reflect 引发的内存分配。

零分配写入关键路径

func (e *jsonEncoder) AddString(key, val string) {
    e.addKey(key)
    // 直接追加引号包裹的字符串,不触发 new(string) 或 append([]byte) 扩容(若缓冲区充足)
    e.strbuf = append(e.strbuf, '"')
    e.strbuf = append(e.strbuf, val...)
    e.strbuf = append(e.strbuf, '"')
}

逻辑分析:strbuf 是 Core 预分配的 []byte(默认 4KB),AddString 全部使用 append 原地扩展;仅当容量不足时才触发一次扩容——而非每次写入都分配新对象。

核心组件协作流程

graph TD
A[Logger.Info] --> B[Core.Check]
B --> C{Level Enabled?}
C -->|Yes| D[Encoder.EncodeEntry]
D --> E[WriteSyncer.Write]
组件 职责 分配行为
Logger API 门面,无状态 零分配
Core 日志路由与同步控制 一次性缓冲区分配
Encoder 字节级序列化 复用 strbuf

2.2 结构化日志建模:借阅行为事件Schema设计与上下文注入

借阅行为本质是跨系统、有时序依赖的领域事件,需在日志中固化业务语义而非仅记录操作痕迹。

Schema核心字段设计

  • event_id(UUIDv4):全局唯一事件标识
  • event_type:枚举值 BOOK_BORROWED / BOOK_RETURNED / RENEWAL_REQUESTED
  • context:嵌套对象,注入用户画像、馆藏元数据、终端设备等上下文

上下文注入策略

{
  "event_id": "a1b2c3d4-5678-90ef-ghij-klmnopqrstuv",
  "event_type": "BOOK_BORROWED",
  "timestamp": "2024-06-15T09:23:41.123Z",
  "context": {
    "user": { "id": "u789", "grade": "senior", "department": "CS" },
    "book": { "isbn": "978-0-306-40615-7", "shelf_id": "L3-042" },
    "device": { "type": "library_kiosk", "os": "Android 14" }
  }
}

该结构确保单条日志可独立完成用户行为归因、资源热度分析与异常终端识别。context 非扁平化设计,保留语义层级,避免字段爆炸。

字段语义对照表

字段 类型 说明 是否必需
event_type string 业务动作类型,驱动下游路由 ✅
context.user.id string 关联统一身份中心 ✅
context.book.isbn string 支持图书粒度统计 ✅
graph TD
  A[借阅请求] --> B{校验权限}
  B -->|通过| C[生成事件]
  B -->|拒绝| D[记录审计事件]
  C --> E[注入实时上下文]
  E --> F[序列化为JSON Schema]

2.3 日志分级策略与采样机制:毫秒级溯源所需的TraceID/RequestID透传实现

日志分级设计原则

  • DEBUG:仅限开发环境,记录变量快照与分支路径;
  • INFO:关键业务节点(如订单创建、支付回调),需含trace_id与request_id;
  • WARN/ERROR:自动附加堆栈+上游调用链上下文。

TraceID透传核心代码

// Spring Boot Filter 中统一注入 TraceID
public class TraceIdFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
        HttpServletRequest request = (HttpServletRequest) req;
        String traceId = Optional.ofNullable(request.getHeader("X-Trace-ID"))
                .orElse(UUID.randomUUID().toString().replace("-", ""));
        MDC.put("trace_id", traceId); // SLF4J Mapped Diagnostic Context
        chain.doFilter(req, res);
        MDC.clear(); // 防止线程复用污染
    }
}

逻辑分析:通过MDC将trace_id绑定至当前线程日志上下文,确保同一请求链路中所有日志自动携带该标识;replace("-", "")保证TraceID为32位纯数字/字母串,适配ELK分词与OpenTelemetry规范。

采样策略对比

策略 适用场景 采样率 风险点
全量采样 核心支付链路 100% 存储成本激增
动态采样 高QPS查询接口 0.1%~5% 可能漏掉偶发异常
错误强制采样 ERROR/WARN日志 100% 保障故障可追溯性

跨服务透传流程

graph TD
    A[Client] -->|X-Trace-ID: abc123| B[API Gateway]
    B -->|MDC + Feign Interceptor| C[Order Service]
    C -->|Ribbon + Header Propagation| D[Inventory Service]
    D -->|Async Log Appender| E[Logstash → ES]

2.4 异步日志缓冲与磁盘落盘优化:高并发借阅场景下的吞吐保障

在每秒超3000次借阅请求的峰值下,同步写日志成为I/O瓶颈。我们采用双缓冲环形队列 + 批量刷盘策略,解耦业务线程与磁盘I/O。

数据同步机制

  • 借阅事件由业务线程写入内存环形缓冲区(大小8MB,无锁CAS更新)
  • 独立日志刷盘线程以200ms间隔或缓冲区达75%阈值触发批量落盘
// RingBufferLogAppender.java(简化版)
public void append(LogEvent event) {
    long seq = ringBuffer.next(); // 无锁获取槽位
    LogEntry entry = ringBuffer.get(seq);
    entry.copyFrom(event);         // 零拷贝序列化
    ringBuffer.publish(seq);       // 发布可见性
}

ringBuffer.next()避免锁竞争;publish()确保JVM内存屏障生效;copyFrom()规避GC压力。

性能对比(TPS & 延迟)

策略 平均延迟 吞吐量(TPS) 99分位延迟
同步文件写入 12.4ms 860 48ms
异步缓冲+批量刷盘 1.7ms 3250 8.3ms
graph TD
    A[借阅请求] --> B[业务线程写RingBuffer]
    B --> C{缓冲区≥75% 或 定时触发?}
    C -->|是| D[刷盘线程批量write+fsync]
    C -->|否| E[继续积累]
    D --> F[OS Page Cache]
    F --> G[磁盘物理落盘]

2.5 Zap与Go HTTP中间件协同:自动捕获请求生命周期与异常堆栈

Zap 日志库与 Go 标准 http.Handler 中间件天然契合,通过装饰器模式无缝注入结构化日志能力。

请求生命周期钩子

在中间件中嵌入 zap.Logger 实例,于 ServeHTTP 前后记录时间戳、状态码、路径及延迟:

func LoggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        l := logger.With(
            zap.String("path", r.URL.Path),
            zap.String("method", r.Method),
            zap.String("remote_ip", getRemoteIP(r)),
        )
        l.Info("request_started")
        // 包装 ResponseWriter 以捕获状态码
        rw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
        next.ServeHTTP(rw, r)
        l.Info("request_finished",
            zap.Int("status_code", rw.statusCode),
            zap.Duration("duration_ms", time.Since(start).Milliseconds()),
        )
    })
}

逻辑分析:该中间件利用 zap.Logger.With() 预绑定请求上下文字段,避免重复序列化;responseWriter 包装器劫持 WriteHeader() 调用以准确捕获最终状态码。time.Since(start).Milliseconds() 确保毫秒级精度且类型安全。

异常堆栈自动注入

当 handler panic 时,借助 recover() 捕获并写入带完整调用栈的 error 字段:

字段名 类型 说明
error string panic 错误消息
stacktrace string debug.Stack() 输出
request_id string 关联 trace 的唯一标识
graph TD
    A[HTTP Request] --> B[LoggingMiddleware]
    B --> C{Handler Panic?}
    C -->|Yes| D[recover → zap.Error()]
    C -->|No| E[Normal Response]
    D --> F[Log with stacktrace]

第三章:Loki日志后端对接与高效率索引实践

3.1 Loki轻量级架构对比分析与Prometheus生态协同原理

Loki摒弃指标存储,专注日志的标签化索引与压缩存储,与Prometheus形成“指标+日志”双维可观测闭环。

架构核心差异

  • Prometheus:拉取式、时序数据库、高内存开销
  • Loki:推式(如Promtail)、无索引日志流、基于标签哈希分片

数据同步机制

Prometheus通过serviceMonitor暴露元数据,Promtail利用relabel_configs复用相同标签体系:

# promtail-config.yaml 片段:对齐Prometheus标签语义
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
  target_label: app
- source_labels: [__meta_kubernetes_namespace]
  target_label: namespace

→ 实现app="api-gateway"在Prometheus指标与Loki日志中语义一致,支撑Grafana中Explore → Logs一键下钻。

协同拓扑示意

graph TD
  A[Prometheus] -->|metrics with labels| B[Grafana]
  C[Promtail] -->|structured logs, same labels| B
  B --> D[Unified Query: label-based log-metric correlation]
维度 Prometheus Loki
存储粒度 每个样本独立 日志流按Stream压缩
查询延迟 毫秒级(内存) 秒级(对象存储)
标签作用 时间序列标识 日志流唯一键

3.2 Go客户端直连Loki:HTTP API封装与Label维度动态构造(tenant_id、book_id、user_id)

核心封装结构

使用 net/http 构建轻量级客户端,避免引入 heavy SDK,通过 url.Values 动态拼接 label 查询参数。

func buildLokiURL(base string, labels map[string]string) string {
    q := url.Values{}
    for k, v := range labels {
        q.Add("match[]", fmt.Sprintf(`{%s="%s"}`, k, v))
    }
    return fmt.Sprintf("%s/loki/api/v1/query_range?%s", base, q.Encode())
}

逻辑说明:match[] 是 Loki 查询 API 的标准参数;tenant_id、book_id、user_id 作为 label 键动态注入,支持多租户隔离与细粒度日志筛选。fmt.Sprintf 确保 label 值安全转义(生产中需进一步 URL 编码)。

Label 组合策略

  • 单维度查询:仅 tenant_id → 全租户概览
  • 双维度组合:tenant_id + book_id → 某租户某电子书全用户行为
  • 三维度全量:tenant_id + book_id + user_id → 个体阅读轨迹追踪
维度组合 查询延迟 存储扫描量 适用场景
tenant_id 高 运维大盘监控
tenant_id+book_id ~300ms 中 内容质量分析
全维度 ~800ms 低 用户行为回溯与调试

请求流式处理

graph TD
    A[Go App] --> B[buildLokiURL]
    B --> C[http.NewRequest]
    C --> D[Do with timeout]
    D --> E[Parse JSON response]
    E --> F[Extract streams & logLines]

3.3 日志流标签策略与查询性能调优:基于借阅行为特征的高效Label设计

在图书借阅系统中,日志流需支撑毫秒级“高频借还+长尾检索”双模查询。直接为每条日志打 user_id、book_isbn 等高基数标签会导致索引膨胀与查询抖动。

标签分层设计原则

  • 静态维度(低基数):library_branch=shanghai_pudong、device_type=mobile
  • 动态行为标识(中低基数):borrow_intent=urgent(基于借阅频次+时间窗口聚合生成)
  • 规避高基数字段:user_id 不直标,改用 user_hash_8=abc123de(MD5前8位哈希)

示例:借阅意图标签生成逻辑

# 基于用户最近1h内借阅次数 + 平均间隔 < 5min → 标记为 urgent
def derive_borrow_intent(event):
    recent_count = redis.zcount(f"u:{event.user_id}:borrow_ts", 
                                time.time() - 3600, "+inf")
    if recent_count >= 3:
        intervals = redis.lrange(f"u:{event.user_id}:intervals", 0, 2)
        avg_gap = sum(map(float, intervals)) / len(intervals) if intervals else 999
        return "urgent" if avg_gap < 300 else "normal"
    return "normal"

该函数输出 borrow_intent 标签,避免实时计算,预置为Loki/Tempo兼容的Label键值对;redis.zcount 提供O(log N)时间复杂度,保障吞吐。

查询性能对比(相同数据量下P95延迟)

Label策略 查询语句示例 P95延迟 索引内存占用
全字段直标 {user_id="U12345", book_isbn="978..."} 1280ms 4.2GB
分层标签 {branch="shanghai_pudong", borrow_intent="urgent"} 86ms 310MB
graph TD
    A[原始日志] --> B[实时解析]
    B --> C{是否满足<br>高频借阅模式?}
    C -->|是| D[borrow_intent=urgent]
    C -->|否| E[borrow_intent=normal]
    D & E --> F[写入Loki:<br>branch, device_type, borrow_intent]

第四章:Grafana可视化告警闭环体系建设

4.1 借阅行为时序图谱构建:毫秒级响应延迟、高频借阅热力图与用户轨迹回放

数据同步机制

采用 Flink CDC 实时捕获 MySQL binlog,经 Kafka 消息队列缓冲后写入 Apache Doris OLAP 数据库,保障端到端延迟

-- Doris 建表语句(支持高并发点查+时序聚合)
CREATE TABLE IF NOT EXISTS borrow_timeline (
  user_id BIGINT COMMENT "用户唯一标识",
  book_id BIGINT COMMENT "图书ID",
  borrow_ts DATETIME(3) COMMENT "毫秒级借阅时间戳",
  loc_code VARCHAR(16) COMMENT "借阅终端编码",
  INDEX idx_user_time (user_id, borrow_ts) USING BITMAP,
  INDEX idx_time_book (borrow_ts, book_id) USING SKIPLIST
) ENGINE=OLAP DISTRIBUTED BY HASH(user_id) BUCKETS 32;

该建表设计通过 DATETIME(3) 精确到毫秒,双维度索引兼顾用户轨迹回放(按 user_id + time 排序扫描)与热力图聚合(按 time + book_id 快速分桶统计)。

实时热力图生成流程

graph TD
  A[Binlog捕获] --> B[Kafka分区按user_id哈希]
  B --> C[Flink窗口聚合:5s滑动/1min滚动]
  C --> D[Doris UPSERT更新热力格网]
  D --> E[前端Canvas实时渲染]

关键性能指标对比

维度 传统批处理 本方案(Flink+Doris)
查询延迟 2–5s ≤120ms(P95)
热力图刷新频率 5分钟 5秒
轨迹回放支持 静态日志 可交互式时间轴拖拽

4.2 异常操作实时检测规则引擎:基于LogQL的未授权访问、批量删书、超限借阅模式识别

核心检测逻辑设计

采用 Loki + Promtail 架构,通过 LogQL 实时匹配日志行为特征。关键规则聚焦三类高危操作:

  • 未授权访问:{job="library-api"} |~ "401|403" | json | status_code == "401" and user_id == "null"
  • 批量删书:{job="book-service"} | json | method == "DELETE" and path =~ "/books/\\d+" | __error__ = "" | count_over_time([5m]) > 50
  • 超限借阅:{job="borrow-service"} | json | event == "BORROW_SUCCESS" | line_format "{{.user_id}} {{.book_id}}" | count by (user_id) > 10

规则参数说明

{job="borrow-service"} 
| json 
| event == "BORROW_SUCCESS" 
| __error__ = "" 
| count_over_time([1h]) by (user_id) > 10
  • json:自动解析 JSON 日志结构;
  • event == "BORROW_SUCCESS":过滤有效借阅事件;
  • count_over_time([1h]):滑动窗口统计频次;
  • > 10:业务定义的单小时借阅阈值。

检测结果联动流程

graph TD
A[原始日志] --> B[Promtail 过滤与标签增强]
B --> C[Loki 存储 + LogQL 查询]
C --> D[告警触发器匹配]
D --> E[推送至 Slack + 生成工单]
行为类型 触发阈值 响应动作
未授权访问 ≥3次/5min 阻断IP + 审计日志归档
批量删书 ≥20次/1min 立即暂停账号 + 人工复核
超限借阅 ≥10次/1h 临时限权 + 发送提醒邮件

4.3 告警通道集成与SLO保障:企业微信/Webhook联动与MTTR指标看板

企业微信告警推送配置

通过 Webhook 实现低延迟告警分发,需在企业微信后台创建自定义机器人并获取 webhook_url:

curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "msgtype": "markdown",
    "markdown": {
      "content": "⚠️ SLO <font color=\"warning\">降级</font>\n> 服务:api-order\n> 当前错误率:12.7% (阈值:5%)\n> 影响时段:2024-06-15 14:22–14:35"
    }
  }'

该脚本触发企业微信 Markdown 消息,color="warning" 支持富文本高亮;msgtype 决定渲染样式,content 中换行与 > 符号适配企业微信 Markdown 解析规则。

MTTR 看板核心指标维度

维度 字段名 说明
告警发现时长 alert_fire_ms Prometheus AlertManager 触发时间戳差值
响应确认时长 ack_time_ms 运维人员首次点击告警链接时间
故障修复时长 resolve_ms 服务指标回归 SLO 阈值内的时间点

告警闭环流程

graph TD
  A[Prometheus 报警] --> B[AlertManager 聚合]
  B --> C{SLO 违规检测}
  C -->|是| D[调用 Webhook 推送企业微信]
  C -->|否| E[静默丢弃]
  D --> F[运维响应 & 标记 ACK]
  F --> G[自动采集 MTTR 各阶段时间]
  G --> H[更新 Grafana MTTR 看板]

4.4 日志-指标-链路三元融合:Zap日志与Prometheus指标、OpenTelemetry追踪数据关联查询

实现可观测性闭环的关键在于打通日志、指标与链路的语义关联。Zap 通过 With(zap.String("trace_id", span.SpanContext().TraceID().String())) 注入 OpenTelemetry TraceID,使每条结构化日志携带上下文锚点。

关联查询核心机制

  • 日志:Zap 输出 trace_id、span_id 字段(JSON 格式)
  • 指标:Prometheus 采集时通过 otel_collector 添加 trace_id 标签(需启用 resource_attributes 导出器)
  • 链路:OTLP exporter 上报 span 数据,含完整 trace context

示例:Zap 日志注入 trace_id

span := otel.Tracer("example").Start(ctx, "http_handler")
logger := zap.L().With(
    zap.String("trace_id", span.SpanContext().TraceID().String()),
    zap.String("span_id", span.SpanContext().SpanID().String()),
)
logger.Info("request processed", zap.String("path", "/api/v1/users"))

逻辑说明:TraceID().String() 返回 32 位十六进制字符串(如 4a7d5e8b1c2f3a4b5c6d7e8f9a0b1c2d),确保与 OTel backend 和 Prometheus label 兼容;zap.String 保证字段可被 Loki/Promtail 正确提取为 log labels。

三元数据关联表

数据类型 关键关联字段 查询工具示例
日志 trace_id, span_id Grafana + Loki
指标 trace_id label Prometheus + MetricsQL
链路 trace_id (root) Jaeger / Tempo
graph TD
    A[Zap Logger] -->|inject trace_id/span_id| B[Structured Log]
    C[OTel SDK] -->|export spans| D[OTLP Collector]
    D --> E[Tempo/Jaeger]
    B -->|forward via Promtail| F[Loki]
    D -->|metrics with trace_id| G[Prometheus]

第五章:生产环境落地挑战与演进路线

真实场景下的配置漂移问题

某金融客户在Kubernetes集群中部署微服务时,发现CI/CD流水线生成的镜像SHA256哈希值与生产环境实际运行容器不一致。根因排查显示:运维人员手动执行kubectl set image覆盖了GitOps声明式配置,且未同步至Argo CD应用仓库。该漂移持续72小时未被检测,直至支付网关出现超时抖动才触发告警。我们通过注入admission webhook拦截非声明式变更,并在Prometheus中新增指标k8s_config_drift_seconds{namespace="prod",app="payment-gateway"}实现秒级感知。

多租户隔离失效的连锁反应

在混合云架构下,三个业务线共享同一套Istio控制平面,但未启用命名空间级PeerAuthentication策略。某次安全扫描发现default命名空间中存在明文传输的数据库连接请求,溯源发现其流量被错误路由至其他租户的mTLS出口网关。修复方案包括:

  • 为每个租户创建独立PeerAuthentication资源
  • 在DestinationRule中强制tls.mode: ISTIO_MUTUAL
  • 通过istioctl analyze --use-kubeconfig每日巡检

性能压测暴露的限流盲区

电商大促前压测显示订单服务P99延迟突增至3.2s(SLA要求≤800ms)。链路追踪定位到Redis连接池耗尽,但redis.clients.jedis.JedisPoolConfig.maxTotal=200已在代码中硬编码。解决方案采用动态配置中心(Apollo)下发参数,并构建以下熔断规则:

组件 触发条件 动作 恢复机制
Redis客户端 连接等待超时率>5%持续60s 切换降级缓存 每30s探测一次健康状态
订单API QPS>1200且错误率>3% 返回HTTP 429 指数退避重试

渐进式灰度发布失败案例

某银行核心系统升级v2.3时,采用基于Header的Canary发布,但Nginx Ingress控制器未正确传递X-Canary头。经抓包确认:上游Envoy代理将自定义Header过滤,需在VirtualService中显式配置headers: request: set: {X-Canary: "true"}。后续建立自动化检查清单:

# 验证Header透传能力
curl -H "X-Canary:true" https://api.bank.com/order | jq '.version'
# 检查Ingress配置合规性
kubectl get ingress -o json | jq '.items[].spec.rules[].http.paths[].backend.serviceName' | grep -q "order-canary"

监控数据采样率陷阱

生产环境启用OpenTelemetry Collector后,发现APM链路丢失率达42%。分析发现otelcol-contrib默认采样策略为probabilistic且sampling_rate=0.001,导致高QPS接口链路被大量丢弃。调整为rate_limiting策略并设置span_per_second=1000,同时在关键业务路径注入SpanContext手动标记:

graph LR
A[用户下单请求] --> B{是否命中风控规则}
B -->|是| C[强制全量采样 span.set_attribute\\(\"critical_path\", \"true\"\\)]
B -->|否| D[使用默认采样率]
C --> E[写入Jaeger后端]
D --> E

安全合规审计缺口

等保2.0三级要求日志留存180天,但Elasticsearch集群仅配置30天自动清理。通过编写Logstash pipeline脚本实现冷热分离:

if [log_type] == "audit" {
  elasticsearch {
    hosts => ["https://es-hot:9200"]
    index => "audit-%{+YYYY.MM.dd}"
  }
  if [timestamp] < "now-120d" {
    elasticsearch {
      hosts => ["https://es-cold:9200"]
      index => "audit-archive-%{+YYYY.MM}"
    }
  }
}

专攻高并发场景,挑战百万连接与低延迟极限。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注