0

我有一个小的 ASP.NET Core 3.1 项目,它应该执行 Odata 请求,然后将信息或异常记录到 Loggly。我正在为此使用 Serilog。

但由于某种原因,它只发送来自 Program.cs 的第一条消息(Log.Debug($"DEBUG: Starting at:{DateTime.Now}");),但不发送除此之外的任何内容。虽然它适用于控制台或文件日志记录。我试图伪造一个异常来触发错误日志记录。但没有任何效果(在 Loggly 中)。

关于为什么会这样以及如何使其正常工作的任何建议?

这是我的代码:

程序.cs:

public class Program
{
    public static void Main(string[] args)
    {
        var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();

        Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(configuration)
            .CreateLogger();

        try
        {
            Log.Debug($"DEBUG: Starting at:{DateTime.Now}");
            CreateHostBuilder(args).Build().Run();
            Log.Debug($"DEBUG: Host created");
        }
        catch (Exception ex)
        {
            Log.Error("Oops something failed!");
            throw new Exception(ex.Message);
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            .UseSerilog();
}

启动.cs:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }
    
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddDbContext<OdataTestObjectContext>(options =>
        {
            options.UseSqlServer(Configuration["ConnectionStrings:Database"]);
        });
        services.AddControllers().AddOData(opt =>
            opt.Filter().Expand().Select().OrderBy().Count().SetMaxTop(100)
                .AddRouteComponents("odata", GetEdmModel()));

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "OdataTest", Version = "v1" });
            c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
        });

        var appSettings = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); 
        var serilogConfig = new LoggerConfiguration().ReadFrom.Configuration(appSettings);  
        services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(serilogConfig.CreateLogger(), true)); 

        services.AddMvc(opts => { opts.Filters.Add(new AutoLogAttribute()); });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger(c =>
            {
                c.RouteTemplate = "/swagger/{documentName}/swagger.json";
            });
            app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "OdataTest v1"));
        }

        app.UseHttpsRedirection();
        ////Send "~/$odata" to debug routing if enable the following middleware
        app.UseODataRouteDebug();
        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

    private static IEdmModel GetEdmModel()
    {
        var builder = new ODataConventionModelBuilder();
        var entitySet = builder.EntitySet<TestObject>("TestObjects");
        entitySet.EntityType.HasKey(entity => entity.Id);
        return builder.GetEdmModel();
    }
}

控制器.cs

[ApiController]
[Route("OData")]
public class TestController : ODataController
{
    private readonly OdataTestObjectContext _context;
    private readonly ILogger<TestController> _logger;

    public TestController(ILogger<TestController> logger, OdataTestObjectContext context)
    {
        _context = context;
        _logger = logger;
    }

    [ApiExplorerSettings(IgnoreApi = true)]
    [EnableQuery]
    public IActionResult Get()
    {
        try
        {
            return Ok(_context.TestObjects);
        }
        catch (Exception ex)
        {
            _logger.LogError("Error happened for Default query! - {0}", ex.Message);
            throw new InvalidOperationException(ex.Message);
        }
    }

    [HttpGet("Top({top})")]
    [EnableQuery]
    public IEnumerable<TestObject> GetTop(int top)
    {
        return _context.TestObjects.OrderByDescending(x => x.Id).Take(top);
    }

    [HttpGet("Enumerable")]
    [EnableQuery]
    public IEnumerable<TestObject> Enumerable()
    {         
        try
        {
            _logger.LogDebug("Executing ENUMERABLE now.");
            //string a = "asd";
            //int s = Convert.ToInt32(a);
            var results = _context.SaleInvoicesAndProducts.AsEnumerable();
            int z = 1;
            if (results.Any())
                z = 0;
            int i = 10 / z;
            return results;
        }
        catch (Exception ex)
        {
            _logger.LogError("Error happened for Enumerable query! - {0}", ex.Message);
            throw new Exception();
        }
    }

AutoLogAttribute.cs(这只是输出带有一些请求参数的日志):

   public class AutoLogAttribute : TypeFilterAttribute
    {
        public AutoLogAttribute() : base(typeof(AutoLogActionFilterImpl))
        {

        }

        private class AutoLogActionFilterImpl : IActionFilter
        {
            private readonly ILogger<AutoLogAttribute> _logger;
            public AutoLogActionFilterImpl(ILoggerFactory loggerFactory)
            {
                _logger = loggerFactory.CreateLogger<AutoLogAttribute>();
            }

            public void OnActionExecuting(ActionExecutingContext context)
            {
                // perform some business logic work
                _logger.LogInformation($"queryString: {context.HttpContext.Request.QueryString}");

                _logger.LogDebug($"queryString (Debug): {context.HttpContext.Request.QueryString}");
            }

            public void OnActionExecuted(ActionExecutedContext context)
            {
                //TODO: log body content and response as well
                _logger.LogInformation($"host: {context.HttpContext.Request.Host}");
                _logger.LogInformation($"patheAndQuery: {context.HttpContext.Request.GetEncodedPathAndQuery()}");

                _logger.LogDebug($"path (Debug): {context.HttpContext.Request.Path}");
                _logger.LogDebug($"host (Debug): {context.HttpContext.Request.Host}");
                _logger.LogDebug($"patheAndQuery (Debug): {context.HttpContext.Request.GetEncodedPathAndQuery()}");
            }
        }
    }

appsetting.json

    {
      "Serilog": {
        "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.Loggly" ],
        "MinimumLevel": {
          "Default": "Debug",
          "Override": {
            "Microsoft": "Debug",
            "System": "Debug"
          }
        },
        "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
        "WriteTo": [
          { "Name": "Console" },
          {
            "Name": "File",
            "Args": { "path": "C:\\ODATA\\log.json" }
          },
          {
            "Name": "Loggly",
            "Args": {
              "customerToken": "mytoken",
              "tags": "mytest"
            }
          }
        ],
    },
  "ConnectionStrings": {
    "Database": "Server=(localdb)\\MSSQLLocalDB;Initial Catalog=MyTestDB;Integrated Security=true;MultiSubnetFailover=True;MultipleActiveResultSets=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
    
    }
4

1 回答 1

0

您可以尝试清除提供者:

 Host
  ****
 .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
        })
 .UseSerilog();

另外,如果您已经在 Host 上配置了日志记录,则不需要将额外的配置放入Startup.cs

于 2022-02-09T23:51:06.870 回答