Elastic.Extensions.Logging编辑

用于 Microsoft.Extensions.Logging 的 Elastic 日志记录提供程序。

使用 Elastic 通用架构 (ECS) 直接写入 Elasticsearch,并从消息和范围值中进行结构化数据的语义日志记录。结果可以在 Kibana 控制台中查看和查询。

安装编辑

添加对 Elastic.Extensions.Logging 包的引用

<PackageReference Include="Elastic.Extensions.Logging" Version="8.6.0" />

用法编辑

然后,在主机构造期间使用提供的扩展方法将提供程序添加到 loggingBuilder。

using Elastic.Extensions.Logging;

// ...

    .ConfigureLogging((hostContext, loggingBuilder) =>
    {
        loggingBuilder.AddElasticsearch();
    })

默认配置将写入在 https://127.0.0.1:9200/ 上运行的本地 Elasticsearch。

发送一些日志事件后,打开 Kibana(例如 https://127.0.0.1:5601/),并为“dotnet-*”定义一个索引模式,并使用时间过滤器“@timestamp”。

然后,您可以发现索引的日志事件。要添加的一些有用列是 log.levellog.loggerevent.codemessagetagsprocess.thread.id

如果您在运行多个应用程序或在多个服务器上运行,您可能希望包含 service.typeservice.versionhost.hostname

其他字段定义如下,所有单独的消息和范围值都作为 labels.* 自定义键值对进行记录,例如 labels.CustomerId

基本配置编辑

为了部署,您通常需要使用实际的服务器位置覆盖配置。另一个有用的配置值是环境标签,例如开发/暂存/生产。

{
  "Logging": {
    "Elasticsearch": {
      "NodeUris": [ "https://elastic-staging.example.com:9200" ],
      "Tags": [ "Staging" ]
    }
  }
}

注意: 您不需要任何配置就可以使用本地 Elasticsearch 实例,因为它默认为 https://127.0.0.1:9200/

配置设置编辑

日志记录提供程序将自动使用别名为 Elasticsearch 的任何日志记录设置进行配置。

使用以下默认设置。

{
  "Logging": {
    "Elasticsearch": {
      "IncludeHost": true,
      "IncludeProcess": true,
      "IncludeScopes": true,
      "IncludeUser": true,
      "Index": "dotnet-{0:yyyy.MM.dd}",
      "IndexOffset": null,
      "IsEnabled": true,
      "ListSeparator": ", ",
      "MapCorrelationValues": true,
      "Tags": [],
      "ShipTo": {
        "NodePoolType": "SingleNode",
        "NodeUris": [ "https://127.0.0.1:9200" ]
      }
    }
  }
}
设置 类型 描述

IncludeHost

布尔值

默认 true;设置为 false 以禁用记录主机值。

IncludeProcess

布尔值

默认 true;设置为 false 以禁用记录进程值。

IncludeScopes

布尔值

默认 true;设置为 false 以禁用记录范围值。

IncludeUser

布尔值

默认 true;设置为 false 以禁用记录用户详细信息。

Index

格式

用于使用当前时间戳生成 Elasticsearch index 的格式字符串。默认值为 dotnet-{0:yyyy.MM.dd}

IndexOffset

时间跨度

覆盖以设置用于生成 index 的偏移量。默认值为 null,它使用系统本地偏移量;使用 "00:00&" 表示 UTC。

IsEnabled

布尔值

默认 true;设置为 false 以禁用日志记录器。

ListSeparator

字符串

用于 labels.* 值中的 IEnumerable 的分隔符。默认值为 ", "

Tags

数组

要包含在消息中的其他标签。用于指定环境或其他详细信息,例如 [ "Staging", "Priority"]

ShipTo 设置可以具有以下属性,具体取决于连接池的类型。

设置 类型 描述

ApiKey

字符串

API 密钥,其中连接池类型为云,并通过 API 密钥进行身份验证。

CloudId

字符串

云 ID,其中连接池类型为云。

NodePoolType

枚举

默认值为 Singlenode,或 Sniffing 表示多个节点,或 Cloud 表示提供了 CloudId。其他支持的值为 StaticSticky

NodeUris

数组

要连接到的 Elasticsearch 节点的 URI(s)。默认值为单个节点 [ "https://127.0.0.1:9200" ]

Password

字符串

密码,其中连接池类型为云,并通过用户名/密码进行身份验证。

Username

字符串

用户名,其中连接池类型为云,并通过用户名/密码进行身份验证。

如果要从其他部分进行配置,则可以手动配置

    .ConfigureLogging((hostContext, loggingBuilder) =>
    {
        loggingBuilder.AddElasticsearch(options =>
            hostContext.Configuration.Bind("Logging:CustomElasticsearch", options));
    })

当然,也可以在代码中进行配置,例如添加环境作为标签。

Elastic Cloud 配置编辑

如果提供了 CloudId,则 ConnectionPoolType 默认为 Cloud

{
  "Logging": {
    "Elasticsearch": {
      "ShipTo": {
        "CloudId": "12345",
        "ApiKey": "abcdef"
      }
    }
  }
}

输出 - Elastic 通用架构 (ECS)编辑

发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)

