Frage

Ich habe Log4net in einem statischen Umhüllung eingehüllt und wollen log

loggingEvent.LocationInformation.MethodName
loggingEvent.LocationInformation.ClassName

Doch alles, was ich ist der Name meiner Wrapper erhalten.

Wie kann ich diese Informationen melden Sie sich ein forwardingappender und eine statische Wrapper-Klasse wie

mit
Logger.Debug("Logging to Debug");
Logger.Info("Logging to Info");
Logger.Warn("Logging to Warn");
Logger.Error(ex);
Logger.Fatal(ex);
War es hilfreich?

Lösung 2

Nun, der Fehler wurde irgendwo in meinem appender aber der Vollständigkeit halber sind krank, die Antwort auf die nach meinem besten Wissen:

Die Fassade Sie benötigen sollten ILogger und NICHT ILog wickeln

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

Andere Tipps

Was ist mit dem %M und %C Variablen? http: //logging.apache. org / log4net / log4net-1.2.11 / release / sdk / log4net.Layout.PatternLayout.html

Verwendung, so etwas wie:

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

Ist das nicht tun, was Sie nach?

Just erklären Sie Ihre Log-Variable wie folgt ...

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

Dann können Sie es normalerweise verwenden.

Dieser Beitrag hat mir geholfen, herauszufinden, wie meine eigenen Wrapper zu schreiben, so im Gegenzug, dachte, Sie könnten meine komplette Klasse wie den Logger zu wickeln, die ganz gut zu funktionieren scheint und tatsächlich dauert etwas mehr als halb so viel Zeit wie eine ILog mit direkt !

Alles, was erforderlich ist, die entsprechende xml die Protokollierung in der Konfigurationsdatei einzurichten und

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

in Ihrem AssemblyInfo.cs und es sollte leicht arbeiten.

Eine Anmerkung: Ich verwende Log4NetDash mit einer ernsthaft einfachen Set-up so betrogen haben und einige Informationen in den falschen Feldern setzen (zB Stack-Trace in Domain-Feld), das funktioniert immer noch für mich, da ich interessiere mich nicht, wo die Information wird angezeigt, aber Sie können dieses Problem beheben möchten, wenn Sie Sachen sind Einrichten richtig, wenn Sie Zeit ersparen!

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

ich einfach so etwas wie %stacktrace{2} als Umwandlungsmuster verwenden würde.

Ausgabebeispiel:

  

MyNamespace.ClassName.Method> Common.Log.Warning

wo MyNamespace.ClassName.Method ist eine Methode, die meine Wrapper und Common.Log.Warning ist ein Verfahren der Wrapper-Klasse aufruft.

Conversion Muster können hier .

Das einzige, was ich tun denken kann (wie ich nicht verwenden derzeit log4net) ist ein stacktrace (neue Stacktrace) anzufordern und einen Rahmen gehen die Informationen, die Sie benötigen. Ich bin aber nicht sicher über die Laufzeit-Performance Auswirkungen dieser.

Ich werde nur mehr Code der richtigen Antwort von Claus schreiben

  

In der Wrapper-Klasse

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

und so weiter für den Rest Methoden.

  

in web.config oder app.config log4net.Layout.PatternLayout   Sie können einige Conversion Patterns wie verwenden:

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

Klicken Sie auf hier zu lernen, wie zu implementieren log4net in .NET-Core 2.2

Die folgenden Schritte sind aus dem obigen Link genommen und brechen wie log4net in ein .NET-Core-2.2-Projekt hinzuzufügen.

Als erstes führen Sie den folgenden Befehl in der Paket-Manager-Konsole:

Install-Package Log4Net_Logging -Version 1.0.0

Dann einen log4net.config mit den folgenden Informationen hinzufügen (bitte bearbeiten Sie Ihr Set zusammenpassen):

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

Dann fügen Sie den folgenden Code in einen Controller (dies ist ein Beispiel, bearbeiten Sie es, bevor es zu dem Controller hinzufügen):

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

Dann rufen Sie die entsprechende Controller-Aktion (das obige Beispiel, rufen Sie /Values/Get mit einem HTTP-GET), und Sie erhalten die Ausgabe passend zu dem folgenden:

  

2019.06.05 19: 58: 45.103 [9] INFO- [Log4NetLogging_Project.Controllers.ValuesController.Get: 23] - Dies ist Info Anmeldung

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top