【问题标题】:Limit NLog Database Target Size限制 NLog 数据库目标大小
【发布时间】:2014-11-18 03:20:25
【问题描述】:

如何配置 NLog,使其记录到数据库表(在我的情况下为 SQL Server)并在特定时间段后清除行?

我正在使用带有database target 的NLog。 file target 有多个选项可以翻转并最终删除日志文件(例如,按日期/时间、大小等)。我希望能够在 NLog 中使用类似的东西。

以下 NLog 文件目标配置允许我将日志设置为保留一段时间,然后完全过期。

<targets async="true">
    <target xsi:type="File"
        name="TraceFile"
        layout="${longdate} - ${level:uppercase=true} - ${callsite:className=true:fileName=true:includeSourcePath=true
          :methodName=true}: ${message}${onexception:${newline}EXCEPTION\: ${exception:format=ToString}}"
        fileName="${logFolder}\${appName}\Trace\Trace.log"
        archiveFileName="${logFolder}\${appName}\Trace\Trace_${shortdate}.log"
        archiveNumbering="Sequence"
        archiveEvery="Day"
        maxArchiveFiles="5"
            />
    <target xsi:type="File"
        name="DebugFile"
        layout="${longdate} - ${level:uppercase=true} - ${callsite:className=true:fileName=true:includeSourcePath=true
          :methodName=true}: ${message}${onexception:${newline}EXCEPTION\: ${exception:format=ToString}}"
        fileName="${logFolder}\${appName}\Debug\Debug.log"
        archiveFileName="${logFolder}\${appName}\Debug\Debug_${shortdate}.log"
        archiveNumbering="Sequence"
        archiveEvery="Day"
        maxArchiveFiles="10"
            />
</targets>

【问题讨论】:

    标签: sql-server logging nlog


    【解决方案1】:

    简单的答案是否定的。NLog 没有参数可以像处理文件目标一样自动清理数据库目标。但是,要做到这一点,您可以...

    你可以修改你的 NLog.Config 文件 CommandText

    <target name="database" xsi:type="Database" connectionStringName="nlog">
         <commandText>
            insert into myLogTable (LogDateColumn, LogMessageColumn) values (GETDATE(), @message);
            delete from myLogTable where LogDateColumn <= DATEADD(DAY, -7, GETDATE());
         </commandText>
         <parameter name="@message" layout="${message}"/>
    </target>
    

    诚然,这是基本的普通示例,但您可以使用 SQL 变得更复杂。此外,诚然,这可能有点费力......每次插入时都要删除。

    您可以每晚使用正常的预定 SQL 作业等运行删除语句。

    只是提供替代品。

    希望这会有所帮助。

    【讨论】:

    • 天哪,你真是个天才,我试图做一个自定义的 LayoutRenderer 来完成同样的功能。谢谢:)
    • 感谢您提供此替代方案。我最终创建了一个 sql 作业。
    • 仅供参考,您还可以从 NLog commandText 调用存储过程。如果更改存储过程比更改配置文件更容易,这是一个优势。您可以将插入和删除语句放在存储过程中,以使您的 commandText 保持简单。有关调用存储过程的示例,请参见此处stackoverflow.com/questions/5214015/…
    • NLog.config 抱怨 DATEADD 的小于号
    【解决方案2】:

    我最终创建了一个 sql server 作业来执行此操作。我在第一步也是唯一的一步中添加了以下 sql。该脚本确实假定表的名称是Log

    DECLARE @DaysToKeepTrace INT
    DECLARE @DaysToKeepDebug INT
    DECLARE @DaysToKeepInfo INT
    DECLARE @DaysToKeepWarn INT
    DECLARE @MonthsToKeepError INT
    DECLARE @Now DATETIME
    
    SET @DaysToKeepTrace = 5
    SET @DaysToKeepDebug = 10
    SET @DaysToKeepInfo = 15
    SET @DaysToKeepWarn = 30
    SET @MonthsToKeepError = 6
    SET @Now = GETDATE()
    
    DELETE FROM [dbo].[Log]
    WHERE 
        [Level] = 'Trace'
        AND
        DATEDIFF(DAY, time_stamp, @Now) > @DaysToKeepTrace
    
    DELETE FROM [dbo].[Log]
    WHERE 
        [Level] = 'Debug'
        AND
        DATEDIFF(DAY, time_stamp, @Now) > @DaysToKeepDebug
    
    DELETE FROM [dbo].[Log]
    WHERE 
        [Level] = 'Info'
        AND
        DATEDIFF(DAY, time_stamp, @Now) > @DaysToKeepInfo
    
    DELETE FROM [dbo].[Log]
    WHERE 
        [Level] = 'Warn'
        AND
        DATEDIFF(DAY, time_stamp, @Now) > @DaysToKeepWarn
    
    DELETE FROM [dbo].[Log]
    WHERE 
        ([Level] = 'Error' OR [Level] = 'Fatal' )
        AND
        DATEDIFF(MONTH, time_stamp, @Now) > @MonthsToKeepError
    

    交错的方法允许您保留任何更严重的日志消息以供查看和理想地修复。

    我不想每次 NLog 写入数据库时​​都运行它。我知道这不是每条消息,但可以在交通缓慢的时间安排这项工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 2018-06-19
      • 1970-01-01
      • 2017-01-13
      • 1970-01-01
      相关资源
      最近更新 更多