代码:
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Reflection;using System.Text;using System.Threading.Tasks;namespace Utils{ ////// 写日志类 /// public class LogUtil { #region 字段 private static object _lock = new object(); private static string _path = null; private static int _fileSize = 10 * 1024 * 1024; //日志分隔文件大小 #endregion #region 写文件 ////// 写文件 /// private static void WriteFile(string log, string path) { try { if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } using (FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(fs)) { #region 日志内容 string value = string.Format(@"{0} {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), log); #endregion sw.WriteLine(value); sw.Flush(); } fs.Close(); } } catch { } } #endregion #region 生成日志文件路径 ////// 生成日志文件路径 /// private static string CreateLogPath(string folder) { if (_path == null) { UriBuilder uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase); _path = Path.GetDirectoryName(Uri.UnescapeDataString(uri.Path)); } int index = 0; string logPath; bool bl = true; do { index++; logPath = Path.Combine(_path, folder + DateTime.Now.ToString("yyyyMMdd") + (index == 1 ? "" : "_" + index.ToString()) + ".txt"); if (File.Exists(logPath)) { FileInfo fileInfo = new FileInfo(logPath); if (fileInfo.Length < _fileSize) { bl = false; } } else { bl = false; } } while (bl); return logPath; } #endregion #region 写错误日志 public static void LogError(Exception ex, string log = null) { LogError(string.IsNullOrEmpty(log) ? ex.Message + "\r\n" + ex.StackTrace : (log + ":") + ex.Message + "\r\n" + ex.StackTrace); } ////// 写错误日志 /// public static void LogError(string log) { Task.Factory.StartNew(() => { lock (_lock) { WriteFile("[Error] " + log, CreateLogPath("Log\\Error\\")); } }); } #endregion #region 写操作日志 ////// 写操作日志 /// public static void Log(string log) { Task.Factory.StartNew(() => { lock (_lock) { WriteFile("[Info] " + log, CreateLogPath("Log\\Info\\")); } }); } #endregion }}
测试代码:
private void button2_Click(object sender, EventArgs e){ int n = 10000; DateTime dtStart = DateTime.Now; for (int i = 1; i <= n; i++) { ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object obj) { int j = (int)obj; Utils.LogUtil.Log("测试" + j.ToString()); if (j == n) { double sec = DateTime.Now.Subtract(dtStart).TotalSeconds; MessageBox.Show(n + "条日志完成,耗时" + sec.ToString("0.000") + "秒"); } }), i); }}
测试结果截图:
Winform程序设置日志路径:
LogUtil.LogPath = Application.StartupPath;
ASP.NET MVC程序设置日志路径:
private static string _path = ConfigurationManager.AppSettings["LogPath"];
改进日志文件路径生成版:
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Utils{ ////// 写日志类 /// public class LogUtil { #region 字段 private static object _lock = new object(); private static int _fileSize = 10 * 1024 * 1024; //日志分隔文件大小 private static string _strNow = DateTime.Now.ToString("yyyyMMdd"); private static string _pathInfoLog; private static string _pathErrorLog; private static int _indexInfoLog = 1; private static int _indexErroLog = 1; private static long _sizeInfoLog = 0; private static long _sizeErrorLog = 0; #endregion #region 初始化 ////// 初始化 /// /// 日志路径 /// 日志分隔文件大小 public static void Init(string path, int? fileSize = null) { _pathInfoLog = Path.Combine(path, "Log\\Info"); _pathErrorLog = Path.Combine(path, "Log\\Error"); if (fileSize != null) _fileSize = fileSize.Value; if (!Directory.Exists(_pathInfoLog)) Directory.CreateDirectory(_pathInfoLog); if (!Directory.Exists(_pathErrorLog)) Directory.CreateDirectory(_pathErrorLog); InitIndex(_pathInfoLog, ref _indexInfoLog, ref _sizeInfoLog); InitIndex(_pathErrorLog, ref _indexErroLog, ref _sizeErrorLog); } #endregion #region 初始化文件index和size private static void InitIndex(string path, ref int index, ref long fileSize) { ListfileList = Directory.GetFiles(path, _strNow + "*").ToList(); fileSize = 0; index = 1; string logPath = CreateLogPath(path, index); while (fileList.Exists(a => a == logPath)) { FileInfo fileInfo = new FileInfo(logPath); if (fileInfo.Length < _fileSize) { fileSize = fileInfo.Length; break; } index++; logPath = CreateLogPath(path, index); } } #endregion #region 写文件 /// /// 写文件 /// private static void WriteFile(string log, string path, ref long fileSize) { try { if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } using (FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(fs)) { #region 日志内容 string value = string.Format(@"{0} {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), log); #endregion sw.WriteLine(value); sw.Flush(); fileSize = fs.Length; } fs.Close(); } } catch { } } #endregion #region 生成日志文件路径 ////// 生成日志文件路径 /// private static string CreateLogPath(string path, int index) { if (_pathInfoLog == null) throw new Exception("请先执行LogUtil.Init方法初始化"); return Path.Combine(path, _strNow + (index == 1 ? string.Empty : "_" + index) + ".txt"); } ////// 生成日志文件路径 /// private static string CreateLogPath(string path, ref int index, bool isInfoLog) { if ((isInfoLog && _sizeInfoLog > _fileSize) || (!isInfoLog && _sizeErrorLog > _fileSize)) { index++; } return CreateLogPath(path, index); } #endregion #region 写错误日志 ////// 写错误日志 /// public static void LogError(string log) { Task.Factory.StartNew(() => { lock (_lock) { WriteFile("[Error] " + log, CreateLogPath(_pathErrorLog, ref _indexErroLog, false), ref _sizeErrorLog); } }); } #endregion #region 写操作日志 ////// 写操作日志 /// public static void Log(string log) { Task.Factory.StartNew(() => { lock (_lock) { WriteFile("[Info] " + log, CreateLogPath(_pathInfoLog, ref _indexInfoLog, true), ref _sizeInfoLog); } }); } #endregion }}