我正在使用Log4net
。我最近决定将跟踪侦听器添加到我的配置文件中,以捕获Log4net
本身生成的任何错误。 (该
Log4net FAQ包含此示例配置。)
(我在谈论Log4net
由于无法完成其工作而产生错误消息的情况。我不是在谈论配置它来记录应用程序错误。)
在测试时,我在测试项目中弄乱了Log4net
配置,以强制Log4net
或ADO.Net Appender
错误,以验证Trace Listener设置是否正确处理了它们
我发现,即使关闭Log4net
调试,也会将内部Log4net
错误写入跟踪侦听器。 这就是我想要的。
这是我通过调整Log4net.Layout
中app.config
的类型名称来生成的示例错误,以引用不存在的类型。这是Trace Listener文件中唯一的条目,这就是我想要的。
log4net:ERROR Failed to find type [log4net.Layout.RawTimeStampLayoutXX]
System.TypeLoadException: Could not load type [log4net.Layout.RawTimeStampLayoutXX]. Tried assembly [log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a] and all loaded assemblies
at log4net.Util.SystemInfo.GetTypeFromString(Assembly relativeAssembly, String typeName, Boolean throwOnError, Boolean ignoreCase)
at log4net.Util.SystemInfo.GetTypeFromString(String typeName, Boolean throwOnError, Boolean ignoreCase)
at log4net.Repository.Hierarchy.XmlHierarchyConfigurator.CreateObjectFromXml(XmlElement element, Type defaultTargetType, Type typeConstraint)
log4net:ERROR Failed to create object to set param: layout
但是,我还发现,如果错误发生在外部系统中(例如,在下面的示例中,SQL Server错误),则错误将仅出现在跟踪侦听器文件中{{1}调试已打开。这意味着它被大量的内部管家信息所包围。
Log4net
我不想一直打开调试,只是为了捕获这种错误。这个应用程序每天运行70次,每次运行产生25KB的调试跟踪监听器输出,仅来自内部管理。我不想涉及兆字节的噪音来找到一个信号。
所以,我的问题:
log4net:ERROR [AdoNetAppender] ErrorCode: GenericFailure. Exception while writing to database
System.Data.SqlClient.SqlException (0x80131904): Must declare the scalar variable "@log_date".
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at log4net.Appender.AdoNetAppender.SendBuffer(IDbTransaction dbTran, LoggingEvent[] events)
at log4net.Appender.AdoNetAppender.SendBuffer(LoggingEvent[] events)
ClientConnectionId:8ddb2758-4adc-495e-af8b-c16e0acc937a
Error Number:137,State:2,Class:15
调试的情况下捕获跟踪侦听器中Appender
致命的错误?答案 0 :(得分:1)
我找到了解决方案。一个漂亮,优雅的。
Log4net
中的所有Appender类都有一个名为ErrorHandler
的公共属性。默认情况下,这被设置为名为OnlyOnceErrorHandler
的类的实例,该类将错误记录到调试源(如果已启用),然后停止报告错误。
但您可以通过配置覆盖此内容:
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\logfile.txt" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
<maxSizeRollBackups value="-1" />
<maximumFileSize value="50GB" />
<errorHandler type="MyTraceLoggingErrorHandler, MyAssembly" />
ErrorHandler
实现了非常简单的接口IErrorHandler
,可以做任何你想做的事情。
在我的情况下,我只是将它收到的消息和例外写入TraceListener
:
Trace.WriteLine(message);
Trace.WriteLine(errorCode);
Trace.WriteLine(e.Message);
Trace.WriteLine(e.StackTrace);
这解决了我的问题。