【问题标题】:Why Serilog PostgreSQL sink is not working through Configuration?为什么 Serilog PostgreSQL 接收器无法通过配置工作?
【发布时间】:2021-03-17 21:35:06
【问题描述】:

我已经通过代码尝试了用于 Serilog 的 PostgreSQL sink,它的工作原理就像一个魅力。
这是工作代码:

    static void Main(string[] args)
    {
        var connectionString = "Server=localhost; Port=5432; Database=subscriptions_log; User Id=postgres;Password=postgres";
        string tableName = "errorlog";

        IDictionary<string, ColumnWriterBase> columnWriters = new Dictionary<string, ColumnWriterBase>
        {
            {"message", new RenderedMessageColumnWriter(NpgsqlDbType.Text) },
            {"level", new LevelColumnWriter(true, NpgsqlDbType.Varchar) },
            {"raise_date", new TimestampColumnWriter(NpgsqlDbType.Timestamp) },
            {"exception", new ExceptionColumnWriter(NpgsqlDbType.Text) }
        };

        using var log = new LoggerConfiguration()
            .WriteTo.Console()
            .WriteTo.PostgreSQL(connectionString, tableName, columnWriters)
            .CreateLogger();

        log.Information("Hello, Serilog!");
    }

但是当我通过配置文件使用它时,serlig 在数据库中创建表但没有插入任何行,因为 “Npgsql.NpgsqlBinaryImporter.Complete()” 找不到。
"这里是详细的错误:

Exception while emitting periodic batch from Serilog.Sinks.PostgreSQL.PostgreSQLSink:
        System.MissingMethodException:
        Method not found: 'Void Npgsql.NpgsqlBinaryImporter.Complete()'.
   at Serilog.Sinks.PostgreSQL.PostgreSQLSink.ProcessEventsByCopyCommand(IEnumerable`1 events, NpgsqlConnection connection)
   at Serilog.Sinks.PostgreSQL.PostgreSQLSink.EmitBatch(IEnumerable`1 events)
   at Serilog.Sinks.PeriodicBatching.PeriodicBatchingSink.EmitBatchAsync(IEnumerable`1 events)
   at Serilog.Sinks.PeriodicBatching.PeriodicBatchingSink.OnTick()

项目文件

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0"     />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables"     Version="5.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
    <PackageReference Include="Npgsql" Version="5.0.3" />
    <PackageReference Include="Serilog" Version="2.10.1-dev-01285" />
    <PackageReference Include="Serilog.Settings.Configuration" Version="3.2.0-dev-00264" />
    <PackageReference Include="Serilog.Sinks.Console" Version="4.0.0-dev-00839" />
    <PackageReference Include="Serilog.Sinks.File" Version="5.0.0-dev-00909" />
    <PackageReference Include="Serilog.Sinks.PeriodicBatching" Version="2.3.0" />
    <PackageReference Include="Serilog.Sinks.PostgreSQL" Version="2.2.0" />
    <PackageReference Include="Serilog.Sinks.PostgreSQL.Configuration" Version="1.0.0" />
  </ItemGroup>

</Project>

配置文件

        {
        "Serilog": {
            "Using": [ "Serilog.Sinks.PostgreSQL.Configuration" ],
            "MinimumLevel": "Debug",
            "Enrich": [ "WithMachineName" ],
            "WriteTo": [
                {
                    "Name": "PostgreSQL",
                    "Args": {
                        "connectionString": "LogsDb",
                        "tableName": "errorlogs",
                        "needAutoCreateTable": true
                    }
                }
            ]
        },
        "ConnectionStrings": {
            "LogsDb": "Server=localhost; Port=5432; Database=subscriptions_log; User Id=postgres;Password=postgres"
        },
        "Columns": {
            "message": "RenderedMessageColumnWriter",
            "level": {
                "Name": "LevelColumnWriter",
                "Args": {
                    "renderAsText": true,
                    "dbType": "Varchar"
                }
            },
            "raise_date": "TimestampColumnWriter",
            "exception": "ExceptionColumnWriter"
        }
    }

以及调用方法:

    static void Main(string[] args)
    {
        Serilog.Debugging.SelfLog.Enable(msg => Debug.WriteLine(msg));
        Serilog.Debugging.SelfLog.Enable(Console.Error);

        IConfiguration configuration = new ConfigurationBuilder()
            .SetBasePath(Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..")))
            .AddJsonFile("serilog.json", optional: false, reloadOnChange: true)
            .AddEnvironmentVariables()
            .AddCommandLine(args)
            .Build();

        using var log = new LoggerConfiguration()
            .ReadFrom.Configuration(configuration)
            .CreateLogger();

        log.Error("Hello, Serilog!");
    }

配置文件与here 描述的完全相同。出于测试目的,我尝试使用 .net 5.0 和 3.1 均未成功。
不幸的是,我无法通过代码使用它,因为我正在使用使用 serilog 记录到 sql server 的 3rd 方库,我只能通过配置切换到 PostgrSQL。有什么帮助吗?

【问题讨论】:

    标签: .net serilog serilog-postgresql


    【解决方案1】:

    您收到此错误的原因是因为Serilog.Sinks.PostgreSQL 依赖于 Npgsql v4.0.2,但您强制将 Npgsql 升级到与最新版本的 Serilog.Sinks.PostgreSQL (@987654324) 不兼容的v5.0.3 @ 在撰写本文时)。

    <PackageReference Include="Npgsql" Version="5.0.3" />
    

    这是 Npgsql 中导致 MissingMethodException 的二进制重大更改,因为... 4.x 中预期的方法在 5.x 中不再存在。

    一个直接的解决方案是删除 Npgsql 包引用并使用将由 Serilog.Sinks.PostgreSQL 传递添加的 v4.2.0。或者,您可以将 Npgsql 升级到最新的 4.x 版本,在撰写本文时为 v4.1.8

    长期的解决方案是在Serilog.Sinks.PostgreSQL 的 repo 中打开一个问题,以便他们可以发布一个依赖 Npgsql 5.x 的新版本。

    更新Serilog.Sinks.PostgreSQL 似乎不再维护,这里有一个可用的分支:https://github.com/SeppPenner/SerilogSinkForPostgreSQL,它是最新的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多