简体   繁体   English

.NET 核心。 使用 Serilog 时日志未发送到 Loggly

[英].NET Core. Logs not sent to Loggly, while using Serilog

I have a small ASP.NET Core 3.1 project that should execute the Odata request and then log either info or exception into the Loggly.我有一个小的 ASP.NET Core 3.1 项目,它应该执行 Odata 请求,然后将信息或异常记录到 Loggly 中。 I'm using Serilog for this.我为此使用 Serilog。

But for some reason, it only sends the very first message from the Program.cs only ( Log.Debug($"DEBUG: Starting at:{DateTime.Now}"); ), but does not send anything other than that.但出于某种原因,它只发送来自 Program.cs 的第一条消息( Log.Debug($"DEBUG: Starting at:{DateTime.Now}"); ),但不发送除此之外的任何内容。 While it works fine for the Console or File logging.虽然它适用于控制台或文件日志记录。 I have tried to fake an exception to trigger the Error logging.我试图伪造一个异常来触发错误记录。 But nothing works (in the Loggly).但没有任何效果(在 Loggly 中)。

Any suggestions on why is that and how to make it work properly?关于为什么会这样以及如何使其正常工作的任何建议?

Here is my code:这是我的代码:

Program.cs:程序.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();
}

Startup.cs:启动.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();
    }
}

Controller.cs Controller.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 (this just outputs logs with some request's parameters): 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 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": "*"
    
    }

You can try to clear providers:您可以尝试清除提供者:

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

Also, if you have configured logging on Host, you don't need to put the additional configuration into Startup.cs另外,如果你已经在主机上配置了日志记录,你不需要把额外的配置放到Startup.cs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM