Getting NLog to send out JSON with proper headers?
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
Cont开发者_Python百科ent-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"}
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.
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
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 }
};
精彩评论