PostgreSql 的 NLog 数据库配置问题

NLog DB Configration Problem For PostgreSql

我正在使用 nlog,它对日志文件运行良好,但我也想在数据库中添加日志信息。 但这对我不起作用。 我找不到我的问题。 我正在使用 postgresql 作为数据库。 我正在使用 .NET5 NLog 4.7.10

nlog.config:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  
  <targets>
    <target name="allfile" xsi:type="File"
            fileName="D:\BEBKA.JobTracking.logs${shortdate}.log"/>
    
    <target xsi:type="Database" name="db" dbProvider="Npgsql.NpgsqlConnection, Npgsql" connectionstring="Server=127.0.0.1;Port=5432;Database=BEBKAJobTracking;User Id=postgres;Password=123;">
      <commandText>
        INSERT INTO public."Logs"("Type", "Method", "StatusCode", "StackTrace", "MethodName", "Message", "RequestData", "ResponseData", "Ip", "CreatedDate", "CreatedId")
        VALUES (@Type, @Method, @StatusCode, @StackTrace, @MethodName, @Message, @RequestData, @ResponseData, @Ip, @CreatedDate, @CreatedId);
      </commandText>
      <parameter name="@Type" layout="${type}"/>
      <parameter name="@Method" layout="${method}"/>
      <parameter name="@StatusCode" layout="${statusCode}"/>
      <parameter name="@StackTrace" layout="${stackTrace}"/>
      <parameter name="@MethodName" layout="${methodName}"/>
      <parameter name="@Message" layout="${message}"/>
      <parameter name="@RequestData" layout="${requestData}"/>
      <parameter name="@ResponseData" layout="${responseData}"/>
      <parameter name="@Ip" layout="${ip}"/>
      <parameter name="@CreatedDate" layout="${createdDate}"/>
      <parameter name="@CreatedId" layout="${createdId}"/>
    </target>
  </targets>
  <rules>
    <logger name="*" minlevel="Trace" writeTo="allfile" />
    <logger name="db" minlevel="Trace" writeTo="db" />
  </rules>
</nlog> 

我的记录器服务

using BEBKA.Infrastructure.Abstractions.Core;
using BEBKA.Infrastructure.Abstractions.Loggger.Interfaces;
using NLog;

namespace BEBKA.Infrastructure.Services
{
    public class LoggerService : ILoggerService
    {
        private static readonly ILogger logger = LogManager.GetCurrentClassLogger();

        public void LogDebug(ILog log)
        {
            logger.Debug(log.Message);
        }

        public void LogDebug(string message)
        {
            logger.Debug(message);
        }

        public void LogError(ILog log)
        {
            logger.Error(log.Message);
        }

        public void LogError(string message)
        {
            logger.Error(message);
        }

        public void LogInfo(ILog log)
        {
            //TODO: Need Bugfix
            LogEventInfo theEvent = new(LogLevel.Info, "db", log.Message);
            SetLogEventInfo(theEvent, log);
            logger.Log(theEvent);

            //logger.Info("{message}",log.Message);   
        }

        public void LogInfo(string message)
        {
            logger.Info(message);
        }

        public void LogWarn(ILog log)
        {
            logger.Warn(log.Message);
        }

        public void LogWarn(string message)
        {

            logger.Warn(message);
        }
        private static void SetLogEventInfo(LogEventInfo theEvent, ILog
    data)
        {
            theEvent.Properties["Type"] = data.Type;
            theEvent.Properties["Method"] = data.Method;
            theEvent.Properties["StatusCode"] = data.StatusCode;
            theEvent.Properties["StackTrace"] = data.StackTrace;
            theEvent.Properties["MethodName"] = data.MethodName;
            theEvent.Properties["Message"] = data.Message;
            theEvent.Properties["RequestData"] = data.RequestData;
            theEvent.Properties["ResponseData"] = data.ResponseData;
            theEvent.Properties["Ip"] = data.Ip;
            theEvent.Properties["CreatedDate"] = data.CreatedDate;
            theEvent.Properties["CreatedId"] = data.CreatedId;
        }
    }
}

................................................ ..................................................... ..................................................... ..................................................... ..................................................... ............

您遇到了几个问题:

  1. 事件属性必须在 ${event-properties}
  2. 的帮助下呈现
      <parameter name="@Type" layout="${event-properties:type}"/>
      <parameter name="@Method" layout="${event-properties:method}"/>
      <parameter name="@StatusCode" layout="${event-properties:statusCode}"/>
      <parameter name="@StackTrace" layout="${event-properties:stackTrace}"/>
      <parameter name="@MethodName" layout="${event-properties:methodName}"/>
      <parameter name="@Message" layout="${event-properties:message}"/>
      <parameter name="@RequestData" layout="${event-properties:requestData}"/>
      <parameter name="@ResponseData" layout="${event-properties:responseData}"/>
      <parameter name="@Ip" layout="${event-properties:ip}"/>
      <parameter name="@CreatedDate" layout="${event-properties:createdDate}"/>
      <parameter name="@CreatedId" layout="${event-properties:createdId}"/>
  1. 不应分配 Logger-Name,但必须为 null 才能进行过滤
    public class LoggerService : ILoggerService
    {
        private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
        private static readonly ILogger Dblogger = LogManager.GetLogger("db");

        public void LogInfo(ILog log)
        {
            LogEventInfo theEvent = new(LogLevel.Info, null, log.Message);
            SetLogEventInfo(theEvent, log);
            Dblogger.Log(theEvent); // DbLogger matches <logger name="db" minlevel="Trace" writeTo="db" />
        }

有点令人困惑的是,所有 LogEventInfo 构造函数都将 Logger-name 作为输入参数,但它永远不应该被分配。试图对此进行改进,但我的拉取请求被拒绝了:https://github.com/NLog/NLog/issues/4086

请注意,也可以将 ILog 记录为单个对象,如 Dblogger.Info("{payload}", data) 并提取单个属性,如下所示:${eventproperties:payload:objectpath=CreatedId}