1

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

Dave
  • 1,822
  • 2
  • 27
  • 36
  • You can write your own log target. See https://github.com/NLog/NLog/wiki/Extending-NLog –  Feb 22 '16 at 16:48
  • 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 Feb 22 '16 at 21:42
  • You can get the formatted message easily in your custom target. `Layout.Render(logEventInfo)` – Julian Feb 23 '16 at 09:15
  • 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 Feb 23 '16 at 14:40
  • 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. –  Feb 23 '16 at 15:02
  • Amy - you misunderstand or I am not clear. There is only one server or application that is making the logging call, and that is what wants the callback every time something is logged for a certain logger. How do I get a custom target to call my application back using the standard logger methods? – Dave Feb 23 '16 at 18:53
  • The custom logger can accept one or more callback functions to call whenever a log message is emitted. It doesn't need to know anything beyond what functions to call. You're effectively *adding* callback functionality to NLog. Callbacks don't exist in NLog by default. You can add them. –  Feb 23 '16 at 21:55

1 Answers1

1

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.