示例文档编辑

_source 字段是来自 LoggerProvider 的发送消息,以及 _index_id(GUID)。

{
  "_index": "dotnet-2020.04.12",
  "_type": "_doc",
  "_id": "563503a8-9d10-46ff-a09f-c6ccbf124db9",
  "_version": 1,
  "_score": null,
  "_source": {
    "MessageTemplate": "Unexpected error processing customer {CustomerId}.",
    "Scopes": [
      "IP address 2001:db8:85a3::8a2e:370:7334",
      "PlainScope"
    ],
    "agent": {
      "version": "1.0.0+bd3ad6",
      "type": "Elastic.Extensions.Logging.LoggerProvider"
    },
    "ecs": {
      "version": "1.5.0"
    },
    "error": {
      "message": "Calculation error",
      "type": "System.Exception",
      "stack_trace": "System.Exception: Calculation error\n ---> System.DivideByZeroException: Attempted to divide by zero.\n   at HelloElasticsearch.Worker.ExecuteAsync(CancellationToken stoppingToken) in /home/sly/Code/essential-logging/examples/HelloElasticsearch/Worker.cs:line 80\n   --- End of inner exception stack trace ---\n   at HelloElasticsearch.Worker.ExecuteAsync(CancellationToken stoppingToken) in /home/sly/Code/essential-logging/examples/HelloElasticsearch/Worker.cs:line 84"
    },
    "event": {
      "code": "5000",
      "action": "ErrorProcessingCustomer",
      "severity": 3
    },
    "host": {
      "os": {
        "platform": "Unix",
        "full": "Linux 4.15.0-91-generic #92-Ubuntu SMP Fri Feb 28 11:09:48 UTC 2020",
        "version": "4.15.0.91"
      },
      "hostname": "VUB1804",
      "architecture": "X64"
    },
    "log": {
      "level": "Error",
      "logger": "HelloElasticsearch.Worker"
    },
    "process": {
      "thread": {
        "id": 10
      },
      "pid": 25982,
      "name": "HelloElasticsearch"
    },
    "service": {
      "type": "HelloElasticsearch",
      "version": "1.0.0"
    },
    "user": {
      "id": "[email protected]",
      "name": "sly",
      "domain": "VUB1804"
    },
    "@timestamp": "2020-04-13T21:25:22.3352989+10:00",
    "tags": [
      "Development"
    ],
    "labels": {
      "ip": "2001:db8:85a3::8a2e:370:7334",
      "CustomerId": "12345"
    },
    "message": "Unexpected error processing customer 12345.",
    "trace": {
      "id": "c20bde1071f7cf4e9a6f368c824e05f7"
    },
    "transaction": {
      "id": "92ba5ee64d963746"
    }
  },
  "fields": {
    "@timestamp": [
      "2020-04-13T11:25:22.335Z"
    ]
  },
  "sort": [
    1586777122335
  ]
}

