【问题标题】:NLog with Windsor Castle - how to save log to database (.NET Core 3.1)NLog with Windsor Castle - 如何将日志保存到数据库 (.NET Core 3.1)
【发布时间】:2021-08-19 15:10:57
【问题描述】:

我正在处理以下问题 - 经过多次尝试后,我能够将 NLog 与温莎城堡一起使用,但它仅在我将消息字符串记录到文件时才有效。现在想把自定义的日志信息保存到数据库中但是真的不知道怎么做。

我的 nlog.config:

<targets>
  <target name="file" xsi:type="File" fileName="C:\temp\example.log" layout="${longdate}|${level:uppercase=true}|${message}|${exception}" />
  <target name="database" xsi:type="Database"    
   connectionString = "connectionString"
   commandText="INSERT INTO [dbo].[EventLog]
   (
    [CreateDate],
    [UserProfileId],
    [IsError],
    [Type],
    [Username],
    [Message],
    [Description],
    [StackTrace],
    [AddressIP]
    ) VALUES (
    @CreateDate,
    @UserProfileId,
    @IsError,
    @Type,
    @Username,
    @Message,
    @Description,
    @StackTrace,
    @AddressIP
   )">
   <parameter name="@CreateDate" layout="${event-properties:item=CreateDate}" />
   <parameter name="@UserProfileId" layout="${event-properties:item=UserProfileId}" />
   <parameter name="@IsError" layout="${event-properties:item=IsError}" />
   <parameter name="@Type" layout="${event-properties:item=Type}" />
   <parameter name="@Username" layout="${event-properties:item=Username}" />
   <parameter name="@Message" layout="${event-properties:item=Message}" />
   <parameter name="@Description" layout="${event-properties:item=Description}" />
   <parameter name="@StackTrace" layout="${event-properties:item=StackTrace}" />
   <parameter name="@AddressIP" layout="${event-properties:item=AddressIP}" />
  </target>
</targets>
<rules>
  <logger name="logger" minlevel="Trace" writeTo="database" />
  <logger name="*" minlevel="Trace" writeTo="file" />
</rules>

有了这个配置(带有注释的数据库部分),我可以将日志写入“example.log”。

 _logger.Info("test-info");

我尝试过这样的事情:

_logger.InfoFormat("\"CreateDate\": {0}, \"Message\": {1}, \"IsError\": {2}, \"Type\": {3}, \"Id\": {4}",
            new object[] {
                DateTime.Now,
                "abcd",
                true,
                1,
                Guid.NewGuid()
            });

但异常表示不可能将 Id 解析为唯一标识符。我尝试在 nlog.config 中使用 CASE-END,我发现 Id 没有作为参数传递(可能还有其他数据)。

第一个例外:

System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting from a character string to uniqueidentifier.

添加后 CASE WHEN @Id = '' THEN NULL ELSE convert(uniqueidentifier, @Id) END,

System.Data.SqlClient.SqlException (0x80131904): Cannot insert the value NULL into column 'Id', table 'ERS.opt.Dev.dbo.EventLog'; column does not allow nulls. INSERT fails.

如何格式化日志以传递上述模式中的数据并将其保存到数据库?

【问题讨论】:

  • 你试过把&lt;logger name="logger" minlevel="Trace" writeTo="database" /&gt;改成&lt;logger name="*" minlevel="Trace" writeTo="database" /&gt;吗?
  • 您是否检查过 NLog InternalLogger 的输出是否有任何错误:github.com/NLog/NLog/wiki/Internal-Logging
  • 但是现在的问题是我不知道如何将参数传递给这个日志 - 有只写消息的方法,而不是复杂的日志。 InternalLogger 没有显示任何错误。

标签: castle-windsor asp.net-core-3.1 nlog


【解决方案1】:

您可以使用消息模板来执行结构化日志记录:

_logger.InfoFormat("\"CreateDate\": {CreateDate}, \"Message\": {Message}, \"IsError\": {IsError}, \"Type\": {Type}, \"Id\": {Id}",
            new object[] {
                DateTime.Now,
                "abcd",
                true,
                1,
                Guid.NewGuid()
            });

另请参阅:https://github.com/NLog/NLog/wiki/How-to-use-structured-logging

请注意,默认情况下 database-target &lt;parameter&gt; 使用 DbType="String"。如果 database-column 是用其他数据类型定义的,那么请确保显式指定 DbType 以便它与该列匹配。

【讨论】:

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