Log4Net记录日志到SQLServer数据库

Log4Net记录日志到SQLServer数据库,第1张

概述Log4Net配置步骤: 1、在项目中添加Log4Net引用,可在nuget包工具中下载 2、在项目中添加Log4Net.config文件并配置 <?xml version="1.0"?><configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfiguration

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)]


4、重写Log4Net服务并创建单例

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数据库所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/1164617.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存