标准字段编辑

字段 类型 描述

@timestamp

日期

记录消息的 DateTimeOffset,包括本地偏移量。

message

字符串

格式化的日志消息和参数。

tags

数组

来自配置的自定义标签,例如 [ "Staging", "Priority" ]。可以有多个值。

event.action

字符串

记录的 EventId 的名称,例如 ErrorProcessingCustomer

event.code

字符串

EventId 的数值(作为字符串),例如 5000

event.severity

长整型

与日志级别相对应的 syslog 严重程度,2 = 严重错误、3 = 错误、4 = 警告、6 = 信息、7 = 调试和跟踪。(也用于 ConsoleLoggerProvider 的 Systemd 格式)

log.level

字符串

日志级别:CriticalErrorWarningInformationDebugTrace

log.logger

字符串

日志记录器的类别名称(命名空间和类),例如 HelloElasticsearch.Worker

event.severity 字段是数值,可用于按级别对事件进行排序,例如 Kibana 查询 event.severity &lt;= 4 将获取所有日志级别为 Warning 或更糟的消息。

错误字段编辑

如果日志消息包含异常,则异常详细信息将在错误字段中报告。

字段 类型 描述

error.message

字符串

任何异常的 Message 属性。

error.stack_trace

字符串

异常的完整详细信息,Exception.ToString(),包括堆栈跟踪以及任何内部异常的堆栈跟踪。

error.type

字符串

错误消息的类型,例如 System.DivideByZeroException

自定义字段编辑

遵循 ECS 约定,这些使用替代标题大小写来识别它们是非标准字段。

字段 类型 描述

MessageTemplate

字符串

原始消息模板,例如“处理客户 {CustomerId} 时出现意外错误”。

Scopes

数组

字符串格式范围值的数组,按添加顺序排列。

标签值编辑

字段 类型 描述

labels.*

字符串

所有命名参数值和命名范围值的自定义键值对。所有值都是字符串(没有嵌套对象)。

标签值可以通过其键访问,例如,如果消息或范围包含参数 CustomerId,则该值将作为 labels.CustomerId 记录,可以在 Kibana 中使用“labels.CustomerId: 12345”进行搜索。

示例

以下将生成两个标签,来自消息的 labels.EndTime 和来自范围的 labels.CustomerId

using (_logger.BeginScope("{CustomerId}", customerId))
{
  _logger.LogWarning("End of processing reached at {EndTime}.", end);
}

标签来自消息(状态)和任何范围值(可以通过配置选项禁用)。在 Microsoft.Extensions.Logging 中,内部 FormattedLogValues 用于 ILogger 的日志级别和范围重载;它实现了 IEnumerable&lt;KeyValuePair&lt;string,object&gt;&gt; 接口,该接口用于提取单个参数值。

ECS 中的 labels 属性不应包含嵌套对象,因此值将转换为关键字字符串。对于大多数对象,这仅仅是调用 ToString(),而某些类型则具有特定格式,例如,在列表上调用字符串通常没有用,因此会记录列表的内容。

标签值格式

类型 格式

字节

十六进制,例如“9A”

字节[]

带前缀的十六进制,例如“0x12789AF0”

DateTimeOffset

ISO 格式,例如“2020-01-02T03:04:05.000000+06:00”

DateTime

在大多数情况下,应使用 DateTimeOffset 代替(1)。如果 DateTime 用于仅日期(没有时间分量),则其格式为日期,例如“2020-01-02”。如果它包含时间分量,则使用往返(“o”)格式。

IEnumerable

用“,” 分隔的值(可配置)

IDictionary<string, object>

包含键值对的字符串,例如 token="0x12789AF0" count="5"

其他值

ToString() 的结果,包括标量值,例如,数字 5.3 记录为字符串“5.3”

(1) 请参阅 https://docs.microsoft.com/en-us/dotnet/standard/datetime/choosing-between-datetime

