问题
I got use the following class to print out messages using log4net:
public class Message
{
public String Text { get; set; }
public int Id { get; set; }
public override string ToString()
{
return Text;
}
}
I use Logger.Info(MessageInstance)
, so log4net just invokes the ToString
method and prints out the message. I would like to also log the Id
property of the message object, but I cannot figure out how to achive this.
My conversion pattern looks similiar to this:
<conversionPattern value="%date %-5level %message%newline" />
I tried adding %message{Id}
but that would just print the whole message twice.
Any Suggestions?
回答1:
I just wrote a custom pattern, which allows to read properies of the message object.
public class ReflectionReader : PatternLayoutConverter
{
public ReflectionReader()
{
_getValue = GetValueFirstTime;
}
protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
writer.Write(_getValue(loggingEvent.MessageObject));
}
private Func<object, String> _getValue;
private string GetValueFirstTime(object source)
{
_targetProperty = source.GetType().GetProperty(Option);
if (_targetProperty == null)
{
_getValue = x => "<NULL>";
}
else
{
_getValue = x => String.Format("{0}", _targetProperty.GetValue(x, null));
}
return _getValue(source);
}
private PropertyInfo _targetProperty;
}
Combine with this:
public class ReflectionLayoutPattern : PatternLayout
{
public ReflectionLayoutPattern()
{
this.AddConverter("item", typeof(ReflectionReader));
}
}
Config looks like this:
<layout type="MyAssembly.MyNamespace.ReflectionLayoutPattern, MyAssembly">
<conversionPattern value="[%item{Id}]	%message%newline" />
</layout>
回答2:
You can use a CustomXmlLayout class that derives from XmlLayoutBase and override the FormatXml method. This method takes a LoggingEvent object as parameter which will contain the MessageObject that was passed to the log method.
public class SpecialXmlLayout : XmlLayoutBase
{
protected override void FormatXml(XmlWriter writer, LoggingEvent loggingEvent)
{
Message message = loggingEvent.MessageObject as Message;
writer.WriteStartElement("LoggingEvent");
writer.WriteElementString("Message", GetMessage(message));
// ... write other things
writer.WriteEndElement();
}
}
Inside the GetMessaage method create your string as you would like from the message.
Then use this layout class in log4net config:
<log4net>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<applicationName value="My Application" />
<layout type="Namespace.SpecialXmlLayout">
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="ERROR" />
<param name="LevelMax" value="FATAL" />
</filter>
</appender>
</log4net>
This is the idea. For more specific details you will have to consult the log4Net SDK documentation.
来源:https://stackoverflow.com/questions/15806793/log4net-custom-property-logging