log4net简介(摘抄于百度百科):
log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台、文件、数据库等)的工具。
log4net是Apache软件基金会Apache Logging Services工程的一部分。Apache日志服务工程致力于为程序调试和审计提供跨语言的日志服务。
log4net特征
-
支持多数框架
-
可输出日志到多种目标
-
层级日志体系
-
可使用XML配置
-
可动态配置
-
记录上下文信息
-
被检验过的体系
-
模块化和可扩展化设计
-
灵活、高性能
本文采用的版本为:1.2.13.0
直接代码上代码,按照步骤即可完成(无需配置xml配置文件):
1、Loger.cs
using System; using System.Data; using System.Configuration; using System.Reflection; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using log4net; using logertest; using logertest.Func; /// <summary> /// Loger 的摘要说明 /// </summary> public class Loger { static IWebLog ilog = null; public static string username = "系统"; public static string exceptiontype = "系统异常"; public static string optiontype = "操作日志"; public static void CreateLoger() { //username = HttpContext.Current.Session == null // ? username : HttpContext.Current.Session["uid"] == null ? "" //: HttpContext.Current.Session["uid"].ToString(); if (ilog == null) { Log4netHelper.LoadADONetAppender(); Log4netHelper.LoadRollingFileAppender(); ilog = WebLogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); } } /// <summary> /// 系统异常使用 /// </summary> /// <param name="titlname">标题</param> /// <param name="exceptionmsg">具体异常信息</param> public static void Debug(string titlname, Exception ex) { CreateLoger(); if (ilog != null) if (ilog.IsDebugEnabled) ilog.Debug(username, exceptiontype, System.Web.HttpContext.Current.Request.UserHostAddress, System.Web.HttpContext.Current.Request.Url.ToString(), titlname, ex); } /// <summary> /// 系统异常使用 /// </summary> /// <param name="titlname">信息</param> public static void Debug(string titlname) { CreateLoger(); if (ilog != null) if (ilog.IsDebugEnabled) // ilog.Debug(username, exceptiontype, System.Web.HttpContext.Current.Request.UserHostAddress,System.Web.HttpContext.Current.Request.Url.ToString(), titlname); ilog.Debug(username, exceptiontype, "", "", titlname); } /// <summary> /// 操作日志 /// </summary> /// <param name="titlname">信息</param> public static void Info(string titlname) { CreateLoger(); if (ilog != null) if (ilog.IsInfoEnabled) ilog.Info(username, optiontype, System.Web.HttpContext.Current.Request.UserHostAddress, System.Web.HttpContext.Current.Request.Url.ToString(), titlname); } /// <summary> /// 系统异常使用 /// </summary> /// <param name="titlname">信息</param> public static void Error(string titlname) { CreateLoger(); if (ilog != null) if (ilog.IsErrorEnabled) { //在出现未处理的错误时运行的代码 ilog.Error(username, exceptiontype, HttpContext.Current.Request.UserHostAddress, HttpContext.Current.Request.Url.ToString(), titlname); } } /// <summary> /// 系统异常使用 /// </summary> /// <param name="titlname">信息</param> public static void Error(string titlname, Exception ex) { CreateLoger(); if (ilog != null) if (ilog.IsErrorEnabled) { //在出现未处理的错误时运行的代码 ilog.Error(username, exceptiontype, HttpContext.Current.Request.UserHostAddress, HttpContext.Current.Request.Url.ToString(), ex.Message, ex); } } }
2、Log4netHelper.cs 主要是log4net配置(配置写入数据库或者文本中的规则),偷了个懒(数据连接直接写在代码中,大家可以提出来):
using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Web; using log4net; using log4net.Appender; using log4net.Config; using log4net.Layout; using System.Configuration; using System.Data.SqlClient; namespace logertest.Func { public static class Log4netHelper { //记录异常日志数据库连接字符串 private static string _ConnectionString = "Data Source=.;Initial Catalog=XXXXX;Persist Security Info=True;User ID=sa;Password=XXXXX";// ConfigurationSettings.AppSettings["ConnectionSQLString"].ToString(); /// <summary> /// 使用SQLSERVER 记录异常日志 /// </summary> /// <Author>juno</Author> /// <date>2011-05-01</date> public static void LoadADONetAppender() { LoadRollingFileAppender(); log4net.Repository.Hierarchy.Hierarchy hier = log4net.LogManager.GetLoggerRepository() as log4net.Repository.Hierarchy.Hierarchy; if (hier != null) { log4net.Appender.AdoNetAppender adoAppender = new log4net.Appender.AdoNetAppender(); adoAppender.Name = "AdoNetAppender"; adoAppender.CommandType = CommandType.Text; adoAppender.BufferSize = 1; adoAppender.ConnectionType = "System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; adoAppender.ConnectionString = _ConnectionString; adoAppender.CommandText = @"INSERT INTO SYSTEMLOG ([Date],[Thread],[Level],[Logger],[Message],[Exception],[ClientIP],[RequestUrl],[Username],[Logtype]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception,@ClientIP,@RequestUrl,@Username,@Logtype)"; adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@log_date", DbType = System.Data.DbType.DateTime, Layout = new log4net.Layout.RawTimeStampLayout() }); adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@thread", DbType = System.Data.DbType.String, Size = 255, Layout = new Layout2RawLayoutAdapter(new PatternLayout("%thread")) }); adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@log_level", DbType = System.Data.DbType.String, Size = 50, Layout = new Layout2RawLayoutAdapter(new PatternLayout("%level")) }); adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@logger", DbType = System.Data.DbType.String, Size = 255, Layout = new Layout2RawLayoutAdapter(new PatternLayout("%logger")) }); adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@message", DbType = System.Data.DbType.String, Size = 4000, Layout = new Layout2RawLayoutAdapter(new PatternLayout("%message")) }); adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@ClientIP", DbType = System.Data.DbType.String, Size = 255, Layout = new Layout2RawLayoutAdapter(new PatternLayout("%property{ClientIP}")) }); adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@RequestUrl", DbType = System.Data.DbType.String, Size = 255, Layout = new Layout2RawLayoutAdapter(new PatternLayout("%property{RequestUrl}")) }); adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@Username", DbType = System.Data.DbType.String, Size = 255, Layout = new Layout2RawLayoutAdapter(new PatternLayout("%property{Username}")) }); adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@Logtype", DbType = System.Data.DbType.String, Size = 255, Layout = new Layout2RawLayoutAdapter(new PatternLayout("%property{Logtype}")) }); adoAppender.AddParameter(new AdoNetAppenderParameter { ParameterName = "@exception", DbType = System.Data.DbType.String, Size = 4000, Layout = new Layout2RawLayoutAdapter(new ExceptionLayout()) }); adoAppender.ActivateOptions(); BasicConfigurator.Configure(adoAppender); } } /// <summary> /// 使用文本记录异常日志 /// </summary> /// <Author>juno</Author> /// <date>2011-05-01</date> public static void LoadFileAppender() { string currentPath = AppDomain.CurrentDomain.BaseDirectory; string txtLogPath = string.Empty; string iisBinPath = AppDomain.CurrentDomain.RelativeSearchPath; if (!string.IsNullOrEmpty(iisBinPath)) txtLogPath = Path.Combine(iisBinPath, "ErrorLog.txt"); else txtLogPath = Path.Combine(currentPath, "ErrorLog.txt"); log4net.Repository.Hierarchy.Hierarchy hier = log4net.LogManager.GetLoggerRepository() as log4net.Repository.Hierarchy.Hierarchy; FileAppender fileAppender = new FileAppender(); fileAppender.Name = "LogFileAppender"; fileAppender.File = txtLogPath; fileAppender.AppendToFile = true; PatternLayout patternLayout = new PatternLayout(); patternLayout.ConversionPattern = " 记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline"; patternLayout.ActivateOptions(); fileAppender.Layout = patternLayout; //选择UTF8编码,确保中文不乱码。 fileAppender.Encoding = Encoding.UTF8; fileAppender.ActivateOptions(); BasicConfigurator.Configure(fileAppender); } /// <summary> /// 使用文本记录异常日志 /// </summary> /// <Author>juno</Author> /// <date>2011-05-01</date> public static void LoadRollingFileAppender() { log4net.Repository.Hierarchy.Hierarchy hier = log4net.LogManager.GetLoggerRepository() as log4net.Repository.Hierarchy.Hierarchy; RollingFileAppender rollingFile = new RollingFileAppender(); rollingFile.File = "log/"; rollingFile.AppendToFile = true; rollingFile.RollingStyle = RollingFileAppender.RollingMode.Date; rollingFile.DatePattern = "yyyyMMdd'.txt'"; rollingFile.StaticLogFileName = false; PatternLayout patternLayout = new PatternLayout(); patternLayout.ConversionPattern = "记录时间:%d 线程:[%t] %n%-5p %m%n"; patternLayout.ActivateOptions(); rollingFile.Layout = patternLayout; //选择UTF8编码,确保中文不乱码。 rollingFile.Encoding = Encoding.UTF8; rollingFile.ActivateOptions(); BasicConfigurator.Configure(rollingFile); } } }
3、IWebLog定义接口
using System; using System.Collections.Generic; using System.Linq; using System.Web; using log4net; namespace logertest.Func { public interface IWebLog : ILog { void Info(string username, string logtype, string clientIP, string requestUrl, object message); void Info(string username, string logtype, string clientIP, string requestUrl, object message, Exception t); void Warn(string username, string logtype, string clientIP, string requestUrl, object message); void Warn(string username, string logtype, string clientIP, string requestUrl, object message, Exception t); void Error(string username, string logtype, string clientIP, string requestUrl, object message); void Error(string username, string logtype, string clientIP, string requestUrl, object message, Exception t); void Fatal(string username, string logtype, string clientIP, string requestUrl, object message); void Fatal(string username, string logtype, string clientIP, string requestUrl, object message, Exception t); void Debug(string username, string logtype, string clientIP, string requestUrl, object message); void Debug(string username, string logtype, string clientIP, string requestUrl, object message, Exception t); } }
4、WebLogImpl实现IWebLog定义的接口
using System; using System.Collections.Generic; using System.Linq; using System.Web; using log4net.Core; using log4net.Repository.Hierarchy; using logertest.Func; namespace logertest.Func { public class WebLogImpl : LogImpl, IWebLog { /// <summary> /// The fully qualified name of this declaring type not the type of any subclass. /// </summary> private readonly static Type ThisDeclaringType = typeof(WebLogImpl); public WebLogImpl(ILogger logger) : base(logger) { } #region Implementation of IWebLog public void Info(string username,string logtype,string clientIP, string requestUrl, object message) { Info(username, logtype, clientIP, requestUrl, message, null); } public void Info(string username, string logtype, string clientIP, string requestUrl, object message, System.Exception t) { if (this.IsInfoEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t); loggingEvent.Properties["ClientIP"] = clientIP; loggingEvent.Properties["RequestUrl"] = requestUrl; loggingEvent.Properties["Username"] = username; loggingEvent.Properties["Logtype"] = logtype; Logger.Log(loggingEvent); } } public void Warn(string username, string logtype, string clientIP, string requestUrl, object message) { Warn(username, logtype, clientIP, requestUrl, message, null); } public void Warn(string username, string logtype, string clientIP, string requestUrl, object message, System.Exception t) { if (this.IsWarnEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Warn, message, t); loggingEvent.Properties["ClientIP"] = clientIP; loggingEvent.Properties["RequestUrl"] = requestUrl; loggingEvent.Properties["Username"] = username; loggingEvent.Properties["Logtype"] = logtype; Logger.Log(loggingEvent); } } public void Error(string username, string logtype, string clientIP, string requestUrl, object message) { Error(username, logtype, clientIP, requestUrl, message, null); } public void Error(string username, string logtype, string clientIP, string requestUrl, object message, System.Exception t) { if (this.IsErrorEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Error, message, t); loggingEvent.Properties["ClientIP"] = clientIP; loggingEvent.Properties["RequestUrl"] = requestUrl; loggingEvent.Properties["Username"] = username; loggingEvent.Properties["Logtype"] = logtype; Logger.Log(loggingEvent); } } public void Fatal(string username, string logtype, string clientIP, string requestUrl, object message) { Fatal(username, logtype, clientIP, requestUrl, null); } public void Fatal(string username, string logtype, string clientIP, string requestUrl, object message, System.Exception t) { if (this.IsFatalEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Fatal, message, t); loggingEvent.Properties["ClientIP"] = clientIP; loggingEvent.Properties["RequestUrl"] = requestUrl; loggingEvent.Properties["Username"] = username; loggingEvent.Properties["Logtype"] = logtype; Logger.Log(loggingEvent); } } public void Debug(string username, string logtype, string clientIP, string requestUrl, object message) { Debug(username, logtype, clientIP, requestUrl, message, null); } public void Debug(string username, string logtype, string clientIP, string requestUrl, object message, System.Exception t) { if (this.IsDebugEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Fatal, message, t); loggingEvent.Properties["ClientIP"] = clientIP; loggingEvent.Properties["RequestUrl"] = requestUrl; loggingEvent.Properties["Username"] = username; loggingEvent.Properties["Logtype"] = logtype; Logger.Log(loggingEvent); } } #endregion Implementation of IWebLog } }
5、用于保存WebLogImpl 对象的包装器映射
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Web; using log4net; using log4net.Core; using logertest.Func; namespace logertest.Func { public class WebLogManager { #region Static Member Variables /// <summary> /// The wrapper map to use to hold the <see cref="WebLogImpl"/> objects /// </summary> private static readonly WrapperMap s_wrapperMap = new WrapperMap(new WrapperCreationHandler(WrapperCreationHandler)); #endregion #region Constructor /// <summary> /// Private constructor to prevent object creation /// </summary> private WebLogManager() { } #endregion #region Type Specific Manager Methods /// <summary> /// Returns the named logger if it exists /// </summary> /// <remarks> /// <para>If the named logger exists (in the default hierarchy) then it /// returns a reference to the logger, otherwise it returns /// <c>null</c>.</para> /// </remarks> /// <param name="name">The fully qualified logger name to look for</param> /// <returns>The logger found, or null</returns> public static IWebLog Exists(string name) { return Exists(Assembly.GetCallingAssembly(), name); } /// <summary> /// Returns the named logger if it exists /// </summary> /// <remarks> /// <para>If the named logger exists (in the specified domain) then it /// returns a reference to the logger, otherwise it returns /// <c>null</c>.</para> /// </remarks> /// <param name="domain">the domain to lookup in</param> /// <param name="name">The fully qualified logger name to look for</param> /// <returns>The logger found, or null</returns> public static IWebLog Exists(string domain, string name) { return WrapLogger(LoggerManager.Exists(domain, name)); } /// <summary> /// Returns the named logger if it exists /// </summary> /// <remarks> /// <para>If the named logger exists (in the specified assembly's domain) then it /// returns a reference to the logger, otherwise it returns /// <c>null</c>.</para> /// </remarks> /// <param name="assembly">the assembly to use to lookup the domain</param> /// <param name="name">The fully qualified logger name to look for</param> /// <returns>The logger found, or null</returns> public static IWebLog Exists(Assembly assembly, string name) { return WrapLogger(LoggerManager.Exists(assembly, name)); } /// <summary> /// Returns all the currently defined loggers in the default domain. /// </summary> /// <remarks> /// <para>The root logger is <b>not</b> included in the returned array.</para> /// </remarks> /// <returns>All the defined loggers</returns> public static IWebLog[] GetCurrentLoggers() { return GetCurrentLoggers(Assembly.GetCallingAssembly()); } /// <summary> /// Returns all the currently defined loggers in the specified domain. /// </summary> /// <param name="domain">the domain to lookup in</param> /// <remarks> /// The root logger is <b>not</b> included in the returned array. /// </remarks> /// <returns>All the defined loggers</returns> public static IWebLog[] GetCurrentLoggers(string domain) { return WrapLoggers(LoggerManager.GetCurrentLoggers(domain)); } /// <summary> /// Returns all the currently defined loggers in the specified assembly's domain. /// </summary> /// <param name="assembly">the assembly to use to lookup the domain</param> /// <remarks> /// The root logger is <b>not</b> included in the returned array. /// </remarks> /// <returns>All the defined loggers</returns> public static IWebLog[] GetCurrentLoggers(Assembly assembly) { return WrapLoggers(LoggerManager.GetCurrentLoggers(assembly)); } /// <summary> /// Retrieve or create a named logger. /// </summary> /// <remarks> /// <para>Retrieve a logger named as the <paramref name="name"/> /// parameter. If the named logger already exists, then the /// existing instance will be returned. Otherwise, a new instance is /// created.</para> /// /// <para>By default, loggers do not have a set level but inherit /// it from the hierarchy. This is one of the central features of /// log4net.</para> /// </remarks> /// <param name="name">The name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IWebLog GetLogger(string name) { return GetLogger(Assembly.GetCallingAssembly(), name); } /// <summary> /// Retrieve or create a named logger. /// </summary> /// <remarks> /// <para>Retrieve a logger named as the <paramref name="name"/> /// parameter. If the named logger already exists, then the /// existing instance will be returned. Otherwise, a new instance is /// created.</para> /// /// <para>By default, loggers do not have a set level but inherit /// it from the hierarchy. This is one of the central features of /// log4net.</para> /// </remarks> /// <param name="domain">the domain to lookup in</param> /// <param name="name">The name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IWebLog GetLogger(string domain, string name) { return WrapLogger(LoggerManager.GetLogger(domain, name)); } /// <summary> /// Retrieve or create a named logger. /// </summary> /// <remarks> /// <para>Retrieve a logger named as the <paramref name="name"/> /// parameter. If the named logger already exists, then the /// existing instance will be returned. Otherwise, a new instance is /// created.</para> /// /// <para>By default, loggers do not have a set level but inherit /// it from the hierarchy. This is one of the central features of /// log4net.</para> /// </remarks> /// <param name="assembly">the assembly to use to lookup the domain</param> /// <param name="name">The name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IWebLog GetLogger(Assembly assembly, string name) { return WrapLogger(LoggerManager.GetLogger(assembly, name)); } /// <summary> /// Shorthand for <see cref="LogManager.GetLogger(string)"/>. /// </summary> /// <remarks> /// Get the logger for the fully qualified name of the type specified. /// </remarks> /// <param name="type">The full name of <paramref name="type"/> will /// be used as the name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IWebLog GetLogger(Type type) { return GetLogger(Assembly.GetCallingAssembly(), type.FullName); } /// <summary> /// Shorthand for <see cref="LogManager.GetLogger(string)"/>. /// </summary> /// <remarks> /// Get the logger for the fully qualified name of the type specified. /// </remarks> /// <param name="domain">the domain to lookup in</param> /// <param name="type">The full name of <paramref name="type"/> will /// be used as the name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IWebLog GetLogger(string domain, Type type) { return WrapLogger(LoggerManager.GetLogger(domain, type)); } /// <summary> /// Shorthand for <see cref="LogManager.GetLogger(string)"/>. /// </summary> /// <remarks> /// Get the logger for the fully qualified name of the type specified. /// </remarks> /// <param name="assembly">the assembly to use to lookup the domain</param> /// <param name="type">The full name of <paramref name="type"/> will /// be used as the name of the logger to retrieve.</param> /// <returns>the logger with the name specified</returns> public static IWebLog GetLogger(Assembly assembly, Type type) { return WrapLogger(LoggerManager.GetLogger(assembly, type)); } #endregion #region Extension Handlers /// <summary> /// Lookup the wrapper object for the logger specified /// </summary> /// <param name="logger">the logger to get the wrapper for</param> /// <returns>the wrapper for the logger specified</returns> private static IWebLog WrapLogger(ILogger logger) { return (IWebLog)s_wrapperMap.GetWrapper(logger); } /// <summary> /// Lookup the wrapper objects for the loggers specified /// </summary> /// <param name="loggers">the loggers to get the wrappers for</param> /// <returns>Lookup the wrapper objects for the loggers specified</returns> private static IWebLog[] WrapLoggers(ILogger[] loggers) { IWebLog[] results = new IWebLog[loggers.Length]; for (int i = 0; i < loggers.Length; i++) { results[i] = WrapLogger(loggers[i]); } return results; } /// <summary> /// Method to create the <see cref="ILoggerWrapper"/> objects used by /// this manager. /// </summary> /// <param name="logger">The logger to wrap</param> /// <returns>The wrapper for the logger specified</returns> private static ILoggerWrapper WrapperCreationHandler(ILogger logger) { return new WebLogImpl(logger); } #endregion } }
CREATE TABLE [dbo].[SYSTEMLOG]( [Id] [int] IDENTITY(1,1) NOT NULL, [Date] [datetime] NOT NULL, [Thread] [varchar](3) NULL, [Level] [varchar](10) NULL, [Logger] [varchar](255) NULL, [Message] [varchar](255) NULL, [Exception] [varchar](4000) NULL, [ClientIP] [varchar](12) NULL, [RequestUrl] [varchar](100) NULL, [Username] [varchar](50) NULL, [Logtype] [varchar](20) NULL, PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]