C#项目中使用日志框架Log4net
背景
无论是软件的开发期间还是发布后的运维期间,日志对软件来说都是起着非常重要的作用,软件的规模越大、复杂度越高,日志的重要性也越高。在代码的关键位置进行日志记录已经是每个程序员必须要做的,今天就来说说很流行的一个日志框架Log4net。Java程序员基本都熟悉log4j,Log4net其实就是log4j的.net实现。
准备条件
要想使用Log4net,首先下载log4net.dll,并在对应的项目中引用此dll。
下载地址:http://logging.apache.org/log4net/download_log4net.cgi
日志服务简单封装
为了更加方便的使用日志框架,通常需要对其进行封装,代码如下:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.IO;
using log4net;
using log4net.Config;
namespace Wongoing.Log
{
/// <summary>
/// 泛型日志服务类,封装Log4Net
/// </summary>
/// <typeparam name="T"></typeparam>
public class LogService<T>
{
#region 单例实现
private static LogService<T> _instance = null;
private ILog log;
private LogService()
{
XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile));
log = LogManager.GetLogger(typeof(T));
}
public static LogService<T> Instance
{
get
{
if (_instance == null)
{
_instance = new LogService<T>();
}
return _instance;
}
}
#endregion
#region 封装log4net的ILog方法
public void Debug(object message)
{
log.Debug(message);
}
public void DebugFormatted(string format, params object[] args)
{
log.DebugFormat(CultureInfo.InvariantCulture, format, args);
}
public void Info(object message)
{
log.Info(message);
}
public void InfoFormatted(string format, params object[] args)
{
log.InfoFormat(CultureInfo.InvariantCulture, format, args);
}
public void Warn(object message)
{
log.Warn(message);
}
public void Warn(object message, Exception exception)
{
log.Warn(message, exception);
}
public void WarnFormatted(string format, params object[] args)
{
log.WarnFormat(CultureInfo.InvariantCulture, format, args);
}
public void Error(object message)
{
log.Error(message);
}
public void Error(object message, Exception exception)
{
log.Error(message, exception);
}
public void ErrorFormatted(string format, params object[] args)
{
log.ErrorFormat(CultureInfo.InvariantCulture, format, args);
}
public void Fatal(object message)
{
log.Fatal(message);
}
public void Fatal(object message, Exception exception)
{
log.Fatal(message, exception);
}
public void FatalFormatted(string format, params object[] args)
{
log.FatalFormat(CultureInfo.InvariantCulture, format, args);
}
public bool IsDebugEnabled
{
get
{
return log.IsDebugEnabled;
}
}
public bool IsInfoEnabled
{
get
{
return log.IsInfoEnabled;
}
}
public bool IsWarnEnabled
{
get
{
return log.IsWarnEnabled;
}
}
public bool IsErrorEnabled
{
get
{
return log.IsErrorEnabled;
}
}
public bool IsFatalEnabled
{
get
{
return log.IsFatalEnabled;
}
}
#endregion
#region 删除日志文件
/// <summary>
/// 删除日志
/// </summary>
public void DeleteLogFile()
{
try
{
int maxSize = 90; //默认保留90天的日志
if (!String.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings["LogSaveDays"]))
{
string strMaxSize = System.Configuration.ConfigurationManager.AppSettings["LogSaveDays"];
int.TryParse(strMaxSize, out maxSize);
}
string logFilePath = String.Empty; //定义日志文件目录变量
log4net.Appender.IAppender[] appenders = this.log.Logger.Repository.GetAppenders();
foreach (log4net.Appender.IAppender appender in appenders)
{
if (appender.Name == "FileAppender" && appender.GetType().Name == "RollingFileAppender")
{
log4net.Appender.RollingFileAppender rollingFileAppender = appender as log4net.Appender.RollingFileAppender;
logFilePath = Path.GetDirectoryName(rollingFileAppender.File); //获取日志文件目录
break;
}
}
if (!String.IsNullOrEmpty(logFilePath))
{
//logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, logFilePath);
if (Directory.Exists(logFilePath))
{
DirectoryInfo dir = new DirectoryInfo(logFilePath);
FileInfo[] logFiles = dir.GetFiles();
if (logFiles != null && logFiles.Length > maxSize)
{
Dictionary<string, FileInfo> dicFiles = new Dictionary<string, FileInfo>();
List<string> lstFileNames = new List<string>();
foreach (FileInfo fi in logFiles)
{
dicFiles.Add(fi.FullName, fi);
lstFileNames.Add(fi.FullName);
}
lstFileNames.Sort();
for (int i = 0; i < lstFileNames.Count - maxSize; i++)
{
dicFiles[lstFileNames[i]].Delete();
}
}
}
}
}
catch (Exception ex)
{
this.Error("删除日志文件发生错误:" + ex.Message);
}
}
#endregion
}
/// <summary>
/// 日志服务类,封装Log4Net
/// </summary>
public sealed class LogService
{
#region 单例实现
private static LogService _instance = null;
private ILog log;
private LogService()
{
XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile));
log = LogManager.GetLogger(typeof(LogService));
}
public static LogService Instance
{
get
{
if (_instance == null)
{
_instance = new LogService();
}
return _instance;
}
}
#endregion
#region 封装log4net的ILog方法
public void Debug(object message)
{
log.Debug(message);
}
public void DebugFormatted(string format, params object[] args)
{
log.DebugFormat(CultureInfo.InvariantCulture, format, args);
}
public void Info(object message)
{
log.Info(message);
}
public void InfoFormatted(string format, params object[] args)
{
log.InfoFormat(CultureInfo.InvariantCulture, format, args);
}
public void Warn(object message)
{
log.Warn(message);
}
public void Warn(object message, Exception exception)
{
log.Warn(message, exception);
}
public void WarnFormatted(string format, params object[] args)
{
log.WarnFormat(CultureInfo.InvariantCulture, format, args);
}
public void Error(object message)
{
log.Error(message);
}
public void Error(object message, Exception exception)
{
log.Error(message, exception);
}
public void ErrorFormatted(string format, params object[] args)
{
log.ErrorFormat(CultureInfo.InvariantCulture, format, args);
}
public void Fatal(object message)
{
log.Fatal(message);
}
public void Fatal(object message, Exception exception)
{
log.Fatal(message, exception);
}
public void FatalFormatted(string format, params object[] args)
{
log.FatalFormat(CultureInfo.InvariantCulture, format, args);
}
public bool IsDebugEnabled
{
get
{
return log.IsDebugEnabled;
}
}
public bool IsInfoEnabled
{
get
{
return log.IsInfoEnabled;
}
}
public bool IsWarnEnabled
{
get
{
return log.IsWarnEnabled;
}
}
public bool IsErrorEnabled
{
get
{
return log.IsErrorEnabled;
}
}
public bool IsFatalEnabled
{
get
{
return log.IsFatalEnabled;
}
}
#endregion
#region 删除日志文件
/// <summary>
/// 删除日志
/// </summary>
public void DeleteLogFile()
{
try
{
int maxSize = 90; //默认保留90天的日志
if (!String.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings["LogSaveDays"]))
{
string strMaxSize = System.Configuration.ConfigurationManager.AppSettings["LogSaveDays"];
int.TryParse(strMaxSize, out maxSize);
}
string logFilePath = String.Empty; //定义日志文件目录变量
log4net.Appender.IAppender[] appenders = this.log.Logger.Repository.GetAppenders();
foreach (log4net.Appender.IAppender appender in appenders)
{
if (appender.Name == "FileAppender" && appender.GetType().Name == "RollingFileAppender")
{
log4net.Appender.RollingFileAppender rollingFileAppender = appender as log4net.Appender.RollingFileAppender;
logFilePath = Path.GetDirectoryName(rollingFileAppender.File); //获取日志文件目录
break;
}
}
if (!String.IsNullOrEmpty(logFilePath))
{
//logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, logFilePath);
if (Directory.Exists(logFilePath))
{
DirectoryInfo dir = new DirectoryInfo(logFilePath);
FileInfo[] logFiles = dir.GetFiles();
if (logFiles != null && logFiles.Length > maxSize)
{
Dictionary<string, FileInfo> dicFiles = new Dictionary<string, FileInfo>();
List<string> lstFileNames = new List<string>();
foreach (FileInfo fi in logFiles)
{
dicFiles.Add(fi.FullName, fi);
lstFileNames.Add(fi.FullName);
}
lstFileNames.Sort();
for (int i = 0; i < lstFileNames.Count - maxSize; i++)
{
dicFiles[lstFileNames[i]].Delete();
}
}
}
}
}
catch (Exception ex)
{
this.Error("删除日志文件发生错误:" + ex.Message);
}
}
#endregion
}
}
使用封装的服务类记录日志
/// <summary>
/// 序列化和反序列化处理类
/// </summary>
public class SerializeHandler
{
#region 序列化和反序列化
/// <summary>
/// 序列化指定类型的对象到指定的文件
/// </summary>
/// <typeparam name="T">要序列化的对象类型</typeparam>
/// <param name="obj">要序列化的对象</param>
/// <param name="fileName">保存对象数据的完整文件名</param>
public static void Serialize<T>(T obj, string fileName)
{
lock (fileName)
{
try
{
string dir = Path.GetDirectoryName(fileName); //获取文件路径
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
BinaryFormatter formatter = new BinaryFormatter();
FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
formatter.Serialize(fs, obj);
fs.Close();
}
catch (Exception ex)
{
Wongoing.Log.LogService<SerializeHandler>.Instance.Error(ex.Message, ex);
}
}
}
}
关键使用代码
Wongoing.Log.LogService<SerializeHandler>.Instance.Error(ex.Message, ex);
Wongoing.Log.LogService<SerializeHandler>.Instance.Warn("警告信息");
Wongoing.Log.LogService<SerializeHandler>.Instance.Info("日志信息");
Wongoing.Log.LogService<SerializeHandler>.Instance.Debug("调试信息");
配置文件App.config/Web.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
</configSections>
<log4net>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="FATAL"/>
<foreColor value="Red, HighIntensity"/>
</mapping>
<mapping>
<level value="ERROR"/>
<foreColor value="Red"/>
</mapping>
<mapping>
<level value="WARN"/>
<foreColor value="Yellow"/>
</mapping>
<mapping>
<level value="INFO"/>
<foreColor value="White"/>
</mapping>
<mapping>
<level value="DEBUG"/>
<foreColor value="Green"/>
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level- %message%newline"/>
</layout>
</appender>
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log\"/>
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd".txt"" />
<StaticLogFileName value="false"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level- %message%newline"/>
</layout>
<!--多线程写入支持-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="ColoredConsoleAppender"/>
<appender-ref ref="FileAppender"/>
</root>
</log4net>
</configuration>