您的位置:首页 > 其它

文件日志类-FileLogHelper

2013-01-18 14:21 176 查看
该类主要用于对程序进行跟踪,记录程序运行过程,便于查找问题所在。

/// <summary>
/// 文件日志类
/// </summary>
public class FileLogHelper
{
private static FileLogHelper _instance;
private static readonly object lockObject = new object();

private bool IsEnabledLog = true; // 是否启用日志功能
private bool IsRecordStackInfo = true; // 是否记录堆栈信息
private long fileMaxLenth; // 日志文件的最大长度(字节)
private FileStream fs;
private string filePath;

/// <summary>
/// 单例模式
/// </summary>
public static FileLogHelper Instance
{
get
{
lock (lockObject)
{
if (_instance == null)
{
_instance = new FileLogHelper();
}
return _instance;
}
}
}

/// <summary>
/// 加载配置文件信息
/// </summary>
private FileLogHelper()
{
NameValueCollection appSettings = System.Configuration.ConfigurationManager.AppSettings;
string isEnabled = appSettings["LogIsEnabled"];
string isRecordStack = appSettings["IsRecordStack"];
string maxLimit = appSettings["LogFileMaxLimit"];

bool enabled;
if (bool.TryParse(isEnabled, out enabled))
{
IsEnabledLog = enabled;
}
else
{
IsEnabledLog = true; // 默认启用日志功能
}

bool recordStack;
if (bool.TryParse(isRecordStack, out recordStack))
{
IsRecordStackInfo = recordStack;
}
else
{
IsRecordStackInfo = true; // 默认记录堆栈信息
}

int fileMaxLimit, max;
if (int.TryParse(maxLimit, out max))
{
fileMaxLimit = Math.Max(5, max); // 限制最小5M
fileMaxLimit = Math.Min(20, max); // 限制最大20M
}
else
{
fileMaxLimit = 10; // 默认20M
}
fileMaxLenth = fileMaxLimit * 1024 * 1024;

filePath = GetLogFilePath();
fs = new FileStream(filePath, FileMode.Append, FileAccess.Write);
}

/// <summary>
/// 记录文件日志
/// </summary>
/// <param name="content">日志内容</param>
public void Log(string content)
{
if (!IsEnabledLog || string.IsNullOrWhiteSpace(content))
{
return;
}

StringBuilder sb = new StringBuilder();
sb.Append("-----------------------------------------------------------------------------------\r\n");
sb.AppendFormat("【时间】{0}\r\n", DateTime.Now.ToString("HH:mm:ss"));
if (IsRecordStackInfo)
{
sb.Append("【堆栈信息】\r\n");
#region 获取堆栈信息
StackTrace trace = new StackTrace(true);
StackFrame[] frames = trace.GetFrames();
int maxLenth = frames.Select(c => c.GetMethod().Name.Length).Max();
int tabNum = (maxLenth + 7) / 8;
sb.Append("\t方法");
//并行计算
Parallel.For(0, tabNum, (i) => { sb.Append("\t"); });
sb.Append("行号\t列号\t文件\r\n");
foreach (StackFrame frame in frames)
{
sb.AppendFormat("\t{0}", frame.GetMethod().Name);
int num = (int)Math.Ceiling((decimal)(tabNum * 8 - frame.GetMethod().Name.Length) / 8);
//并行计算
Parallel.For(0, num, (i) => { sb.Append("\t"); });
sb.AppendFormat("{0}\t{1}\t{2}\r\n", frame.GetFileLineNumber(), frame.GetFileColumnNumber(), frame.GetFileName());
}
#endregion
}
sb.Append("【内容】\r\n\t" + content + "\r\n\r\n");

byte[] data = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); // Encoding.GetBytes(string s); s必须实例化
fs.Write(data, 0, data.Length);

FileInfo fi = new FileInfo(filePath);
if (fi.Length >= fileMaxLenth)
{
filePath = GetLogFilePath();
fs = new FileStream(filePath, FileMode.Append, FileAccess.Write);
}
}

/// <summary>
/// 取得当前所应操作的日志文件的路径
/// </summary>
/// <returns></returns>
public string GetLogFilePath()
{
string strFilePath = string.Empty;
string strYearMonthDay = DateTime.Now.ToString("yyyyMMdd");
string logSavePath = string.Format("{0}\\log", System.AppDomain.CurrentDomain.BaseDirectory.TrimEnd("\\".ToCharArray()));
// 判断日志保存目录是否存在,不存在则新建
if (!System.IO.Directory.Exists(logSavePath))
{
System.IO.Directory.CreateDirectory(logSavePath);
}

//判断当天是否已有日志文件
string[] strFilesArray = Directory.GetFiles(logSavePath, "log_" + strYearMonthDay + "_*.txt");
if (strFilesArray.Length == 0)
{
strFilePath = string.Format("{0}\\log_{1}_1.txt", logSavePath, strYearMonthDay);

//之前没有当日的日志文件,则需要新建
using (File.CreateText(strFilePath))
{

}
}
else
{
int maxOrder = 1, fileOrder;
string fileName = null;

#region 获取编号最大的日志文件
for (int i = 0; i < strFilesArray.Length; i++)
{
fileName = strFilesArray[i].Trim();
fileName = fileName.Substring(fileName.LastIndexOf('_') + 1);
fileName = fileName.Replace(".txt", "");
fileOrder = Convert.ToInt32(fileName);
if (fileOrder > maxOrder)
{
maxOrder = fileOrder;
}
}
#endregion

strFilePath = string.Format("{0}\\log_{1}_{2}.txt", logSavePath, strYearMonthDay, maxOrder);
//判断最新文件(即编号最大)是否超容
FileInfo fileInfo = new FileInfo(strFilePath);
if (fileInfo.Length >= fileMaxLenth)
{
//超容了,则新建之
int newOrder = maxOrder + 1;
strFilePath = string.Format("{0}\\log_{1}_{2}.txt", logSavePath, strYearMonthDay, newOrder);
using (File.CreateText(strFilePath))
{

}
}
}
return strFilePath;
}

/// <summary>
/// /获取指定文件夹的大小
/// </summary>
/// <param name="dir">目录实例</param>
/// <returns></returns>
public static long FolderSize(System.IO.DirectoryInfo dir)
{
if (dir == null || !dir.Exists)
{
return 0;
}
long size = 0;
FileInfo[] files = dir.GetFiles();
foreach (System.IO.FileInfo info in files)
{
size += info.Length;
}
DirectoryInfo[] dirs = dir.GetDirectories();
foreach (DirectoryInfo dirinfo in dirs)
{
size += FolderSize(dirinfo);
}
return size;
}
}


需要在配置文件中进行配置的项:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!--是否启用日志记录功能,默认为true-->
<add key="LogIsEnabled" value="true"/>
<!--是否同时记录堆栈信息(文件,方法,行号,列号),默认为true-->
<add key="IsRecordStack" value="true"/>
<!--单个日志文件的最大限制(单位:MB),默认为10(范围[5-20])-->
<add key="LogFileMaxLimit" value="10"/>
</appSettings>
</configuration>


方法调用:

FileLogHelper.Instance.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));


运行结果:
-----------------------------------------------------------------------------------
【时间】11:48:27
【堆栈信息】
方法    行号   列号   文件
Log     106   17    E:\QvodVideoCombiner\QvodVideoCombiner\FileLogHelper.cs
FileCreate 30   17   E:\QvodVideoCombiner\QvodVideoCombiner\Program.cs
Main    23   13   E:\QvodVideoCombiner\QvodVideoCombiner\Program.cs
【内容】
2013-01-18 48:27 测试一下:0)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: