【.NET】Log4net将操作日志写入数据库
配置文件可以参考上篇博文【.NET】log4net配置文件解析.
先在Global.aspx中添加这样一句代码,来读取配置文件,初始化log4net的环境.
public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { log4net.Config.XmlConfigurator.Configure(); }
新建一个Log文件夹,将日志下面所需类都建在该文件夹下.养成编码好习惯.要注意这些类的命名空间一定要一致.
第一个LogMessage类.
这个类包括了自定义属性,就是所有要写入数据库的字段,对应了配置文件insert语句的内容.
using System.Web; using System.Web.SessionState; namespace LogDB { /// <summary> ///LogMessage 的摘要说明 /// </summary> public class LogMessage : IRequiresSessionState { public LogMessage() { } public LogMessage(string userID, string userName,string ip,string clazz,string method,string result) { this.userid = userID; this.username = userName; this.ip = ip; this.clazz = clazz; this.method = method; this.result = result; } private string userid; public string Userid { get { return userid; } set { userid = value; } } private string username; public string Username { get { return username; } set { username = value; } } private string ip; public string Ip { get{return ip;} set{ip=value;} } private string clazz; public string Clazz { get{return clazz;} set{clazz=value;} } private string method; public string Method { get{return method;} set{method=value;} } private string result; public string Result { get { return result; } set { result = value; } } } }
第二个CustomLayout类.
这个类自定义了日志输出类型,实现思路是把自定义的字段放进Hashtable,有多少个自定义字段就写Add多少个,字段名称和配置文件保持一致,这里的命名空间和配置文件如下部分对应.
using System; using System.Collections; using System.IO; using log4net.Core; using log4net.Layout.Pattern; using log4net.Util; using log4net.Layout; namespace LogDB { public class CustomLayout : log4net.Layout.LayoutSkeleton { public const string DefaultConversionPattern = "%message%newline"; public const string DetailConversionPattern = "%timestamp [%thread] %level %logger %ndc - %message%newline"; private static Hashtable s_globalRulesRegistry; private string m_pattern; private PatternConverter m_head; private Hashtable m_instanceRulesRegistry = new Hashtable(); static CustomLayout() { s_globalRulesRegistry = new Hashtable(6); s_globalRulesRegistry.Add("username", typeof(UserNamePatternConverter)); s_globalRulesRegistry.Add("userid", typeof(UserIdPatternConverter)); s_globalRulesRegistry.Add("ip", typeof(IpPatternConverter)); s_globalRulesRegistry.Add("clazz", typeof(ClazzPatternConverter)); s_globalRulesRegistry.Add("method", typeof(MethodPatternConverter)); s_globalRulesRegistry.Add("result", typeof(ResultPatternConverter)); } //-------------------------------------------------------------------- public CustomLayout() : this(DefaultConversionPattern) { } public CustomLayout(string pattern) { IgnoresException = true; m_pattern = pattern; if (m_pattern == null) { m_pattern = DefaultConversionPattern; } ActivateOptions(); } public string ConversionPattern { get { return m_pattern; } set { m_pattern = value; } } /// <summary> /// 对Hashtable中的值进行转换 /// </summary> /// <param name="pattern"></param> /// <returns></returns> virtual protected PatternParser CreatePatternParser(string pattern) { PatternParser patternParser = new PatternParser(pattern); foreach (DictionaryEntry entry in s_globalRulesRegistry) { patternParser.PatternConverters[entry.Key] = entry.Value; } foreach (DictionaryEntry entry in m_instanceRulesRegistry) { patternParser.PatternConverters[entry.Key] = entry.Value; } return patternParser; } override public void ActivateOptions() { m_head = CreatePatternParser(m_pattern).Parse(); PatternConverter curConverter = m_head; while (curConverter != null) { PatternLayoutConverter layoutConverter = curConverter as PatternLayoutConverter; if (layoutConverter != null) { if (!layoutConverter.IgnoresException) { this.IgnoresException = false; break; } } curConverter = curConverter.Next; } } override public void Format(TextWriter writer, LoggingEvent loggingEvent) { if (writer == null) { throw new ArgumentNullException("writer"); } if (loggingEvent == null) { throw new ArgumentNullException("loggingEvent"); } PatternConverter c = m_head; while (c != null) { c.Format(writer, loggingEvent); c = c.Next; } } public void AddConverter(ConverterInfo converterInfo) { AddConverter(converterInfo.Name, converterInfo.Type); } public void AddConverter(string name, Type type) { if (name == null) throw new ArgumentNullException("name"); if (type == null) throw new ArgumentNullException("type"); if (!typeof(PatternConverter).IsAssignableFrom(type)) { throw new ArgumentException("The converter type specified [" + type + "] must be a subclass of log4net.Util.PatternConverter", "type"); } m_instanceRulesRegistry[name] = type; } public sealed class ConverterInfo { private string m_name; private Type m_type; public ConverterInfo() { } public string Name { get { return m_name; } set { m_name = value; } } public Type Type { get { return m_type; } set { m_type = value; } } } } }
然后是UserIdPatternConverter/UserNamePatternConverter/IpPatternConverter等一系列类.有多少个自定义字段就有多少个类,和customLayout下面保持一致.
LogUtil类.
logUtil类封装了记录日志的方法,共外部调用,参数为各自定义字段,方法体内调用log4net的方法.
using log4net; /// <summary> ///LogUtil 的摘要说明 /// </summary> public class LogUtil { public LogUtil() { } private LogDB.LogMessage message = null; public void WriteLog(string strLoggerName, string userID, string userName,string ip,string clazz,string method,string result) { log4net.ILog log = log4net.LogManager.GetLogger(strLoggerName); message = new LogDB.LogMessage(userID, userName,ip,clazz,method,result);//用到字段辅助类 log.Info(message); } }
测试一下我们的项目.
添加default.aspx,在后台代码中编写测试:
namespace LogDB { public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { LogUtil logUtil = new LogUtil(); logUtil.WriteLog("AuthoritySystem", "1", "1", "1", "1", "1", "1"); logUtil.WriteLog("BaseSystem", "1", "1", "1", "1", "1", "1"); logUtil.WriteLog("ExamSystem", "1", "1", "1", "1", "1", "1"); logUtil.WriteLog("EvaluationSystem", "1", "1", "1", "1", "1", "1"); logUtil.WriteLog("FreshSystem", "1", "1", "1", "1", "1", "1"); } } }
生成后运行,所有的操作都被记录在了数据库里,5个子系统的日志分别记录在5张表中.
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。