Common.Logging с PostSharp и NLog 2.0
Я использую Common.Logging в качестве оболочки вокруг NLog 2.0. Я сделал это, чтобы в будущем я мог заменить NLog другим провайдером журналов.
Я также использую PostSharp, чтобы не писать блок try catch каждый раз, когда он мне нужен. У меня есть класс, который наследует OnMethodBoundaryAspect:
[Serializable]
public class LogMethodAttribute : OnMethodBoundaryAspect
{
private ILog logger;
public LogMethodAttribute()
{
this.logger = LogManager.GetCurrentClassLogger();
}
public override void OnEntry(MethodExecutionArgs args)
{
logger.Debug(string.Format("Entering {0}.{1}.", args.Method.DeclaringType.Name, args.Method.Name));
}
public override void OnExit(MethodExecutionArgs args)
{
logger.Debug(string.Format("Leaving {0}.{1}.", args.Method.DeclaringType.Name, args.Method.Name));
}
public override void OnException(MethodExecutionArgs args)
{
logger.Error(args.Exception.Message,args.Exception);
}
}
Я настроил Common.Logging следующим образом в моем файле web.config:
<configSections>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog20">
<arg key="configType" value="FILE" />
<arg key="configFile" value="~/NLog.config" />
</factoryAdapter>
</logging>
</common>
NLog.Config выглядит так:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
throwExceptions="true"
internalLogLevel="Debug"
internalLogToConsoleError="true"
internalLogFile="c:\new projects/nlog-app.txt"
>
<!--
See http://nlog-project.org/wiki/Configuration_file
for information on customizing logging rules and outputs.
-->
<targets>
<target name="database"
xsi:type="Database"
commandText="INSERT INTO LogEvent(EventDateTime, EventLevel, UserName, MachineName, EventMessage, ErrorSource, ErrorClass, ErrorMethod, ErrorMessage, InnerErrorMessage) VALUES(@EventDateTime, @EventLevel, @UserName, @MachineName, @EventMessage, @ErrorSource, @ErrorClass, @ErrorMethod, @ErrorMessage, @InnerErrorMessage)"
dbProvider="System.Data.SqlClient">
<connectionString>
Data Source=...;Initial Catalog=myDB;User Id=user;Password=pass;
</connectionString>
<installConnectionString>
Data Source=...;Initial Catalog=myDB;User Id=user;Password=pass;
</installConnectionString>
<!-- parameters for the command -->
<parameter name="@EventDateTime" layout="${date:s}" />
<parameter name="@EventLevel" layout="${level}" />
<parameter name="@UserName" layout="${identity}" />
<parameter name="@MachineName" layout="${machinename}" />
<parameter name="@EventMessage" layout="${message}" />
<parameter name="@ErrorSource" layout="${event-context:item=error-source}" />
<parameter name="@ErrorClass" layout="${event-context:item=error-class}" />
<parameter name="@ErrorMethod" layout="${event-context:item=error-method}" />
<parameter name="@ErrorMessage" layout="${event-context:item=error-message}" />
<parameter name="@InnerErrorMessage" layout="${event-context:item=inner-error-message}" />
<!-- commands to install database -->
<install-command>
<text>CREATE DATABASE myDB</text>
<connectionString> Data Source=...;Initial Catalog=myDB;User Id=user;Password=pass;</connectionString>
<ignoreFailures>true</ignoreFailures>
</install-command>
<install-command>
<text>
CREATE TABLE LogEvent(
EventId int primary key not null identity(1,1),
EventDateTime datetime,
EventLevel nvarchar(50),
UserName nvarchar(50),
MachineName nvarchar(1024),
EventMessage nvarchar(MAX),
ErrorSource nvarchar(1024),
ErrorClass nvarchar(1024),
ErrorMethod nvarchar(1024),
ErrorMessage nvarchar(MAX),
InnerErrorMessage nvarchar(MAX));
</text>
</install-command>
<!-- commands to uninstall database -->
<uninstall-command>
<text>DROP DATABASE myDB</text>
<connectionString> Data Source=...;Initial Catalog=myDB;User Id=user;Password=pass;</connectionString>
<ignoreFailures>true</ignoreFailures>
</uninstall-command>
</target>
</targets>
<rules>
<logger name="*" levels="Error" writeTo="database" />
</rules>
</nlog>
Проблема в том, что ничего не вставлено в мою таблицу. Например, когда я помещаю регистратор в свой HomeController на страницу индекса и вызываю logger.Error("ошибка"), он добавляет запись в мою таблицу.
Кто-нибудь может мне помочь?
2 ответа
Добавить статический регистратор свойств в свой класс Aspect
public class LogAspect : OnMethodBoundaryAspect
{
/// <summary>
/// Gets or sets the logger.
/// </summary>
public static ILogger logger { get; set; }
установите переменную logger в вашем методе init приложения с вашим классом ILogger и исключите все методы перед этой инициализацией с помощью AttributeExclude.
[LogAspect(AttributeExclude = true)]
protected void Application_Start()
{
_windsorContainer = new WindsorContainer();
ApplicationDependencyInstaller.RegisterLoggingFacility(_windsorContainer);
LogAspect.logger = _windsorContainer.Resolve<ILogger>();
Украшаете ли вы методы вашего контроллера созданным вами атрибутом LogMethodAttribute?
Кроме того, вы захотите настроить правило ведения журнала так, чтобы оно включало больше уровней, кроме просто "Ошибка", иначе это все, что вы будете регистрировать.
Попробуйте это:
<rules>
<logger name="*" minLevel="Trace" writeTo="database" />
</rules>
Редактировать:
Вы пытались перенести инициализацию вашего регистратора в ваш метод?
public override void OnEntry(MethodExecutionArgs args)
{
this.logger = LogManager.GetCurrentClassLogger();
logger.Debug(string.Format("Entering {0}.{1}.", args.Method.DeclaringType.Name, args.Method.Name));
}
Согласно курсу Дональда Белхэма Pluralsight, конструкторы аспектов не выполняются во время выполнения, поэтому, возможно, ваш регистратор не настроен должным образом.