Pau*_*eld 17 log4net exception
我们刚刚开始使用Log4Net(并且希望我们之前完成它).虽然我们可以看到内部异常等,但是在记录异常时输出中似乎缺少的一件事是"Exception.Data"中保存的任何键/值信息.无论如何我们可以"开箱即用"吗?如果没有,因为我们真的只是刚刚开始寻找实现此功能的方法?
作为示例,请参阅下面的基本伪代码.我们不想用上下文信息污染异常消息只是问题所在(我们可能已经丢失了更多有助于调查实际问题的数据信息).但是现在我们在日志中看到的只是异常类型,消息,任何堆栈跟踪 - 但没有异常"数据".这意味着在我们的日志中我们丢失了客户ID等.我们如何轻松地将这些信息记录到我们的日志中(无需在每个异常捕获中手动编写代码).
try
{
var ex = new ApplicationException("Unable to update customer");
ex.Data.Add("id", customer.Id);
throw ex;
}
catch(ApplicationException ex)
{
logger.Error("An error occurred whilst doing something", ex);
throw;
}
Run Code Online (Sandbox Code Playgroud)
Jer*_*n K 20
继Stefan的领导之后:
namespace YourNamespace {
public sealed class ExceptionDataPatternConverter : PatternLayoutConverter {
protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) {
var data = loggingEvent.ExceptionObject.Data;
if (data != null) {
foreach(var key in data.Keys) {
writer.Write("Data[{0}]={1}" + Environment.NewLine, key, data[key]);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在您的配置中添加%ex_data和转换器:
<appender ...>
...
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%date %d{HH:mm:ss.fff} [%t] %-5p %c %l - %m%n %ex_data"/>
<converter>
<name value="ex_data" />
<type value="YourNamespace.ExceptionDataPatternConverter" />
</converter>
</layout>
Run Code Online (Sandbox Code Playgroud)
我认为更接近这个问题的log4net方法就是写一个PatternLayoutConverter.这里可以找到一个例子.
在转换方法中,您可以像这样访问您的数据(并按您喜欢的方式编写):
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
var data = loggingEvent.ExceptionObject.Data;
}
Run Code Online (Sandbox Code Playgroud)
如果定义了多个appender,则可以使用自定义渲染器,而不是为每个布局定义转换器.
网络/的app.config
<log4net>
...
<renderer renderingClass="YourNamespace.ExceptionObjectLogger, YourAssembly" renderedClass="System.Exception" />
...
</log4net>
Run Code Online (Sandbox Code Playgroud)
ExceptionObjectLogger
public class ExceptionObjectLogger : IObjectRenderer
{
public void RenderObject(RendererMap rendererMap, object obj, TextWriter writer)
{
var ex = obj as Exception;
if (ex == null)
{
// Shouldn't happen if only configured for the System.Exception type.
rendererMap.DefaultRenderer.RenderObject(rendererMap, obj, writer);
}
else
{
rendererMap.DefaultRenderer.RenderObject(rendererMap, obj, writer);
const int MAX_DEPTH = 10;
int currentDepth = 0;
while (ex != null && currentDepth <= MAX_DEPTH)
{
this.RenderExceptionData(rendererMap, ex, writer, currentDepth);
ex = ex.InnerException;
currentDepth++;
}
}
}
private void RenderExceptionData(RendererMap rendererMap, Exception ex, TextWriter writer, int depthLevel)
{
var dataCount = ex.Data.Count;
if (dataCount == 0)
{
return;
}
writer.WriteLine();
writer.WriteLine($"Exception data on level {depthLevel} ({dataCount} items):");
var currentElement = 0;
foreach (DictionaryEntry entry in ex.Data)
{
currentElement++;
writer.Write("[");
ExceptionObjectLogger.RenderValue(rendererMap, writer, entry.Key);
writer.Write("]: ");
ExceptionObjectLogger.RenderValue(rendererMap, writer, entry.Value);
if (currentElement < dataCount)
{
writer.WriteLine();
}
}
}
private static void RenderValue(RendererMap rendererMap, TextWriter writer, object value)
{
if (value is string)
{
writer.Write(value);
}
else
{
IObjectRenderer keyRenderer = rendererMap.Get(value.GetType());
keyRenderer.RenderObject(rendererMap, value, writer);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6943 次 |
| 最近记录: |