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,它使用系统本地偏移量;对于 UTC,请使用 "00:00&"

IsEnabled

布尔值

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

ListSeparator

字符串

用于 IEnumerablelabels.* 值的分隔符。默认为 ", "

设置 类型 描述

Tags

IsEnabled

数组

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

IsEnabled

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

ApiKey

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

CloudId

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

ListSeparator

NodePoolType

枚举

IsEnabled

默认为 Singlenode,或者对于多个节点为 Sniffing,或者如果提供了 CloudId 则为 Cloud。其他支持的值为 StaticSticky

NodeUris

IsEnabled

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

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) 类型 描述

示例文档

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

标准字段

字段

IsEnabled

@timestamp

日期

ListSeparator

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

message

IsEnabled

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

tags

IsEnabled

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

event.action

已记录的 EventId 的名称,例如 ErrorProcessingCustomer

event.code

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

IsEnabled

event.severity

长整型

IsEnabled

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

log.level

日志级别:CriticalErrorWarningInformationDebugTrace

编辑

log.logger

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

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

IsEnabled

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

错误字段

IsEnabled

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

error.message

IsEnabled

任何异常的 Message 属性。

error.stack_trace

编辑

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

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

error.type

IsEnabled

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

自定义字段

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 中的日志级别和范围的重载;它实现了 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"

编辑

其他值

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

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

IsEnabled

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

代理字段

IsEnabled

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

agent.type

IsEnabled

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

agent.version

编辑

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

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

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

service.type

IsEnabled

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

service.version

IsEnabled

入口程序集的信息版本号,例如 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 脚本作为示例。

跟踪字段

编辑
发送到 Elasticsearch 的日志消息遵循 Elastic 通用架构 (ECS) 类型 描述

trace.id

IsEnabled

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

transaction.id

IsEnabled

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

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。 RuntimeInformation.OSArchitecture 的值。

host.hostname

IsEnabled

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

host.os.full

IsEnabled

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

host.os.platform

IsEnabled

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

host.os.version

IsEnabled

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

进程字段

编辑

可以通过配置禁用。

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

process.name

IsEnabled

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

process.pid

已记录的 EventId 的名称,例如 ErrorProcessingCustomer

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

process.thread.id

已记录的 EventId 的名称,例如 ErrorProcessingCustomer

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

process.thread.name

IsEnabled

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

用户字段

编辑

可以通过配置禁用。

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

user.domain

IsEnabled

当前域,可能是计算机名称或 Windows 域。 Environment.UserDomainName 的值。

user.id

IsEnabled

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

user.name

IsEnabled

当前用户。 Environment.UserName 的值。