该类主要用于对程序进行跟踪,记录程序运行过程,便于查找问题所在。
/// <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)