【问题标题】:Getting NLog to send out JSON with proper headers?让 NLog 发送带有正确标头的 JSON?
【发布时间】:2011-10-26 00:52:59
【问题描述】:

尝试使用 NLog 从我们的 C# 应用程序中发送 JSON 编码的日志,将它们转储到 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"}

【问题讨论】:

  • 请发布您在应用程序和 CoucheDb 的代码和配置方面的内容

标签: c# json logging couchdb nlog


【解决方案1】:

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

我认为您必须基于使用自定义HttpNetworkSenderNetworkTarget 创建自定义目标,并包含配置以适当地设置WebRequest 上的内容类型。

【讨论】:

  • 或者如果你想真正疯狂,你可以尝试将整个 HTTP 会话嵌入到布局中,然后将地址设置为 TCP。不确定这是否可行,但可能会很有趣。
  • 修补 HttpNetworkSender 很简单,成功了。
  • 您介意将补丁贡献给社区吗?我有同样的问题。谢谢!
【解决方案2】:

如果有人仍然偶然发现,这里是自定义 http 目标 (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"));
}

来自配置代码:

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

【讨论】:

    【解决方案3】:

    NLog 版本。 4.5 WebService Target具有配置自定义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>
    

    另见https://github.com/nlog/NLog/wiki/WebService-target

    【讨论】:

      猜你喜欢
      • 2014-04-24
      • 1970-01-01
      • 1970-01-01
      • 2017-12-20
      • 1970-01-01
      • 2019-04-29
      • 2020-02-21
      • 1970-01-01
      • 2021-07-07
      相关资源
      最近更新 更多