手动日志关联编辑

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

手动日志关联(结构化)编辑

为了将结构化日志与跟踪关联,应将以下字段添加到您的日志中

  • trace.id
  • transaction.id

给定一个事务对象,您可以使用 Transaction.TraceId 属性获取其跟踪 ID,并使用 Transaction.Id 属性获取其事务 ID。

您还可以使用 Elastic.Apm.Agent.Tracer.CurrentTransaction 属性在代码中的任何位置访问当前活动事务。

public (string traceId, string transactionId) GetTraceIds()
{
	if (!Agent.IsConfigured) return default;
	if (Agent.Tracer.CurrentTransaction == null) return default;
	return (Agent.Tracer.CurrentTransaction.TraceId, Agent.Tracer.CurrentTransaction.Id);
}

如果代理已配置并且存在活动事务,则 traceIdtransactionId 将始终返回当前跟踪和事务 ID,您可以手动将其添加到日志中。确保在将它们发送到 Elasticsearch 时将它们存储在 trace.idtransaction.id 字段中。

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

为了将非结构化日志(例如,基本的 printf 样式日志记录,如 Console.WriteLine)与跟踪关联,您需要在日志消息中包含跟踪 ID,然后使用 Filebeat 提取它们。

如果您已经拥有事务对象,那么您可以使用 TraceIdId 属性。两者都是 string 类型,因此您可以简单地将它们添加到日志中。

var currentTransaction = //Get Current transaction, e.g.: Agent.Tracer.CurrentTransaction;

Console.WriteLine($"ERROR [trace.id={currentTransaction.TraceId} transaction.id={currentTransaction.Id}] an error occurred");

这将打印类似于以下内容的日志消息

    ERROR [trace.id=cd04f33b9c0c35ae8abe77e799f126b7 transaction.id=cd04f33b9c0c35ae] an error occurred

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

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