Подтвердить что ты не робот

Когда использовать "вложенный диагностический контекст" (NDC)?

Играя с log4net, я видел возможность использовать стеки с потоками контекстных ярлыков, называемых NDC.

Метки, помещенные в этот стек, отображаются в PatternLayout, указывая параметр формата %x или %ndc.

Использование - это что-то вроде:

ILog log = log4net.LogManager.GetLogger(...) ;

//pattern layout format: "[%ndc] - %message%newline"

log.Info("message 1"); 
using(log4net.NDC.Push("context")
{
    using(log4net.NDC.Push("inner_context")
    {
      log.Info("message 2"); 
    }
    log.Info("message 3"); 
}
log.Info("message 4"); 

Результат выглядит примерно так:

null - message 1
context inner_context - message 2
context - message 3
null - message 4

В вашем опыте программирования с log4net, когда вы нашли эту функцию полезной?

4b9b3361

Ответ 1

В серверном приложении, таком как ASP.NET.

Например, вы можете вставлять информацию о текущем запросе в NDC.

Ответ 2

Хотите пример?

Возьмите следующий веб-API, написанный с использованием ASP.NET MVC4:

// GET api/HypervResource
public string Get()
{
    logger.Debug("Start of service test");
    System.Threading.Thread.Sleep(5000); // simulate work
    logger.Debug("End of service test");
    return "HypervResource controller running, use POST to send JSON encoded RPCs";
}

При выполнении параллельных запросов HTTP-запросов регистрация может чередоваться. Например.

2013-06-27 13:28:11,967 [10] DEBUG HypervResource.WmiCalls [(null)] - Start of service test
2013-06-27 13:28:12,976 [12] DEBUG HypervResource.WmiCalls [(null)] - Start of service test
2013-06-27 13:28:14,116 [13] DEBUG HypervResource.WmiCalls [(null)] - Start of service test
2013-06-27 13:28:16,971 [10] DEBUG HypervResource.WmiCalls [(null)] - End of service test
2013-06-27 13:28:17,979 [12] DEBUG HypervResource.WmiCalls [(null)] - End of service test
2013-06-27 13:28:19,119 [13] DEBUG HypervResource.WmiCalls [(null)] - End of service test

В этом простом примере вы можете использовать идентификатор потока для различения запросов, но это может стать сложным, так как файл журнала растет сложнее.

Лучшей альтернативой является предоставление уникальных идентификаторов, которые группируют сообщения журнала для одного и того же запроса. Мы можем обновить код следующим образом:

// GET api/HypervResource
public string Get()
{
    using(log4net.NDC.Push(Guid.NewGuid().ToString()))
    {
        logger.Debug("Start of service test");
        System.Threading.Thread.Sleep(5000); // simulate work
        logger.Debug("End of service test");
        return "HypervResource controller running, use POST to send JSON encoded RPCs";
    }
}

Это создает журнал, который вы можете grep, чтобы увидеть проблемы, связанные с конкретным запросом. Например.

2013-06-27 14:04:31,431 [11] DEBUG HypervResource.WmiCalls [525943cb-226a-43c2-8bd5-03c258d58a79] - Start of service test
2013-06-27 14:04:32,322 [12] DEBUG HypervResource.WmiCalls [5a8941ee-6e26-4c1d-a1dc-b4d9b776630d] - Start of service test
2013-06-27 14:04:34,450 [13] DEBUG HypervResource.WmiCalls [ff2246f1-04bc-4451-9e40-6aa1efb94073] - Start of service test
2013-06-27 14:04:36,434 [11] DEBUG HypervResource.WmiCalls [525943cb-226a-43c2-8bd5-03c258d58a79] - End of service test
2013-06-27 14:04:37,325 [12] DEBUG HypervResource.WmiCalls [5a8941ee-6e26-4c1d-a1dc-b4d9b776630d] - End of service test
2013-06-27 14:04:39,453 [13] DEBUG HypervResource.WmiCalls [ff2246f1-04bc-4451-9e40-6aa1efb94073] - End of service test

Ответ 3

Эти функции полезны, когда у вас много журналов. Когда у вас будет много журналов? Диагностика странной ошибки в производственной системе с выходами чередования. Наличие дополнительных контекстов дает вам возможность фильтровать выход или не выводить ненужные журналы.

Вложенные контексты другого случая могут быть полезны, если метод или некоторая функция вызывается несколько раз в разных контекстах, и вам нужен способ различать их.