Получение NLog для отправки JSON с правильными заголовками? - PullRequest
8 голосов
/ 12 августа 2011

Попытка использовать 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"}

Ответы [ 2 ]

4 голосов
/ 12 августа 2011

Глядя на источник HttpNetworkSender , я не вижу очевидного способа передачи типа содержимого в WebRequest.

Я думаю, вам нужно будет создать пользовательскую цель на основе NetworkTarget, которая использует пользовательский HttpNetworkSender, и включить config для установки типа содержимого для WebRequest соответствующим образом.

0 голосов
/ 02 февраля 2017

В случае, если кто-то все еще споткнется об этом, вот простая демонстрация для пользовательской цели 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 }
};
...