Elastic.Extensions.Logging
编辑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.level
、log.logger
、event.code
、message
、tags
和 process.thread.id
。
如果您正在运行多个应用程序或在多个服务器上运行,您可能需要包含 service.type
、service.version
和 host.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 |
布尔值 |
默认值为 |
IncludeProcess |
布尔值 |
布尔值 |
默认值为 |
布尔值 |
IncludeScopes |
布尔值 |
布尔值 |
默认值为 |
IncludeUser |
布尔值 |
默认值为 |
Index |
格式 |
用于使用当前时间戳生成 Elasticsearch |
IndexOffset |
布尔值 |
时间跨度 |
覆盖以设置用于生成 |
IsEnabled |
布尔值 |
默认值为 |
ListSeparator |
字符串 |
用于 IEnumerable
中 labels.*
值的分隔符。默认为 ", "
。
设置 | 类型 | 描述 |
---|---|---|
Tags |
IsEnabled |
数组 |
要包含在消息中的其他标签。用于指定环境或其他详细信息,例如 |
IsEnabled |
ShipTo 设置可以具有以下属性,具体取决于连接池的类型。 |
ApiKey |
API 密钥,其中连接池类型为云,并通过 API 密钥进行身份验证。 |
CloudId |
云 ID,其中连接池类型为云。 |
ListSeparator |
NodePoolType |
枚举 |
IsEnabled |
默认为 |
NodeUris |
IsEnabled |
要连接到的 Elasticsearch 节点的 URI。默认为单个节点 |
Password
.ConfigureLogging((hostContext, loggingBuilder) => { loggingBuilder.AddElasticsearch(options => hostContext.Configuration.Bind("Logging:CustomElasticsearch", options)); })
密码,其中连接池类型为云,并通过用户名/密码进行身份验证。
Username
编辑用户名,其中连接池类型为云,并通过用户名/密码进行身份验证。
{ "Logging": { "Elasticsearch": { "ShipTo": { "CloudId": "12345", "ApiKey": "abcdef" } } } }
如果要从其他部分配置,则可以手动配置
编辑当然,也可以在代码中进行配置,例如将环境添加为标签。
Elastic Cloud 配置
编辑如果提供了 CloudId
,则 ConnectionPoolType
默认为 Cloud
{ "_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 ] }
输出 - Elastic 通用架构 (ECS)
编辑发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
该 |
||
字段 |
IsEnabled |
@timestamp |
日期 |
ListSeparator |
记录消息的 |
message |
IsEnabled |
格式化的日志消息和参数。 |
tags |
IsEnabled |
来自配置的自定义标签,例如 |
event.action |
已记录的 EventId 的名称,例如 |
event.code |
EventId 的数字值(作为字符串),例如 |
IsEnabled |
event.severity |
长整型 |
IsEnabled |
与日志级别对应的 syslog 严重性,2 = 严重,3 = 错误,4 = 警告,6 = 信息,7 = 调试和跟踪。(也用于 ConsoleLoggerProvider 的 Systemd 格式) |
log.level
日志级别:Critical
、Error
、Warning
、Information
、Debug
或 Trace
。
编辑log.logger
发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
日志记录器的类别名称(命名空间和类),例如 |
IsEnabled |
该 |
IsEnabled |
如果日志消息包含异常,则异常详细信息将在错误字段中报告。 |
|
error.message |
IsEnabled |
任何异常的 |
error.stack_trace
编辑异常的完整详细信息,Exception.ToString()
,包括堆栈跟踪和任何内部异常的堆栈跟踪。
发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
error.type |
IsEnabled |
错误消息的类型,例如 |
ListSeparator |
遵循 ECS 约定,这些使用替代标题大小写来识别它们是非标准字段。 |
MessageTemplate
编辑发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
原始消息模板,例如“处理客户 {CustomerId} 时发生意外错误”。 |
IsEnabled |
Scopes |
按添加顺序排列的字符串格式范围值的数组。
labels.*
using (_logger.BeginScope("{CustomerId}", customerId)) { _logger.LogWarning("End of processing reached at {EndTime}.", end); }
所有命名参数值和命名范围值的自定义键/值对。所有值都是字符串(没有嵌套对象)。
可以通过其键访问标签值,例如,如果消息或范围包含参数 CustomerId,则该值将记录为 labels.CustomerId
,可以使用“labels.CustomerId: 12345”在 Kibana 中搜索。
示例
类型 | 以下将生成两个标签,来自消息的 labels.EndTime 和来自范围的 labels.CustomerId |
---|---|
标签取自消息(状态)和任何范围值(可以通过配置选项禁用)。在 Microsoft.Extensions.Logging 中,内部 FormattedLogValues 用于 ILogger 中的日志级别和范围的重载;它实现了 |
ECS 中的 |
标签值格式 |
格式 |
字节 |
十六进制,例如“9A” |
字节数组 |
带前缀的十六进制,例如“0x12789AF0” |
DateTimeOffset |
ISO 格式,例如“2020-01-02T03:04:05.000000+06:00” |
DateTime |
在大多数情况下,应使用 |
IEnumerable |
用“, ”(可配置)分隔的值 |
IDictionary<string, object>
包含键值对的字符串,例如 token="0x12789AF0" count="5"
编辑其他值
发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
|
IsEnabled |
(1) 请参阅 https://docs.microsoft.com/en-us/dotnet/standard/datetime/choosing-between-datetime |
IsEnabled |
这些标识正在使用的日志记录提供程序的版本。 |
|
agent.type |
IsEnabled |
日志记录提供程序程序集的名称, |
agent.version
编辑日志记录程序集的信息版本号,例如 1.1.1+bd3ad63
。
这些值从入口程序集 Assembly.GetEntryAssembly()
中提取,使用 Name
和 AssemblyInformationalVersionAttribute
值(如果未设置信息版本,则回退到程序集 Version
)。
发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
service.type |
IsEnabled |
入口程序集的名称,例如 |
service.version |
IsEnabled |
入口程序集的信息版本号,例如 |
注意: 您应该使用一个能够正确设置程序集信息版本的构建流程。例如,如果您有一个使用 Git 的 .NET 项目,您可以安装本地工具 GitVersion.Tool
,并使用它根据 Git 分支信息自动生成语义版本号。
安装工具
dotnet new tool-manifest dotnet tool install GitVersion.Tool
然后使用该工具创建可在构建流程中使用的语义版本号
dotnet tool restore dotnet gitversion
欢迎使用此存储库中的 build.ps1
脚本作为示例。
跟踪字段
编辑发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
trace.id |
IsEnabled |
跨服务跟踪关联标识符。来自 |
transaction.id |
IsEnabled |
此服务的交易,例如单个请求标识符。如果采用 W3C 格式,则从 |
ASP.NET 会自动在各层之间传递关联标识符;从 3.0 开始,它还支持 W3C Trace Context 标准(https://www.w3.org/TR/trace-context/)。
如果采用 W3C 格式,则 Activity.Current.RootId
的值用作跨服务标识符(在 W3C 格式中,这是跟踪 ID),Activity.Current.Id
的 Span ID 部分用于事务,否则使用完整值(这与 ASP.NET 的工作方式一致)。
建议开启 W3C 格式,以确保与其他系统的兼容性。
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
主机字段
编辑可以通过配置禁用。
发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
host.architecture |
IsEnabled |
处理器架构,例如 X64。 |
host.hostname |
IsEnabled |
计算机名称。 |
host.os.full |
IsEnabled |
操作系统的完整描述。 |
host.os.platform |
IsEnabled |
操作系统平台。 |
host.os.version |
IsEnabled |
操作系统版本。 |
进程字段
编辑可以通过配置禁用。
发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
process.name |
IsEnabled |
当前进程名称。来自 |
process.pid |
已记录的 EventId 的名称,例如 |
当前进程 ID。来自 |
process.thread.id |
已记录的 EventId 的名称,例如 |
当前线程 ID。 |
process.thread.name |
IsEnabled |
线程名称。来自 |
用户字段
编辑可以通过配置禁用。
发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS)。 | 类型 | 描述 |
---|---|---|
user.domain |
IsEnabled |
当前域,可能是计算机名称或 Windows 域。 |
user.id |
IsEnabled |
当前用户主体名称(如果已设置)。 |
user.name |
IsEnabled |
当前用户。 |