让 NLog 发送带有正确标头的 JSON?

发布于 2024-11-29 02:37:14 字数 1071 浏览 0 评论 0原文

尝试使用 NLog 将 JSON 编码的日志从我们的 C# 应用程序发送出去,将它们转储到 CouchDB 中。但是,使用 Network 目标,我似乎找不到正确设置 Content-Type 标头的方法;否则 CouchDB 不会与我的输入有任何关系。

CouchDB 是开箱即用的,当前 NLog 配置:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" throwExceptions="true">
    <variable name="FileLayout" value='{ "date":"${longdate}","level":"${level}","message":${message}}' />
    <targets>
      <target name="logfile" xsi:type="Network" address="http://127.0.0.1:5984/logger/" layout="${FileLayout}" />
    </targets>
    <rules>
      <logger name="*" minlevel="Trace" writeTo="logfile" />
    </rules>
  </nlog>

以及原始 HTTP(已编辑主机名):

POST http://127.0.0.1:5984/logger/ HTTP/1.1
Host: 127.0.0.1:5984
Content-Length: 221
Expect: 100-continue

{ "date":"2011-08-12 13:38:06.4603","level":"Info","message":{"backlog":0, "too_busy":0, "io_threads":1000, "threads":32766, "messages_processed":0}, "ProcessName": "foobar"}

Trying to use NLog to send JSON-encoded logs out of our C# app, to dump them into CouchDB. However, using the Network target, I can't seem to find a way to set the Content-Type header properly; and CouchDB won't have anything to do with my input otherwise.

CouchDB is out-of-the-box, Current NLog config:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" throwExceptions="true">
    <variable name="FileLayout" value='{ "date":"${longdate}","level":"${level}","message":${message}}' />
    <targets>
      <target name="logfile" xsi:type="Network" address="http://127.0.0.1:5984/logger/" layout="${FileLayout}" />
    </targets>
    <rules>
      <logger name="*" minlevel="Trace" writeTo="logfile" />
    </rules>
  </nlog>

And the raw HTTP (hostnames edited):

POST http://127.0.0.1:5984/logger/ HTTP/1.1
Host: 127.0.0.1:5984
Content-Length: 221
Expect: 100-continue

{ "date":"2011-08-12 13:38:06.4603","level":"Info","message":{"backlog":0, "too_busy":0, "io_threads":1000, "threads":32766, "messages_processed":0}, "ProcessName": "foobar"}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰葑 2024-12-06 02:37:14

查看 HttpNetworkSender source,我没有看到将内容类型传递给 WebRequest 的明显方法。

我认为您必须基于使用自定义 HttpNetworkSender 的 NetworkTarget 创建自定义目标,并包含配置以设置 WebRequest< 上的内容类型/代码> 适当的。

Looking at the HttpNetworkSender source, I don't see an obvious way to pass in a content type to the WebRequest.

I think you will have to create a custom target based on the NetworkTarget which uses a custom HttpNetworkSender, and include config to set the content-type on the WebRequest Appropriately.

另类 2024-12-06 02:37:14

NLog版本。 4.5 WebService Target 能够配置自定义标头。

<target xsi:type="WebService"
         name="CouchDB"
         url="http://127.0.0.1:5984/logger/"
         protocol="JsonPost"
         encoding="utf-8">
      <parameter layout="FileLayout" />
      <header name="Content-Type" layout="application/json" />
</target>

另请参阅 https://github.com/nlog/NLog/wiki/WebService-target< /a>

NLog ver. 4.5 WebService Target has the ability to configure custom headers.

<target xsi:type="WebService"
         name="CouchDB"
         url="http://127.0.0.1:5984/logger/"
         protocol="JsonPost"
         encoding="utf-8">
      <parameter layout="FileLayout" />
      <header name="Content-Type" layout="application/json" />
</target>

See also https://github.com/nlog/NLog/wiki/WebService-target

べ繥欢鉨o。 2024-12-06 02:37:14

如果有人仍然偶然发现这一点,这里是自定义 http 目标 (NLog v4.xx) 的简单演示。

public class WebPostTarget : Target
{
    public string ServerUrl { get; set; }
    private readonly HttpClient _client = new HttpClient();

    protected override void Write(LogEventInfo logEvent)
    {
        PostData(new [] { logEvent.AsLogModel() }); 
    }

    protected override void Write(AsyncLogEventInfo[] logEvents)
    {
        var data = logEvents.Select(x => x.LogEvent.AsLogModel()).ToArray();
        PostData(data);
    }

    private void PostData(object data)
    {
        if (!ServerUrl.IsNullOrEmpty())
        {
            // add your custom headers to the client if you need to 
            _client.PostJsonAsync(ServerUrl, data).FireAndForget();
        }
    }
}
// HttpClientExtensions
public static async Task<HttpResponseMessage> PostJsonAsync(this HttpClient client, string url, object data)
{
    return await client.PostAsync(url, new StringContent(data.ToJson(), Encoding.UTF8, "application/json"));
}

从配置代码来看:

var asyncWebTarget = new AsyncTargetWrapper()
{
    Name = "web_batch_logServer",
    BatchSize = 100,
    TimeToSleepBetweenBatches = 1000,
    OverflowAction = AsyncTargetWrapperOverflowAction.Grow,
    WrappedTarget = new WebPostTarget { ServerUrl = logServerUrl }
};

In case someone still stumble on this, here is simple demo for custom http target (NLog v4.x.x).

public class WebPostTarget : Target
{
    public string ServerUrl { get; set; }
    private readonly HttpClient _client = new HttpClient();

    protected override void Write(LogEventInfo logEvent)
    {
        PostData(new [] { logEvent.AsLogModel() }); 
    }

    protected override void Write(AsyncLogEventInfo[] logEvents)
    {
        var data = logEvents.Select(x => x.LogEvent.AsLogModel()).ToArray();
        PostData(data);
    }

    private void PostData(object data)
    {
        if (!ServerUrl.IsNullOrEmpty())
        {
            // add your custom headers to the client if you need to 
            _client.PostJsonAsync(ServerUrl, data).FireAndForget();
        }
    }
}
// HttpClientExtensions
public static async Task<HttpResponseMessage> PostJsonAsync(this HttpClient client, string url, object data)
{
    return await client.PostAsync(url, new StringContent(data.ToJson(), Encoding.UTF8, "application/json"));
}

From configuration code:

var asyncWebTarget = new AsyncTargetWrapper()
{
    Name = "web_batch_logServer",
    BatchSize = 100,
    TimeToSleepBetweenBatches = 1000,
    OverflowAction = AsyncTargetWrapperOverflowAction.Grow,
    WrappedTarget = new WebPostTarget { ServerUrl = logServerUrl }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文