2013-01-18 30 views
3

我使用Common.Logging作爲NLog 2.0的包裝。我已經這樣做了,以便將來可以將NLog替換爲另一個日誌記錄提供程序。Common.Logging與PostSharp和NLog 2.0

我也使用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(「一個錯誤」)時,它爲我的表添加了一條記錄。

有人可以幫我嗎?

+0

我對NLog一無所知,但是這條線看起來很可疑; 'this.logger = LogManager.GetCurrentClassLogger();'。在這種情況下,不會得到與方面類相關的「記錄器」,而不是裝飾類? –

+1

'記錄器'會很好,它只會以當前類名命名。 – Chris

回答

0

你用你創建的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)); 
} 

每唐納德Belcham的Pluralsight當然,一方面構造不會在運行時執行,因此,也許你的記錄器沒有得到正確設置。

+0

是的,我用LogMethodAttribute裝飾了我的方法。我只需要在這種特殊情況下記錄我的錯誤,這樣就可以記錄錯誤級別。 –

+0

@JurgenVandw:對不起,我想我仍然試圖理解你的問題,然後......如果你手動把logger.Error()放在你的控制器方法中,但是OnEntry/OnExit不起作用,你會說它有效。您正在將OnEntry/OnExit登錄到調試級別,並且您尚未指定編寫調試消息的位置。如果您在控制器方法中手動使用logger.Debug(),它會起作用嗎?它不應該,除非你在這裏遺漏了一些代碼... – Chris

0

在類看點在應用程序初始化方法中添加靜態屬性記錄

public class LogAspect : OnMethodBoundaryAspect 
{ 
    /// <summary> 
    /// Gets or sets the logger. 
    /// </summary> 
    public static ILogger logger { get; set; } 

集記錄變量與ILogger類和排除這種初始化與AttributeExclude之前的所有方法。

[LogAspect(AttributeExclude = true)] 
    protected void Application_Start() 
    { 
     _windsorContainer = new WindsorContainer(); 
     ApplicationDependencyInstaller.RegisterLoggingFacility(_windsorContainer); 
     LogAspect.logger = _windsorContainer.Resolve<ILogger>(); 
+0

請不要發佈幾個問題完全相同的答案。如果同一個答案適用於多個問題,那麼這個問題是重複的。你應該標記(或關閉,如果你有足夠的聲望),而不是回答。 – ChrisF

+0

好的,謝謝你的建議 – nick2paris