使用 C# 和 .NET 记录 Datadog

Zap*_*dor 4 .net c# datadog

我正在尝试从我的 C# 应用程序发布 Datadog-logs。我设法使用 Postman 发送具有所需结构的日志,但我只是不知道如何从代码中实现相同的目标。我尝试过的:

  1. 使用 DogStatsD - 但我不想安装代理,我宁愿使用 Datadog REST API 来发布我的日志。
  2. 使用 Serilog.Sinks.Datadog.Logs - 这似乎很容易使用,但我不知道它是如何工作的,以及是否可以更改日志结构。默认情况下,生成的 json 中有 MessageTemplate 和 Properties 字段。我希望能够在一条消息中发送我自己的结构,而不是使用 MessageTemplate。那可能吗?

在 Datadog UI 日志部分中查看所需的日志

{
    hostname: myHost
    myStuff {   
    item1: item_val1
    item2: item_val2
    }
    otherStuff: oh wow this is cool
    service: MyService
}
Run Code Online (Sandbox Code Playgroud)

以下是我使用 Postman 发送的内容以实现此结果

网址:https://http-intake.logs.datadoghq.com/v1/input

标题:

DD-API-KEY: my_api_key
Content-Type: application/json
Run Code Online (Sandbox Code Playgroud)

身体:

{
    "ddsource": "mySource",
    "ddtags": "myTag: myVal, myValWithoutTag",
    "hostname": "myHost",
    "message": {
        "myStuff":
        {
            "item1": "item_val1",
            "item2": "item_val2"
        },
        "otherStuff": "oh wow this is cool"
    },
    "service": "MyService"
}
Run Code Online (Sandbox Code Playgroud)

使用数据日志串行接收器是否可以实现相同(甚至相似)的结果?如果没有的话,我怎样才能在C#中达到这个结果呢?

这是我从代码中尝试的:

var config = new DatadogConfiguration(url: "intake.logs.datadoghq.com", port: 443, useSSL: true, useTCP: true);
using (var log = new LoggerConfiguration().WriteTo.DatadogLogs(
        "<myApiKey>",
        source: "mySource",
        service: "myService",
        host: "myHost",
        tags: new string[] {"myTag:myVal", "myValWithoutTag"},
        configuration: config
    ).
    CreateLogger())
{
    var messageTemplate = "{message}";
    var message = new
    {
        myStuff = new
        {
            item1 = "item_val1",
            item2 = "item_val2"
        }
    };

    log.Information(messageTemplate, message);
}
Run Code Online (Sandbox Code Playgroud)

Datadog UI 日志部分中出现了不需要的结果:

{
    host: myHost
    level: Information
    MessageTemplate: {message}
    Properties: {   
    message: { myStuff = { item1 = item_val1, item2 = item_val2 } }
    }
    service: myService
    Timestamp: 2021-05-17T00:13:14.2614896+03:00
}
Run Code Online (Sandbox Code Playgroud)

标签部分确实有效,主机和服务部分也相同。我不介意添加级别和时间戳,但我希望将正文更改为像 Postman 示例中那样的行为(只是将消息作为 JSON)。所以我的问题是:

  • 是否可以使用 Datadog Serilog 接收器控制消息正文格式?
  • 有没有我没有尝试过的好的替代方案?(除了写我自己的客户,这是我倾向于的)
  • 谁能向我解释它是如何工作的?我无法理解水槽的概念。谁能解释它是如何工作的?为什么没有实际的 REST HTTP 客户端来执行此任务?

谢谢!

小智 5

您确实不需要使用代理来向 Datadog 发送和自定义日志。它对于提供跟踪和其他指标来说非常酷。不幸的是,无法在 Datadog 日志记录配置中更改 MessageTemplate。仅将 MessageTemplate 之类的消息放入 Serilog 中:

var message = "Service started";
logger.Information(message);
Run Code Online (Sandbox Code Playgroud)

您可以通过两种方式添加属性。使用 Serilog Enrich:

var config = new DatadogConfiguration(url: "intake.logs.datadoghq.com", port: 443, useSSL: true, useTCP: true);
using (var log = new LoggerConfiguration()
    .Enrich.WithProperty(item1, item_val1)
    .WriteTo.DatadogLogs(
      "<myApiKey>",
      source: "mySource",
      service: "myService",
      host: "myHost",
      tags: new string[] {"myTag:myVal", "myValWithoutTag"},
      configuration: config
).
CreateLogger())
Run Code Online (Sandbox Code Playgroud)

或者通过中间件推送 LogContext 中的属性:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Serilog.Context;

namespace MyProject.Middlewares
{
  public class LogPropertyMiddleware
  {
    private readonly RequestDelegate _next;

    public LogUserInfoMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        LogContext.PushProperty("item1", "item_val1");

        await _next.Invoke(context);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

添加中间件到启动:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
   .....
   .....
   app.UseMiddleware<LogPropertyMiddleware>();
   .....
}
Run Code Online (Sandbox Code Playgroud)