目录
Log4net
Log4net是一个.Net版的开源日志框架,它的功能很强大,可以将日志分为不同的等级,以不同的格式输出到不同的存储介质中,比如:数据库、txt文件、内存缓冲区、邮件、控制台、ANSI终端、远程接收端等等。
NuGet安装
配置文件
新建配置文件log4net.config, 在文件属性–>复制到输出目录->选择始终复制(将文件复制到执行目录下,以便代码加载)
示例(输出到控制台和文件):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!--声明一个名为“log4net“的自定义配置节-->
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<!--Appenders用来定义日志的输出方式,即日志要写到那种介质上去-->
<!--控制台Trace Appender --> <!--ConsoleAppender:将日志输出到应用程序控制台-->
<appender name="TraceConsoleAppender" type="log4net.Appender.ConsoleAppender">
<!--Layout用于控制Appender的输出格式-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date:%-5level - %message%newline" />
</layout>
</appender>
<!--控制台Error Appender -->
<appender name="ErrorConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date:%-5level - %message%newline" />
</layout>
</appender>
<!--文件Trace Appender --> <!--RollingFileAppender:将日志以回滚文件的形式写到文件中-->
<appender name="TraceLogFileAppender" type="log4net.Appender.RollingFileAppender">
<!--日志文件路径(相对路径), 按照日期形式输出时,直接连接元素DatePattern的value形成文件路径-->
<file value="Logs\TraceLogs\Log_"/>
<!--是否追加到文件-->
<appendToFile value="true"/>
<!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数-->
<param name="MaxSizeRollBackups" value="50" />
<!--是否只写到一个文件中-->
<StaticLogFileName value="false" />
<!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
<rollingstyle value="Date"/>
<datePattern value="yyyyMMdd'.txt'"/>
<!--使用过滤器可以过滤掉Appender输出的内容, LevelRangeFilter:日志等级在指定范围内的事件才被记录, 框架提供多种过滤器-->
<filter type="log4net.Filter.LevelRangeFilter">
<LevelMin value="DEBUG"/>
<LevelMax value="WARN"/>
</filter>
<layout type="log4net.Layout.PatternLayout">
<!--日志起始-->
<header value="--------------- TRACE LOG START ----------------------- " />
<!--日志结尾-->
<Footer value="---------------- TRACE LOG CLOSE ----------------------- " />
<!-- 输出格式: 发生日志事件的本地时间 :日志等级 - 输出的消息 换行-->
<ConversionPattern value="%date:%-5level - %message%newline" />
</layout>
</appender>
<!--文件Error Appender -->
<appender name="ErrorLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\ErrorLogs\Log_" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd'.txt'" />
<staticLogFileName value="false" />
<layout type="log4net.Layout.PatternLayout">
<header value="--------------- ERROR LOG START ----------------------- " />
<Footer value="--------------- ERROR LOG CLOSE ----------------------- " />
<ConversionPattern value="%date:%-5level - %message%newline" />
</layout>
</appender>
<!--Logger是直接和应用程序交互的组件。Logger只是产生日志,然后由它引用的Appender记录到指定的媒介,并由Layout控制输出格式-->
<logger name="TraceLog">
<!--log日志级别: OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL-->
<!--高于等级设定值的方法都能写入日志。例如当我们设成Info时,logger.Debug就会被忽略而不写入文件,但是FATAL,ERROR,WARN,INFO会被写入,因为他们等级高于INFO。-->
<level value="ALL"/>
<!--引用上文定义的appender-->
<appender-ref ref="TraceLogFileAppender"/>
<appender-ref ref="TraceConsoleAppender"/>
</logger>
<logger name="ErrorLog">
<level value="WARN"/>
<appender-ref ref="ErrorConsoleAppender"/>
<appender-ref ref="ErrorLogFileAppender"/>
</logger>
</log4net>
</configuration>
代码加载
using System;
using log4net;
//使用配置文件log4net.config, Watch=true : 监视配置文件,当配置文件发生变化的时候,就会重新加载。
[assembly:log4net.Config.XmlConfigurator(ConfigFile ="log4net.config",Watch =true)]
namespace LoginManagement.Common
{
public class LogHelper
{
//获得配置文件中相应的Logger,其中"TraceLog/ErrorLog"便是我们自定义的日志对象<logger>的name的值。
private static ILog m_TraceLog = LogManager.GetLogger("TraceLog");
private static ILog m_ErrorLog = LogManager.GetLogger("ErrorLog");
// ************************************************************************************************************
// 函数名:TraceIn
// 输入参数:
// className: 类名称
// func: 函数名
// info: 参数信息
// 输出参数:无
// 返回值:无
// 说明:输出函数输入信息
// ************************************************************************************************************
public static void TraceIn(string className, string func, string info)
{
string msg = string.Format("{0}.{1} <- {2}",className,func,info);
if (m_TraceLog.IsInfoEnabled)
{
m_TraceLog?.Info(msg);
}
}
// ************************************************************************************************************
// 函数名:TraceOut
// 输入参数:
// className: 类名称
// func: 函数名
// info: 返回值和输出参数
// 输出参数:无
// 返回值:无
// 说明:输出函数返回信息
// ************************************************************************************************************
public static void TraceOut(string className, string func, string info)
{
string msg = string.Format("{0}.{1} -> {2}", className, func, info);
if (m_TraceLog.IsInfoEnabled)
{
m_TraceLog?.Info(msg);
}
}
// ************************************************************************************************************
// 函数名:LogError
// 输入参数:
// className: 类名称
// func: 函数名
// info: 报错信息
// 输出参数:无
// 返回值:字节数组
// 说明:输出错误信息
// ************************************************************************************************************
public static void LogError(string className, string func, string info)
{
string msg = string.Format("{0}.{1} -> {2}", className, func, info);
if (m_ErrorLog.IsErrorEnabled)
{
m_ErrorLog?.Error(msg);
}
}
// ************************************************************************************************************
// 函数名:LogErrorException
// 输入参数:
// className: 类名称
// func: 函数名
// info: 报错信息
// 输出参数:无
// 返回值:字节数组
// 说明:输出错误信息&异常
// ************************************************************************************************************
public static void LogErrorException(string className, string func, string info, Exception ex)
{
string msg = string.Format("{0}.{1} -> {2}", className, func, info);
if (m_ErrorLog.IsErrorEnabled)
{
m_ErrorLog?.Error(msg,ex);
}
}
}
}
调用
using System.Reflection;
private void DoLogin(object o)
{
try
{
LogHelper.TraceIn(MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name, string.Format("object o:{0}", o));
if (string.IsNullOrEmpty(LoginModel.UserName))
{
LoginModel.ErrorMessage = "用户名不能为空";
LogHelper.LogError(MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name, "登录失败,用户名不能为空");
return;
}
// ...
}
catch (Exception ex)
{
LogHelper.LogErrorException(MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name, "登录异常" , ex);
}
}
输出
根据log4net.config配置的文件路径,生成对应的log文件夹和文件
其他说明
Appenders
- AdoNetAppender 将日志记录到数据库中。可以采用SQL和存储过程两种方式。
- AnsiColorTerminalAppender 将日志高亮输出到ANSI终端。
- AspNetTraceAppender 能用asp.net中Trace的方式查看记录的日志。
- BufferingForwardingAppender 在输出到子Appenders之前先缓存日志事件。
- ConsoleAppender 将日志输出到应用程序控制台。
- EventLogAppender 将日志写到Windows Event Log。
- FileAppender 将日志输出到文件。
- ForwardingAppender 发送日志事件到子Appenders。
- LocalSyslogAppender 将日志写到local syslog service (仅用于UNIX环境下)。
- MemoryAppender 将日志存到内存缓冲区。
- NetSendAppender 将日志输出到Windows Messenger service.这些日志信息将在用户终端的对话框中显示。
- OutputDebugStringAppender 将日志输出到Debuger,如果程序没有Debuger,就输出到系统Debuger。如果系统Debuger也不可用,将忽略消息。
- RemoteSyslogAppender 通过UDP网络协议将日志写到Remote syslog service。
- RemotingAppender 通过.NET Remoting将日志写到远程接收端。
- RollingFileAppender 将日志以回滚文件的形式写到文件中。
- SmtpAppender 将日志写到邮件中。
- SmtpPickupDirAppender 将消息以文件的方式放入一个目录中,像IIS SMTP agent这样的SMTP代理就可以阅读或发送它们。
- TelnetAppender 客户端通过Telnet来接受日志事件。
- TraceAppender 将日志写到.NET trace 系统。
- UdpAppender 将日志以无连接UDP数据报的形式送到远程宿主或用UdpClient的形式广播。
Filters
- DenyAllFilter 阻止所有的日志事件被记录
- LevelMatchFilter 只有指定等级的日志事件才被记录
- LevelRangeFilter 日志等级在指定范围内的事件才被记录
- LoggerMatchFilter 与Logger名称匹配,才记录
- PropertyFilter 消息匹配指定的属性值时才被记录
- StringMathFilter 消息匹配指定的字符串才被记录
日志等级
- FATAL(致命错误):记录系统中出现的能使用系统完全失去功能,服务停止,系统崩溃等使系统无法继续运行下去的错误。例如,数据库无法连接,系统出现死循环。
- ERROR(一般错误):记录系统中出现的导致系统不稳定,部分功能出现混乱或部分功能失效一类的错误。例如,数据字段为空,数据操作不可完成,操作出现异常等。
- WARN(警告):记录系统中不影响系统继续运行,但不符合系统运行正常条件,有可能引起系统错误的信息。例如,记录内容为空,数据内容不正确等。
- INFO(一般信息):记录系统运行中应该让用户知道的基本信息。例如,服务开始运行,功能已经开户等。
- DEBUG (调试信息):记录系统用于调试的一切信息,内容或者是一些关键数据内容的输出。
layout节点配置说明
- %m(message):输出的日志消息;
- %n(newline):换行;
- %d(datetime):输出当前语句运行的时刻;
- %r(runtime):输出程序从运行到执行到当前语句时消耗的毫秒数;
- %t(threadid):当前语句所在的线程ID ;
- %p(priority): 日志的当前日志级别;
- %c(class):当前日志对象的名称;
- %L:输出语句所在的行号;
- %F:输出语句所在的文件名;
- %-10:表示最小长度为10,如果不够,则用空格填充
参考: