manigandham / serilog-sinks-googlecloudlogging

Serilog sink that writes events to Google Cloud Logging
MIT License
41 stars 25 forks source link

Support for Microsoft.Extensions.Logging.ILogger #66

Closed pflajszer closed 1 year ago

pflajszer commented 1 year ago

Hello, Thanks for this awesome library.

I'm having one major issue that prevents me from using this as my daily driver. No logs are written to GCP when using ILogger and ILogger<T>

Program.cs:


var config = new GoogleCloudLoggingSinkOptions
{
    ProjectId = "MY_PROJECT_ID",
    GoogleCredentialJson = "MY_GOOGLE_CREDENTIALS",
    LogName = "MY_LOG_NAME",
};
Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration)
    .MinimumLevel.Verbose()
    .WriteTo.GoogleCloudLogging(config)
    .WriteTo.Console()
    .WriteTo.Seq(serverUrl: "http://localhost:8081")
    .Enrich.FromLogContext()
    .Enrich.WithMachineName()
    .Enrich.WithProcessId()
    .Enrich.WithThreadId()
    .CreateLogger();

// Add services to the container.
builder.Services.AddApplicationServices();
builder.Services.AddInfrastructureServices(builder.Configuration);
builder.Services.AddWebUIServices();

builder.Host.UseSerilog();
Log.Information("Application starting up");
var app = builder.Build();

app.UseSerilogRequestLogging();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseOpenApi();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

The above logs the "Application starting up" log (as I'm using Log.Information), this also works OK outside of the Program.cs file. It doesn't work when injecting ILogger, ILogger<T> from Microsoft.Extensions.Logging.ILogger library. It's worth noting it also does not work with Serilog.ILogger either.

Example that does not work:

using Microsoft.Extensions.Logging;

namespace MyApp;

public class SomeService
{
    private readonly ILogger _logger;

    public SomeService(ILogger<SomeService> logger)
    {
        _logger = logger;
    }

    public async Task DoSomething(CancellationToken cancellationToken)
    {
        var msg = "I'm logging something to several places";
        _logger.LogInformation(msg);
        Serilog.Log.Information(msg);
    }
}

From the above, the Log.Information log will be written to all sinks, the ILogger message will be written to all but GCP.

manigandham commented 1 year ago

ILogger support is automatically provided by Serilog and the TestWeb project has examples: https://github.com/manigandham/serilog-sinks-googlecloudlogging/blob/5c25042e1dd98cabf5c05477db3dad4ae658da06/src/TestWeb/Program.cs#L55

Try running that project with your config and see what happens. You can also enable the Serilog SelfLog diagnostics if the issue is only with GCP.

https://github.com/serilog/serilog/wiki/Debugging-and-Diagnostics

pflajszer commented 1 year ago

thanks, I've missed a property in GoogleCloudLoggingSinkOptions that I'd argue it should be set to false by default - UseSourceContextAsLogName. I've explicitly set the LogName when constructing the options, but it gets overwritten by the SourceContext.

Thanks for your help!

manigandham commented 1 year ago

Ok glad its solved.

Also the options are described on the readme: https://github.com/manigandham/serilog-sinks-googlecloudlogging#sink-options

The SourceContext setting matches the default behavior of .NET logging and is set so that you can see where a log entry comes from. This is also referred to as the category and allows for filtering by name prefix: https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line#log-category

pflajszer commented 1 year ago

Ah, this is insightful. Thanks a lot!