Elastic.Extensions.Logging 8.11.1
前缀已保留
dotnet add package Elastic.Extensions.Logging --version 8.11.1
NuGet\Install-Package Elastic.Extensions.Logging -Version 8.11.1
<PackageReference Include="Elastic.Extensions.Logging" Version="8.11.1" />
paket add Elastic.Extensions.Logging --version 8.11.1
#r "nuget: Elastic.Extensions.Logging, 8.11.1"
// Install Elastic.Extensions.Logging as a Cake Addin #addin nuget:?package=Elastic.Extensions.Logging&version=8.11.1 // Install Elastic.Extensions.Logging as a Cake Tool #tool nuget:?package=Elastic.Extensions.Logging&version=8.11.1
Elasticsearch 日志记录器提供者
Elasticsearch-Logstash-Kibana (ELK) 堆栈日志记录器提供者针对 Microsoft.Extensions.Logging。
使用 Elastic Common Schema (ECS) 直接写入 Elasticsearch,对来自消息和范围值的结构化数据进行语义日志记录。可以在 Kibana 控制台中查看和查询结果。
日志记录器使用 Elasticsearch.Net 低级客户端 来管理到 Elasticsearch 的网络连接。
使用方法
添加对 Elastic.Extensions.Logging
包的引用
dotnet add package Elastic.Extensions.Logging
然后,在主机构造期间使用提供的扩展方法将提供者添加到日志Builder中。
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 | 布尔值 | 默认 true ;将 false 设置为禁用主机值记录。 |
IncludeProcess | 布尔值 | 默认 true ;将 false 设置为禁用进程值记录。 |
IncludeScopes | 布尔值 | 默认 true ;将 false 设置为禁用作用域值记录。 |
IncludeUser | 布尔值 | 默认 true ;将 false 设置为禁用用户详情记录。 |
Index | 格式 | 用于生成 Elasticsearch index 的格式字符串,使用当前时间戳。默认为 dotnet-{0:yyyy.MM.dd} 。 |
IndexOffset | 时间 span | 覆盖以设置用于生成 index 的偏移量。默认值是 null ,使用系统本地偏移量;使用 "00:00" 表示 UTC。 |
IsEnabled | 布尔值 | 默认 true ;将 false 设置为禁用日志记录器。 |
ListSeparator | 字符串 | 用于 labels.* 值中的 IEnumerable 的分隔符。默认是 ", " 。 |
Tags | 数组 | 要包含在消息中的其他标签。用于指定环境或其他详细信息,例如 [ "Staging", "Priority" ] |
根据连接池类型,ShipTo 设置可以具有以下属性:
设置 | 类型 | 描述 |
---|---|---|
ApiKey | 字符串 | API 键,当连接池类型为 Cloud 并通过 API 键验证时。 |
CloudId | 字符串 | Cloud ID,当连接池类型为 Cloud。 |
NodePoolType | 枚举 | 默认为 Singlenode ,对于多个节点为 Sniffing ,如果提供 CloudId 则为 Cloud 。其他支持的值是 Static 或 Sticky 。 |
NodeUris | 数组 | 要连接的 Elasticsearch 节点的 URI(s)。默认为一个节点 [ "https://127.0.0.1:9200" ] |
Password | 字符串 | 密码,当连接池类型为 Cloud 并通过用户名/密码验证时。 |
Username | 字符串 | 用户名,当连接池类型为 Cloud 并通过用户名/密码验证时。 |
如果您想从不同的部分进行配置,可以手动配置
.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 Common Schema (ECS)
发送到 Elasticsearch 的日志消息遵循 Elastic Common Schema (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 | long | 与日志级别对应的 syslog 严重性,2 = 危急,3 = 错误,4 = 警告,6 = 信息,7 = 调试和跟踪。(也用于 ConsoleLoggerProvider 的 Systemd 格式) |
log.level | 字符串 | 日志级别:Critical 、Error 、Warning 、Information 、Debug 或 Trace 。 |
log.logger | 字符串 | 记录器的类别名称(命名空间和类),例如 HelloElasticsearch.Worker 。 |
event.severity
字段是数值,可以用来按级别排序事件,例如 Kibana 查询 event.severity <= 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<KeyValuePair<string, object>>
接口,用于提取单个参数值。
在 ECS 中的 labels
属性不应包含嵌套对象,因此值被转换为关键字字符串。对于大多数对象,这只需调用 ToString(),对于某些类型的特定格式,例如在列表上调用字符串通常不是很有用,因此记录列表的内容。
标签值格式化
类型 | 格式化 |
---|---|
byte | 十六进制,例如 "9A"。 |
byte[] | 前缀十六进制,例如 "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()
,根据Name
和AssemblyInformationalVersionAttribute
的值(如果有设置为信息版本,否则使用装配的Version
)。
字段 | 类型 | 描述 |
---|---|---|
service.type | 字符串 | 入口汇编的名字,HelloElasticsearch 。 |
service.version | 字符串 | 入口汇编的信息版本号,例如:1.2.0-beta.1+79d095a 。 |
注意:您应该使用正确设置装配信息版本的构建过程。例如,如果您使用git的dotnet项目,可以安装本地工具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 | long | 当前进程ID。从Process.GetCurrentProcess() 获取。 |
process.thread.id | long | 当前线程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 。 |
产品 | 版本 兼容和附加计算的目标框架版本。 |
---|---|
.NET | net5.0 已计算。 net5.0-windows 已计算。 net6.0 已计算。 net6.0-android 已计算。 net6.0-ios 已计算。 net6.0-maccatalyst 已计算。 net6.0-macos 已计算。 net6.0-tvos 已计算。 net6.0-windows 已计算。 net7.0 已计算。 net7.0-android 已计算。 net7.0-ios 已计算。 net7.0-maccatalyst 已计算。 net7.0-macos 已计算。 net7.0-tvos 已计算。 net7.0-windows 已计算。 net8.0 已计算。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。 |
.NET Core | netcoreapp2.0 已计算。 netcoreapp2.1 已计算。 netcoreapp2.2 已计算。 netcoreapp3.0 已计算。 netcoreapp3.1 已计算。 |
.NET 标准化 | netstandard2.0 兼容。 netstandard2.1 兼容。 |
.NET 框架 | net461 已计算。 net462 已计算。 net463 已计算。 net47 已计算。 net471 已计算。 net472 已计算。 net48 已计算。 net481 已计算。 |
MonoAndroid | monoandroid 已计算。 |
MonoMac | monomac 已计算。 |
MonoTouch | monotouch 已计算。 |
Tizen | tizen40 已计算。 tizen60 已计算。 |
Xamarin.iOS | xamarinios 已计算。 |
Xamarin.Mac | xamarinmac 已计算。 |
Xamarin.TVOS | xamarintvos 已计算。 |
Xamarin.WatchOS | xamarinwatchos 已计算。 |
-
.NETStandard 2.0
- Elastic.CommonSchema (>= 8.11.1)
- Elastic.Ingest.Elasticsearch.CommonSchema (>= 8.11.1)
- Microsoft.Extensions.Logging.Configuration (>= 2.1.0)
-
.NETStandard 2.1
- Elastic.CommonSchema (>= 8.11.1)
- Elastic.Ingest.Elasticsearch.CommonSchema (>= 8.11.1)
- Microsoft.Extensions.Logging.Configuration (>= 2.1.0)
NuGet包 (2)
显示依赖于Elastic.Extensions.Logging的前两个NuGet包
包 | 下载 |
---|---|
BitzArt.OpenTelemetry.BoilerPlate OpenTelemetry的一些模板代码 |
|
Gench.Logging
包描述 |
GitHub仓库
此包未被任何流行GitHub仓库使用。