Обновить
Комментарии 18
Я бы еще добавил про необходимость для Info, Trace и Debug — вызовов предварительно проверять, разрешено ли логирование вызовами методов IsInfoEnabled, IsTraceEnabled и IsDebugEnabled соответственно. Это позволит поднять производительность приложения, когда логи будут выключены на этих уровнях. Для Error и Warn это обычно лишнее (поскольку запись в них происходит относительно редко), а для «информационных» уровней как раз необходимо.
Ну это чисто выигрыше в одном вызове. Есть уверенность на 90%, что в Trace и Debug первой же строкой идет проверка Is...Enabled. В общем, только больше кода писать, а в том что дадите какой-то прирост — я очень сильно сомневаюсь.
Собственно она там и есть. Я ссылку на исходный код класса привел.
Необоснованно пока, но предположу, что данном случае методы должны подставляться при jit-копиляции. (что тоже упомянуто)
Поэтому, предпроверка просто бессмысленна.

Но все же, пока не дописал бенчмарки, развивать бы эту тему не стал.
При вызове функции выполняется сбор параметров. А еще иногда для того, чтобы передать что-то в лог, нужно перед этим выполнить дополнительные операции. Если все это можно завернуть в один логический блок, то лучше все же добавить проверку. Иначе дополнительные преобразования будут выполняться впустую. Ну это так уж, эти решения были навеяны отсутствием макросов С++. Как это в С++ — написал макрос LOG, а внутри #ifdef, и при отключенных логах лишнего кода вообще не будет. Ближайший аналог такой оптимизации в C# — ручная проверка перед вызовом самых часто отрабатывающих логов.
Именно для этого они сделали в Nlog 2.0 «Lambda-based delayed message computation», а вообще, как и писал автор — сообщение для логирования должно рассчитываться как можно более простым способом.
Для исключения лишнего кода в C# используйте те же директивы
#define LOG // обязательно первая строчка файла
...
#ifdef LOG 
do sth 
#else 
do sth else 
#endif
И вас возненавидят. Качество проекта хорошо определяется по плотности ифдефов на квадратный сантиметр кода
А мне нравится уникальная фича, реализованная в google log (С++) — можно управлять уровнем логирования не только глобально, но и per-source file (проверяется __FILE__ в точке вызова, результаты кешируются).

Можно ли это в каком-то виде перенести на managed-платформу?
В каком-то можно, если у вас есть PDB файлы — тогда можно получать данные о положении функций в стеке относительно файлов и принимать решение на основе этой информации.
NLog не кроссплатформенный, у него имеются веселые проблемы с Mono, которые исправлять вроде и не собираются.

Да, log4net продолжает развиваться, хоть многие и говорили, что он заглох. Я использую именно его. Хоть допилить своими плагинами и оберткой все-таки пришлось, но он гораздо стабильнее.

Кстати по поводу оберток, где это они убивают возможность оптимизации? Хорошо написанная обертка — просто фасад перед самим логгером. В моем случае, она просто предоставляет тот же GetCurrentClassLogger(), которого в log4net нету и пару плюшек вроде выполнения форматирования сообщения только при включенном логировании уровня. Ну и инкапсуляция, я в любой момент могу перевести весь проект на дрогой логгер, если захочу, без замены кода в 100500 файликах.
Если хочется еще оптимизировать, достаточно проставить атрибуты Conditional на методы ненужных уровней в обертке. Но в моем случае, мне очень полезны хоть несколько трейсов-дебагов, залогированных перед ошибкой.
Это не у NLog проблемы с Моно, а у Моно проблемы, на которые напоролся NLog.
а я использовал NLog в моне и не заметил особых проблем кроме потока незакрывающегося, которую кстати легко обойти.
На правах рекламы.
https://github.com/Belorus/XLog — простенький hi-performance логгер для pcl.
НЛО прилетело и опубликовало эту надпись здесь
Хочу поделиться парой мыслей по поводу логирования, комментарии приветствуются ;) Правда мои мысли относятся больше к логированию в файлы.
Если у вас есть несколько экземпляров вашей службы\приложения на разных машинах — добавляйте «название» машины в имя файла с логом — это потом поможет с меньшей проблемой сливать логи в одно место, правда немножко усложнит их публикацию.
Не используйте логгирование для сбора статистики. Тут стоит уточнить один момент… Можно использовать логи для сбора статистики вашего приложения, но не стоит использовать для этого само логирование ;) Это в частности позволит вам делать логи таким образом, что бы они не только легко читались, но и в том числе парсились, и кроме этого отделить логику сбора статистики\мониторинга от самого приложения (собирать статистику должно отдельное приложение).
Иногда я вижу, как перед записью в лог экранируются некоторые значения (например затираются пароли в запросе), думаю это частный пример «лишних вычислений», к тому же я считаю, что это ни сколько не увеличивает безопасность (если злоумышленник добрался до логов...). Хотя конечно это касается в первую очередь серверных логоф, на клиенте такое экранирование может быть не лишним (правда логировать такое на клиенте — это тоже отдельная тема).
Спасибо за советы и мысли. логирование мне надо в других вещах, но суть не меняется :)
Спасибо за дополнение.
«сбор статистики вашего приложения» — так понял, имели ввиду профилирование (profiling), т.е. контроль производительности.

Я для этих целей, настраиваю вывод лога в CSV. Загружаю его в Calc (Excel). Настраиваю фильтры на интересующую операцию. Далее, добавляю колонку, которая вычисляет разницу времени вывода сообщения.

Дальше, по обстоятельствам. Но обычно, можно отыскать в каком окружении код начинает резко медленнее работать.
для обобщенного интерфейса уже есть обертки. CommonLogging вполне себе…
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.