Log4net自定义信息存入数据库

来源:互联网 发布:it企业招人难 编辑:程序博客网 时间:2024/05/29 17:57

Asp.Net 应用 ;Oracle数据库

1. 新建数据库表Log

create table LOG

(

 --默认信息

  DATETIME  DATE,

  THREAD    VARCHAR2(255),

  LOG_LEVEL VARCHAR2(255),

  LOGGER    VARCHAR2(255),

  MESSAGE   VARCHAR2(4000),

 --自定义信息

  USERID    VARCHAR2(50),

  USERNAME  VARCHAR2(20),

)

2. 新建Asp.Net网站 解决方案名:Log4net

  (1) 添加引用

       System.Data.OracleClient

       log4net.dll

  (2) 添加全局配置文件Global.asax

  (3) 根目录添加文件夹Log用来存放日志输出的文本文件

到此项目结构如:

3. 配置文件web.config请看清楚位置,配置文件中的其它内容默认即可-数据库连接字符串一定要改正确

[html] view plain copy
  1. <?xml version="1.0"?>  
  2. <configuration>  
  3.     <configSections>  
  4.         <!-- log4net-->  
  5.         <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>  
  6.           
  7.     </configSections>  
  8.     <log4net>  
  9.         <!--   
  10.         根节点<root>可以对日志级别进行控制<level value="INFO"/>  
  11.         在这个根节点处可以设置appender列表如:  
  12.         AdoNetAppender_Oracle 存入数据库  
  13.         ColoredConsoleAppender 输出到控制台  
  14.         RollingFileAppender 输出到文本文件  
  15.         这里灵活定义,在这里选择INFO级别并且输入到Oracle数据库  
  16.          -->  
  17.         <root>  
  18.             <level value="INFO"/>  
  19.             <appender-ref ref="AdoNetAppender_Oracle"/>  
  20.         </root>  
  21.         <!--  
  22.         这个logger可要可不要,如果不要会默认根节点执行  
  23.         如果配置,会根据配置里面的<level value="INFO"/>  
  24.         到根节点中找到相应级别然后调用appender输出  
  25.         有这个节点的好处,可以程序中通过name="WebLogger"  
  26.         得到用哪一个logger模式控制日志信息  
  27.         -->  
  28.         <logger name="WebLogger">  
  29.             <level value="INFO"/>  
  30.         </logger>  
  31.         <logger name="开发用">  
  32.             <level value="DEBUG"/>  
  33.             <appender-ref ref="RollingFileAppender"/>  
  34.         </logger>  
  35.         <!--  
  36.         输出到文本文件  
  37.         网站根目录Log/log.txt  
  38.         -->  
  39.         <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">  
  40.             <file value="Log/log.txt"/>  
  41.             <appendToFile value="true"/>  
  42.             <maxSizeRollBackups value="20"/>  
  43.             <maximumFileSize value="500"/>  
  44.             <rollingStyle value="Date"/>  
  45.             <datePattern value="yyyy-MM-dd"/>  
  46.             <staticLogFileName value="true"/>  
  47.             <layout type="log4net.Layout.PatternLayout">  
  48.                 <param name="Header" type="log4net.Util.PatternString" value="[%date]%newline"/>  
  49.                 <param name="Footer" value="  
  50.   
  51. "/>  
  52.                 <conversionPattern value="%-5level %date %logger - %message%newline"/>  
  53.             </layout>  
  54.         </appender>  
  55.         <!--Oracle数据库-->  
  56.         <appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNetAppender">  
  57.             <!-- Oracle数据源 ,本地安装Oracle客户端-->  
  58.             <connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>  
  59.             <!-- Oracle连接字符串-->  
  60.             <connectionString value="data source=jdlcerp;User ID=jduser;Password=jduser"/>  
  61.             <!--  
  62.             Log4net默认数据表中有Datetime,Thread,Log_Level,Logger,Message这五个字段  
  63.             数据库表名Log  
  64.             我们创建数据表时,可以根据自已需求  
  65.             在这里创建的Log表多加userid,username两个字段  
  66.             数据表自已提前在数据库定义好            
  67.             -->  
  68.             <commandText value="INSERT INTO Log (Datetime,Thread,Log_Level,Logger,Message,userid,username) VALUES (:log_date, :thread, :log_level, :logger, :message,:userid,:username)"/>  
  69.             <!--  
  70.              设置缓存区大小  
  71.              1表明有一条日志就要写入  
  72.              如果10就表示日志到达10条时一起写入  
  73.              -->  
  74.             <bufferSize value="1"/>  
  75.             <!--默认已有的成员 -->  
  76.             <parameter>  
  77.                 <parameterName value=":log_date"/>  
  78.                 <dbType value="DateTime"/>  
  79.                 <layout type="log4net.Layout.RawTimeStampLayout"/>  
  80.             </parameter>  
  81.             <parameter>  
  82.                 <parameterName value=":thread"/>  
  83.                 <dbType value="String"/>  
  84.                 <size value="255"/>  
  85.                 <layout type="log4net.Layout.PatternLayout">  
  86.                     <conversionPattern value="%thread"/>  
  87.                 </layout>  
  88.             </parameter>  
  89.             <parameter>  
  90.                 <parameterName value=":log_level"/>  
  91.                 <dbType value="String"/>  
  92.                 <size value="50"/>  
  93.                 <layout type="log4net.Layout.PatternLayout">  
  94.                     <conversionPattern value="%level"/>  
  95.                 </layout>  
  96.             </parameter>  
  97.             <parameter>  
  98.                 <parameterName value=":logger"/>  
  99.                 <dbType value="String"/>  
  100.                 <size value="255"/>  
  101.                 <layout type="log4net.Layout.PatternLayout">  
  102.                     <conversionPattern value="%logger"/>  
  103.                 </layout>  
  104.             </parameter>  
  105.             <parameter>  
  106.                 <parameterName value=":message"/>  
  107.                 <dbType value="String"/>  
  108.                 <size value="4000"/>  
  109.                 <layout type="log4net.Layout.PatternLayout">  
  110.                     <conversionPattern value="%message"/>  
  111.                 </layout>  
  112.             </parameter>  
  113.             <!--自定义成员 -->  
  114.             <parameter>  
  115.                 <parameterName value=":userid"/>  
  116.                 <dbType value="String"/>  
  117.                 <size value="50"/>  
  118.                 <!--  
  119.                 CustomLayout类的命名空间由自己定义  
  120.                 请注意否则这里找不到定义的字段  
  121.                 此例定义命名空间是:Log4Net  
  122.                 在这个命名空间下写了一个类CustomLayout  
  123.                 用来配置自定义的字段  
  124.                 -->  
  125.                 <layout type="Log4Net.CustomLayout">  
  126.                     <conversionPattern value="%userid"/>  
  127.                 </layout>  
  128.             </parameter>  
  129.             <parameter>  
  130.                 <parameterName value=":username"/>  
  131.                 <dbType value="String"/>  
  132.                 <size value="20"/>  
  133.                 <layout type="Log4Net.CustomLayout">  
  134.                     <conversionPattern value="%username"/>  
  135.                 </layout>  
  136.             </parameter>  
  137.         </appender>  
  138.     </log4net>  
  139.   
  140. </configuration>  

