Skip to content

NLog cloud logging with Azure function or AWS lambda

Rolf Kristensen edited this page Aug 20, 2019 · 38 revisions

Logging in the cloud

Standard log files doesn't always work well in the cloud. It can be difficult to access the log files after the function / lambda has completed.

The easy solution is to perform logging to these locations:

Then update the configuration for the function / lambda to perform capture of the output and save it to cloud storage. The execution of the function / lambda will then not be bothered with any network issues to the cloud storage.

The NLog JsonLayout can then be configured to enable structured logging.

Writing to ILambdaContext ILambdaLogger in AWS

var lambdaLogger = lambaContext.Logger;
var targetLayout = new NLog.Layouts.Layout("${message}${exception:format=tostring}");  // Can also be JsonLayout
var loggerTarget = new NLog.Targets.MethodCallTarget("MyTarget", (logEvent,parms) => lambdaLogger.LogLine(parms[0].ToString()));
loggerTarget.Parameters.Add(new NLog.Targets.MethodCallParameter(targetLayout);
var nlogConfig = new NLog.Config.LoggingConfiguration();
nlogConfig.AddRuleForAllLevels(loggerTarget);
NLog.LogManager.Configuration = nlogConfig;
var nlogLogger = NLog.LogManager.GetCurrentClassLogger();
nlogLogger.Info("Hello World");

Configure NLog as logging provider in Azure

Register NLog using FunctionsStartup in Startup.cs:

[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]

namespace MyNamespace
{
    public class Startup : FunctionsStartup
    {
        public Startup()
        {
            // TODO Load NLog.config or setup NLog targets using API
        }

        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddLogging((loggingBuilder) =>
            {
               // loggingBuilder.SetMinimumLevel(LogLevel.Trace); // Update default MEL-filter
               loggingBuilder.AddNLog();
            });
        }
    }
}

Setup filtering for Microsoft Extension Logging (MEL) in host.json:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "MyNamespace": "Information"
    }
  }
}

See also Use dependency injection in .NET Azure Functions

Initialize NLog in Azure Functions v2

There is an optimization in Azure Functions v2 so it will allow reuse of static variables. This means first thread will initialize, and all new threads will reuse.

When using NLog directly (Without [FunctionsStartup] as shown above), then it is recommended to make use of static NLog.Logger like this:

namespace MyServiceBusFunctions
{
   static readonly NLog.Logger Log = LogManager.GetLogger("MyFunction");

   [FunctionName( "MyFunction" )]
   public static void Run( [ServiceBusTrigger( "TestTopicName", "TestSubscriptionName", Connection = "TestSubscriptionConnectionString" )] string messageContents, ExecutionContext context, int deliveryCount, DateTime enqueuedTimeUtc, string messageId )
   {
       Log.Info("Hello World");
   }
}

Redirect NLog to Microsoft Extension ILogger in Azure

If you have a library that depends on NLog-Logging, and not interested in using NLog as Logging Provider. Then you can setup NLog to forward output to a standard Microsoft ILogger using MicrosoftILoggerTarget.

MicrosoftILoggerTarget can help:

var loggerTarget = new NLog.Extensions.Logging.MicrosoftILoggerTarget(azureILogger);
loggerTarget.Layout = new NLog.Layouts.Layout("${message}${exception:format=tostring}");  // Can also be JsonLayout
var nlogConfig = new NLog.Config.LoggingConfiguration();
nlogConfig.AddRuleForAllLevels(loggerTarget);
NLog.LogManager.Configuration = nlogConfig;
var nlogLogger = NLog.LogManager.GetCurrentClassLogger();
nlogLogger.Info("Hello World");

This will redirect the output of NLog into the Azure ILogger, so it will be stored where the Azure Function is configure to store its logging.

Writing directly to cloud storage

It is possible for the lambda / function to write directly to the cloud storage, but it might be more fragile. The cloud usually has high latency so the execution might be affected by timeouts/retries etc. Make sure to use the matching region of the cloud storage. Very important to flush before exit.

See the different NLog Integrations (Cloud)