从 Serilog 获取数据

Serilog 是适用于 .NET 应用程序的常用日志记录框架。 开发人员可以使用 Serilog 来根据记录器的名称、记录器级别和消息模式以任意粒度控制要输出哪些日志语句。 Serilog 接收器也称为追加器,可将日志数据流式传输到表,可以在其中对日志进行实时分析和可视化。

本文介绍了如何使用 Serilog 引入数据。

有关数据连接器的完整列表,请参阅数据连接器概述

先决条件

创建 Microsoft Entra 服务主体

Microsoft Entra 应用程序身份验证用于需要在没有用户在场的情况下访问 KQL 数据库表的应用程序。 若要使用 Serilog 连接器引入数据,需要创建并注册一个 Microsoft Entra 服务主体,然后授权此主体作为连接器用于将数据引入到 KQL 数据库的标识。

Microsoft Entra 服务主体可以通过 Azure 门户或以编程方式进行创建,如以下示例所示。

你稍后将授予此服务主体访问 Kusto 资源所需的权限。

  1. 通过 Azure CLI 登录到你的 Azure 订阅。 然后在浏览器中进行身份验证。

    az login
    
  2. 选择要托管主体的订阅。 当你有多个订阅时,此步骤是必需的。

    az account set --subscription YOUR_SUBSCRIPTION_GUID
    
  3. 创建服务主体。 在此示例中,服务主体名为 my-service-principal

    az ad sp create-for-rbac -n "my-service-principal" --role Contributor --scopes /subscriptions/{SubID}
    
  4. 从返回的 JSON 数据中复制 appIdpasswordtenant 供将来使用。

    {
      "appId": "1234abcd-e5f6-g7h8-i9j0-1234kl5678mn",
      "displayName": "my-service-principal",
      "name": "my-service-principal",
      "password": "1234abcd-e5f6-g7h8-i9j0-1234kl5678mn",
      "tenant": "1234abcd-e5f6-g7h8-i9j0-1234kl5678mn"
    }
    

现已创建了 Microsoft Entra 应用程序和服务主体。

创建目标表和引入映射

为传入数据创建一个目标表,并创建一个引入映射,将引入的数据列映射到目标表中的列。 在以下步骤中,表架构和映射对应于从示例应用发送的数据。

  1. 在查询编辑器中运行以下表创建命令,并将占位符 TableName 替换为目标表的名称:

    .create table <TableName> (Timestamp: datetime, Level: string, Message: string, Exception: string, Properties: dynamic, Position: dynamic, Elapsed: int)
    
  2. 运行以下创建引入映射命令,将占位符 TableName 替换为目标表名称,将 TableNameMapping 替换为引入映射的名称:

    .create table <TableName> ingestion csv mapping '<TableNameMapping>' '[{"Name":"Timestamp","DataType":"","Ordinal":"0","ConstValue":null},{"Name":"Level","DataType":"","Ordinal":"1","ConstValue":null},{"Name":"Message","DataType":"","Ordinal":"2","ConstValue":null},{"Name":"Exception","DataType":"","Ordinal":"3","ConstValue":null},{"Name":"Properties","DataType":"","Ordinal":"4","ConstValue":null},{"Name":"Position","DataType":"","Ordinal":"5","ConstValue":null},{"Name":"Elapsed","DataType":"","Ordinal":"6","ConstValue":null}]'
    
  3. 根据创建 Microsoft Entra 服务主体授予服务主体数据库引入者角色,并提供使用数据库的权限。 有关详细信息,请参阅示例。 将占位符 DatabaseName 替换为目标数据库的名称,将 ApplicationID 替换为创建 Microsoft Entra 服务主体时保存的 AppId 值。

    .add database <DatabaseName> ingestors ('aadapp=<ApplicationID>') 'App Registration'
    

在 ASP.NET Core 应用程序中使用 Serilog

本部分介绍了如何将 Serilog 集成到 ASP.NET Core 应用程序中,以记录数据并将其发送到 KQL 表。

安装包

添加 Serilog.Sinks.AzureDataExplorer NuGet 库包。 使用 Install-Package 命令指定 NuGet 包的名称。

Install-Package Serilog.Sinks.AzureDataExplorer

将 Serilog 接收器添加到应用

