NLog:记录行号和使用NLog的wrapper class时的调用方法

NLog: Recording Line number and calling method when using wrapper class for NLog

我正在使用 NLog 进行日志记录,感谢这些答案:

我的大部分工作正常。我编写了自己的包装器 class 来强制用户从一组名称列表中选择一个 LoggerName。所有代码如下。除了一个小问题外,一切正常。

  1. callsite 和 callsite-linenumber 打印出的行号和调用方法是包装器中的调用函数和行号 class 而不是调用包装器的方法和行号class。这并不奇怪,我猜这是一个常见问题。有没有简单的修复方法,或者我可以以某种方式创建自己的布局选项,使用传递到方法中的行号?或者还有其他建议吗?

    using System;
    namespace Common.NLogEx
    {
        public enum LoggerNames
        {
        Database,
        Thermal,
        StateMachine,
        App,
        Poll
       }
    
        public enum LogLevel
       {
        Trace,
        Debug,
        Info,
        Warn,
        Error,
        Fatal,
        Off,
        Warning
        }
    
    public static class Logger
    {
    
        public static void Log(LoggerNames name, LogLevel level , string message)
        {
            if (level == LogLevel.Warning)
                level = LogLevel.Warn;
            NLog.LogLevel nLevel = NLog.LogLevel.FromString(level.ToString());
            NLog.LogManager.GetLogger(name.ToString()).Log(nLevel,message);
        }
    
        public static void Log(LoggerNames name, LogLevel level, Exception ex, string message)
        {
            if (level == LogLevel.Warning)
                level = LogLevel.Warn;
            NLog.LogLevel nLevel = NLog.LogLevel.FromString(level.ToString());
            NLog.LogManager.GetLogger(name.ToString()).Log(nLevel, ex, message, null);
        }
    }
    

    }

和 NLog 配置文件:

<?xml version="1.0" encoding="utf-8" ?>

<target name="logfile" xsi:type="File" fileName="${basedir}/Logs/file.txt" />
<target name="logconsole" xsi:type="Console" />
<target name="excelfile" xsi:type="File" fileName="${cached:cached=true:Inner=${basedir}/Logs/${date:format=yyyy-MM-dd hh.mm.ss}:CacheKey=${shortdate}}.csv" archiveAboveSize="32000000" archiveFileName="${basedir}/Logs/Archives/${date:format=yyyy-MM-dd hh.mm.ss}.{#####}.csv" archiveEvery="Day" archiveNumbering="Sequence" maxArchiveFiles="0">

  <layout xsi:type="CsvLayout">
    <!-- Layout Options -->

    <column name="time" layout="${longdate}" />
    <column name="level" layout="${level}"/>
    <column name="logger" layout="${logger}"/>
    <column name="message" layout="${message}" />
    <column name="callsite" layout="${callsite}" />
    <column name="callsite-linenumber" layout="${callsite-linenumber}" />
    <column name="exception" layout="${exception:format=toString,StackTrace}${newline}" />

  </layout>
</target>
</targets>

<rules>

<logger name="*" minlevel="Debug" writeTo="logconsole" />    
<logger name="*" minlevel="Debug" writeTo="excelfile" />    
</rules>
</nlog>

知道了!做了更好的搜索,发现了这个奇妙的问题和答案:

How to retain callsite information when wrapping NLog 您只需将包装器 class 类型传递给 "Log" 方法。

对于任何感兴趣的人,这是我的新包装 class。最后一种方法使用了"typeof"思路。

public static class Logger
{
    private static string _unclassified = "Unclassified";
    [Obsolete("Please supply a LoggerName and LoggerLevel")]
    public static void Log(string message)
    {          
        Log(_unclassified,LogLevel.Info, message,null);
    }
    [Obsolete("Please supply a LoggerName")]
    public static void Log(LogLevel level, string message)
    {
        Log(_unclassified,level,message,null);
    }

    [Obsolete("Please supply a LoggerName and LoggerLevel")]
    public static void Log(Exception ex)
    {          
        Log(_unclassified,LogLevel.Info, "",ex);
    }

    public static void Log(LoggerNames name, LogLevel level , string message)
    {

        NLog.LogLevel nLevel = NLog.LogLevel.FromString(level.ToString());
        Log(name.ToString(), level, message);
    }

    public static void Log(LoggerNames name, LogLevel level, Exception ex, string message)
    {

        NLog.LogLevel nLevel = NLog.LogLevel.FromString(level.ToString());
        Log(name.ToString(),level,message,ex);
    }

    private static void Log(string loggerName, LogLevel level, string message, Exception ex = null)
    {
        if (level == LogLevel.Warning)
            level = LogLevel.Warn;
        NLog.LogLevel nLevel = NLog.LogLevel.FromString(level.ToString());

        LogEventInfo logEvent = new LogEventInfo(nLevel,loggerName,null,message,null,ex);
        NLog.LogManager.GetLogger(loggerName).Log(typeof(Logger), logEvent);
    }
}