4. App_Code中添加类文件,以实现自定义信息

  (1)添加自字义字段类 ,创建一个新字段,添加这样一个类

     1) UserIdPatternConverter.cs

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using log4net.Layout.Pattern;  
  5. using System.IO;  
  6. using log4net.Core;  
  7. namespace Log4net  
  8. {  
  9.     internal sealed class UserIdPatternConverter : PatternLayoutConverter  
  10.     {  
  11.         override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)  
  12.         {  
  13.             LogMessage logMessage = loggingEvent.MessageObject as LogMessage;  
  14.             if (logMessage != null)  
  15.                 writer.Write(logMessage.Userid);  
  16.         }  
  17.     }  
  18. }  

     2) UserNamePatternConverter.cs

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using log4net.Layout.Pattern;  
  5. using System.IO;  
  6. using log4net.Core;  
  7. namespace Log4net  
  8. {  
  9.     internal sealed class UserNamePatternConverter : PatternLayoutConverter   
  10.     {  
  11.         override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)  
  12.         {  
  13.             LogMessage logMessage = loggingEvent.MessageObject as LogMessage;  
  14.             if (logMessage != null)  
  15.                 writer.Write(logMessage.Username);  
  16.         }  
  17.     }  
  18. }  

  (2) 添加字段辅助类LogMessage.cs

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Web;  
  5. using System.Web.SessionState;  
  6. namespace Log4net  
  7. {  
  8.     public class LogMessage:IRequiresSessionState  
  9.     {  
  10.         public LogMessage(){  }  
  11.         public LogMessage(string userID,string UserName)  
  12.         {  
  13.             this.userid = userID;  
  14.             this.username = UserName;  
  15.         }  
  16.         private string userid;  
  17.         public string Userid  
  18.         {  
  19.             get { return userid; }  
  20.             set { userid = value; }  
  21.         }  
  22.         private string username;  
  23.         public string Username  
  24.         {  
  25.             get { return username; }  
  26.             set { username = value; }  
  27.         }  
  28.     }  
  29. }  

  (3) 添加字段转换类CustomLayout.cs

