zoukankan      html  css  js  c++  java
  • log4net菜鸟指南二----生成access和txt

    前言

    有可能目标计算机缺少某些组件,导致无法生成access文件,或者打不开文件,这时txt文件就可以方便的使用了

    一,标准的控制台程序输出日志到access

    <?xml version="1.0" encoding="utf-8" ?>
    <log4net xmlns="urn:log4net">
      <root xmlns="">
        <level value="ALL" />
        <appender-ref ref="AdoNetAppender_Access" />
      </root>
      <appender  xmlns="" name="AdoNetAppender_Access" type="log4net.Appender.AdoNetAppender">
        <connectionString value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=loglog.mdb" />
        <commandText value="INSERT INTO Table1([LogDate],[Thread],[logLevel],[Logger],[Message]) VALUES(@logDate, @thread, @logLevel,@logger,@message)" />
    
        <!--BufferSize为缓冲区大小,只有日志记录超10条才会一块写入到数据库-->
        <bufferSize value="10"/>
        <!--定义各个参数-->
        <parameter>
          <parameterName value="@logDate" />
          <dbType value="String" />
          <size value="240" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date" />
          </layout>
        </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="240" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%level" />
          </layout>
        </parameter>
        <parameter>
          <parameterName value="@logger" />
          <dbType value="String" />
          <size value="240" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%logger" />
          </layout>
        </parameter>
        <parameter>
          <parameterName value="@message" />
          <dbType value="String" />
          <size value="240" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%message" />
          </layout>
        </parameter>
      </appender>
    </log4net>
    Access.config

    注意:(1)文件属性设置为:如果较新则复制

             (2)connectionString设置里面的文件路径。绝对路径

             (3)在AssemblyInfo.cs文件里添加

                     [assembly: log4net.Config.XmlConfigurator(ConfigFile = "Access.config", Watch = true)]

            (4)在ConnectionString里面对应的路径中,创建log4net.mdb数据库,并创建表

    CREATE TABLE [LogDetails] (
        ID   AutoIncrement,
        [logDate] longText,
        [Thread] longText,
        [logLevel] longText,
        [Logger] longText,
        [Message] longText,
        Primary  Key  (ID)
    )

    (5)添加代码 

    log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
                Random random = new Random();
                for (int i = 0; i < 2; i++)
                {
                    //记录错误日志 
                    if (log.IsErrorEnabled)
                        log.Debug("你引起了一个错误,错误ID为:" + random.Next().ToString());
    
                    //记录严重错误  
                    if (log.IsFatalEnabled)
                        log.Fatal("你引发了一个终结者错误,可能导致系统终止,ID为:" + random.Next().ToString());
                    //记录一般信息 
                    if (log.IsInfoEnabled)
                        log.Info("你计划记录一个信息,id为:" + random.Next().ToString());
                    //记录调试信息  
                    if (log.IsDebugEnabled)
                        log.Debug("调试信息,调试ID为:" + random.Next().ToString());
                    //记录警告信息 
                    if (log.IsWarnEnabled)
                    {
                        log.Warn("警告:警告ID为:" + random.Next().ToString());
                    }
                }
    main

    注意:在64位的Windows7系统调试时,如果office是32位将你的应用程序将原有的AnyCPU更改为CPU x86.

            如果是64位,安装64位的Jet40驱动

           否则会报错:未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序。

      其它数据库,基本和Access类似,只是在连接字符串和,插入部分有所不同。 

    二、通过代码控制

    1、引入log4net.dll

    2、添加配置文件 myLog4net.config

    <?xml version="1.0"?>
    <configuration>
    
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
      </configSections>
      
      <log4net>
        <appender name="AllRollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <param name="File" value="Log"/>
          <!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
            <param name= "RollingStyle" value= "Composite"/>
          <!--按日期产生文件夹和文件名[在日期方式与混合方式下使用]-->
          <param name= "DatePattern" value= "yyyy-MM-dd\yyyy-MM-dd&quot;log.txt&quot;"/>
          <!--是否追加到文件-->
          <param name= "AppendToFile" value= "false"/>
          <!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数-->
          <param name= "MaxSizeRollBackups" value= "1"/>
          <!--是否只写到一个文件中-->
          <param name= "StaticLogFileName" value= "false"/>
          <!--每个文件的大小。只在混合方式与文件大小方式下使用。
          超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。
          可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
            <param name= "maximumFileSize" value="50MB"/> 
               
          <layout type="logDemo.ReflectionLayout">
            <param name="ConversionPattern" value="[%-5level] [%date] [%property{Function}:%property{Line}] message:%property{Message} %newline" />
          </layout>
          
          <filter type="log4net.Filter.LevelRangeFilter">
            <param name="LevelMin" value="Debug" />
            <param name="LevelMax" value="Fatal" />
          </filter>  
        </appender>
        
        <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
          <mapping>
            <level value="ERROR" />
            <foreColor value="Red, HighIntensity" />
          </mapping>
          <mapping>
            <level value="Info" />
            <foreColor value="Green" />
          </mapping>
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
          </layout>
          <filter type="log4net.Filter.LevelRangeFilter">
            <param name="LevelMin" value="Info" />
            <param name="LevelMax" value="Fatal" />
          </filter>
          <filter type="log4net.Filter.DenyAllFilter" />
        </appender>
    
          <!--定义输出到数据库中,这里举例输出到Access数据库中,数据库为C盘的log4net.mdb-->
        <appender name="AdoNetAppender_Access" type="log4net.Appender.AdoNetAppender">
          <!--连接数据库字符串-->
          <connectionString value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=access\Log.mdb" />
          <!--插入到表Log-->
          <commandText value="INSERT INTO LogDetails (
                     LogDate,
             Thread,
             LogLevel,
                     File,
                     Function,
                     Line,
             Message,
                     MainModule,
                     SubModule,
                   CustomModule1,
                     CustomModule2)
               VALUES (
                             @logDate,
                     @thread,
                     @logLevel,
                             @file,
                             @function,
                             @line,
                     @message,
                             @mainModule,
                             @subModule,
                           @customModule1,
                             @customModule2)" />
          <!--BufferSize为缓冲区大小,只有日志记录超设定值才会一块写入到数据库-->
          <bufferSize value="1" />
          <!--定义各个参数-->
          <parameter>
            <parameterName value="@logDate" />
            <dbType value="String" />
            <size value="32" />
            <layout type="log4net.Layout.PatternLayout">
              <conversionPattern value="%date" />
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@thread" />
            <dbType value="String" />
            <size value="16" />
            <layout type="log4net.Layout.PatternLayout">
              <conversionPattern value="%thread" />
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@logLevel" />
            <dbType value="String" />
            <size value="8" />
            <layout type="log4net.Layout.PatternLayout">
              <conversionPattern value="%level" />
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@file" />
            <dbType value="String" />
            <size value="128" />
            <layout type="logDemo.ReflectionLayout">
              <conversionPattern value="%property{File}" />
            </layout>
          </parameter>
            <parameter>
            <parameterName value="@function" />
            <dbType value="String" />
            <size value="128" />
            <layout type="logDemo.ReflectionLayout">
              <conversionPattern value="%property{Function}" />
            </layout>
          </parameter>
            <parameter>
            <parameterName value="@line" />
            <dbType value="String" />
            <size value="8" />
            <layout type="logDemo.ReflectionLayout">
              <conversionPattern value="%property{Line}" />
            </layout>
          </parameter>       
          <parameter>
            <parameterName value="@message" />
            <dbType value="String" />
            <size value="255" />
            <layout type="logDemo.ReflectionLayout">
              <conversionPattern value="%property{Message}" />
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@mainModule" />
            <dbType value="String" />
            <size value="32" />
            <layout type="logDemo.ReflectionLayout">
              <conversionPattern value="%property{MainModule}" />
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@subModule" />
            <dbType value="String" />
            <size value="32" />
            <layout type="logDemo.ReflectionLayout">
              <conversionPattern value="%property{SubModule}" />
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@customModule1" />
            <dbType value="String" />
            <size value="255" />
            <layout type="logDemo.ReflectionLayout">
              <conversionPattern value="%property{CustomModule1}" />
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@customModule2" />
            <dbType value="String" />
            <size value="32" />
            <layout type="logDemo.ReflectionLayout">
              <conversionPattern value="%property{CustomModule2}" />
            </layout>
          </parameter>
    
          <filter type="log4net.Filter.LevelRangeFilter">
            <param name="LevelMin" value="Debug" />
            <param name="LevelMax" value="Fatal" />
            <filter type="log4net.Filter.DenyAllFilter" />
          </filter>
        </appender>
    
        <root>
          <level value="all" />
          <appender-ref ref="ColoredConsoleAppender"/>
          <appender-ref ref="AllRollingLogFileAppender"/>
            <appender-ref ref="AdoNetAppender_Access"/>
        </root>
      </log4net>
      
    </configuration>

     3、代码引用

    ①通过重写布局Layout输出传入的 message对象的属性    ReflectionLayout.cs

    using log4net.Layout;
    using log4net.Layout.Pattern;
    using System.Reflection;
    
    namespace logDemo
    {
        // 通过重写布局Layout输出传入的 message对象的属性
        // 通过继承log4net.Layout.PatternLayout类,使用log4net.Core.LoggingEvent类的方法得到了要输出的message类的名称,然后通过反射得到各个属性的值,使用PatternLayout类AddConverter方法传入得到的值。
        public class ReflectionLayout : PatternLayout
        {
            public ReflectionLayout()
            {
                this.AddConverter("property", typeof(ReflectionPatternConverter));
            }
    
            public ReflectionLayout(string pattern)
                : this()
            {
                base.ConversionPattern = pattern;
            }
        }
        
        public class ReflectionPatternConverter : PatternLayoutConverter
        {
            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.Repository, loggingEvent.GetProperties());
                }
            }
    
            /// <summary>
            /// 通过反射获取传入的日志对象的某个属性的值
            /// </summary>
            /// <param name="property"></param>
            /// <returns></returns>
            private object LookupProperty(string property, log4net.Core.LoggingEvent loggingEvent)
            {
                object propertyValue = string.Empty;
                PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);
                if (propertyInfo != null)
                {
                    propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);
    
                }
                return propertyValue;
            }
        }    
    }

    ②自定义输出多列的类   LogModule.cs

    namespace logDemo
    {
        public class LogModule
        {
            /// <summary>
            /// 无参构造函数
            /// </summary>
            public LogModule()
            { }
    
            /// <summary>
            /// logModule构造方法
            /// </summary>
            /// <param name="dutModule"></param>
            /// <param name="message"></param>
            /// <param name="mainModule"></param>
            /// <param name="subModule"></param>
            /// <param name="customModule1"></param>
            /// <param name="customModule2"></param>
            /// <param name="file"></param>
            /// <param name="function"></param>
            /// <param name="line"></param>
            public LogModule(string mainModule = "",
                            string subModule = "",
                            string customModule1 = "",
                            string customModule2 = "",
                            string file = "",
                            string function = "",
                            string line = "",
                            string message = "")
            {
                this.MainModule = mainModule;
                this.SubModule = subModule;
                this.CustomModule1 = customModule1;
                this.CustomModule2 = customModule2;
                this.File = file;
                this.Function = function;
                this.Line = line;
                this.Message = message;
            }
    
            private string mainModule = "";
            /// <summary>
            /// 场景模块信息
            /// </summary>
            public string MainModule
            {
                get { return mainModule; }
                set { mainModule = value; }
            }
    
            private string subModule = "";
            /// <summary>
            /// 子场景模块
            /// </summary>
            public string SubModule
            {
                get { return subModule; }
                set { subModule = value; }
            }
    
            private string customModule1 = "";
            /// <summary>
            /// 自定义1模块
            /// </summary>
            public string CustomModule1
            {
                get { return customModule1; }
                set { customModule1 = value; }
            }
    
            private string customModule2 = "";
            /// <summary>
            /// 自定义2模块
            /// </summary>
            public string CustomModule2
            {
                get { return customModule2; }
                set { customModule2 = value; }
            }
    
            private string file = "";
            /// <summary>
            /// 文件名(类名)
            /// </summary>
            public string File
            {
                get { return file; }
                set { file = value; }
            }
    
            private string function = "";
            /// <summary>
            /// 方法名
            /// </summary>
            public string Function
            {
                get { return function; }
                set { function = value; }
            }
    
            private string line = "";
            /// <summary>
            /// 行号
            /// </summary>
            public string Line
            {
                get { return line; }
                set { line = value; }
            }
    
            private string message = "";
            /// <summary>
            /// 信息,主要收集需要收集的log信息(log内容)
            /// </summary>
            public string Message
            {
                get { return message; }
                set { message = value; }
            }
        }
    }

    ③添加类  LogHelper.cs

    using System;
    using log4net;
    using System.IO;
    using log4net.Core;
    
    namespace logDemo
    {
        public class LogHelper
        {
            //如果定义了<logger>节点,则这里传入logger的name的值
            log4net.ILog log = log4net.LogManager.GetLogger("logName");
    
            protected log4net.ILog Log
            {
                get { return log; }
                set { log = value; }
            }
    
            LogModule module;
            /// <summary>
            /// 带入log模块信息
            /// </summary>
            /// <param name="module"></param>
            public LogHelper(LogModule module)
            {
                this.module = module;
            }    
    
            /// <summary>
            /// 打印log发送到log4ent
            /// </summary>
            /// <param name="level">等级</param>
            /// <param name="msg">log信息</param>
            public void Print(Levels level, String msg)
            {         
                module.Message = msg;
                module.File = new System.Diagnostics.StackTrace(true).GetFrame(1).GetFileName();
                module.Function = new System.Diagnostics.StackTrace(true).GetFrame(1).GetMethod().ToString();
                module.Line = new System.Diagnostics.StackTrace(true).GetFrame(1).GetFileLineNumber().ToString();
                
                Print(level, module);
            }
    
            /// <summary>
            /// log信息发送到log4net进行打印
            /// </summary>
            /// <param name="level">等级</param>
            /// <param name="module">log模块</param>
            private void Print(Levels level, LogModule module)
            {
                if (module == null)
                    return;
    
                if (level.Equals(Levels.FATAL))
                    Log.Fatal(module);
    
                if (level.Equals(Levels.ERROR))
                    Log.Error(module);
    
                if (level.Equals(Levels.DEBUG))
                    Log.Debug(module);
    
                if (level.Equals(Levels.WARN))
                    Log.Warn(module);
    
                if (level.Equals(Levels.INFO))
                    Log.Info(module);
            }
        }
    
        /// <summary>
        /// 自定义log等级
        /// </summary>
        public enum Levels
        {
            OFF = 0,
            FATAL,
            ERROR,
            WARN,
            INFO,
            DEBUG
        }
    }

    ④用自定义的列输出日志

    using System;
    using System.Windows.Forms;
    using System.IO;
    using ADOX;
    
    namespace logDemo
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            
            private void Form1_Load(object sender, EventArgs e)
            {          
                //如果没有数据库则创建一个
                CreateAcces(Path.Combine(Application.StartupPath, "access"));
    
                //监听配置文件的变化
                log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine(Application.StartupPath, "myLog4net.config")));
            }
    
            public static LogHelper newlog;
            private void button1_Click(object sender, EventArgs e)
            {
                LogModule module1 = new LogModule("main信息", "sub信息", "自定义1", "自定义2");
                newlog = new LogHelper(module1);
                newlog.Print(Levels.FATAL, "fatal级别的message");
    
                LogModule module2 = new LogModule();
                module2.MainModule = "mianModule";
                module2.SubModule = "SubModule";
                module2.CustomModule1 = "CustomModule1";
                newlog = new LogHelper(module2);
                newlog.Print(Levels.DEBUG, "debug级别的message");
            }
    
            /// <summary>
            /// access操作类
            /// </summary>
            /// <param name="accessDirectoryPath"></param>
            public static void CreateAcces(string accessDirectoryPath)
            {
                // 目录不存在 则创建目录
                string temppath = accessDirectoryPath;
                if (!Directory.Exists(temppath))
                {
                    Directory.CreateDirectory(temppath);
                }
    
                string mdbPath = Path.Combine(accessDirectoryPath, "Log.mdb");
                if (File.Exists(mdbPath)) //检查数据库是否已存在   
                {
                    return;
                }
    
                // 数据库不存在 则创建数据库  (可以加上密码,这样创建后的数据库必须输入密码后才能打开)
                mdbPath = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + mdbPath;
    
                // 创建一个CatalogClass对象的实例,   
                ADOX.CatalogClass cat = new ADOX.CatalogClass();
    
                // 使用CatalogClass对象的Create方法创建ACCESS数据库
                cat.Create(mdbPath);
    
                // 连接数据库
                ADODB.Connection conn = new ADODB.Connection();
                conn.Open(mdbPath, null, null, -1);
    
                cat.ActiveConnection = conn;
    
                // 创建一个自动增长的主键列
                Column col = new Column();
                col.ParentCatalog = cat;
                col.Type = DataTypeEnum.adInteger;
                col.Name = "ID";
                col.DefinedSize = 9;
                col.Properties["AutoIncrement"].Value = true;
    
                // 创建表
                Table table = new Table();
                table.Name = "LogDetails";
    
                table.Columns.Append(col, DataTypeEnum.adInteger, 9);
                table.Keys.Append("FirstPrimaryKey", KeyTypeEnum.adKeyPrimary, col, null, null);
    
                // 表中添加自定义列
                table.Columns.Append("LogDate", DataTypeEnum.adVarWChar, 32);
                table.Columns.Append("Thread", DataTypeEnum.adVarWChar, 16);
                table.Columns.Append("LogLevel", DataTypeEnum.adVarWChar, 8);
                table.Columns.Append("File", DataTypeEnum.adVarWChar, 128);
                table.Columns.Append("Function", DataTypeEnum.adVarWChar, 128);
                table.Columns.Append("Line", DataTypeEnum.adVarWChar, 8);
                
                table.Columns.Append("Message", DataTypeEnum.adVarWChar, 255);
                table.Columns.Append("MainModule", DataTypeEnum.adVarWChar, 32);
                table.Columns.Append("SubModule", DataTypeEnum.adVarWChar, 32);
                table.Columns.Append("CustomModule1", DataTypeEnum.adVarWChar, 255);
                table.Columns.Append("CustomModule2", DataTypeEnum.adVarWChar, 32);
    
                cat.Tables.Append(table);
    
                //创建数据库后关闭连接
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat.ActiveConnection);
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat);
            }         
        }
    }

    ⑤输出结果,以txt和access两种形式保存

    DebugLog2018-07-052018-07-05log.txt

    Debugaccesslog.mdb

    参考

    [1]log4net示例2-日志输入存入Access

    [2]非常完善的Log4net详细说明

  • 相关阅读:
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(三)安装spark2.2.1
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二)安装hadoop2.9.0
    JPA(七):映射关联关系------映射双向多对一的关联关系
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(一)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网。
    JPA(六):映射关联关系------映射单向一对多的关联关系
    JPA(五):映射关联关系------映射单向多对一的关联关系
    Java-Shiro(四):Shiro Realm讲解(一)Realm介绍
    JPA(四):EntityManager
    JPA(三):JPA基本注解
    Java-Shiro(三):Shiro与Spring MVC集成
  • 原文地址:https://www.cnblogs.com/code1992/p/9244398.html
Copyright © 2011-2022 走看看