1

I have a React app that uses a .NET 7 API. We are using Graylog for logging. The idea is to provide an API endpoint for the react app to POST its error logs. I want to use a different log source if the errors are coming from the web app. In order to do it, I have written a middleware class based on the route of the request. If /logs route is hit, I add a new logger configuration to the Logger factory.

Middleware class:

using Gelf.Extensions.Logging;

namespace MyProject1.Api.Extensions
{
    public class LoggingMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IConfiguration _configuration;
        private readonly ILoggerFactory _loggerFactory;

        public LoggingMiddleware(
            RequestDelegate next,
            IConfiguration configuration,
            ILoggerFactory loggerFactory)
        {
            _next = next;
            _configuration = configuration;
            _loggerFactory = loggerFactory;
        }

        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Path.StartsWithSegments("/logs"))
            {
                var gelfOptions = new GelfLoggerOptions();
                _configuration.GetSection("Logging:WebAppGELF").Bind(gelfOptions);
                gelfOptions.AdditionalFields["machine_name"] = Environment.MachineName;

                _loggerFactory.AddGelf(gelfOptions);

                await _next(context);
            }
            else
            {
                await _next(context);
            }
        }
    }
}

Here's the logging section in appsettings.json:

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    },
    "GELF": {
      "Host": "xxx.graylog.com",
      "LogSource": "API"
    },
    "WebAppGELF": {
      "Host": "xxx.graylog.com",
      "LogSource": "WebApp"
    }
  }

The configuration in program.cs:

app.UseMiddleware<LoggingMiddleware>();

using (var serviceScope = app.Services.CreateScope())
{
    var services = serviceScope.ServiceProvider;
    var logger = services.GetRequiredService<MyProject1.Logging.IMyLogger<MyProject1.Api.Extensions.Project1Exception>>();
    app.ConfigureExceptionHandler(logger);
}

With the above, two log entries are being written every time the /logs endpoint is hit. Content is the same but one log entry contains LogSource : API and the other contains LogSource : WebApp. I assume this is happening because the logger factory contains two loggers and both are being invoked.

What's the right way of doing this? Basically, I want to use different loggers or logging configurations based on the controller or class the logger is being used in.

Junaid
  • 941
  • 2
  • 14
  • 38
  • Do you want inject different loggers for controllers ? Have a look at [this](https://stackoverflow.com/questions/69440907/inject-different-loggers-for-controllers-in-asp-net-mvc). Or log from other classes, see [this](https://stackoverflow.com/questions/39031585/how-do-i-log-from-other-classes-than-the-controller-in-asp-net-core) – Qing Guo Aug 17 '23 at 07:43

0 Answers0