日志关联

编辑

日志关联允许您导航到属于特定跟踪的所有日志,反之亦然:对于特定日志,查看其记录的上下文以及用户提供的参数。

为了将您的应用程序中的日志与 Elastic APM Go Agent 捕获的事务相关联,您的日志必须包含以下一个或多个标识符:

为了将日志与服务和环境相关联,日志还应包含以下字段:

手动日志关联

编辑

如果代理提供的日志集成不适合或您的应用程序不可用,那么您可以使用代理的API手动注入跟踪 ID。您可以采取两种主要方法,具体取决于您使用的是结构化日志还是非结构化日志。

手动日志关联(结构化)

编辑

为了将结构化日志与跟踪和服务关联,应将上述定义的字段添加到日志中。

给定一个事务对象,您可以使用apm.Transaction.TraceContext方法获取其跟踪 ID 和事务 ID。类似地,给定一个 span 对象,您可以使用apm.Span.TraceContext获取其 span ID。

如果您使用上下文 API 来启动事务和 span,那么您可以使用apm.TransactionFromContext获取上下文的当前事务,并使用apm.SpanFromContext获取当前 span。请注意,如果未对事务进行采样,则apm.TransactionFromContext将返回nil。类似地,span 可能会被代理丢弃,因此apm.SpanFromContext也可能返回nil

labels := make(map[string]string)
tx := apm.TransactionFromContext(ctx)
if tx != nil {
	traceContext := tx.TraceContext()
	labels["trace.id"] = traceContext.Trace.String()
	labels["transaction.id"] = traceContext.Span.String()
	if span := apm.SpanFromContext(ctx); span != nil {
		labels["span.id"] = span.TraceContext().Span
	}
}

请按照本文使用 Filebeat 提取 JSON 编码的日志:如何使用 Elastic APM Go 代理检测您的 Go 应用程序

手动日志关联(非结构化)

编辑

为了关联非结构化日志(例如,基本 printf 样式日志,如标准库的log包),您需要在日志消息中包含跟踪 ID。然后,使用 Filebeat 提取它们。

如果您已经有一个事务或 span 对象,请使用Transaction.TraceContextSpan.TraceContext方法。跟踪、事务和 span ID 类型都提供了String方法,这些方法会生成其规范的十六进制编码字符串表示形式。

traceContext := tx.TraceContext()
spanID := span.TraceContext().Span
log.Printf("ERROR [trace.id=%s transaction.id=%s span.id=%s] an error occurred", traceContext.Trace, traceContext.Span, spanID)

如果您处理的是上下文对象,您可能更喜欢使用TraceFormatter函数。例如,您可以将其作为参数提供给log.Printf,如下所示:

log.Printf("ERROR [%+v] an error occurred", apm.TraceFormatter(ctx))

这将打印类似如下的日志消息:

2019/09/17 14:48:02 ERROR [trace.id=cd04f33b9c0c35ae8abe77e799f126b7 transaction.id=cd04f33b9c0c35ae span.id=960834f4538880a4] an error occurred

为了使日志关联工作,必须从日志消息中提取跟踪 ID 并将其存储在 Elasticsearch 文档中的单独字段中。这可以通过使用摄取管道来解析数据来实现,特别是通过使用grok 处理器来实现。

{
  "description": "...",
  "processors": [
    {
      "grok": {
        "field": "message",
        "patterns": ["%{YEAR}/%{MONTHNUM}/%{MONTHDAY} %{TIME} %{LOGLEVEL:log.level} \\[trace.id=%{TRACE_ID:trace.id}(?: transaction.id=%{SPAN_ID:transaction.id})?(?: span.id=%{SPAN_ID:span.id})?\\] %{GREEDYDATA:message}"],
        "pattern_definitions": {
          "TRACE_ID": "[0-9A-Fa-f]{32}",
          "SPAN_ID": "[0-9A-Fa-f]{16}"
        }
      }
    }
  ]
}