2010-11-29 2 views
11

У меня есть несколько различных веб-сервисов, открытых на моем веб-сайте. Вот цели, которые я хочу достичь:log4net: как настроить данные для хранения

  1. Хранить все данные в БД в одной таблице;
  2. Каждая запись должна иметь текстовое поле с именем «service/component»;
  3. Необходимо сохранить все параметры дохода при вызове любого метода;
  4. Необходимо сохранить все параметры результата и сообщения об ошибках, если возникло какое-либо исключение.

Мое первоначальное намерение было использовать log4net. Но из этих проходов (http://sadi02.wordpress.com/2008/09/15/how-to-store-log-in-database-using-log4net/, http://logging.apache.org/log4net/release/config-examples.html) я не вижу простой способ для добавления пользовательских данных в таблицу журналов.

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

Спасибо.

ответ

2

Ни один из предложенных ответов не работает для меня. Проблема в том, что мне нужно иметь несколько настраиваемых полей. Для меня кажется слишком сложным создавать разные экземпляры регистратора или настраивать значения столбцов каждый раз через «свойства».

Я поеду (фактически, уже реализован) пользовательский регистратор, который поместил данные в БД.

1

Рассматривая документацию log4net, можете ли вы выяснить, как получить ваши пользовательские данные, записанные в файл? Если это так, вы также сможете получить те же данные, которые зарегистрированы в базе данных. Просто добавьте в таблицу больше столбцов, больше столбцов в узле <command text> AdoNetAppender и еще <parameter> узлов.

Я думаю, что у вас будет какая-то работа, чтобы выполнить входные и исходящие параметры. Вам нужно, чтобы они вошли в отдельные столбцы (возможно, это было непросто сделать чисто)? Это нормально, если они записываются вместе с сообщением?

Например, если у вас есть следующий метод, который вы хотите поместить вход в:

public void DoSomething(int x, int y) 
{ 
    log.Info("Inside DoSomething"); 
} 

Что вы хотите, чтобы ваш выход выглядеть? Вы хотите, чтобы «стандартная» информация log4net отображалась в отдельных столбцах (timestamp, loggername, level, message)? Как насчет параметров? Если х и у отображаются в отдельных столбцах (возможно, не очень легко сделать, если каждый метод не имеет такое же количество параметров) или это нормально, если параметры были авторизованы как это:

public void DoSomething(int x, int y) 
{ 
    ILog log = LogManager.GetLogger("abc"); 
    log.InfoFormat("Parameters: x = {0}, y = {1}", x, y); 
    log.Info("Inside DoSomething"); 
} 

Операторы журнала будут генерировать сообщения что будет выглядеть примерно так:

11/29/2010 16:36:00 | abc | INFO | Parameters: x = 10, y = 20 
11/29/2010 16:36:00 | abc | INFO | Inside DoSomething 

Я использовал | чтобы показать, какие поля будут иметь макет шаблона, который показывает временную метку, имя пользователя, уровень журнала и сообщение.

Рассмотрение решения AOP, такого как PostSharp, может помочь вам, поскольку вы можете относительно легко добавлять входные/выходные регистрации без «загрязнения» исходного кода вашего приложения с помощью протоколирующих операторов. Внутри аспекта ведения журнала вы должны иметь доступ к параметрам метода.

Возможно, у меня что-то не хватает, но я подозреваю, что если вы хотите сохранить свои параметры метода как отдельные столбцы в базе данных, вам будет трудно это сделать. Если вы удовлетворены объединением всех параметров (вручную) для каждого метода в виде одного столбца (по существу, форматированной строки), то это будет проще.Одна цена, которую вы должны будете заплатить, заключается в том, что вам придется явно регистрировать все параметры (если вы не отправляете маршрут AOP).

Если вы планируете использовать log4net, вы также должны рассмотреть возможность использования NLog. Это не обязательно поможет вам в проблемах, описанных выше, но я думаю, что это достойный конкурент log4net.

[EDIT]

Чтобы получить «имя компонента», регистрируемые log4net, вы должны назвать свои регистраторы для компонентов. Когда вы вызываете LogManager.GetLogger (имя), вы можете передать любое имя (или тип). Общий шаблон должен иметь код, как это в каждом классе:

public class MyClass 
{ 
    private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

    public void DoSomething(int x) 
    { 
    logger.InfoFormat("Inside DoSomething. x = {0}", x); 
    } 
} 

Это позволит получить регистратор имени с полным именем класса (имен + имя класса). Если вы делаете это в каждом классе, вы можете контролировать ведение журнала (уровень, к которому это приложение добавляется и т. Д.) Для каждого класса. Таким образом, вы можете легко включить регистрацию для Class1 в Info и выполнить регистрацию для Class2 Off и т. Д. Это дает вам возможность максимально контролировать ваш журнал.

Теперь, в вашем файле конфигурации, вы не обязаны указывать каждый регистратор (т. Е. Каждое полное имя класса) явно. Вы можете просто настроить корневой журнал, а затем эти настройки будут применены к каждому регистратору. Вы можете управлять ведением журнала по пространству имен. Например, если вы работаете на CompanyX и у вас есть четкие правила пространства имен, ваши пространства имен может выглядеть следующим образом:

CompanyX 
CompanyX.DataAccess 
CompanyX.DataAccess.Read 
CompanyX.DataAccess.Write 
CompanyX.GUI 
CompanyX.Forms 
CompanyX.Controls 

В пределах каждого пространства имен, вы можете иметь различный класс (например, несколько разных читателей данных, вспомогательные классы, авторов данных, и т.д). С такими классами, как это, и с вашими классами, регистрирующими журналы, как описано выше, вы можете легко настроить ведение журнала для всех классов в CompanyX или всех регистраторов в CompanyX.DataAccess или CompanyX.DataAccess.Read и т. Д. Вы даже можете отключить все протоколирования , но включите его для этого трудного класса, который дает вам проблемы.

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

ILog logger = LogManager.GetLogger("DataAccess"); 
ILog logger = LogManager.GetLogger("Performance"); 
ILog logger = LogManager.GetLogger("UI"); 

И так далее. Я не вижу, что это приносит большую пользу, используя полное имя класса. Если ваше пространство имен хорошо организовано, то ваша способность настраивать ведение журнала будет иметь максимальную гибкость с минимальными усилиями с вашей стороны.

Другое слово на NLog ... NLog очень похож на log4net. Он имеет полезную функцию, чтобы быть в состоянии автоматически возвращает регистратор для текущего класса:

Logger logger = NLog.LogManager.GetCurrentClassLogger(); 

Это, по крайней мере, сохраняет некоторые печатать с вашей стороны. NLog также просто вышел с новой версией (в настоящее время в бета-версии).

Не знаю, помогло ли это, но я надеюсь, что так оно и было!

Удачи вам!

+0

Хорошо иметь все параметры в 1 поле, но (как я упоминал в комментарии к другому ответу). Я хотел бы иметь имя компонента в отдельном столбце (без изменения глобального контекста для каждого вызова). Также я хотел бы иметь 3 дополнительных столбца: income_data, result_data, error_message. Возможно, я мог бы настроить несколько разных экземпляров журнала (1 на компонент)? И в этом случае мне не нужно менять глобальные настройки каждый раз? Извините, я новичок в log4net. – Budda 2010-11-30 03:49:26

+0

Да, вы, вероятно, хотите иметь хотя бы один регистратор на один компонент. Я добавил несколько примеров в свой ответ. – wageoghe 2010-11-30 14:52:06

14

В соответствии с этим discussion, процесс довольно прост.

Первый шаг, чтобы обновить текст команды в декларации Appender в ваш конфигурационный файл:

<commandText value="INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception],[MyColumn]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception,@MyColumn)"/>   

Следующим шагом будет добавить новое определение параметров для пользовательского столбца:

<parameter> 
    <parameterName value="@MyColumn "/> 
    <dbType value="String" /> 
    <size value="255" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%property{MyColumn}" /> 
    </layout> 
</parameter> 

Наконец, вы можете получить доступ к значению через свойство GlobalContext в log4net:

log4net.GlobalContext.Properties["MyColumn"] = "MyValue"; 
log.Debug("My message"); 

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

Смежные вопросы