0

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.

Julian
  • 33,915
  • 22
  • 119
  • 174
Steve Lam
  • 979
  • 1
  • 17
  • 40

1 Answers1

2

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

Rolf Kristensen
  • 17,785
  • 1
  • 51
  • 70
  • Is it safe while inherits AsyncTaskTarget and configs async=true in config file? I saw on document said "Async attribute and AsyncWrapper Don't combine the Async attribute and AsyncWrapper. This will only slow down processing and will behave unreliably" – Steve Lam Feb 14 '20 at 04:19
  • I have another solution by move the code in `Write` method into another method which supports returning `Task` and make it `public`, `Write` method will call the new method and Health-check will call the new method from target. Is it good solution? – Steve Lam Feb 14 '20 at 04:20
  • Yes you could just add `_raygunClient.SendInBackground(...).ContinueWith(t => ReportError(t.Exception), TaskContinuationOptions.OnlyOnFaulted)` – Rolf Kristensen Feb 14 '20 at 13:00