Ведение журнала в служебных классах

Я хочу внедрить ведение журнала в нескольких служебных классах, например. г. ДБИ. Как лучше всего это сделать с помощью Log::Log4perl?

Я думаю, что можно создать подкласс DBI (скажем, MyDBI) и переопределить некоторые методы, чтобы заставить их вести журнал. Но есть проблема с категориями. Если вы создаете регистратор с

Log::Log4perl->get_logger(ref $self || $self)

тогда все записи журнала принадлежат MyDBI и их будет сложно отфильтровать. Так что мне кажется лучше передать регистратор в MyDBI из вызывающего модуля (скажем, MyModule), чтобы эта категория была семантически правильной. Первый вопрос, это вообще нормально? Я имею в виду, есть ли какие-то подводные камни в отношении такого подхода?

Второй вопрос, как передать логгер на MyDBI? У меня есть идея объявить глобальную переменную, например. г. $MyDBI::logger и установить в вызывающем методе:

local $MyDBI::logger = Log::Log4perl->get_logger(ref $self || $self);

Существует традиционная неприязнь к глобальным переменным. Можете ли вы придумать лучший способ?

EDIT: Конечно, лучший код — это отсутствие кода. caller было бы достаточно, если бы учитывалось наследование.

Третий вопрос: можно ли войти в обе категории, MyDBI и MyModule, с помощью Log::Log4perl, если они иерархически не связаны?


person codeholic    schedule 03.03.2010    source источник


Ответы (1)


Я настоятельно рекомендую вам вести журнал независимо от вызывающей стороны в отдельном регистраторе либо для каждой функции, либо для каждого модуля, чтобы вы могли запускать свой модуль независимо от log4perl, используемого в вашей вызывающей стороне. Каждый модуль создаст свой собственный регистратор с Log::Log4perl->get_logger("module name").
Если вызывающая программа не создаст никакого приложения, программа просто ничего не зарегистрирует, а log4perl в модулях будет игнорироваться с функциональной точки зрения.
Log4Perl реализует одноэлементный шаблон для создания регистратора, который похож на глобальную переменную.
Ваше ведение журнала должно быть максимально детализированным, и, как правило, я регистрирую в отладке любой входной параметр и любой результат функции/метода. Если это действительно необходимо, вы также можете использовать трассировку стека, чтобы узнать вызывающего абонента, который привел к состоянию ошибки. Добавление его в параметры лишь добавляет сложности.

Следующие рецепты могут дать вам дополнительные идеи о гибкости конфигурации log4perl.Рецепты Log4Perl Вся идея для меня состоит в том, чтобы оставить код неизменным и изменить конфигурацию ведения журнала в зависимости от моих фактических требований к ведению журнала/отслеживанию ошибок (которые могут измениться в будущем). Сохранение кода без изменений, если это возможно, даже более важно для модулей, так как вы хотите избежать тестирования всех вызывающих программ.

Если кратко ответить на ваши вопросы. 1.) Каждый модуль должен иметь свой собственный логгер 2.) Таким образом, не добавляйте логгеры в интерфейс 3.) Log4Perl будет логировать на всех уровнях в зависимости от конфигурации вашего приложения. Таким образом, вы контролируете то, что вы видите, а не видите - нормальный уровень обычно будет INFO, а определенные модули могут находиться в отладке. В неблагоприятных случаях макет шаблона позволит вам добавить трассировку стека в журнал исключительно с конфигурацией.

person weismat    schedule 09.03.2010
comment
Извините, я не понял первое предложение. Что вы подразумеваете под вызывающим, запускать свой модуль независимо от log4perl? Не могли бы вы сделать это более явным? - person codeholic; 09.03.2010
comment
Например. при написании тестовых классов вы можете создать некоторые модули, которые не обязательно будут реализовывать log4perl - вы можете просто пропустить его, тогда как вам нужно добавить много логики, если он является частью вашего интерфейса. - person weismat; 09.03.2010