使用以下步骤:

  • 将 Serilog 接收器添加到应用。
  • 配置接收器使用的变量。
  • 生成并运行应用。
  1. 将以下代码添加到应用:

    using Serilog.Sinks.AzureDataExplorer;
    
  2. 配置 Serilog 接收器,并使用后面的表中的信息替换占位符:

    var log = new LoggerConfiguration()
    .WriteTo.AzureDataExplorerSink(new AzureDataExplorerSinkOptions
    {
        IngestionEndpointUri = "<TargetURI>",
        DatabaseName = "<MyDatabase>",
        TableName = "<MyTable>",
        BufferBaseFileName = "<BufferBaseFileName>"
    })
    .CreateLogger();
    
    变量 说明
    IngestionEndPointUri 引入 URI
    DatabaseName 目标数据库的名称,区分大小写。
    TableName 现有目标表的名称,区分大小写。 例如,SerilogTest 是在创建目标表和引入映射中创建的表的名称。
    AppId 用于身份验证的应用程序客户端 ID。 在创建 Microsoft Entra 服务主体中保存了此值。
    AppKey 用于身份验证的应用程序密钥。 在创建 Microsoft Entra 服务主体中将此值保存为 password
    租户 应用程序注册到的租户的 ID。 在创建 Microsoft Entra 服务主体中保存了此值。
    BufferBaseFileName 缓冲区文件的可选基本文件名。 如果你要求日志持久保留,而不会因与群集连接失败而丢失,请设置此值。 例如,C:/Temp/Serilog

    有关更多选项,请参阅接收器选项

  3. 使用 Serilog 接收器将数据发送到数据库。 例如:

    log.Verbose("Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);
    log.Information("Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);
    log.Warning("Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);
    log.Error(new Exception(), "Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);
    log.Debug("Processed {@Position} in {Elapsed:000} ms. ", position, elapsedMs);
    
  4. 生成并运行应用。 例如,如果使用的是 Visual Studio,请按 F5。

  5. 验证数据是否在表中。 运行以下查询,将占位符替换为上一步中创建的表的名称:

    <TableName>
    | take 10
    

运行示例应用

如果没有自己的数据要测试,则可以使用含示例数据的示例日志生成器应用来测试 Serilog 接收器的配置和使用。

  1. 使用以下 git 命令克隆 Serilog 接收器的 git 存储库

    git clone https://github.com/Azure/serilog-sinks-azuredataexplorer
    
  2. 设置以下环境变量以配置 Serilog 接收器:

    变量 说明
    IngestionEndPointUri 引入 URI
    DatabaseName 目标数据库的名称,区分大小写。
    TableName 现有目标表的名称,区分大小写。 例如,SerilogTest 是在创建目标表和引入映射中创建的表的名称。
    AppId 用于身份验证的应用程序客户端 ID。 在创建 Microsoft Entra 服务主体中保存了此值。
    AppKey 用于身份验证的应用程序密钥。 在创建 Microsoft Entra 服务主体中保存了此值。
    租户 应用程序注册到的租户的 ID。 在创建 Microsoft Entra 服务主体中保存了此值。
    BufferBaseFileName 缓冲区文件的基本文件名。 如果你要求日志持久保留,而不会因与群集连接失败而丢失,请设置此值。 例如: C:/Temp/Serilog

    可以手动或使用以下命令设置环境变量:

    $env:ingestionURI="<ingestionURI>"
    $env:appId="<appId>"
    $env:appKey="<appKey>"
    $env:tenant="<tenant>"
    $env:databaseName="<databaseName>"
    $env:tableName="<tableName>"
    
  3. 在终端中,浏览到克隆的存储库的根文件夹,然后运行以下 .NET 命令来生成应用:

    dotnet build src
    
  4. 在终端中,浏览到 samples 文件夹,然后运行以下 .NET 命令来运行该应用:

    dotnet build run
    
  1. 选择目标 KQL 数据库,然后运行以下查询来浏览引入的数据,将占位符 TableName 替换为目标表的名称:

    <TableName>
    | take 10
    

    输出应该类似于以下输出:

    Timestamp Level 消息 Exception 属性 Position 占用时间
    2023-03-12 1248:474590 信息 Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34
    2023-03-12 1248474770 警告 Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34
    2023-03-12 1248475590 错误 Zohar Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34
    2023-03-12 1248474790 信息 Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34
    2023-03-12 124847.5610 警告 Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34
    2023-03-12 124847.5620 错误 Zohar Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34
    2023-03-12 124847.5630 信息 Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34
    2023-03-12 124847.5660 错误 Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34
    2023-03-12 124847.5670 信息 Zohar Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34
    2023-03-12 124847.5680 警告 Processed { Latitude: 25, Longitude:30} {"Position": { "Latitude": 25, "Longitude":30} { "Latitude": 25, "Longitude":30} 34