注意上面配置代码中:log4net.Layout.PatternLayout 是log4net本身提供的配置模板,如果你有的字段需要用到其本身的模板字段的话,就可以使用。
还需要注意这段话: ,它表明,我们将会利用log4net提供的已有的property转义模板来识别我们的字段。
但是如果你有自定义字段的话,你就需要自己写layout和converter了。在上面的配置文件中,content,s_id,t_id是我自定义的三个字段,如何让这三个字段也写入到数据库呢,我们一步一步来配置。
首先,需要将三个自定义字段放到一个entity类中:
namespace FuNong.Framework.Logger
{
public class LogContent
{
public LogContent(string content, string s_id, string t_id)
{
this.content = content;
this.s_id = s_id;
this.t_id = t_id;
}
public string content { get; set; }
public string s_id { get; set; }
public string t_id { get; set; }
}
}
然后,定义我们自己的layout,由于我们使用了property字段模板,所以我们这里需要按照如下方式添加:
namespace FuNong.Framework.Logger
{
public class CustomLayout:PatternLayout
{
public CustomLayout()
{
this.AddConverter("property", typeof(XPatternConverter));
}
}
}
最后,就是我们的Converter实现了:
namespace FuNong.Framework.Logger
{
public class XPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent)
{
if (this.Option != null)
{
// Write the value for the specified key
WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));
}
else
{
// Write all the key value pairs
WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());
}
}
///
/// 通过反射获取传入的日志对象的某个属性的值
///
///
///
private Object LookupProperty(String property, log4net.Core.LoggingEvent loggingEvent)
{
Object propertyValue = String.Empty;
PropertyInfo propertyInfo;
propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);
if (propertyInfo != null)
{
propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);
}
return propertyValue;
}
}
}
从上面代码,我们可以看到,log4net会通过反射来识别我们logContent这个entity中的字段,然后逐个赋值,再写到数据库的。
下面我们稍微包装一下:
namespace FuNong.Framework.Logger
{
public interface ILoggerService
{
void Debug(object message);
void Error(object message);
void Fatal(object message);
void Info(object message);
void Warn(object message);
}
}
namespace FuNong.Framework.Logger
{
public class LoggerService:ILoggerService
{
public LoggerService()
{
log4net.Config.XmlConfigurator.Configure();
logger = LogManager.GetLogger(typeof(LoggerService));
}
private readonly ILog logger;
public void Info(object message)
{
logger.Info(message);
}
public void Warn(object message)
{
logger.Warn(message);
}
public void Debug(object message)
{
logger.Debug(message);
}
public void Error(object message)
{
logger.Error(message);
}
public void Fatal(object message)
{
logger.Fatal(message);
}
}
}
由于我用了autofac做ioc,所以我们就直接看使用方法吧:
protected override void OnAuthorization(AuthorizationContext filterContext)
{
if (auth)
{
var collection = cookie.GetCookieCollection("FuNong.UserInfo.Login");
if (collection == null)
{
logger.Warn(new LogContent("用户登陆信息提取失败,将会跳转到登陆界面...", "1", "2"));
filterContext.Result = new RedirectResult("Home/Login");
}
else
{
logger.Info(new LogContent("用户验证成功,请继续之前操作...","1","2"));
}
}
}
这样,当我们运行起来后,我们就发现,程序已经将数据写入数据库了。
整个配置不难,但是细节挺多,稍微不小心,就可能导致写入不到数据库。