2013-05-06 65 views
0

我正在使用自定義ADONetAppender,它定義了基本參數Date,Thread,Level等,還使用了自定義Parameter appender。看起來,在運行SQL Server 2008 R2的Win 7 developmet機器上,它工作正常,並且添加了特殊參數,該參數與位列綁定並且是必需的(非空值)。定製log4net ADONET appender在某些機器上不工作

在Win Server 2003計算機上運行服務時(嘗試一個運行SQL Server 2005,另一個運行於2008 R2),log4net無法將日誌追加到數據庫,但是我的其他appender可以工作。我知道log4net有內部調試,但是這是運行一個服務,所以我沒有訪問控制檯。與不同版本的Windows或其他一些建議的調試操作有兼容性問題嗎?

如果我要刪除額外的參數,日誌將被寫入數據庫。

<log4net> 
    <appender name="LogFileAppender" type="log4net.Appender.FileAppender"> 
     <param name="File" value="C:\Logs\Log.txt" /> 
     <param name="AppendToFile" value="true" /> 
     <param name="ImmediateFlush" value="true" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <param name="Header" value="[Header]&#xD;&#xA;" /> 
     <param name="Footer" value="[Footer]&#xD;&#xA;" /> 
     <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" /> 
     </layout> 
    </appender> 
    <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender"> 
     <bufferSize value="1"/> 
     <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> 
     <connectionString value="Data Source=localhost\SQLEXPRESS;Initial Catalog=mydb;Integrated Security=True"/> 
     <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception],[IsCritical]) VALUES&#xD;&#xA;  (@log_date, @thread, @log_level, @logger, @message, 

@exception, @is_critical)" 
                     /> 
     <parameter> 
     <parameterName value="@log_date"/> 
     <dbType value="DateTime"/> 
     <layout type="log4net.Layout.RawUtcTimeStampLayout"/> 
     </parameter> 
     <parameter> 
     <parameterName value="@thread"/> 
     <dbType value="String"/> 
     <size value="32"/> 
     <layout type="log4net.Layout.PatternLayout"> 
      <conversionPattern value="%t"/> 
     </layout> 
     </parameter> 
     <parameter> 
     <parameterName value="@log_level"/> 
     <dbType value="String"/> 
     <size value="512"/> 
     <layout type="log4net.Layout.PatternLayout"> 
      <conversionPattern value="%p"/> 
     </layout> 
     </parameter> 
     <parameter> 
     <parameterName value="@logger"/> 
     <dbType value="String"/> 
     <size value="512"/> 
     <layout type="log4net.Layout.PatternLayout"> 
      <conversionPattern value="%c"/> 
     </layout> 
     </parameter> 
     <parameter> 
     <parameterName value="@message"/> 
     <dbType value="String"/> 
     <size value="4000"/> 
     <layout type="log4net.Layout.PatternLayout"> 
      <conversionPattern value="%m"/> 
     </layout> 
     </parameter> 
     <parameter> 
     <parameterName value="@exception"/> 
     <dbType value="String"/> 
     <size value="2000"/> 
     <layout type="log4net.Layout.ExceptionLayout"/> 
     </parameter> 
     <parameter type="MyApp.Logging.IsCriticalAdoNetParameter"> 
     <parameterName value="@is_critical"/> 
     <dbType value="Boolean"/> 
     <size value="10"/> 
     <layout type="log4net.Layout.PatternLayout" value=""/> 
     </parameter> 
    </appender> 
    <root> 
     <level value="DEBUG" /> 
     <appender-ref ref="LogFileAppender" /> 
     <appender-ref ref="ADONetAppender"/> 
    </root> 
    </log4net> 

自定義參數:

public class IsCriticalAdoNetParameter : AdoNetAppenderParameter 
    { 
     public override void FormatValue(IDbCommand command, LoggingEvent loggingEvent) 
     { 
      // Lookup the parameter 
      IDbDataParameter param = (IDbDataParameter)command.Parameters[ParameterName]; 

      // extension method, returns bool. 
      param.Value = loggingEvent.IsCritical(); 
     } 
    } 

更新,做了一些調試與具有相同的日誌部分小型控制檯應用程序。它似乎在炸燬專欄名稱。這似乎暗示該專欄不存在,但確實如此。我想知道是否將布爾轉換爲實際的SQL數據類型的問題?

log4net: XmlHierarchyConfigurator: Setting Property [Layout] to object [log4net. 
Layout.Layout2RawLayoutAdapter] 
log4net: XmlHierarchyConfigurator: Setting Collection Property [AddParameter] to 
object [log4net.Appender.AdoNetAppenderParameter] 
log4net: SystemInfo: Loaded type [MyApp.Logging.IsCriticalAdoNetPar 
ameter] from assembly [MyApp, Version=2.0.0.2929, Culture=neutral, 
PublicKeyToken=null] by searching loaded assemblies. 
log4net: XmlHierarchyConfigurator: Setting Property [ParameterName] to String va 
lue [@is_critical] 
log4net: XmlHierarchyConfigurator: Setting Property [DbType] to DbType value [Bo 
olean] 
log4net: XmlHierarchyConfigurator: Setting Property [Size] to Int32 value [1] 
log4net: XmlHierarchyConfigurator: Parameter [layout] specified subtype [log4net 
.Layout.PatternLayout] 
log4net: XmlHierarchyConfigurator: Performing additional conversion of value fro 
m [PatternLayout] to [IRawLayout] 
log4net: XmlHierarchyConfigurator: Setting Property [Layout] to Layout2RawLayout 
Adapter value [log4net.Layout.Layout2RawLayoutAdapter] 
log4net: XmlHierarchyConfigurator: Setting Collection Property [AddParameter] to 
object [MyApp.Logging.IsCriticalAdoNetParameter] 
log4net: XmlHierarchyConfigurator: Created Appender [ADONetAppender] 
log4net: XmlHierarchyConfigurator: Adding appender named [ADONetAppender] to log 
ger [root]. 
log4net: XmlHierarchyConfigurator: Hierarchy Threshold [] 
log4net:ERROR [AdoNetAppender] Exception while writing to database 
System.Data.SqlClient.SqlException (0x80131904): Invalid column name 'IsCritical 
'. 
Statement(s) could not be prepared. 
    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolea 
n breakConnection) 
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception 
, Boolean breakConnection) 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 

回答

0

首先,我改變了我的自定義參數爲1的大小,因爲它是一個布爾值(位)。雖然這沒有解決問題,但它是一個更正確的配置。

<parameter type="MyApp.Logging.IsCriticalAdoNetParameter"> 
    <parameterName value="@is_critical"/> 
    <dbType value="Boolean"/> 
    <size value="1"/> 
    <layout type="log4net.Layout.PatternLayout" value=""/> 
    </parameter> 

最後,它似乎是通過一些跟蹤,自定義參數不是一個加載的程序集,所以我明確構造參數在引導階段後,我跑了XML配置。我認爲log4net使用反射很難找到Appender,因爲它還不是一個加載的程序集。

XmlConfigurator.Configure(); 
    // this ensure the ado net appender is loaded. 
    IsCriticalAdoNetParameter adoNetParameter = new IsCriticalAdoNetParameter();