Introduced with NLog 4.5
It is really easy:
NLog.Targets.TargetWithContext
Write(LogEventInfo logEvent)
method.this.RenderLogEvent(this.Layout, logEvent)
to get the message text, and invoke this.GetAllProperties(logEvent)
to get structured properties.⚠️ Don't forget to register your custom component when loading NLog config!
See also the updated How to write a custom async target
using NLog; using NLog.Config; using NLog.Targets; namespace MyNamespace { [Target("MyFirst")] public sealed class MyFirstTarget : TargetWithContext { public MyFirstTarget() { this.IncludeEventProperties = true; // Include LogEvent Properties by default } public Layout Host { get; set; } = "localhost"; protected override void Write(LogEventInfo logEvent) { string logMessage = this.RenderLogEvent(this.Layout, logEvent); string hostName = this.RenderLogEvent(this.Host, logEvent); IDictionary<string,object> logProperties = this.GetAllProperties(logEvent); SendTheMessageToRemoteHost(hostName, logMessage, logProperties); } private void SendTheMessageToRemoteHost(string hostName, string message, IDictionary<string, object> properties) { // TODO - write me } } }TargetWithContext Features Additional Context Properties
Users can easily configure additional context information:
<target type="MyFirst" name="first"> <contextproperty name="MachineName" layout="${machinename}" /> <contextproperty name="ThreadId" layout="${threadid}" /> </target>
Without needing to inject the details upfront when doing the logging. It is automatically captured by the NLog engine.
ScopeContext Properties can be used to provide context-specific details (Ex. request-correlationid from ILogger.BeginScope
).
To automatically capture properties injected into ScopeContext (Before NLog 5.0 it was called IncludeMDLC)
<target type="MyFirst" name="first" includeScopeProperties="true"> ... </target>
TargetWithContext will by default ensure that all captured property-values are included in output, and will automatically generate new unique key-name when name-collission. If wanting to merge properties, so one context can override another context, then one can do it like this:
<target type="MyFirst" excludeProperties="RequestId"> <contextproperty name="RequestId" layout="${event-properties:RequestId:whenEmpty=${scope-property=RequestId:whenEmpty=DefaultValue}}" /> </sometarget>
Instead of DefaultValue
then you could also use one of the NLog LayoutRenderers available. Ex. ${aspnet-TraceIdentifier} or ${activity:property=TraceId}. Or alternative skip whenEmpty=DefaultValue
and rely on IncludeEmptyValue="false"
(default).
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4