When using wrapper, how to preserve class and method name for Log4Net to log?

前端 未结 3 1451
野的像风
野的像风 2020-11-28 16:37

I need a Log4net wrapper - to be exposed to a number of different components in a large app. I obviously want to retain the class and method name when logging but I would ke

相关标签:
3条回答
  • 2020-11-28 17:03

    I usually add something this... (it's all the functionality I need)

    MethodBase.GetCurrentMethod().Name
    

    you could always create a wrapper for Log4Net that takes any params you need (like MethodBase)?

    0 讨论(0)
  • 2020-11-28 17:08

    Create your wrapper class like this...

    public static class LogFourNet
        {
            // Define a static logger variable so that it references the
            private static readonly ILog Log = LogManager.GetLogger(typeof(LogFourNet));
    
            static LogFourNet()
            {
                XmlConfigurator.Configure(
                       new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
                Log.Info("Log4net is configured.");
            }
    
            public static void Info(object currentObj, string msg, [CallerLineNumber] int lineNumber = 0,
                [CallerFilePath] string caller = "", [CallerMemberName] string memberName = "")
            {
                Log.Info("[" + currentObj.GetType().Namespace + "." +
                         Path.GetFileNameWithoutExtension(caller) + "." + memberName + ":" + lineNumber + "] - " + msg);
            }
    
            public static void Debug(object currentObj, string msg, [CallerLineNumber] int lineNumber = 0,
                [CallerFilePath] string caller = "", [CallerMemberName] string memberName = "")
            {
                Log.Debug("[" + currentObj.GetType().Namespace + "." +
                          Path.GetFileNameWithoutExtension(caller) + "." + memberName + ":" + lineNumber + "] - " + msg);
            }
    
            public static void Error(object currentObj, string msg, [CallerLineNumber] int lineNumber = 0,
                [CallerFilePath] string caller = "", [CallerMemberName] string memberName = "")
            {
                Log.Error("[" + currentObj.GetType().Namespace + "." +
                          Path.GetFileNameWithoutExtension(caller) + "." + memberName + ":" + lineNumber + "] - " + msg);
            }
        }
    

    Configure your log4net.config file in the following manner...

    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
      </configSections>
      <log4net>
        <appender name="FileAppender" type="log4net.Appender.FileAppender">
          <file value="logfile.log" />
          <appendToFile value="true" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%d [%t] %-5p - %m%n" />
          </layout>
        </appender>
        <root>
          <!--LogLevel: OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL -->
          <level value="ALL" />
          <appender-ref ref="FileAppender" />
        </root>
      </log4net>
    </configuration>
    

    Now just use above these methods like this...

    // need to pass this(current obj) as we want to log full class name
    LogFourNet.Debug(this, "started something from wrapper");
    
    output:
    -------
    2017-02-04 15:38:37,549 [1] DEBUG [WebAPI_DI.Startup.Configuration:25] - started something from wrapper
    
    0 讨论(0)
  • 2020-11-28 17:12

    Log4net allows you to access method name for instance like this %method. This is not the fastest operation but if you need to debug something you may very well use it. I believe your question is about the fact that log4net will not output the correct method name if you use a wrapper.

    To solve that problem you have to look at how log4net wrote the ILog implementation. This is basically a wrapper around the internal log4net Logger and therefore the very same problem applies to the ILog implementation, too. I did basically the following:

    // define a field such as this
    private static readonly Type ThisDeclaringType = typeof(MyLogWrapper);
    
    // in constructor. Note: I use the internal Logger!
    this.Logger = LogManager.GetLogger(name).Logger;
    
    // I created a WriteLog method that calls the internal logger like this
    // you will need to translate to the internal log levels
    // message and ex are the items I want to log (ex can be null)
    this.Logger.Log(MyLogWrapper.ThisDeclaringType, log4netLevel, message, ex);
    

    Obviously there are some things to do yet, but the important points are mentioned.

    0 讨论(0)
提交回复
热议问题