前言

有可能目标计算机缺少某些组件,导致无法生成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=log\log.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 = ; i < ; 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().GetFileName();
module.Function = new System.Diagnostics.StackTrace(true).GetFrame().GetMethod().ToString();
module.Line = new System.Diagnostics.StackTrace(true).GetFrame().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 = ,
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, -); cat.ActiveConnection = conn; // 创建一个自动增长的主键列
Column col = new Column();
col.ParentCatalog = cat;
col.Type = DataTypeEnum.adInteger;
col.Name = "ID";
col.DefinedSize = ;
col.Properties["AutoIncrement"].Value = true; // 创建表
Table table = new Table();
table.Name = "LogDetails"; table.Columns.Append(col, DataTypeEnum.adInteger, );
table.Keys.Append("FirstPrimaryKey", KeyTypeEnum.adKeyPrimary, col, null, null); // 表中添加自定义列
table.Columns.Append("LogDate", DataTypeEnum.adVarWChar, );
table.Columns.Append("Thread", DataTypeEnum.adVarWChar, );
table.Columns.Append("LogLevel", DataTypeEnum.adVarWChar, );
table.Columns.Append("File", DataTypeEnum.adVarWChar, );
table.Columns.Append("Function", DataTypeEnum.adVarWChar, );
table.Columns.Append("Line", DataTypeEnum.adVarWChar, ); table.Columns.Append("Message", DataTypeEnum.adVarWChar, );
table.Columns.Append("MainModule", DataTypeEnum.adVarWChar, );
table.Columns.Append("SubModule", DataTypeEnum.adVarWChar, );
table.Columns.Append("CustomModule1", DataTypeEnum.adVarWChar, );
table.Columns.Append("CustomModule2", DataTypeEnum.adVarWChar, ); cat.Tables.Append(table); //创建数据库后关闭连接
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat.ActiveConnection);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat);
}
}
}

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

Debug\Log\2018-07-05\2018-07-05log.txt

Debug\access\log.mdb

参考

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

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

log4net菜鸟指南二----生成access和txt的更多相关文章

  1. log4net菜鸟指南

    log4net的作用 提供一个记录日志的框架,可以将日志信息记录到文件(txt.xml等).控制台.Windows事件日志和数据库(MSSQL.Acess.Oracle.DB2和SQLite等). 要 ...

  2. 使用PowerDesigner生成Access数据库

    PowerDesigner生成Access数据库 自从使用PD以来一直知道可以支持access但一直没有搞明白如何通过脚本来创建access数据表.在PD的tools里终于找到的答案,具体 文件都在C ...

  3. Log4Net使用指南之用log4net记录日志到数据库(含有自定义属性)------附Demo例子源代码

    Log4NET简介 log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具. 前提 最近做项目 ...

  4. P6 EPPM R16.1安装与配置指南(二)

    P6 EPPM R16.1安装与配置指南(一) http://www.cnblogs.com/endv/p/5634620.html P6 EPPM R16.1安装与配置指南(二) 环境变量配置 新建 ...

  5. Common lisp菜鸟指南(译)

    Common lisp菜鸟指南(译) Common lisp菜鸟指南(译)

  6. Swift语言指南(二)--语言基础之注释和分号

    原文:Swift语言指南(二)--语言基础之注释和分号 注释 通过注释向自己的代码中注入不可执行的文本,作为你自己的笔记或提示.Swift编译器运行时会忽略注释. Swift的注释与C语言极其相似,单 ...

  7. App架构师实践指南二之App开发工具

    App架构师实践指南二之App开发工具     1.Android Studio 2.编译调试---条件断点.右键单击断点,在弹出的窗口中输入Condition条件.---日志断点.右键单击断点,在弹 ...

  8. Foxmail邮箱最新应用指南二

    Foxmail邮箱最新应用指南二 1.打开Foxmail主界面—工具—账号管理,或者鼠标右击任何已有账号—属性,弹出账号管理窗口,点击左下角的“新建”按钮: 2.输入邮箱地址,下一步→选择邮箱类型(I ...

  9. idea+maven+spring+cxf创建webservice应用(二)生成客户端程序

    idea+maven+spring+cxf创建webservice应用(二)生成客户端程序,以上一篇为基础"idea+maven+spring+cxf创建webservice应用" ...

随机推荐

  1. STF 连接其它操作系统上的安卓设备实操介绍【转】

    功能简介:https://www.jianshu.com/p/464fadaeb1d7 搭建教程:https://blog.csdn.net/xl_lx/article/details/7944586 ...

  2. python - work4

    # -*- coding:utf-8 -*- '''@project: jiaxy@author: Jimmy@file: work_20181108.py@ide: PyCharm Communit ...

  3. day03_12 缩进介绍

    python比较变态,必须缩进,而C可以不缩进,世界上只有python这门语言要求必须缩进 tab键是缩进,shift+tab往左移动 SyntaxError:invalid syntax 语法错误 ...

  4. acm之图论基础

    1.图的定义 图 是一个顶点集合V和一个顶点间关系的集合E组成,记G=(V,E) V:顶点的有限非空集合. E:顶点间关系的有限集合(边集). 存在一个结点v,可能含有多个前驱节点和后继结点. 1顶点 ...

  5. Scrum基础知识图谱

    啰嗦一下 最近在学习scrum项目管理的知识,书上知识点分散,很难有整体的视角来看scrum有哪些核心知识,故制作了思维导图,望给和我一样容易迷失的人一样,起到一个指引作用,废话不多说,直接上图 图谱

  6. hibernate缓存详解

    hibernate中提供了两级缓存,一级缓存是Session级别的缓存,它属于事务范围的缓存,该级缓存由hibernate管理,应用程序无需干预:二级缓存是SessionFactory级别的缓存,该级 ...

  7. [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)

    [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 …… 接着他们发现自己收 ...

  8. jquery中append、prepend, before和after方法的区别(一)

    原文:http://blog.csdn.net/woosido123/article/details/64439490 在 jquery中append() 与 prepend()是在元素内插入内容(该 ...

  9. 【CF500D】New Year Santa Network(树上统计)

    ..]of longint; z:..]of extended; n,i,m,tot,x1:longint; ans,fenmu,y1:extended; procedure add(a,b:long ...

  10. 【CF645D】 Robot Rapping Results Report(拓扑排序,二分)

    题意:有一张N点M边的有向图,求最小的K使根据前K条边就能够确定图是否有唯一的拓扑序, 若没有唯一拓扑序输出-1 思路:二分答案再拓扑排序,以入度为0的节点作为新的一层,若某一层的节点个数<&g ...