⑴ 如何利用log4Net自定义属性配置功能记录完整的日志信息
如何利用log4Net自定义属性配置功能记录完整的日志信息log4Net作为专业的log记录控件,对于它的强大功能大家一定不陌生。下面我将详细介绍如何利用其自定义属性,让日志信息更完整。一,创建测试工程,log4Net组件可以自己从网上下载,也可通过Nuget进行安装。二,创建日志模型及数据库表,因为我们的日志信息可以输出为文本,也可以输出到数据库。三,添加MyLayout,MyPatternConverter类扩展PatternLayout。四,添加Log4Net.config文件,进行输入方式定义。<?xml version="1.0" encoding="utf-8" ?><configuration><configSections><section name="log4net" type="log4net.Config.,log4net"/></configSections><log4net><!– ConversionPattern 解释%m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息%n(new line):换行%d(datetime):输出当前语句运行的时刻%r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数%t(thread id):当前语句所在的线程ID%p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等%c(class):当前日志对象的名称%L:输出语句所在的行号%F:输出语句所在的文件名%-数字:表示该项的最小长度,如果不够,则用空格填充–><!–定义输出到控制台命令行中–><logger name="myLogger"><level value="ALL"/><appender-ref ref="ConsoleAppender" /></logger><!–定义输出到控制台命令行中–><appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"><layout type="Log4NetTest.MyLayout"><param name="ConversionPattern" value="日志时间:%d %n日志级别:%-5p %n用 户 ID:%Property{UserID} %n用户姓名:%Property{UserName} %n日志信息:%Property{Message} %n异常信息:%exception %n%n" /></layout></appender><!–定义输出到windows事件中–><appender name="WindowsAppender" type="log4net.Appender.EventLogAppender"><layout type="Log4NetTest.MyLayout"><param name="ConversionPattern" value="日志时间:%d %n日志级别:%-5p %n用 户 ID:%Property{UserID} %n用户姓名:%Property{UserName} %n日志信息:%Property{Message} %n异常信息:%exception %n%n" /></layout></appender><!–定义输出到文件中–><appender name="TextAppender" type="log4net.Appender.RollingFileAppender"><param name="File" value="Log\\" /><param name="AppendToFile" value="true" /><param name="MaxFileSize" value="10240" /><param name="MaxSizeRollBackups" value="100" /><param name="StaticLogFileName" value="false" /><param name="DatePattern" value="yyyyMMdd" /><param name="RollingStyle" value="Date" /><layout type="Log4NetTest.MyLayout"><param name="ConversionPattern" value="日志时间:%d %n日志级别:%-5p %n用 户 ID:%Property{UserID} %n用户姓名:%Property{UserName} %n日志信息:%Property{Message} %n异常信息:%exception %n%n" /></layout></appender><!–定义输出到数据库–><appender name="DataBaseAppender" type="log4net.Appender.AdoNetAppender"><!–日志缓存写入条数–><bufferSize value="1" /><!–日志数据库连接串–><connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /><connectionString value="data source=.\SQL2008;initial catalog=Demo;integrated security=false;persist security info=True;User ID=sa;Password=1qaz" /><!–日志数据库脚本–><commandText value="INSERT INTO LogInfo ([LogDate],[LogLevel],[UserId],[UserName],[Message],[Exception]) VALUES (@LogDate, @LogLevel,@UserId,@UserName, @Message, @Exception)" /><!–日志时间LogDate –><parameter><parameterName value="@LogDate" /><dbType value="String" /><size value="30" /><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%date{yyyy-MM-dd HH:mm:ss}" /></layout></parameter><!–日志类型LogLevel –><parameter><parameterName value="@LogLevel" /><dbType value="String" /><size value="10" /><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%level" /></layout></parameter><!–自定义UserId –><parameter><parameterName value="@UserId" /><dbType value="String" /><size value="20" /><layout type="Log4NetTest.MyLayout"><conversionPattern value="%Property{UserID}" /></layout></parameter><!–自定义UserName –><parameter><parameterName value="@UserName" /><dbType value="String" /><size value="50" /><layout type="Log4NetTest.MyLayout"><conversionPattern value="%Property{UserName}" /></layout></parameter><!–自定义Message –><parameter><parameterName value="@Message" /><dbType value="String" /><size value="200" /><layout type="Log4NetTest.MyLayout"><conversionPattern value="%Property{Message}" /></layout></parameter><!–异常信息Exception –><parameter><parameterName value="@Exception" /><dbType value="String" /><size value="4000" /><layout type="log4net.Layout.ExceptionLayout" /></parameter></appender></log4net></configuration>五,添加LogHelper.cs类进行各自信息的写入操作。using System;using System.Diagnostics;using System.IO;using System.Windows.Forms;using log4net;[assembly: log4net.Config.XmlConfigurator(Watch = true)]namespace Log4NetTest{public class LogHelper{/// <summary>/// LoggerName/// </summary>public static string LoggerName = string.Empty;/// <summary>/// 用户ID/// </summary>public static string UserID = string.Empty;/// <summary>/// 用户名称/// </summary>public static string UserName = string.Empty;private static ILog iLog;private static LogEntity logEntity;/// <summary>/// 接口/// </summary>private static ILog log{get{string path = Application.StartupPath + @"\Log4Net.config";log4net.Config.XmlConfigurator.Configure(new FileInfo(path));if (iLog == null){iLog = log4net.LogManager.GetLogger(LoggerName);}else{if (iLog.Logger.Name != LoggerName){iLog = log4net.LogManager.GetLogger(LoggerName);}}return iLog;}}/// <summary>/// 构造消息实体/// </summary>/// <param name="message"></param>/// <returns></returns>private static LogEntity BuildMessageMode(string message){if (logEntity == null){logEntity = new LogEntity();logEntity.UserID = UserID;logEntity.UserName = UserName;logEntity.Message = message;}elselogEntity.Message = message;return logEntity;}/// <summary>/// 调试/// </summary>/// <param name="message">消息</param>public static void Debug(string message){if (log.IsDebugEnabled)log.Debug(BuildMessageMode(message));}/// <summary>/// 调试/// </summary>/// <param name="message">消息</param>/// <param name="exception">异常</param>public static void Debug(string message, Exception ex){if (log.IsDebugEnabled)log.Debug(BuildMessageMode(message), ex);}/// <summary>/// 信息/// </summary>/// <param name="message">消息</param>public static void Info(string message){if (log.IsInfoEnabled)log.Info(BuildMessageMode(message));}/// <summary>/// 信息/// </summary>/// <param name="message">消息</param>/// <param name="exception">异常</param>public static void Info(string message, Exception ex){if (log.IsInfoEnabled)log.Info(BuildMessageMode(message), ex);}/// <summary>/// 一般错误/// </summary>/// <param name="message">消息</param>public static void Error(string message){if (log.IsErrorEnabled)log.Error(BuildMessageMode(message));}/// <summary>/// 一般错误/// </summary>/// <param name="message">消息</param>/// <param name="exception">异常</param>public static void Error(string message, Exception exception){if (log.IsErrorEnabled)log.Error(BuildMessageMode(message), exception);}/// <summary>/// 警告/// </summary>/// <param name="message">消息</param>public static void Warn(string message){if (log.IsWarnEnabled)log.Warn(BuildMessageMode(message));}/// <summary>/// 警告/// </summary>/// <param name="message">消息</param>/// <param name="exception">异常</param>public static void Warn(string message, Exception ex){if (log.IsWarnEnabled)log.Warn(BuildMessageMode(message), ex);}/// <summary>/// 严重/// </summary>/// <param name="message">消息</param>public static void Fatal(string message){if (log.IsFatalEnabled)log.Fatal(BuildMessageMode(message));}/// <summary>/// 严重/// </summary>/// <param name="message">消息</param>/// <param name="exception">异常</param>public static void Fatal(string message, Exception ex){if (log.IsFatalEnabled)log.Fatal(BuildMessageMode(message), ex);}}}六,进行日志效果测试,只要通过修改Log4Net.config,就可实现各种方式的输入。输出到控制台:<logger name="myLogger"><level value="ALL"/><appender-ref ref="ConsoleAppender" /></logger>输出到文件:<logger name="myLogger"><level value="ALL"/><appender-ref ref="TextAppender" /></logger>输出到数据库:<logger name="myLogger"><level value="ALL"/><appender-ref ref="DataBaseAppender" /></logger>
⑵ log4net配置文件解析
<log net>
<root>
<level value= ALL />
<appender ref ref= rollingFile />
</root>
<appender name= rollingFile type= log net Appender RollingFileAppender log net >
<param name= File value= log txt />
<param name= AppendToFile value= false />
<param name= RollingStyle value= Date />
<param name= DatePattern value= yyyy MM dd />
<param name= StaticLogFileName value= true />
<layout type= log net Layout PatternLayout log net >
<param name= ConversionPattern value= %d [%t] % p %c %m%n />
<param name= Header value= header />
<param name= Footer value= footer />
</layout>
</appender>
<appender name= consoleApp type= log net Appender ConsoleAppender log net >
<layout type= log net Layout PatternLayout log net >
<param name= ConversionPattern value= %d [%t] % p %c %m%n />
</layout>
</appender>
<logger name= Log NetTest LogTest >
<level value= DEBUG />
<appender ref ref= rollingFile />
<appender ref ref= coloredConsoleApp />
<appender ref ref= SystemEvent />
</logger>
</log net>
log net配置节的XSD层次如下
<log net>
<root><level /><appender ref ref= /></root>
<appender name= type= Appender的完全限定类名 >
<param name= value= />
<layout type= log net Layout PatternLayout log net >
<param name= value= />
</layout>
</appender>
<logger>
<level value= />
<appender ref ref= />
</logger>
log net是log net配置节的根标记
root标记定义一个根级别的记录者 log net的记录者采用层级组织的 每一个LOGGER(ROOT也是一个LOGGER 只不过 他是祖先而已 别的方面 跟其他LOGGER一样) 都可以定义Level
level定义记录的日志级别 就是说 你要记录哪个级别以上的日志 级别由高往低依次是:
None
Fatal
ERROR
WARN
DEBUG
INFO
ALL
级别的定义要注意 如果你定义DEBUG 那么低于DEBUG级别以下的信息 将不会记入日志 啥意思呢?就是说 就算你在程序里 用()来写入一个日志信息 可是你在配置中指定level为DEBUG 由于INFO级别低于DEBUG 所以 不会被记入日志 这样的处理非常灵活
Logger还有一个配置就是appender ref了 ref是参照的意思 log net的架构非常有意思 可扩展性非常高非常值得借鉴 他分为四个要素:
logger
appender
layout
filter
logger是负责日志的记录者
appender提供记录的介质
layout负责把记入的内容格式化
filter负责把内容进行筛选
可以说 整个过程就是一个日志流水线 每个成员负责其中的一个环节
logger发出记录信息 appender接到信息 根据内部的layout配置对记录信息格式化 根据filter决定此信息是否被过滤掉 最后 将其序列化
因此 logger的appender ref就是定义说 LOGGER要找谁去将内容写入磁盘 流或其他介质 因此 十分重要吧
既然是ref引用 那肯定要定义这个被引用的appender对象了呀
每个appender都代表了一个输出介质
name属性指定其名称 type则是log net Appender命名空间的一个类的名称 意思是 指定使用哪种介质
log net支持的appender类型有十几种 最常用的有rollingFileAppender AdoNetAppender EventLogAppender FileAppender 分别把日志记入文件 系统日志和数据库
除此之外 appender内的其他参数都用param标记 以key/value形式定义于其内
这里有个小提示 每一个appender log net并没有在文档中提出他们需要哪些参数 那么 我们怎么知道呢?
原来 这些param的名称 你可以直接查对应的appender类的属性名即可 例如 使用EventLogAppender时 通过查看类的属性 我们知道其有
LogName ApplicationName属性 那么 意味着 你可以直接在这个APPENDER的param里加入以下内容:
<param name= LogName value= Application />
<param name= ApplicationName value= log netTest />
定义了appender的NAME及TYPE属性 以及使用param为其指定参数后 一个appender就建立了 你可以使用他的名字在LOGGER的<appender ref中去 引用它 那么 引用它的LOGGER在写入日志时 就是写到了APPENDER中定义的介质中去了
一个LOGGER可以引用多个APPENDER 其结果是 同一个日志 被同时记录到多个介质中去 便如 同时发邮件 写入系统日志 发送到远程主机 不过 虽然可以这样做 但是还是要小心 因为 会对性能有一定的影响 除非你需要 否则 不要乱用此功能
另外 appender中可以定义可选的layout
layout的定义非常有必要 如果你不想将来看到你的日志会感觉头晕的话 虽然log net帮你写入日志 但是 日志信息的格式却是我们使用者自行定义的layout的type参数指定使用哪个类的定义来格式化 常用的有XmlLayout SimpleLayout PatternLayout 这个当然要根据你的需要 以及你要产生的格式来选啦 如果你要输出成XML文档格式 你肯定不能用simplelayout吧
layout使用param以KEY/VALUE形式定义其参数
各个Layout类使用的参数当然不一样啦 具体的 你可以去看各个Layout类的属性
其中 PatternLayout可以使用ConversionPattern参数来指定一个格式化字符串
以及可以指定一个Header参数 做为日志开头的字符串 Footer来指定结尾字符串
这里有一个小技巧 日志中开头和结尾总想产生回车符吧 虽然logger在写入一条日志会自动回车 可是Header和FOOTER却不会 咋办?用
吗?(我从别人的BLOG上看到过)经实践
会原样定改日志 根本不会转换 其实 我们可以用XML实体呀 使用&# ;&# ;就可以在指定位置插入一个回车换行符了
最后 像log net的文档中说的那样 如果你不想你的日志文件变得很大 使读写的性能下降的话 建议你还是分级管理日志 把粒度变小点 也就是说 除了定义ROOT外 最后 对每一个模块或每一个实体 依据用途 目的 定义各自的LOGGER配置 这样的好处是日志被分散了 日志文件增长就没那么快了 每一个LOGGER的结构跟ROOT是一模一样的 这里不再叙述了 像前面说的那样 如果你相让日志产生层级关系 你可以跟他们的NAME属性像C#中的namespace那样命名就可以了
要说明的是 LOGGER的定义是非必须的 只是一种建议罢了 Log net的配置中 除了必须定义一个ROOT和一个APPENDER外 其他的都是可选的
lishixin/Article/program/net/201311/11448
⑶ 在VSCode写.netCore 踩坑记三(log4net日志配置)
1、在vscode内输入快捷键 ctrl + shift + P 选择 “NuGet Packge Manager:add package” 安装包:
2、创建一个helpers文件夹用于存放log类
复制以下两个文件到项目上 1、log4net.config 文件存放在根目录
2、LogHelper.cs 文件存放在 helpers 文件夹内
配置后当前目录结构
修改 Program.cs 文件
—————————————重点,重点来了————————————-
build时.netcore不会帮你生成config配置文件(如果有办法请指正),必须自行把log4net.config 复制到生成项目的根目录上
⑷ log4net配置文件怎么记录ip跟错误页地址
第一步:在项目中添加对log4net.dll的引用,这里引用版本是1.2.10.0。第二步:程序启动时读取log4net的配置文件。如果是CS程序,在根目录的Program.cs中的Main方法中添加:log4net.Config.XmlConfigurator.Configure();如果是BS程序,在根目录的Global.asax.cs(没有新建一个)中的Application_Start方法中添加:log4net.Config.XmlConfigurator.Configure();