代理字段编辑

这些标识正在使用的日志记录提供程序的版本。

字段 类型 描述

agent.type

字符串

日志记录提供程序程序集的名称,Elastic.Extensions.Logging.LoggerProvider

agent.version

字符串

记录器程序集的信息版本号,例如 1.1.1+bd3ad63

ecs.version

字符串

使用的 ECS 标准版本,当前为 1.5

服务字段编辑

标识正在运行并生成日志的应用程序/服务。

这些值从入口程序集 Assembly.GetEntryAssembly() 中获取,使用 NameAssemblyInformationalVersionAttribute 值(如果信息版本未设置,则回退到程序集 Version)。

字段 类型 描述

service.type

字符串

入口程序集的名称,例如 HelloElasticsearch

service.version

字符串

入口程序集的信息版本号,例如 1.2.0-beta.1+79d095a

注意: 您应该使用在构建过程中正确设置程序集信息版本的构建流程。例如,如果您有一个使用 Git 的 .NET 项目,您可以安装本地工具 GitVersion.Tool,并使用它从 Git 分支信息中自动生成语义版本号。

要安装该工具,请执行以下操作

dotnet new tool-manifest
dotnet tool install GitVersion.Tool

然后使用该工具创建一个可以在构建流程中使用的语义版本号

dotnet tool restore
dotnet gitversion

欢迎使用此存储库中的 build.ps1 脚本作为示例。

跟踪字段编辑

字段 类型 描述

trace.id

字符串

跨服务跟踪关联标识符。来自 System.Diagnostics 中的 Activity.Current.RootId,并回退到 CorrelationManager.ActivityId。可以通过消息或作用域值 trace.id 覆盖。

transaction.id

字符串

此服务的交易,例如单个请求标识符。如果使用 W3C 格式,则从 System.Diagnostics 中的 Activity.Current.Id 解析 SpanId,否则仅使用完整的 Activity.Current.Id(例如,如果使用分层结构)。可以通过消息或作用域值 transaction.id 覆盖。

ASP.NET 将自动在层之间传递关联标识符;从 3.0 开始,它还支持 W3C 跟踪上下文标准 (https://www.w3.org/TR/trace-context/)。

Activity.Current.RootId 的值用作跨服务标识符(在 W3C 格式中,这是跟踪 ID),如果使用 W3C 格式,则使用 Activity.Current.Id 的 Span ID 部分作为交易,否则使用完整值(这与 ASP.NET 的工作方式一致)。

建议打开 W3C 格式,以与其他系统兼容

Activity.DefaultIdFormat = ActivityIdFormat.W3C;

主机字段编辑

可以通过配置禁用。

字段 类型 描述

host.architecture

字符串

处理器架构,例如 X64。 RuntimeInformation.OSArchitecture 的值。

host.hostname

字符串

计算机名称。 Environment.MachineName 的值。

host.os.full

字符串

操作系统完整描述。 RuntimeInformation.OSDescription 的值。

host.os.platform

字符串

操作系统平台。 Environment.OSVersion.Platform 的值。

host.os.version

字符串

操作系统版本。 Environment.OSVersion.Version 的值。

进程字段编辑

可以通过配置禁用。

字段 类型 描述

process.name

字符串

当前进程名称。来自 Process.GetCurrentProcess()

process.pid

长整型

当前进程 ID。来自 Process.GetCurrentProcess()

process.thread.id

长整型

当前线程 ID。 Thread.CurrentThread.ManagedThreadId 的值。

process.thread.name

字符串

线程名称。来自 Thread.CurrentThread.Name

用户字段编辑

可以通过配置禁用。

字段 类型 描述

user.domain

字符串

当前域,可以是机器名称或 Windows 域。 Environment.UserDomainName 的值。

user.id

字符串

当前用户主体名称(如果已设置)。 Thread.CurrentPrincipal.Identity.Name 的值。

user.name

字符串

当前用户。 Environment.UserName 的值。