log4net을 랩핑 할 때 메소드 이름을 기록하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/157232

  •  03-07-2019
  •  | 
  •  

문제

정적 래퍼에 log4net을 래과 한 상태에서 로그를 작성하고 싶습니다.

loggingEvent.LocationInformation.MethodName
loggingEvent.LocationInformation.ClassName

그러나 내가 얻는 것은 내 래퍼의 이름입니다.

ForwardingAppender 및 정적 래퍼 클래스를 사용하여 해당 정보를 기록하려면 어떻게해야합니까?

Logger.Debug("Logging to Debug");
Logger.Info("Logging to Info");
Logger.Warn("Logging to Warn");
Logger.Error(ex);
Logger.Fatal(ex);
도움이 되었습니까?

해결책 2

글쎄, 오류는 내 애플 렌더 어딘가에 있었지만 완전성을 위해 내 지식의 최선에 대한 답을 포함시킵니다.

필요한 외관은 Ilog가 아닌 Ilogger를 포장해야합니다.

 public static class Logger
 {
    private readonly static Type ThisDeclaringType = typeof(Logger);
    private static readonly ILogger defaultLogger;

    static Logger()
    {
      defaultLogger =
        LoggerManager.GetLogger(Assembly.GetCallingAssembly(),"MyDefaultLoggger");

...

    public static void Info(string message)
    {
        if (defaultLogger.IsEnabledFor(infoLevel))
        {
            defaultLogger.Log(typeof(Logger), infoLevel, message, null);
        }
    }

다른 팁

What about the %M 그리고 %C 변수?http://logging.apache.org/log4net/log4net-1.2.11/release/sdk/log4net.layout.patternlayout.html

사용법, 같은 것 :

<layout type="log4net.Layout.PatternLayout">
  <conversionPattern value="%date [%thread] %-5level %logger [%M %C] - %message%newline" />
</layout>

그게 당신이 따르는 일을하지 않습니까?

로그 변수를 이렇게 선언합니다 ...

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

그런 다음 정상적인 사용할 수 있습니다.

이 게시물은 제 자신의 래퍼를 작성하는 방법을 알아내는 데 도움이되었으므로 대가로 내 래퍼를 작성하는 데 도움이되었으므로, 내 전체 수업이 로거를 포장하는 것을 좋아할 것이라고 생각했습니다.

필요한 것은 구성 파일에서 로깅을 설정하고

[assembly: log4net.Config.XmlConfigurator(Watch = true)] 

AssemblyInfo.cs에서 쉽게 작동해야합니다.

하나의 참고 사항 : 심각한 간단한 설정으로 log4netdash를 사용하고 있으므로 속임수를 쓰고 잘못된 필드에 정보를 넣었습니다 (예 : 도메인 필드의 스택 추적). 정보가 어디에 있는지 신경 쓰지 않기 때문에 여전히 작동합니다. 표시되지만 시간을 여는 경우 올바르게 물건을 설정하는 경우이 문제를 해결하고 싶을 수도 있습니다!

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
using log4net;
using log4net.Core;

namespace Utility
{
    public class Logger
    {
        static Logger()
        {
            LogManager.GetLogger(typeof(Logger));
        }

        public static void Debug(string message, params object[] parameters)
        {
            Log(message, Level.Debug, null, parameters);
        }

        public static void Info(string message, params object[] parameters)
        {
            Log(message, Level.Info, null, parameters);
        }

        public static void Warn(string message, params object[] parameters)
        {
            Log(message, Level.Warn, null, parameters);
        }

        public static void Error(string message, params object[] parameters)
        {
            Error(message, null, parameters);
        }

        public static void Error(Exception exception)
        {
            if (exception==null)
                return;
            Error(exception.Message, exception);
        }

        public static void Error(string message, Exception exception, params object[] parameters)
        {
            string exceptionStack = "";

            if (exception != null)
            {
                exceptionStack = exception.GetType().Name + " : " + exception.Message + Environment.NewLine;
                Exception loopException = exception;
                while (loopException.InnerException != null)
                {
                    loopException = loopException.InnerException;
                    exceptionStack += loopException.GetType().Name + " : " + loopException.Message + Environment.NewLine;
                }
            }

            Log(message, Level.Error, exceptionStack, parameters);
        }



        private static void Log(string message, Level logLevel, string exceptionMessage, params object[] parameters)
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += LogEvent;
            worker.RunWorkerAsync(new LogMessageSpec
                                      {
                                          ExceptionMessage = exceptionMessage,
                                          LogLevel = logLevel,
                                          Message = message,
                                          Parameters = parameters,
                                          Stack = new StackTrace(),
                                          LogTime = DateTime.Now
                                      });
        }

        private static void LogEvent(object sender, DoWorkEventArgs e)
        {
            try
            {
                LogMessageSpec messageSpec = (LogMessageSpec) e.Argument;

                StackFrame frame = messageSpec.Stack.GetFrame(2);
                MethodBase method = frame.GetMethod();
                Type reflectedType = method.ReflectedType;

                ILogger log = LoggerManager.GetLogger(reflectedType.Assembly, reflectedType);
                Level currenLoggingLevel = ((log4net.Repository.Hierarchy.Logger) log).Parent.Level;

                if (messageSpec.LogLevel<currenLoggingLevel)
                    return;

                messageSpec.Message = string.Format(messageSpec.Message, messageSpec.Parameters);
                string stackTrace = "";
                StackFrame[] frames = messageSpec.Stack.GetFrames();
                if (frames != null)
                {
                    foreach (StackFrame tempFrame in frames)
                    {

                        MethodBase tempMethod = tempFrame.GetMethod();
                        stackTrace += tempMethod.Name + Environment.NewLine;
                    }
                }
                string userName = Thread.CurrentPrincipal.Identity.Name;
                LoggingEventData evdat = new LoggingEventData
                                             {
                                                 Domain = stackTrace,
                                                 Identity = userName,
                                                 Level = messageSpec.LogLevel,
                                                 LocationInfo = new LocationInfo(reflectedType.FullName,
                                                                                 method.Name,
                                                                                 frame.GetFileName(),
                                                                                 frame.GetFileLineNumber().ToString()),
                                                 LoggerName = reflectedType.Name,
                                                 Message = messageSpec.Message,
                                                 TimeStamp = messageSpec.LogTime,
                                                 UserName = userName,
                                                 ExceptionString = messageSpec.ExceptionMessage
                                             };
                log.Log(new LoggingEvent(evdat));
            }
            catch (Exception)
            {}//don't throw exceptions on background thread especially about logging!
        }

        private class LogMessageSpec
        {
            public StackTrace Stack { get; set; }
            public string Message { get; set; }
            public Level LogLevel { get; set; }
            public string ExceptionMessage { get; set; }
            public object[] Parameters { get; set; }
            public DateTime LogTime { get; set; }
        }
    }
}

나는 단순히 같은 것을 사용할 것입니다 %stacktrace{2} 변환 패턴으로.

출력의 예 :

mynamespace.classname.method> common.log.warning

어디 MyNamespace.ClassName.Method 내 래퍼를 호출하는 방법입니다 Common.Log.Warning 래퍼 클래스의 방법입니다.

변환 패턴을 찾을 수 있습니다 여기.

내가 생각할 수있는 유일한 것은 (현재 log4net을 사용하지 않기 때문에) StackTrace (새 스택 트레이스)를 요청하고 필요한 정보를 얻기 위해 프레임을 되돌아가는 것입니다. 그러나 나는 이것의 런타임 성능 영향에 대해 확신이 없습니다.

클로스의 정답에 대한 더 많은 코드를 쓸 것입니다.

래퍼 클래스에서

public static class Logger
{
   private static readonly ILogger DefaultLogger;

   static Logger()
   {
      defaultLogger = LoggerManager.GetLogger(Assembly.GetCallingAssembly(), "MyDefaultLoggger"); // MyDefaultLoggger is the name of Logger
   }

  public static void LogError(object message)
  {
      Level errorLevel = Level.Error;
      if (DefaultLogger.IsEnabledFor(errorLevel))
      {
          DefaultLogger.Log(typeof(Logger), errorLevel, message, null);
      }
  }

  public static void LogError(object message, Exception exception)
  {
      Level errorLevel = Level.Error;
      if (DefaultLogger.IsEnabledFor(errorLevel))
      {
          DefaultLogger.Log(typeof(Logger), errorLevel, message, exception);
      }
  }

나머지 방법에 대해서도 마찬가지입니다.

web.config 또는 app.config에서 log4net.layout.patternlayout다음과 같은 일부 변환 패턴을 사용할 수 있습니다.

%location %method %line

<layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date{dd/MM/yyyy hh:mm:ss.fff tt} [%thread] %level %logger [%location %method %line] [%C %M] - %newline%message%newline%exception"/>
  </layout>

딸깍 하는 소리 여기 .NET Core 2.2에서 log4net을 구현하는 방법을 배우려면

다음 단계는 위의 링크에서 가져오고 Log4Net을 .NET Core 2.2 프로젝트에 추가하는 방법을 세분화합니다.

먼저 패키지 관리자 콘솔에서 다음 명령을 실행하십시오.

Install-Package Log4Net_Logging -Version 1.0.0

그런 다음 다음 정보와 함께 log4net.config를 추가합니다 (설정과 일치하도록 편집하십시오).

<?xml version="1.0" encoding="utf-8" ?>
<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>

그런 다음 다음 코드를 컨트롤러에 추가합니다 (예제입니다. 컨트롤러에 추가하기 전에 편집하십시오).

public ValuesController()
{
    LogFourNet.SetUp(Assembly.GetEntryAssembly(), "log4net.config");
}
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
    LogFourNet.Info(this, "This is Info logging");
    LogFourNet.Debug(this, "This is Debug logging");
    LogFourNet.Error(this, "This is Error logging");    
    return new string[] { "value1", "value2" };
}

그런 다음 관련 컨트롤러 조치를 호출하십시오 (위의 예를 사용하여 /Values/Get HTTP GET을 사용하면 다음과 일치하는 출력을 받게됩니다.

2019-06-05 19 : 58 : 45,103 [9] info- [log4netlogging_project.controllers.valuescontroller.get : 23]-이것은 정보 로깅입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top