简体   繁体   English

为什么 Serilog PostgreSQL 接收器无法通过配置工作?

[英]Why Serilog PostgreSQL sink is not working through Configuration?

I have tried PostgreSQL sink for Serilog through code and it works like a charm.我已经通过代码为 Serilog 尝试了 PostgreSQL 接收器,它就像一个魅力。
Here is working code:这是工作代码:

    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!");
    }

But when I use it through configuration file serlig creates table in the database but does not insert any rows because of "Npgsql.NpgsqlBinaryImporter.Complete()" not found.但是当我通过配置文件使用它时,serlig 在数据库中创建表但由于找不到“Npgsql.NpgsqlBinaryImporter.Complete()”而没有插入任何行。
"Here is detailed error: “这是详细的错误:

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()

ProjectFile项目文件

<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>

Config File配置文件

        {
        "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"
        }
    }

And the Calling Method:以及调用方法:

    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!");
    }

Configuration file is exactly as described here .配置文件与此处描述的完全相同。 For test purpose I tried with .net 5.0 and 3.1 with out success.出于测试目的,我尝试使用 .net 5.0 和 3.1 均未成功。
Unfortunately I can't use it through code as I am using a 3rd party library that uses serilog for logging to sql server and I have to switch to PostgrSQL only through configuration.不幸的是,我无法通过代码使用它,因为我正在使用使用 serilog 记录到 sql 服务器的第 3 方库,我只能通过配置切换到 PostgrSQL。 Any help?有什么帮助吗?

The reason you get this error is because Serilog.Sinks.PostgreSQL depends on Npgsql v4.0.2 , but you are forcing an upgrade of Npgsql to v5.0.3 which is not compatible with the latest version of Serilog.Sinks.PostgreSQL ( v2.2.0 as of this writing).您收到此错误的原因是因为Serilog.Sinks.PostgreSQL依赖于 Npgsql v4.0.2 ,但是您强制将 Npgsql 升级到与最新版本的 Serilog.Sinks.PostgreSQL ( v2.2.0 )不兼容的v5.0.3截至撰写本文时)。

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

This is binary breaking change in Npgsql which causes the MissingMethodException because... The method expected in 4.x no longer exists in 5.x.这是 Npgsql 中导致MissingMethodException的二进制重大更改,因为... 4.x 中预期的方法在 5.x 中不再存在。

An immediate solution for you, is to remove the Npgsql package reference and use v4.2.0 which will be added transitively by Serilog.Sinks.PostgreSQL.一个直接的解决方案是删除Npgsql package 引用并使用将由 Serilog.Sinks.PostgreSQL 传递添加的 v4.2.0。 Alternatively you can upgrade Npgsql to the latest 4.x version which is v4.1.8 as of this writing.或者,您可以将 Npgsql 升级到撰写本文时的最新 4.x 版本,即v4.1.8

The long-term solution is to open an issue in the repo of Serilog.Sinks.PostgreSQL , so that they can release a new version that takes a dependency on Npgsql 5.x.长期的解决方案是在Serilog.Sinks.PostgreSQL的 repo 中打开一个问题,以便他们可以发布一个依赖 Npgsql 5.x 的新版本。

Update : It looks like the Serilog.Sinks.PostgreSQL is no longer maintained, and there's a fork of available here: https://github.com/SeppPenner/SerilogSinkForPostgreSQL which is up-to-date更新:看起来Serilog.Sinks.PostgreSQL不再维护,这里有一个分支: https://github.com/SeppPenner/SerilogSinkForPostgreSQL这是最新的

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

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