An extension to enable logging through Serilog for Microsoft Azure WebJobs.
This package routes Azure WebJob log messages through Serilog, so you can get information about WebJobs internal operations and function logs to the same Serilog sinks as the rest of your application events.
First, install the Serilog.Extensions.WebJobs NuGet package into your Azure WebJobs console app.
NOTE: The Azure WebJobs SDK already outputs log messages to the console, therefore unless you require extra features of Serilog (additional sinks, extra enrichers, etc.), no additional packages are required.
Install-Package Serilog.Extensions.WebJobs
Next, in your application's Main
method, configure Serilog first:
using Microsoft.Azure.WebJobs;
using Serilog;
class Program
{
static void Main()
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.CreateLogger();
// Other startup code
Finally, configure the Azure WebJob host to use Serilog by adding a call to UseSerilog()
:
var config = new JobHostConfiguration();
config.UseSerilog();
var host = new JobHost(config); // <-- Don't forget it inject to config into the job host.
// The following code ensures that the WebJob will be running continuously
host.RunAndBlock();
}
}
That's all the initialization complete. If you now set-up additional sinks, both the internal WebJob logs, and the logs from any of your functions will gp through Serilog.
Now that Serilog has been configured, it's now possible to use Serilog directly within the WebJob functions.
Instead of writing WebJob functions that take a TextWriter
log like this:
using System.IO;
using Microsoft.Azure.WebJobs;
public class Functions
{
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public static void ProcessQueueMessage([QueueTrigger("queue")] string message, TextWriter log)
{
log.WriteLine(message);
}
}
You can now specify an ILogger
log as a parameter instead:
using Microsoft.Azure.WebJobs;
using Serilog;
public class Functions
{
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public static void ProcessQueueMessage([QueueTrigger("queue")] string message, ILogger log)
{
log.Information(message);
}
}
Any logs written to the Serilog ILogger
will be written to both Serilog, and to the underlying stream that would otherwise have been written to using the TextWriter
. This ensures that logs still show up in the Microsoft Azure WebJobs dashboard.
NOTE: You must inject the ILogger
rather than using the global Log.Logger
otherwise the log messages will not be written to the Microsoft Azure WebJobs dashboard. You will also loose the added benefits of Automatic log message property enrichment.
An additional benefit of using an injected ILogger
into a WebJob function is that the log context is enriched with the FunctionInstanceId property. The FunctionInstanceId property is a unique identifier for every function invocation.
This proves to be very useful when logging to a structured log server, such as Seq.
To demonstrate this feature the example function above had been updated to:
using Microsoft.Azure.WebJobs;
using Serilog;
public class Functions
{
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public static void ProcessQueueMessage([QueueTrigger("queue")] string message, ILogger log)
{
log.Information("About to process the {Message} @ {StartTime:R}", message, DateTime.UtcNow);
await Task.Delay(2000);
log.Information("Additional processing information.");
await Task.Delay(2000);
log.Information("Completed processing the {Message} @ {EndTime:R}", message, DateTime.UtcNow);
}
}
When the function now executes with Seq logging, it provides the possibility to filter by FunctionInstanceId.