Search code examples
asp.net-coreserilog

Serilog dotnet core function app and sql sink


I need to use dotnet5 with Azure Functions so followed the guidance to create a new solution: https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide.

This worked great so next job was to add in serilog with sinks for console and sql server.

I have added nuget packages:

  • Serilog.AspNetCore v4.1.0
  • Serilog.Sinks.MSSqlServer v5.6.0

Here is the Program.Main:

static void Main(string[] args)
{
    string EventName = "Main";
    var columnOptions = new ColumnOptions
    {
        AdditionalColumns = new Collection<SqlColumn>
        {
            new SqlColumn
                {ColumnName = "EventName", DataType = SqlDbType.NVarChar, DataLength = 32, NonClusteredIndex = true}
        }
    };

    Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Override("Microsoft.Azure", LogEventLevel.Warning)
                .Enrich.FromLogContext()
                .WriteTo.Console()
                .WriteTo.MSSqlServer(
                    logEventFormatter: new RenderedCompactJsonFormatter(),
                    restrictedToMinimumLevel: LogEventLevel.Debug,
                    connectionString: "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SmsRouter",
                    sinkOptions: new MSSqlServerSinkOptions
                    {
                        TableName = "LogEvents",
                        AutoCreateSqlTable = true,
                    },
                    columnOptions: columnOptions)
                .CreateLogger();

    try
    {
        Log.Information("Starting up {EventName}", EventName);
        var host = new HostBuilder()
        .UseSerilog()
        .ConfigureFunctionsWorkerDefaults()
        .ConfigureServices(s =>
        {
            //services configured here
        })
        .Build();

        host.Run();
    }
    catch (Exception ex)
    {
        Log.Fatal(ex, "Application start-up failed");
    }
    finally
    {
        Log.CloseAndFlush();
    }
}

You can see the line Log.Information("Starting up {EventName}", EventName); This works and is logged to both console and Sql Server :)

After the App is started it will sit and wait for a Http request - as shown below:

[Function("SendSimpleSms")]
public async Task<QueueAndHttpOutputType> RunSimple([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
    FunctionContext executionContext)
{
    string EventName = "SendSimpleSms";
    try
    {
        Log.Information("Starting: {EventName}", EventName);

My problem is, this log request "Starting: SendSimpleSms" is logged to the console window but not to Sql Server.

Anyone see what I have wrong please?


Solution

  • Thanks to Panagiotis Kanavos for making me aware of the Serilog self-logging.

    I added the following into program.main, after the LoggerConfiguration:

    Serilog.Debugging.SelfLog.Enable(Console.Error);
    

    This then made me aware that the sql sink was unable to log because the length of a custom property exceeded that of its column