Когда я хотел использовать различные уровни ведения журнала, доступные с log4net, я узнал, что мне нужно использовать метод ILogger.Log, который выглядит следующим образом:метод ILogger.Log DeclaringType параметр
void Log(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception);
Мы можем получите ссылку ILogger из нашей обычной ссылки ILOG, чтобы вызвать этот метод, и обычно рекомендуется обернуть этот вызов в методе расширения. Мы получаем следующее:
//typical log4net ILog reference
private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//suggested extension method
public static void Trace(this ILog logger, object message, Exception e)
{
logger.Logger.Log(MethodBase.GetCurrentMethod().DeclaringType, log4net.Core.Level.Trace, message, e);
}
Я заметил, как вызов отражения для получения типа объявления выглядит излишним. Мы уже передали тип объявления GetLogger, когда мы получили ссылку на ILOG. Зачем нам нужно передать другую ссылку на метод Log, который мы вызываем по ссылке ILogger, которую мы получили из нашей ссылки ILOG. Что еще более важно, тип объявления в методе расширения будет классом, который содержит метод расширения. Ведение журнала всех журналов Trace с таким именем класса, как Log4NetExtensions, не имеет смысла. Наконец, отражение должно быть дорогостоящим, хотя отражение в текущем методе может быть дешевле, призывая код отражения каждый раз, когда мы регистрируемся, не звучит правильно. Поэтому я решил сделать тест:
//I just created a logger
var logger = logManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//and then I called Log with different type parameters
logger.Logger.Log(MethodBase.GetCurrentMethod().DeclaringType, log4net.Core.Level.Info, "hello!", null);
logger.Logger.Log(logger.GetType(), log4net.Core.Level.Info, "hello!", null);
logger.Logger.Log(null, log4net.Core.Level.Info, "hello!", null);
logger.Logger.Log(typeof(System.Console), log4net.Core.Level.Info, "hello!", null);
И результирующие журналы выглядели следующим образом:
INFO 2015-05-29 11:06:57,200 [9] Foo.Program - hello!
INFO 2015-05-29 11:06:57,207 [9] Foo.Program - hello!
INFO 2015-05-29 11:06:57,207 [9] Foo.Program - hello!
INFO 2015-05-29 11:06:57,207 [9] Foo.Program - hello!
Таким образом, кажется, что параметр типа к этому методу, игнорируется. Это очень озадачивает. Может ли кто-нибудь подтвердить или опровергнуть эти результаты? Кто-нибудь знает, почему это работает так, как оно есть? Я намерен создать мой метод расширения с нулевым значением для этого параметра. Вы предложили бы то же самое? Я что-то упускаю?
Ниже приведены вопросы, ответы на которые предлагают использовать объявляющий тип в методе расширения:
Log4net creating custom levels
Why isn't there a trace level in log4Net?
Log4net, how to log a verbose message?
это: «поскольку он будет внутренне по умолчанию для типа регистратора». Это то, что я искал. Любые ссылки? Или любое предложение о том, как тестировать? Когда log4net создает трассировку стека? Когда я перехожу в исключение? Но разве исключения не имеют собственных следов стека? –
Вы правы в отношении исключений, имеющих собственную трассировку стека: log4net также [позволяет трассировку стека быть включенным в шаблон] (http://logging.apache.org/log4net/release/sdk/log4net.Layout.PatternLayout. html), но в ретроспективе это не обычный случай использования - в отношении ссылки я посмотрел в источнике [строки 428 и 725] (https://apache.googlesource.com/log4net/+/refs/heads/1.2.12 /src/Repository/Hierarchy/Logger.cs) – stuartd