Pergunta

Eu enrolei o log4net em um invólucro estático e quero registrar

loggingEvent.LocationInformation.MethodName
loggingEvent.LocationInformation.ClassName

No entanto, tudo o que recebo é o nome do meu invólucro.

Como posso registrar essas informações usando um ForwardingAppender e uma classe de invólucro estático como

Logger.Debug("Logging to Debug");
Logger.Info("Logging to Info");
Logger.Warn("Logging to Warn");
Logger.Error(ex);
Logger.Fatal(ex);
Foi útil?

Solução 2

Bem, o erro estava em algum lugar do meu Appender, mas, para completar, incluir a resposta para o melhor de meu conhecimento:

a fachada que você precisa deve embrulhar ilogger e não ilog

 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);
        }
    }

Outras dicas

E o %M e %C variáveis?http://logging.apache.org/log4net/log4net-1.2.11/release/sdk/log4net.layout.patternlayout.html

Uso, algo como:

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

Isso não faz o que você procura?

Basta declarar sua variável de log como esta ...

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

Então você pode usá -lo normalmente.

Este post me ajudou a descobrir como escrever meu próprio invólucro, então, em troca, pensei que você poderia gostar da minha aula completa para embrulhar o madeireiro que parece funcionar bem e realmente leva pouco mais da metade do tempo do que usar um ILOG diretamente!

Tudo o que é necessário é o XML apropriado para configurar o log no arquivo de configuração e

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

no seu AssemblyInfo.cs e deve funcionar facilmente.

Uma nota: estou usando o log4netdash com uma configuração seriamente simples, por isso trapaceou e coloque algumas informações nos campos errados (por exemplo, rastreamento de pilha no campo de domínio), isso ainda funciona para mim, pois não me importo onde a informação é Mostrado, mas você pode querer consertar isso se estiver configurando coisas corretamente se você poupar tempo!

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; }
        }
    }
}

Eu simplesmente usaria algo como %stacktrace{2} como um padrão de conversão.

Exemplo de saída:

Mynamespace.classname.method> Common.log.warning

Onde MyNamespace.ClassName.Method é um método que está chamando meu invólucro e Common.Log.Warning é um método da classe Wrapper.

Padrões de conversão podem ser encontrados aqui.

A única coisa que consigo pensar em fazer (como não uso o log4net atualmente) é solicitar um Stacktrace (New Stacktrace) e voltar um quadro para obter as informações de que você precisa. No entanto, não tenho certeza do impacto no desempenho do tempo de execução disso.

Vou apenas escrever mais código da resposta correta do Claus

Na classe Wrapper

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);
      }
  }

e assim por diante para o restante dos métodos.

em web.config ou app.config log4net.layout.patternlayoutVocê pode usar alguns padrões de conversão como:

%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>

Clique aqui Para aprender a implementar o log4net no .NET Core 2.2

As etapas a seguir são tomadas do link acima e dividem como adicionar log4net a um projeto .NET Core 2.2.

Primeiro, execute o seguinte comando no console do gerenciador de pacotes:

Install-Package Log4Net_Logging -Version 1.0.0

Em seguida, adicione um log4net.config com as seguintes informações (edite -as para corresponder à sua configuração):

<?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>

Em seguida, adicione o código a seguir em um controlador (este é um exemplo, edite -o antes de adicioná -lo ao seu controlador):

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" };
}

Em seguida, ligue para a ação do controlador relevante (usando o exemplo acima, ligue /Values/Get com um http get) e você receberá a saída que corresponde ao seguinte:

2019-06-05 19: 58: 45,103 [9] info- [log4netlogging_project.controllers.valuescontroller.get: 23]-Este é o registro de informações

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top