Search code examples
c#nlograygun

NLog Raygun - How to catch exception when calling SendInBackground


I forked the NLog Raygun from Mindscape to provide more settings of Raygun in NLog.

A RaygunTarget is created and needs to override Write method as follows NLog document (https://github.com/NLog/NLog/wiki/How-to-write-a-custom-target).

To send an exception to Raygun, follows the below code

protected override void Write(LogEventInfo logEvent)
{
    _raygunClient ??= (_raygunClient = CreateRaygunClient());
    ...
    _raygunClient.SendInBackground(exception, tags, userCustomData);
}

SendInBackground returns a Task which we can not mark Write method as async void because it's not the case of using async void.

Everything works fine. We have a swagger to have Healthcheck. I want to check if NLog Raygun is sent successfully but I don't know how to catch the exception in SendInBackground in case API Key is invalid. I mean is there a better way to test whether this RaygunTarget can send a message successfully to Raygun?

If I provide a setting called ThrowOnError and in Write method updated like this

protected override void Write(LogEventInfo logEvent)
{
    _raygunClient ??= (_raygunClient = CreateRaygunClient());
    ...
    var task = _raygunClient.SendInBackground(exception, tags, userCustomData);
    if (_setting.ThrowOnError) task.Wait();
}

It works but a question is: This is a good way to do that? Personally, I think it's not because it introduces a different behavior or side-effect based on a setting.


Solution

  • Instead of inheriting from TargetWithLayout then you can inherit from AsyncTaskTarget:

    protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
    {
        _raygunClient ??= (_raygunClient = CreateRaygunClient());
        ...
        var userCustomData = base.GetAllProperties(logEvent);
        return _raygunClient.SendInBackground(exception, tags, userCustomData);
    } 
    

    See also: https://github.com/NLog/NLog/wiki/How-to-write-a-custom-async-target

    Then you can hook into the NLog InternalLogger using InternalLogger.LogWriter, and forward to healthcheck-api.

    There are plans to improve the API for NLog 5.0 so one can subscribe to an InternalLogger-Event and can also get more context details. Like Target-Name, Target-Type etc. See also: https://github.com/NLog/NLog/issues/3350