1
votes

I am in the process of converting a home grown logging system to NLog and am wondering if there is a way to add an event to a Logger or otherwise support a mechanism where when I log a message I can get a callback with the final formatted message and the LogLevel. I currently use something like this to send server messages back to a connected client.

Thx

1
You can write your own log target. See github.com/NLog/NLog/wiki/Extending-NLoguser47589
Thx Amy. I thought about that but the WCF client context is in the server so not available to a custom logger target. I need to get the completely formatted message that was just written to any target returned to the Log call, or a logger event that tells me what the message was so I can collect several and send to the client or via email.Dave
You can get the formatted message easily in your custom target. Layout.Render(logEventInfo)Julian
Thx Julian. But how would I then get the formatted message back to my application as there is no context for communication with my server that wrote the log message? Also I accumulate some of these messages so that I am able to send email encompassing all logging for a task so the server needs a copy of the message that is written to the log.Dave
How you communicate between servers is a separate problem beyond the scope of the original question. If you want callback capability, you need to write a custom NLog target.user47589

1 Answers

1
votes

This is an MCVE of what I was talking about in the comments. Create a target that accepts some callback functions:

[Target("MyFirst")]
public sealed class MyFirstTarget : TargetWithLayout
{
    private readonly Action<string>[] _callbacks;

    public MyFirstTarget(params Action<string>[] callbacks)
    {
        _callbacks = callbacks;
    }

    protected override void Write(LogEventInfo logEvent)
    {
        foreach (var callback in _callbacks)
        {
            callback(logEvent.FormattedMessage);
        }
    }
}

Configure NLog to use the target. I do this programmatically since the callbacks are passed in the constructor. You can also configure the target in the NLog.config, but your target will need to be a singleton then so you can register the callbacks in code.

class Program
{
    public static void Main()
    {
        LogManager.Configuration.AddTarget("MyFirst", new MyFirstTarget(s => Debug.WriteLine(s)));

        var logger = LogManager.GetCurrentClassLogger();
        logger.Debug("test");
    }
}

With no other NLog configuration (copy this code into an empty project and add the NLog nuget package), this will emit a message to your debug window.