web-dev-qa-db-ja.com

Serilog.Sinks.MSSqlServerがカスタム列を埋めない

周りを見回しましたが、有効な解決策を見つけることができませんでした。すべての例が同じように見えるので、私は何か明白なものを見落としているに違いないと思います。また、これは.NET CoreとSerilogを使用した私の最初の実際のプロジェクトです。

問題

appsettings.jsonで定義され、パイプラインのミドルウェアを介して追加されたデータベースの独自の列にいくつかのカスタムプロパティを(serilogを使用して)ログに記録しようとしています。ただし、同じ項目がプロパティXML列に正しく入力されていても、値はNULLのままです。

したがって、認証されたユーザーに期待される新しいプロパティがあります。

<properties>
    <property key="UserId">ff88ddb9-6f5a-4ad5-a2a8-1d016ff99398</property>
    <property key="UserName">ernst</property>
<properties>

ただし、クエリの最適化のために、これらの値を独自の列に追加したいと思います。

コード

コードは.NET Core 2.1以降で、次のようにSerilogをセットアップしました https://github.com/serilog/serilog-aspnetcore/blob/dev/samples/SimpleWebSample/Program.cs =:

private static IConfiguration Configuration { get; } = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
            .AddEnvironmentVariables()
            .Build();

public static int Main(string[] args)
{
  Log.Logger = new LoggerConfiguration()
      .ReadFrom.Configuration(Configuration)
      .Enrich.FromLogContext()
      .MinimumLevel.Debug()
      .CreateLogger();
  try 
  {
    Log.Information($"Starting web Host in {Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"} environment, version {Util.Version.Long}");
    BuildWebHost(args).Run();
    return 0;
  }
  catch (Exception ex)
  {
    Log.Fatal(ex, "Host terminated unexpectedly");
    return 1;
  }
  finally
  {
    Log.CloseAndFlush();
  }
}

 private static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseConfiguration(Configuration)
                .UseSerilog()
                .CaptureStartupErrors(true)
                .Build();

情報を追加するには、ミドルウェアでLogContext.PushPropertyを使用します。

構成の関連部分:

"Serilog": {
    "Using": [ "Serilog.Sinks.MSSqlServer" ],
    "MinimumLevel": "Debug",
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
    "WriteTo": [
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "Data Source=localhost;Database=MyDb;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
          "tableName": "SeriLog_Custom",
          "autoCreateSqlTable": true,
          "restrictedToMinimumLevel": "Information",
          "columnOptionsSection": {
            "customColumns": [
              {
                "ColumnName": "UserId",
                "DataType": "nvarchar",
                "DataLength": 450,
                "AllowNull": true
              },
              {
                "ColumnName": "UserName",
                "DataType": "nvarchar",
                "DataLength": 256,
                "AllowNull": true

              }
            ]
          }
        }
      }
    ]
  }

さらに、カスタム列を埋めないだけでなく、データベースもこれらの列なしで標準的な方法で作成されるため、手動で追加しました。

これは構成の問題を示している可能性がありますか?

テーブルを作成するSQL:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[SeriLog_Custom](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Message] [nvarchar](max) NULL,
    [MessageTemplate] [nvarchar](max) NULL,
    [Level] [nvarchar](128) NULL,
    [TimeStamp] [datetime] NOT NULL,
    [Exception] [nvarchar](max) NULL,
    [Properties] [xml] NULL,
    [UserId] [nvarchar](450) NULL,
    [UserName] [nvarchar](256) NULL,
 CONSTRAINT [PK_SeriLog_Custom] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

これで、必要な情報を取得できます:

SELECT [Id]
      ,[Message]
      ,[MessageTemplate]
      ,[Level]
      ,[TimeStamp]
      ,[Exception]
      ,[UserId]
      ,[UserName]
      ,[Properties].value('(//property[@key="UserName"]/node())[1]', 'nvarchar(max)') as UserName
      ,[Properties]
  FROM [ECSControl].[dbo].[SeriLog_ECMonitor]
  where [Properties].value('(//property[@key="UserName"]/node())[1]', 'nvarchar(max)') = 'ernst'
  order by id desc;

しかし、私はそれにアクセスしたいです:

SELECT [Id]
      ,[Message]
      ,[MessageTemplate]
      ,[Level]
      ,[TimeStamp]
      ,[Exception]
      ,[UserId]
      ,[UserName]
      ,[Properties]
  FROM [ECSControl].[dbo].[SeriLog_ECMonitor]
  where  UserName = 'ernst'
  order by id desc;
10
Ernst

Serilog.Sinks.MSSqlServer (5.1.2)の最新の安定バージョンは_Microsoft.Extensions.Configuration_をサポートしていません。 Serilog.Settings.Configuration (2.6.1)ref )の最新の安定バージョンと同じです。

プレリリースバージョン_Serilog.Sinks.MSSqlServer 5.1.3-dev-00204_および_Serilog.Settings.Configuration 3.0.0-dev-00119_に更新すると、この問題が解決します。

10
Alex Riabov