Question

J'ai emballé Log4net dans un wrapper statique et je veux me connecter

loggingEvent.LocationInformation.MethodName
loggingEvent.LocationInformation.ClassName

Cependant, tout ce que je reçois est le nom de mon wrapper.

Comment puis-je consigner ces informations à l'aide d'un forwardingappender et d'une classe de wrapper statique comme

Logger.Debug("Logging to Debug");
Logger.Info("Logging to Info");
Logger.Warn("Logging to Warn");
Logger.Error(ex);
Logger.Fatal(ex);
Était-ce utile?

La solution 2

Eh bien, l'erreur se trouvait quelque part dans mon appender mais, pour être complet, incluez la réponse à ma connaissance:

la façade dont vous avez besoin devrait envelopper ILogger et NON 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);
        }
    }

Autres conseils

Qu'en est-il des variables % M et % C ? http: //logging.apache. org / log4net / log4net-1.2.11 / release / sdk / log4net.Layout.PatternLayout.html

Utilisation, quelque chose comme:

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

Cela ne fait-il pas ce que vous recherchez?

Déclarez simplement votre variable de journal comme ceci ...

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

Ensuite, vous pouvez l’utiliser normalement.

Cet article m'a aidé à comprendre comment écrire ma propre enveloppe. En retour, j'ai pensé que vous pourriez aimer que mon cours complet englobe l'enregistreur, ce qui semble fonctionner assez bien et prend en réalité un peu plus de la moitié du temps utilisé directement avec ILog. !

Tout ce qui est requis est le fichier xml approprié pour configurer la journalisation dans le fichier de configuration et

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

dans votre AssemblyInfo.cs et cela devrait fonctionner facilement.

Une note: J'utilise Log4NetDash avec une configuration très simple, alors j'ai triché et mis des informations dans les mauvais champs (par exemple, trace de pile dans le champ Domaine), cela fonctionne toujours pour moi, peu importe où les informations sont affichées, mais vous voudrez peut-être résoudre ce problème si vous configurez les choses correctement si vous gagnez du temps!

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

J'utiliserais simplement quelque chose comme % stacktrace {2} en tant que modèle de conversion.

Exemple de résultat:

  

MyNamespace.ClassName.Method > Common.Log.Warning

MyNamespace.ClassName.Method est une méthode qui appelle mon wrapper et Common.Log.Warning est une méthode de la classe wrapper.

Vous trouverez des modèles de conversion ici . / p>

La seule chose à laquelle je puisse penser (étant donné que je n'utilise pas actuellement log4net) est de demander un stacktrace (nouveau StackTrace), et de revenir en arrière d'un cadre pour obtenir les informations dont vous avez besoin. Cependant, je ne suis pas sûr de l'impact de cela sur les performances d'exécution.

Je vais juste écrire plus de code de la bonne réponse de Claus

  

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

et ainsi de suite pour le reste des méthodes.

  

dans web.config ou app.config log4net.Layout.PatternLayout   vous pouvez utiliser des modèles de conversion tels que:

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

Cliquez sur ici pour apprendre comment mettre en œuvre log4net dans .NET Core 2.2

Les étapes suivantes proviennent du lien ci-dessus et expliquent comment ajouter log4net à un projet .NET Core 2.2.

Tout d'abord, exécutez la commande suivante dans la console Package-Manager:

Install-Package Log4Net_Logging -Version 1.0.0

Ajoutez ensuite un fichier log4net.config contenant les informations suivantes (modifiez-le pour l'adapter à votre configuration):

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

Ajoutez ensuite le code suivant dans un contrôleur (il s'agit d'un exemple, modifiez-le avant de l'ajouter à votre contrôleur):

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

Appelez ensuite l'action de contrôleur appropriée (à l'aide de l'exemple ci-dessus, appelez / Values ??/ Get avec un HTTP GET) et vous recevrez le résultat correspondant à ce qui suit:

  

2019-06-05 19: 58: 45,103 [9] INFO- [Log4NetLogging_Project.Controllers.ValuesController.Get: 23] - C'est une journalisation d'informations

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top