Log4Net配置步骤:
1、在项目中添加Log4Net引用,可在nuget包工具中下载
2、在项目中添加Log4Net.config文件并配置
<?xml version="1.0"?><configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <system.web> <compilation deBUG="true" targetFramework="4.0" /> </system.web> <!--***********************************日志相关配置*************************************--> <log4net> <!--定义输出到数据库中,这里连接字符串会去取Web.config里面定义的名字为GfdbContext的字符串--> <appender name="adonetappender_sqlServer" type="GFG.GloryFinance.Framework.Log4Net.Myadonetappender"> <!--BufferSize为缓冲区大小,只有日志记录超10条才会一块写入到数据库--> <bufferSize value="10" /> <connectionType value="System.Data.sqlClIEnt.sqlConnection,System.Data,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" /> <connectionStringname value="GfdbContext"></connectionStringname> <commandText value="INSERT INTO [Log].[SystemException]([SystemExceptionID],[CreateTime],[Thread],[Level],[Logger],[Methodname],[Message],[IPAddress],[MemberID]) VALUES (NEXT VALUE FOR [Log].[SystemExceptionSequence],@LogDate,@Thread,@LogLevel,@LogType,@Funname,@Message,@IP,@UserID)" /> <!--定义各个参数--> <parameter> <parametername value="@LogDate" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parametername value="@Thread"/> <dbType value="String"/> <size value="240"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread"/> </layout> </parameter> <parameter> <parametername value="@LogLevel" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parametername value="@LogType" /> <dbType value="String" /> <size value="255" /> <layout type="GFG.GloryFinance.Framework.Log4Net.CustomLayout"> <conversionPattern value="%property{logType}" /> </layout> </parameter> <parameter> <parametername value="@Funname" /> <dbType value="String" /> <size value="255" /> <layout type="GFG.GloryFinance.Framework.Log4Net.CustomLayout"> <conversionPattern value="%property{Funname}" /> </layout> </parameter> <parameter> <parametername value="@Message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parametername value="@IP"/> <dbType value="String"/> <size value="255" /> <layout type="GFG.GloryFinance.Framework.Log4Net.CustomLayout"> <param name="ConversionPattern" value="%property{IP}"/> </layout> </parameter> <parameter> <parametername value="@UserID"/> <dbType value="String"/> <size value="255" /> <layout type="GFG.GloryFinance.Framework.Log4Net.CustomLayout"> <param name="ConversionPattern" value="%property{UserID}"/> </layout> </parameter> </appender> <!--定义日志的输出媒介,下面定义日志以四种方式输出。也可以下面的按照一种类型或其他类型输出。--> <root> <!--定义级别OFF FATAL、ERROR、WARN、INFO、DEBUG ALL--> <level value="WARN"></level> <!--文件形式记录日志--> </root> <logger name="iNotes"> <level value="INFO"/> <appender-ref ref="adonetappender_sqlServer" /> </logger> </log4net> <!--***********************************日志相关配置*************************************--></configuration>
注意参照配置文件在数据库中创建日志记录表 [Log].[SystemException]
3、在项目的AssemblyInfo.cs文件中添加以下配置
//日志系统应用程序配置文件[assembly: log4net.Config.XmlConfigurator(Configfile = "Log4Net.config",Watch = true)]
using System;using System.Collections;using System.Configuration;using System.Reflection;using log4net;using log4net.Appender;using log4net.Core;using log4net.Layout;using log4net.Layout.Pattern; /// <summary> ///日志服务,支持自定义属性 /// </summary> public sealed class Log4NetService { /// <summary> /// 日志单例 /// </summary> public static Log4NetService Instance = new Log4NetService(); /// <summary> /// 创建log4net日志记录器 /// </summary> private static IMyLog MyLog = MyLogManager.GetLogger("iNotes"); /// <summary> /// 日志级别枚举 /// </summary> public enum MsgLevel { /// <summary> /// 1. 毁灭级别 /// </summary> Fatal,/// <summary> /// 2. 错误级别 /// </summary> Error,/// <summary> /// 3. 警告级别 /// </summary> Warn,/// <summary> /// 4. 消息级别 /// </summary> Info,/// <summary> /// 5. 调试级别 /// </summary> DeBUG } /// <summary> /// 创建系统日志 /// </summary> /// <param name="level">级别</param> /// <param name="type">类名,可自定义</param> /// <param name="parasHashtable">自定义参数,目前固定三个{UserID;IP;Funname}</param> /// <param name="message">内容</param> public voID Log(MsgLevel level,System.String type,Hashtable parasHashtable,object message) { switch (level) { case MsgLevel.DeBUG: MyLog.DeBUG(type,parasHashtable,message); break; case MsgLevel.Info: MyLog.Info(type,message); break; case MsgLevel.Warn: MyLog.Warn(type,message); break; case MsgLevel.Error: MyLog.Error(type,message); break; case MsgLevel.Fatal: MyLog.Fatal(type,message); break; } } } #region 重写log4net接口 /// <summary> /// 重写ILog接口 /// </summary> public interface IMyLog : ILog { voID DeBUG(string logType,object message); voID DeBUG(string logType,object message,System.Exception t); voID Info(string logType,object message); voID Info(string logType,System.Exception t); voID Warn(string logType,object message); voID Warn(string logType,System.Exception t); voID Error(string logType,object message); voID Error(string logType,System.Exception t); voID Fatal(string logType,object message); voID Fatal(string logType,System.Exception t); } /// <summary> /// 日志方法类,重写新增日志方法 /// </summary> public class MyLogImpl : LogImpl,IMyLog { /// <summary> /// The fully qualifIEd name of this declaring type not the type of any subclass. /// </summary> public Readonly static System.Type ThisDeclaringType = typeof(MyLogImpl); public MyLogImpl(ILogger logger) : base(logger) { } #region 重写添加日志内容的方法 public voID DeBUG(string logType,object message) { DeBUG(logType,message,null); } public voID DeBUG(string logType,System.Exception t) { if (this.IsDeBUGEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType,Logger.Repository,Logger.name,Level.DeBUG,t); loggingEvent.PropertIEs["logType"] = logType; //添加自定义输出项 foreach (DictionaryEntry de in parasHashtable) { loggingEvent.PropertIEs[de.Key.ToString()] = de.Value.ToString(); } Logger.Log(loggingEvent); } } public voID Info(string logType,object message) { Info(logType,null); } public voID Info(string logType,System.Exception t) { if (this.IsInfoEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType,Level.Info,t); loggingEvent.PropertIEs["logType"] = logType; //添加自定义输出项 foreach (DictionaryEntry de in parasHashtable) { loggingEvent.PropertIEs[de.Key.ToString()] = de.Value.ToString(); } Logger.Log(loggingEvent); } } public voID Warn(string logType,object message) { Warn(logType,null); } public voID Warn(string logType,System.Exception t) { if (this.IsWarnEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType,Level.Warn,t); loggingEvent.PropertIEs["logType"] = logType; //添加自定义输出项 foreach (DictionaryEntry de in parasHashtable) { loggingEvent.PropertIEs[de.Key.ToString()] = de.Value.ToString(); } Logger.Log(loggingEvent); } } public voID Error(string logType,object message) { Error(logType,null); } public voID Error(string logType,System.Exception t) { if (this.IsErrorEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType,Level.Error,t); loggingEvent.PropertIEs["logType"] = logType; //添加自定义输出项 foreach (DictionaryEntry de in parasHashtable) { loggingEvent.PropertIEs[de.Key.ToString()] = de.Value.ToString(); } Logger.Log(loggingEvent); } } public voID Fatal(string logType,object message) { Fatal(logType,null); } public voID Fatal(string logType,System.Exception t) { if (this.IsFatalEnabled) { LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType,Level.Fatal,t); loggingEvent.PropertIEs["logType"] = logType; //添加自定义输出项 foreach (DictionaryEntry de in parasHashtable) { loggingEvent.PropertIEs[de.Key.ToString()] = de.Value.ToString(); } Logger.Log(loggingEvent); } } #endregion 重写添加日志内容的方法 /// <summary> /// 获取当前 *** 作用户编号 /// </summary> /// <returns></returns> private string GetUserID() { string account = string.Empty; try { account = "username"; //这里尽可替换,根据你的程序修改相关代码获取当前登录的用户账号 } catch { account = "未登录";// string.Empty; } finally { } return account; } /// <summary> /// 获取当前 *** 作用户IP /// </summary> /// <returns></returns> private string GetIp() { return System.Web.httpContext.Current.Request.UserHostAddress; } } /// <summary> /// 日志管理类 /// </summary> public class MyLogManager { #region 静态成员 /// <summary> /// The wrapper map to use to hold the <see cref="EventIDLogImpl"/> objects /// </summary> private static Readonly WrapperMap s_wrapperMap = new WrapperMap(new WrapperCreationHandler(WrapperCreationHandler)); #endregion #region 构造函数 /// <summary> /// Private constructor to prevent object creation /// </summary> private MyLogManager() { } #endregion #region 成员方法 /// <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 IMyLog 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 IMyLog 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 IMyLog 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 IMyLog[] 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 IMyLog[] 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 IMyLog[] 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 IMyLog 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,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 IMyLog 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,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 IMyLog 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 IMyLog GetLogger(System.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 IMyLog GetLogger(string domain,System.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 IMyLog GetLogger(Assembly assembly,System.Type type) { return WrapLogger(LoggerManager.GetLogger(assembly,type)); } #endregion #region 帮助类 /// <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 IMyLog WrapLogger(ILogger logger) { return (IMyLog)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 IMyLog[] WrapLoggers(ILogger[] loggers) { IMyLog[] results = new IMyLog[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 MyLogImpl(logger); } #endregion } #endregion #region 自定义属性相关 /// <summary> /// 把我们定义的属性转换为log4net所能识别的属性 /// </summary> public class CustomLayout : PatternLayout { public CustomLayout() { this.AddConverter("property",typeof(ReflectionPatternConverter)); } } /// <summary> /// 重写 PatternLayout /// </summary> public class ReflectionPatternConverter : PatternLayoutConverter { /// <summary> /// 重写 PatternLayout /// </summary> /// <param name="writer"></param> /// <param name="loggingEvent"></param> protected overrIDe voID Convert(System.IO.TextWriter writer,log4net.Core.LoggingEvent loggingEvent) { if (Option != null) { WriteObject(writer,loggingEvent.Repository,LookupProperty(Option,loggingEvent)); } else { WriteDictionary(writer,loggingEvent.GetPropertIEs()); } } /// <summary> /// 获取自定义属性的值 /// </summary> /// <param name="property"></param> /// <returns></returns> private object LookupProperty(string property,log4net.Core.LoggingEvent loggingEvent) { object propertyValue = string.Empty; propertyValue = loggingEvent.PropertIEs[property]; return propertyValue; } } #endregion #region 数据库日志相关 /// <summary> /// 将数据库链接字符串独立出来 /// </summary> public class Myadonetappender : adonetappender { private static IMyLog _Log; private string _ConnectionStringname; public string ConnectionStringname { get { return _ConnectionStringname; } set { _ConnectionStringname = value; } } protected static IMyLog Log { get { if (_Log == null) _Log = MyLogManager.GetLogger(typeof(Myadonetappender)); return _Log; } } public overrIDe voID ActivateOptions() { PopulateConnectionString(); base.ActivateOptions(); } /// <summary> /// 获取或设置数据库连接字符串 /// </summary> private voID PopulateConnectionString() { // 如果配置文件中设置了ConnectionString,则返回 if (!String.IsNullOrEmpty(ConnectionString)) return; // 如果配置文件中没有设置ConnectionStringname,则返回 if (String.IsNullOrEmpty(ConnectionStringname)) return; // 获取对应Web.config中的连接字符串配置 ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[ConnectionStringname]; if (settings == null) { if (Log.IsErrorEnabled) Log.ErrorFormat("Connection String name not found in Configuration: {0}",ConnectionStringname); return; } //返回解密的连接字符串 ConnectionString = settings.ConnectionString;// new DESEncrypt().Decrypt(settings.ConnectionString,null); } } #endregion
5、添加调用方法
public class Log4NetHelper { /// <summary> /// 记录系统日志 /// </summary> /// <param name="msgLevel">日志级别</param> /// <param name="classname">类名称</param> /// <param name="funname">方法名</param> /// <param name="msg">日志内容</param> public static voID Log(Log4NetService.MsgLevel msgLevel,string classname,string funname,string msg) { LoginUser loginUser = LoginHelper.GetLoginUser(); Hashtable parasHashtable = new Hashtable(); parasHashtable.Add("UserID",loginUser == null ? "" : loginUser.MemberID.ToString()); //form表单提交的数据 parasHashtable.Add("IP",IPHelper.Instance().AcceptIP()); //Url 参数 parasHashtable.Add("Funname",funname); Log4NetService.Instance.Log(msgLevel,classname,msg); } }
通过以上配置,调用日志服务就可实现日志记录功能了,MVC项目如需自动记录系统异常日志,可参照以下方法实现:
6、新增特性,可对单个Action指定该特性,也可注册为全局特性(所有Action)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple = false)] public class Log4NetFilterattribute : ActionFilterattribute,IExceptionFilter { #region 错误日志 public voID OnException(ExceptionContext filterContext) { if (!filterContext.ExceptionHandled) { //记录日志 Log4NetHelper.Log(Log4NetService.MsgLevel.Error,filterContext.Controller.GetType().ToString(),filterContext.RequestContext.RouteData.Values["action"].ToString(),filterContext.Exception.Message); //设置异常已经处理 filterContext.ExceptionHandled = true; //错误页跳转 filterContext.httpContext.Response.Redirect("/home/500"); } } #endregion }
7、将特性在项目的Global.asax文件注册为全局特性
public class MvcApplication : System.Web.httpApplication { protected voID Application_Start() { AreaRegistration.RegisterallAreas(); RouteConfig.RegisterRoutes(Routetable.Routes); RegisterGlobalFilters(GlobalFilters.Filters); } public static voID RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new Log4NetFilterattribute()); } }这样,MVC项目就可以自动记录数据到数据库了。 总结
以上是内存溢出为你收集整理的Log4Net记录日志到SQLServer数据库全部内容,希望文章能够帮你解决Log4Net记录日志到SQLServer数据库所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)