سؤال

لقد لفت log4net في غلاف ثابت وأريد تسجيل الدخول

loggingEvent.LocationInformation.MethodName
loggingEvent.LocationInformation.ClassName

لكن كل ما أحصل عليه هو اسم غلاف بلدي.

كيف يمكنني تسجيل هذه المعلومات باستخدام جهاز إعادة توجيه وفئة غلاف ثابت مثل

Logger.Debug("Logging to Debug");
Logger.Info("Logging to Info");
Logger.Warn("Logging to Warn");
Logger.Error(ex);
Logger.Fatal(ex);
هل كانت مفيدة؟

المحلول 2

حسنًا ، كان الخطأ في مكان ما في الزائدة الخاصة بي ، لكن من أجل الاكتمال ، قم بتضمين الإجابة على أفضل ما لدي:

الواجهة التي تحتاجها يجب أن تلتف ilogger وليس 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);
        }
    }

نصائح أخرى

ماذا عن %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);

ثم يمكنك استخدامه بشكل طبيعي.

ساعدني هذا المنشور على معرفة كيفية كتابة غلاف خاص بي ، في المقابل ، اعتقدت أنك قد ترغب في لف صفي الكامل للمسجل الذي يبدو أنه يعمل بشكل جيد للغاية ويستغرق ما يزيد عن نصف الوقت مثل استخدام ILOG مباشرة!

كل ما هو مطلوب هو XML المناسب لإعداد التسجيل في ملف التكوين و

[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 هي طريقة فئة الغلاف.

يمكن العثور على أنماط التحويل هنا.

The only thing I can think of doing (as I dont currently use log4net) is to request a stacktrace(new StackTrace), and go back a frame to get the info you need. However, I am unsure of the runtime performance impact of this.

I will just write more code of the correct answer of Claus

In the wrapper class

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

and so on for the rest of methods.

in web.config or app.config log4net.Layout.PatternLayout you can use some Conversion Patterns like:

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

Click here to learn how to implement log4net in .NET Core 2.2

The following steps are taken from the above link, and break down how to add log4net to a .NET Core 2.2 project.

First, run the following command in the Package-Manager console:

Install-Package Log4Net_Logging -Version 1.0.0

Then add a log4net.config with the following information (please edit it to match your set up):

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

Then, add the following code into a controller (this is an example, please edit it before adding it to your controller):

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

Then call the relevant controller action (using the above example, call /Values/Get with an HTTP GET), and you will receive the output matching the following:

2019-06-05 19:58:45,103 [9] INFO-[Log4NetLogging_Project.Controllers.ValuesController.Get:23] - This is Info logging

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top