C# 如何使用XmlLayoutSchemaLog4j布局在Log4Net中记录throwable?
我的Log4Net配置如下所示:C# 如何使用XmlLayoutSchemaLog4j布局在Log4Net中记录throwable?,c#,log4net,log4net-configuration,C#,Log4net,Log4net Configuration,我的Log4Net配置如下所示: <appender name="MainLogFileAppender" type="log4net.Appender.RollingFileAppender"> <param name="File" value="${log4net_log_file_name}"/> <param name="AppendToFile" value="true"/> <rollingStyle value=
<appender name="MainLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="${log4net_log_file_name}"/>
<param name="AppendToFile" value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="1"/>
<maximumFileSize value="1MB"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.XmlLayoutSchemaLog4j">
<locationInfo value="true" />
</layout>
</appender>
<appender name="MemoryAppender" type="log4net.Appender.MemoryAppender" >
<onlyFixPartialEventData value="true" />
</appender>
</log4net>
当我们记录错误时,我从未在日志中看到可丢弃节点。之所以使用当前布局,是因为我们将XML转换为DTO并在UI中显示它们
我还没有找到任何东西来解释为什么Trowable没有被设置并存储在日志中。有什么想法吗(我正在考虑把我的开发盒扔出窗外)
我的日志中有一个错误:
<log4j:event logger="Hsbc.Ice.Shell.ViewModels.ShellViewModel" timestamp="1353076754456" level="ERROR" thread="1"><log4j:message>14 modules did not terminated in a timely manner : TradingCockpitModule,AuthenticationModule,ConfigurationModule,EntitlementsModule,Hsbc.Ice.CreditServices,EncryptionModule,ReportsModule,DiagnosticsModule,InterProcessCommunication,Layout,Logging,PersistenceModule,StorageModule,ICEExplorerManagerServiceModule</log4j:message><log4j:properties><log4j:data name="log4net:UserName" value="HBEU\steveget" /><log4j:data name="log4net:Identity" value="HBEU\steveget" /><log4j:data name="log4jmachinename" value="E8262XDZW4LZKEC" /><log4j:data name="log4japp" value="Hsbc.Ice.Shell.exe" /><log4j:data name="log4net:HostName" value="E8262XDZW4LZKEC" /></log4j:properties><log4j:locationInfo class="Hsbc.Ice.Shell.ViewModels.ShellViewModel" method="<.ctor>b__3" file="d:\CreditFlow\Tools\Hudson\data\jobs\Credit Shell\workspace\src\Shell\Hsbc.Ice.Shell\ViewModels\ShellViewModel.cs" line="107" /></log4j:event>
14个模块没有及时终止:TradingCockpitModule、AuthenticationModule、ConfigurationModule、AuthenticationsModule、AuthenticationsModule、AuthenticationsModule、AuthenticationsModule、AuthenticationsModule、AuthenticationsModule、AuthoritysModule、Hsbc.Ice.CreditServices、EncryptionModule、ReportsModule、DiagnosticsModule、进程间通信、布局、日志记录、PersistenceModule、StorageModule、ICExplorerManagerServiceModule
来自:
throwable:用于输出已绑定到
LoggingEvent,默认情况下,这将输出完整的跟踪
通常通过调用Throwable.printStackTrace()进行查找
因此,Throwable在.Net中是不可用的:也许可以替换异常堆栈跟踪,但尚未实现
private void LogException(Exception ex)
{
_log.Fatal("Unhandled exception", ex);
}
有
您还可以使用ex.StackTrace()
获取信息
如果您希望整个堆栈跟踪在.NET中
NET中没有可丢弃的配置(或者至少我在文档中找不到关于它的任何内容),搜索只会产生有意义的Java结果,因为C中没有可丢弃的
,
,就像Java中一样。在浏览完答案后,我决定尝试基于Stuart Dunkeld的答案的东西,如上所述(给了他答案,我把这个放在这里是为了完整)
基本上,我创建了一个自定义布局,该布局继承并覆盖了现有布局xml格式化程序:
重写方法中的重要位是:
if (exceptionString!=null && !string.IsNullOrEmpty(exceptionString.StackTrace))
{
writer.WriteStartElement("log4j:throwable");
Transform.WriteEscapedXmlString(writer, exceptionString.StackTrace, InvalidCharReplacement);
writer.WriteEndElement();
}
为了完整起见,这里是整个类。这允许我们捕获错误的堆栈跟踪及其消息:
public class Log4NetErrorLogger : XmlLayoutSchemaLog4j
{
private static readonly DateTime Date1970 = new DateTime(1970, 1, 1);
protected override void FormatXml(XmlWriter writer, LoggingEvent loggingEvent)
{
if (loggingEvent.LookupProperty("log4net:HostName") != null &&
loggingEvent.LookupProperty("log4jmachinename") == null)
{
loggingEvent.GetProperties()["log4jmachinename"] = loggingEvent.LookupProperty("log4net:HostName");
}
if (loggingEvent.LookupProperty("log4japp") == null && !string.IsNullOrEmpty(loggingEvent.Domain))
{
loggingEvent.GetProperties()["log4japp"] = loggingEvent.Domain;
}
if (!string.IsNullOrEmpty(loggingEvent.Identity) &&
loggingEvent.LookupProperty("log4net:Identity") == null)
{
loggingEvent.GetProperties()["log4net:Identity"] = loggingEvent.Identity;
}
if (!string.IsNullOrEmpty(loggingEvent.UserName) &&
loggingEvent.LookupProperty("log4net:UserName") == null)
{
loggingEvent.GetProperties()["log4net:UserName"] = loggingEvent.UserName;
}
writer.WriteStartElement("log4j:event");
writer.WriteAttributeString("logger", loggingEvent.LoggerName);
writer.WriteAttributeString("timestamp",
XmlConvert.ToString(
(long)
(loggingEvent.TimeStamp.ToUniversalTime() - Date1970)
.TotalMilliseconds));
writer.WriteAttributeString("level", loggingEvent.Level.DisplayName);
writer.WriteAttributeString("thread", loggingEvent.ThreadName);
writer.WriteStartElement("log4j:message");
Transform.WriteEscapedXmlString(writer, loggingEvent.RenderedMessage, InvalidCharReplacement);
writer.WriteEndElement();
object obj = loggingEvent.LookupProperty("NDC");
if (obj != null)
{
string text = loggingEvent.Repository.RendererMap.FindAndRender(obj);
if (!string.IsNullOrEmpty(text))
{
writer.WriteStartElement("log4j:NDC");
Transform.WriteEscapedXmlString(writer, text, InvalidCharReplacement);
writer.WriteEndElement();
}
}
PropertiesDictionary properties = loggingEvent.GetProperties();
if (properties.Count > 0)
{
writer.WriteStartElement("log4j:properties");
foreach (DictionaryEntry dictionaryEntry in properties)
{
writer.WriteStartElement("log4j:data");
writer.WriteAttributeString("name", (string) dictionaryEntry.Key);
string text = loggingEvent.Repository.RendererMap.FindAndRender(dictionaryEntry.Value);
writer.WriteAttributeString("value", text);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
var exceptionString = loggingEvent.ExceptionObject;
if (exceptionString!=null && !string.IsNullOrEmpty(exceptionString.StackTrace))
{
writer.WriteStartElement("log4j:throwable");
Transform.WriteEscapedXmlString(writer, exceptionString.StackTrace, InvalidCharReplacement);
writer.WriteEndElement();
}
if (LocationInfo)
{
LocationInfo locationInformation = loggingEvent.LocationInformation;
writer.WriteStartElement("log4j:locationInfo");
writer.WriteAttributeString("class", locationInformation.ClassName);
writer.WriteAttributeString("method", locationInformation.MethodName);
writer.WriteAttributeString("file", locationInformation.FileName);
writer.WriteAttributeString("line", locationInformation.LineNumber);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
}
你能从日志中发布一个示例行吗?我在.Net中可以使用类似的布局吗?我应该使用这个特定的布局还是可以使用更好的布局?任何包含
异常的都可以
if (exceptionString!=null && !string.IsNullOrEmpty(exceptionString.StackTrace))
{
writer.WriteStartElement("log4j:throwable");
Transform.WriteEscapedXmlString(writer, exceptionString.StackTrace, InvalidCharReplacement);
writer.WriteEndElement();
}
public class Log4NetErrorLogger : XmlLayoutSchemaLog4j
{
private static readonly DateTime Date1970 = new DateTime(1970, 1, 1);
protected override void FormatXml(XmlWriter writer, LoggingEvent loggingEvent)
{
if (loggingEvent.LookupProperty("log4net:HostName") != null &&
loggingEvent.LookupProperty("log4jmachinename") == null)
{
loggingEvent.GetProperties()["log4jmachinename"] = loggingEvent.LookupProperty("log4net:HostName");
}
if (loggingEvent.LookupProperty("log4japp") == null && !string.IsNullOrEmpty(loggingEvent.Domain))
{
loggingEvent.GetProperties()["log4japp"] = loggingEvent.Domain;
}
if (!string.IsNullOrEmpty(loggingEvent.Identity) &&
loggingEvent.LookupProperty("log4net:Identity") == null)
{
loggingEvent.GetProperties()["log4net:Identity"] = loggingEvent.Identity;
}
if (!string.IsNullOrEmpty(loggingEvent.UserName) &&
loggingEvent.LookupProperty("log4net:UserName") == null)
{
loggingEvent.GetProperties()["log4net:UserName"] = loggingEvent.UserName;
}
writer.WriteStartElement("log4j:event");
writer.WriteAttributeString("logger", loggingEvent.LoggerName);
writer.WriteAttributeString("timestamp",
XmlConvert.ToString(
(long)
(loggingEvent.TimeStamp.ToUniversalTime() - Date1970)
.TotalMilliseconds));
writer.WriteAttributeString("level", loggingEvent.Level.DisplayName);
writer.WriteAttributeString("thread", loggingEvent.ThreadName);
writer.WriteStartElement("log4j:message");
Transform.WriteEscapedXmlString(writer, loggingEvent.RenderedMessage, InvalidCharReplacement);
writer.WriteEndElement();
object obj = loggingEvent.LookupProperty("NDC");
if (obj != null)
{
string text = loggingEvent.Repository.RendererMap.FindAndRender(obj);
if (!string.IsNullOrEmpty(text))
{
writer.WriteStartElement("log4j:NDC");
Transform.WriteEscapedXmlString(writer, text, InvalidCharReplacement);
writer.WriteEndElement();
}
}
PropertiesDictionary properties = loggingEvent.GetProperties();
if (properties.Count > 0)
{
writer.WriteStartElement("log4j:properties");
foreach (DictionaryEntry dictionaryEntry in properties)
{
writer.WriteStartElement("log4j:data");
writer.WriteAttributeString("name", (string) dictionaryEntry.Key);
string text = loggingEvent.Repository.RendererMap.FindAndRender(dictionaryEntry.Value);
writer.WriteAttributeString("value", text);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
var exceptionString = loggingEvent.ExceptionObject;
if (exceptionString!=null && !string.IsNullOrEmpty(exceptionString.StackTrace))
{
writer.WriteStartElement("log4j:throwable");
Transform.WriteEscapedXmlString(writer, exceptionString.StackTrace, InvalidCharReplacement);
writer.WriteEndElement();
}
if (LocationInfo)
{
LocationInfo locationInformation = loggingEvent.LocationInformation;
writer.WriteStartElement("log4j:locationInfo");
writer.WriteAttributeString("class", locationInformation.ClassName);
writer.WriteAttributeString("method", locationInformation.MethodName);
writer.WriteAttributeString("file", locationInformation.FileName);
writer.WriteAttributeString("line", locationInformation.LineNumber);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
}