[csharp] view plain copy
  1. using System;  
  2. using System.Collections;  
  3. using System.IO;  
  4. using log4net.Core;  
  5. using log4net.Layout.Pattern;  
  6. using log4net.Util;  
  7. using log4net.Layout;  
  8. using Log4net;  
  9. namespace Log4Net  
  10. {  
  11.     public class CustomLayout : log4net.Layout.LayoutSkeleton  
  12.     {  
  13.         public const string DefaultConversionPattern ="%message%newline";  
  14.         public const string DetailConversionPattern = "%timestamp [%thread] %level %logger %ndc - %message%newline";  
  15.         private static Hashtable s_globalRulesRegistry;  
  16.         private string m_pattern;  
  17.         private PatternConverter m_head;  
  18.         private Hashtable m_instanceRulesRegistry = new Hashtable();  
  19.         //这里是重点-------------------------------------------------------  
  20.         /// <summary>  
  21.         /// 把自定义的字段放进Hashtable  
  22.         /// 定义多少个写多少个  
  23.         /// 注意这里有名称要和配置文件中的名称一致  
  24.         /// 注意命名空间  
  25.         /// 在配置文件中要用到命名空间  
  26.         /// </summary>  
  27.         static CustomLayout()  
  28.         {  
  29.             s_globalRulesRegistry = new Hashtable(2);  
  30.             s_globalRulesRegistry.Add("username"typeof(UserNamePatternConverter));  
  31.             s_globalRulesRegistry.Add("userid"typeof(UserIdPatternConverter));  
  32.         }  
  33.         //--------------------------------------------------------------------  
  34.         public CustomLayout() : this(DefaultConversionPattern)  
  35.         {}  
  36.         public CustomLayout(string pattern)   
  37.         {  
  38.             IgnoresException = true;  
  39.             m_pattern = pattern;  
  40.             if (m_pattern == null)  
  41.             {  
  42.                 m_pattern = DefaultConversionPattern;  
  43.             }  
  44.             ActivateOptions();  
  45.         }  
  46.         public string ConversionPattern  
  47.         {  
  48.             get { return m_pattern; }  
  49.             set { m_pattern = value; }  
  50.         }  
  51.         /// <summary>  
  52.         /// 对Hashtable中的值进行转换  
  53.         /// </summary>  
  54.         /// <param name="pattern"></param>  
  55.         /// <returns></returns>  
  56.         virtual protected PatternParser CreatePatternParser(string pattern)   
  57.         {  
  58.             PatternParser patternParser = new PatternParser(pattern);  
  59.             foreach(DictionaryEntry entry in s_globalRulesRegistry)  
  60.             {  
  61.                 patternParser.PatternConverters[entry.Key] = entry.Value;  
  62.             }  
  63.             foreach(DictionaryEntry entry in m_instanceRulesRegistry)  
  64.             {  
  65.                 patternParser.PatternConverters[entry.Key] = entry.Value;  
  66.             }  
  67.             return patternParser;  
  68.         }  
  69.         override public void ActivateOptions()   
  70.         {  
  71.             m_head = CreatePatternParser(m_pattern).Parse();  
  72.   
  73.             PatternConverter curConverter = m_head;  
  74.             while(curConverter != null)  
  75.             {  
  76.                 PatternLayoutConverter layoutConverter = curConverter as PatternLayoutConverter;  
  77.                 if (layoutConverter != null)  
  78.                 {  
  79.                     if (!layoutConverter.IgnoresException)  
  80.                     {  
  81.                         this.IgnoresException = false;  
  82.   
  83.                         break;  
  84.                     }  
  85.                 }  
  86.                 curConverter = curConverter.Next;  
  87.             }  
  88.         }  
  89.         override public void Format(TextWriter writer, LoggingEvent loggingEvent)   
  90.         {  
  91.             if (writer == null)  
  92.             {  
  93.                 throw new ArgumentNullException("writer");  
  94.             }  
  95.             if (loggingEvent == null)  
  96.             {  
  97.                 throw new ArgumentNullException("loggingEvent");  
  98.             }  
  99.             PatternConverter c = m_head;  
  100.             while(c != null)   
  101.             {  
  102.                 c.Format(writer, loggingEvent);  
  103.                 c = c.Next;  
  104.             }  
  105.         }  
  106.         public void AddConverter(ConverterInfo converterInfo)  
  107.         {  
  108.             AddConverter(converterInfo.Name, converterInfo.Type);  
  109.         }  
  110.         public void AddConverter(string name, Type type)  
  111.         {  
  112.             if (name == nullthrow new ArgumentNullException("name");  
  113.             if (type == nullthrow new ArgumentNullException("type");  
  114.   
  115.             if (!typeof(PatternConverter).IsAssignableFrom(type))  
  116.             {  
  117.                 throw new ArgumentException("The converter type specified ["+type+"] must be a subclass of log4net.Util.PatternConverter""type");  
  118.             }  
  119.             m_instanceRulesRegistry[name] = type;  
  120.         }  
  121.         public sealed class ConverterInfo  
  122.         {  
  123.             private string m_name;  
  124.             private Type m_type;  
  125.             public ConverterInfo()  
  126.             {}  
  127.             public string Name  
  128.             {  
  129.                 get { return m_name; }  
  130.                 set { m_name = value; }  
  131.             }  
  132.             public Type Type  
  133.             {  
  134.                 get { return m_type; }  
  135.                 set { m_type = value; }  
  136.             }  
  137.         }  
  138.     }  
  139. }  

  (4) 输出日志的工具类LogUtil.cs

[csharp] view plain copy
  1. using System;  
  2. using System.Data;  
  3. using System.Configuration;  
  4. using System.Linq;  
  5. using System.Web;  
  6. using System.Web.Security;  
  7. using System.Web.UI;  
  8. using System.Web.UI.HtmlControls;  
  9. using System.Web.UI.WebControls;  
  10. using System.Web.UI.WebControls.WebParts;  
  11. using System.Xml.Linq;  
  12. using log4net;  
  13. public class LogUtil  
  14. {  
  15.     public LogUtil()  
  16.     {    }  
  17.     private static Log4net.LogMessage message=null;  
  18.     private static ILog _log;  
  19.     public static ILog log  
  20.     {  
  21.         get  
  22.         {  
  23.             if (_log == null)  
  24.             {  
  25.                 //从配置文件中读取Logger对象  
  26.                  _log = log4net.LogManager.GetLogger("WebLogger");  
  27.             }  
  28.             return _log;  
  29.         }  
  30.     }  
  31.     public static void debug()  
  32.     {  
  33.         if (log.IsDebugEnabled)  
  34.         {  
  35.             log.Debug(message);  
  36.         }  
  37.     }  
  38.     public static void error()  
  39.     {  
  40.         if (log.IsErrorEnabled)  
  41.         {  
  42.             log.Error(message);  
  43.         }  
  44.     }  
  45.     public static void fatal()  
  46.     {  
  47.         if (log.IsFatalEnabled)  
  48.         {  
  49.             log.Fatal(message);  
  50.         }  
  51.     }  
  52.     public static void info()  
  53.     {  
  54.         if (log.IsInfoEnabled)  
  55.         {  
  56.             log.Info(message);  
  57.         }  
  58.     }  
  59.     public static void warn()  
  60.     {  
  61.         if (log.IsWarnEnabled)  
  62.         {  
  63.             log.Warn(message);  
  64.         }  
  65.     }  
  66.     /// <summary>  
  67.     /// 需要写日志的地方调用此方法  
  68.     /// </summary>  
  69.     /// <param name="userID">自定义字段</param>  
  70.     /// <param name="UserName">自定义字段</param>  
  71.     /// <param name="level">自定义级别</param>  
  72.     public static void SaveMessage(string userID, string UserName, int level)  
  73.     {  
  74.         message = new Log4net.LogMessage(userID,UserName);//用到字段辅助类  
  75.         switch (level){case 1: info(); breakcase 2: warn(); breakcase 3: error(); breakcase 4: fatal(); breakdefaultbreak; }  
  76.     }  
  77. }  

5. 具体应用

  (1) 在使用日志之前,必须监视Log4net配置;一种可以直接在类中,一种可以配置到全局配置文件中如全局配置     

[csharp] view plain copy
  1. void Application_Start(object sender, EventArgs e)   
  2.    {  
  3.        //在应用程序启动时运行的代码  
  4.        log4net.Config.XmlConfigurator.Configure();  
  5.    }  

  (2) 示例Default.aspx页面,页面为空只是在Page_Load中调用输出日志如:

[csharp] view plain copy
  1. protected void Page_Load(object sender, EventArgs e)  
  2.     {  
  3.         //自定义信息  
  4.         string userID="10000";  
  5.         string userNmae="ajaxtop";  
  6.         //级别:1[一般] 2[警告] 3[错误] 4[严重]  
  7.         int level = 2;      
  8.         LogUtil.SaveMessage(userID,userNmae,level);  
  9.     }  

6. 结果


参考:Log4net基础详解;Log4net基础详解 


7. 对提出问题的朋友表示感谢,但是没能及时回复又表示歉意,为此整理了一个事例,希望可以帮助到有需求的朋友

Log4Net事例源码

原创粉丝点击