2013-05-06 59 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();