使用 Serilog 记录到 SQLite 接收器

问题描述 投票:0回答:3

我无法使 SeriLog 与 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; }
}

程序.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));
    }

启动.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.");
c# sqlite logging .net-5 serilog
3个回答
3
投票

有同样的问题。 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();

0
投票

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

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

解决方案:我在测试时将

batchSize
方法中的
WriteTo.SQLite()
参数值设置为
1
。然后,正如预期的那样,将原木插入两个水槽中。在第一个场景中表为空,因为
batchSize
的默认值为100。更改后的记录器配置(仅用于测试场景):

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

另一个选项:在关闭应用程序之前调用

Log.CloseAndFlush()


0
投票

我刚刚在我的代码中遇到了类似的问题。

在 appsettings.json 中指定“WriteTo”,如下所示,对我来说很有效。

"WriteTo": [
{
    "Name": "SQLite",
    "Args": {
        "sqliteDbPath": "C:\\MyFolder\\My.db",
        "tableName": "Logs"
    }
}

您还可以指定相对路径

"WriteTo": [
{
    "Name": "SQLite",
    "Args": {
        "sqliteDbPath": "Logs/My.db",
        "tableName": "Logs"
    }
}

但请注意,您将找到您的数据库相对于应用程序的 bin 文件夹。 我的位于 MyWebProject/bin/Debug/net7.0/Logs/My.db

我希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.