使用Serilog到SQLite接收器的日志记录

z9gpfhce  于 2023-01-05  发布在  SQLite
关注(0)|答案(2)|浏览(314)

不能使SeriLogSQLite接收器一起工作。

完整源代码:

https://github.com/affableashish/tips-and-tricks/tree/feature/serilog-to-sqlite
我的项目设置如下:
| 我已安装的软件包:|我的SQLite数据库:|
| - ------| - ------|
|

|

|
我的appsettings.json文件看起来像这样:

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "System": "Error",
        "Microsoft": "Error"
      }
    },
    "WriteTo": [
      {
        "Name": "SQLite",
        "Args": {
          "connectionString": "Data Source=WebApp.db",
          "tableName": "Log",
          "batchSize": 1,
          "autoCreateSqlTable": true
        }
      },
      {
        "Name": "Console",
        "Args": {
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} {MachineName} {EnvironmentUserName} [{Level:u4}] <{ThreadId}> [{SourceContext:l}] {Message:lj}{NewLine}{Exception}"
        },
        "theme": "AnsiConsoleTheme.Literate"
      }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId", "WithEnvironmentUserName" ]
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "WebAppConnection": "Data Source=WebApp.db"
  }
}

我的AppDbContext文件如下所示(显示我的日志表):

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    public DbSet<Log> Logs { get; set; }
}

Log模型如下所示:

public class Log
{
    public int Id { get; set; }
    [Column(TypeName = "VARCHAR(500)")]
    public string Message { get; set; }
    [Column(TypeName = "VARCHAR(500)")]
    public string MessageTemplate { get; set; }
    [Column(TypeName = "VARCHAR(500)")]
    public string Level { get; set; }
    public DateTime TimeStamp { get; set; }
    [Column(TypeName = "VARCHAR(800)")]
    public string Exception { get; set; }
    [Column(TypeName = "VARCHAR(500)")]
    public string Properties { get; set; }
}

我的Program.cs如下所示:

public class Program
{
    public static void Main(string[] args)
    {
        // I added this portion - start.
        var environmentName = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "EMPTYENVIRONMENTNAME";
        var config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables()
            .Build();

        ConfigureLogger(config);
 
        // I added this portion - end.

        try
        {
            CreateHostBuilder(args).Build().Run(); // I wrapped this inside try catch.
        }
        catch (Exception ex)
        {
            Serilog.Log.Fatal(ex, "Host terminated unexpectedly");
        }
        finally
        {
            Serilog.Log.Information("Web host stopped.");
            Serilog.Log.CloseAndFlush(); // <-- I added this.
        }
    }

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

     // I added this.
    public static void ConfigureLogger(IConfiguration configuration)
    {
        Serilog.Log.Logger = new LoggerConfiguration()
                                .ReadFrom.Configuration(configuration)
                                .CreateLogger();

        Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));
    }

我的Startup.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.AddRazorPages();

        // I added this portion - start.
        services.AddDbContextPool<AppDbContext>(options =>
        {
            options.UseSqlite(Configuration.GetConnectionString("WebAppConnection")); 
        });

        services.AddScoped<IAppRepository, AppRepository>();
     
        // I added this portion - end.
    }

    // 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();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

现在我试着在这个SQLite接收器上记录一些消息,但是它什么也没有记录,甚至没有抛出任何错误,我只能在控制台上看到日志,而不能在数据库上看到。

_logger.LogInformation("Test message.");

我已经添加了链接到回购协议和步骤来测试它。我会很感激任何帮助。谢谢!

gdrx4gfi

gdrx4gfi1#

有相同的问题。SQLite接收器与MSSqlServer接收器有点不同。您需要将public string RenderedMessage { get; set; }添加到日志实体类中以处理SQLite消息。
这个Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));还应该告诉您数据库连接错误。
下面是我将如何构造sqliteDbPath:

var sqlPath = Environment.CurrentDirectory + @"/WebApp.db";
Log.Logger = new LoggerConfiguration()
    .WriteTo.SQLite(sqliteDbPath:sqlPath,tableName:"Log",batchSize:1)
    .CreateLogger();
neskvpey

neskvpey2#

我今天遇到了类似的问题。当我尝试将一些测试日志记录到两个接收器(File和SQLite)中时-日志只插入到文件中。SQLite数据库已创建,但日志表为空。我的日志记录器配置如下所示:

Log.Logger = new LoggerConfiguration()
    .WriteTo.File("logs.txt")
    .WriteTo.SQLite("logs.db")
    .CreateLogger();

解决方案:我在测试时将WriteTo.SQLite()方法中的batchSize参数值设置为1。然后,日志被插入到两个接收器中,正如预期的那样。在第一个场景中,表为空,因为batchSize的默认值为100。更改后的日志配置(仅针对测试场景):

Log.Logger = new LoggerConfiguration()
    .WriteTo.File("logs.txt")
    .WriteTo.SQLite(sqliteDbPath: "logs.db", batchSize: 1)
    .CreateLogger();

另一种选择:在关闭应用程序之前调用Log.CloseAndFlush()

相关问题