• 文件日志类FileLogHelper


    该类主要用于对程序进行跟踪,记录程序运行过程,便于查找问题所在。

        /// <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)

  • 相关阅读:
    WPF BitmapImage 占用资源无法释放、无法删除问题
    C#窗体加载和控件加载不同步导致控件闪烁
    C#中saveFileDialog(另存为)保存图片文件
    String、StringBuffer、StringBuilder的区别
    线程的上下文切换
    HTTP缓存机制
    MySQL数据库基本操作
    ThreadLocal(线程本地存储)
    CDN(Content Delivery Network)原理
    Java之Object类
  • 原文地址:https://www.cnblogs.com/beijia/p/fileLog.html
Copyright © 2020-2023  润新知