Logging and monitoring

Logging with ILogger

As an alternative to TraceWriter, an instance of ILogger can be used instead.

The advantage of using ILogger instead of TraceWriter is that you get support for structured logging, which allows for richer analytics support. This is helpful if you target your logs at a tool like Application Insights.

[FunctionName("ILoggerHttpLogging")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "GET")]HttpRequestMessage req, ILogger log)
{
    log.LogInformation("101 Azure Function Demo - Logging with ITraceWriter");
    log.LogTrace("Here is a verbose log message");
    log.LogWarning("Here is a warning log message");
    log.LogError("Here is an error log message");
    log.LogCritical("This is a critical log message => {message}", "We have a big problem");
    return req.CreateResponse(HttpStatusCode.OK);
}

Basic logging with TraceWriter

To enable basic logging in your functions, you can include a parameter of type TraceWriter and an instance is provided to you. TraceWriter is defined in the Azure WebJobs SDK. The tracing property in host.json can be used to configure TraceWriter.

[FunctionName("TraceWriterLogging")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "GET")]HttpRequestMessage req, TraceWriter log)
{
    log.Info("101 Azure Function Demo - Basic logging with TraceWriter");
    log.Verbose("Here is a verbose log message");
    log.Warning("Here is a warning log message");
    log.Error("Here is an error log message");

    TraceEvent traceEvent = new TraceEvent(TraceLevel.Info, "and another one!");
    log.Trace(traceEvent);

    return req.CreateResponse(HttpStatusCode.OK);
}

Logging with a third-party logger

If you would rather use your preferred logger, you can easily do so by just adding a NuGet package.

The following code shows a function using the Serilog.Sinks.AzureTableStorage package.

[FunctionName("ThirdPartyLogger")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "GET")]HttpRequestMessage req)
{

    string connectionString = Environment.GetEnvironmentVariable("StorageAccountConnectionString", EnvironmentVariableTarget.Process);

    string tableName = Environment.GetEnvironmentVariable("StorageAccountTableName", EnvironmentVariableTarget.Process);

    Logger log = new LoggerConfiguration()
                .WriteTo.AzureTableStorage(connectionString, storageTableName: tableName, restrictedToMinimumLevel: LogEventLevel.Verbose)
                .CreateLogger();

    log.Debug("Here is a debug message {message}", "with some structured content");

    log.Verbose("Here is a verbose log message");
    log.Warning("Here is a warning log message");
    log.Error("Here is an error log message");

    return req.CreateResponse(HttpStatusCode.OK);
}