LogHelper

队列写日志

       /// <summary>
    /// 多线程安全Log记录工具20180314
    /// lqx
    /// </summary>
    public class LogHelper
    {
        //为了使用DBGView进行在线调试:
        //System.Diagnostics.Debug.WriteLine("Debug模式可见")
        //System.Diagnostics.Trace.WriteLine("Debug、Release都可见");

        private static Thread WriteThread;
        private static readonly Queue<string[]> MsgQueue;

        private static readonly string FilePath;

        private static Boolean autoResetEventFlag = false;
        private static AutoResetEvent aEvent = new AutoResetEvent(false);
        private static bool flag = true;
        public static bool LogFlag = true;

        private static string xmlPath = System.AppDomain.CurrentDomain.BaseDirectory + @"/log.xml";
        static LogHelper()
        {
            FilePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "Log\\";
            WriteThread = new Thread(WriteMsg);
            MsgQueue = new Queue<string[]>();
            WriteThread.Start();
        }

        public static void LogInfo(string msg)
        {
            Monitor.Enter(MsgQueue);
            StringBuilder sb = GetCallerMethodBaseInfo(out MethodBase callerMethod, out string fileName);
            sb.Insert(0, string.Format("{0} {1} ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"), msg));
            string[] data = new string[2] { fileName + "_Info", sb.ToString() };
            MsgQueue.Enqueue(data);
            Monitor.Exit(MsgQueue);
            if (autoResetEventFlag)
            {
                aEvent.Set();
            }
        }
        public static void LogError(string msg)
        {
            Monitor.Enter(MsgQueue);
            StringBuilder sb = GetCallerMethodBaseInfo(out MethodBase callerMethod, out string fileName);
            sb.Insert(0, string.Format("{0} {1} ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"), msg));
            string[] data = new string[2] { fileName + "_Error", sb.ToString() };
            MsgQueue.Enqueue(data);
            Monitor.Exit(MsgQueue);
            if (autoResetEventFlag)
            {
                aEvent.Set();
            }
        }
        public static void LogWarn(string msg)
        {
            Monitor.Enter(MsgQueue);
            StringBuilder sb = GetCallerMethodBaseInfo(out MethodBase callerMethod, out string fileName);
            sb.Insert(0, string.Format("{0} {1} ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"), msg));
            string[] data = new string[2] { fileName + "_Warn", sb.ToString() };
            MsgQueue.Enqueue(data);
            Monitor.Exit(MsgQueue);
            if (autoResetEventFlag)
            {
                aEvent.Set();
            }
        }

        /// <summary>
        /// ExitThread是退出日志记录线程的方法,一旦退出,无法开启,一般在程序关闭时执行
        /// </summary>
        public static void ExitThread()
        {
            flag = false;
            aEvent.Set();//恢复线程执行
        }
        private static void WriteMsg()
        {
            try
            {
                while (flag)
                {
                    //进行记录
                    if (LogFlag)
                    {
                        autoResetEventFlag = false;
                        if (!Directory.Exists(FilePath))
                        {
                            Directory.CreateDirectory(FilePath);
                        }
                        //写日志前先删除日志
                        if (File.Exists(xmlPath))
                        {
                            new AsyDispose().LogDeal(false, xmlPath);
                        }
                        //读取配置日志文件最大容量大小,默认10M
                        int maxsize = LogConfig.logfliesize == 0 ? 10 : LogConfig.logfliesize;
                        while (MsgQueue.Count > 0)
                        {

                            Monitor.Enter(MsgQueue);
                            string[] msg = MsgQueue.Dequeue();
                            Monitor.Exit(MsgQueue);
                            string fileName = FilePath + DateTime.Now.ToString("yyyy-MM-dd") + "_" + msg[0] + "_.log";
                            var logStreamWriter = new StreamWriter(fileName, true);
                            logStreamWriter.WriteLine(msg[1]);
                            if (GetFileSize(fileName) > 1024 * maxsize)//大于10M
                            {
                                logStreamWriter.Flush();
                                logStreamWriter.Close();
                                CopyToBak(fileName);
                                logStreamWriter = new StreamWriter(fileName, false);
                                logStreamWriter.Write("");
                                logStreamWriter.Flush();
                                logStreamWriter.Close();
                                logStreamWriter = new StreamWriter(fileName, true);
                            }
                            //下面用于DbgView.exe工具进行在线调试
                            //System.Diagnostics.Debug.WriteLine("BS_Debug:" + msg);
                            //System.Diagnostics.Trace.WriteLine("BS_Release:" + msg);
                            logStreamWriter.Flush();
                            logStreamWriter.Close();
                        }

                        autoResetEventFlag = true;
                        aEvent.WaitOne();
                    }
                    else
                    {
                        autoResetEventFlag = true;
                        aEvent.WaitOne();
                    }
                }
            }
            catch (Exception ex) { }
        }
        private static long GetFileSize(string fileName)
        {
            long strRe = 0;
            if (File.Exists(fileName))
            {
                var myFs = new FileInfo(fileName);
                strRe = myFs.Length / 1024;
                //Console.WriteLine(strRe);
            }
            return strRe;
        }
        private static void CopyToBak(string sFileName)
        {
            int fileCount = 0;
            string sBakName = "";
            do
            {
                fileCount++;
                sBakName = sFileName + "." + fileCount + ".BAK";
            }
            while (File.Exists(sBakName));
            File.Copy(sFileName, sBakName);
        }

        public static StringBuilder GetCallerMethodBaseInfo(out MethodBase outCallerMethod, out string fileName)
        {
            var result = new StringBuilder();
            fileName = "";
            result.AppendLine();
            outCallerMethod = null;
            try
            {
                MethodBase callerMethod = null;
                var i = 2;
                while (true)
                {
                    var curstackFrame = new System.Diagnostics.StackFrame(i, true);
                    if (curstackFrame == null)
                    {
                        break;
                    }
                    if (curstackFrame.GetILOffset() < 0)
                    {
                        break;
                    }
                    callerMethod = curstackFrame?.GetMethod();

                    if (callerMethod == null)
                    {
                        break;
                    }
                    if (outCallerMethod == null)
                    {
                        outCallerMethod = callerMethod;

                    }
                    if (i == 2)
                    {
                        string className = "";
                        if (callerMethod.DeclaringType.Name.ToString().Length > 20)
                            className = callerMethod.DeclaringType.Name.ToString().Substring(0, 20);
                        else
                            className = callerMethod.DeclaringType.Name.ToString();
                        fileName = className + "_" + callerMethod.Name;
                        fileName = fileName.Replace("<", "").Replace(">", "");//预防非法字符
                    }

                    result.AppendLine("调用栈:" + callerMethod.DeclaringType + "." + callerMethod.Name + " (" + curstackFrame.GetFileLineNumber() + ")");

                    i++;
                }

                return result;
            }
            catch (Exception ex) { return result; }
        }
    }

    /// <summary>
    /// 获取配置
    /// </summary>
    public class LogConfig
    {
        private static string xmlPath = "";
        /// <summary>
        /// 文件夹名称
        /// </summary>
        public static string folderstr { get; set; }
        /// <summary>
        /// 文件尾缀
        /// </summary>
        public static string postfixStr { get; set; }
        /// <summary>
        /// 保留天数
        /// </summary>
        public static string obligateStr { get; set; }
        /// <summary>
        /// 单个日志文件最大容量,单位M,默认10M
        /// </summary>
        public static int logfliesize { get; set; }
        static LogConfig()
        {
            xmlPath = System.AppDomain.CurrentDomain.BaseDirectory + @"/Lib.LogManager.xml";
            if (File.Exists(xmlPath))
            {
                XDocument document = XDocument.Load(xmlPath);
                XElement root = document.Root;
                //获取根元素下的所有子元素
                IEnumerable<XElement> enumerable = root.Elements();
                foreach (XElement item in enumerable)
                {
                    if (item.Name == "folder")
                    {
                        folderstr = item.Value;
                    }
                    else if (item.Name == "postfix")
                    {
                        postfixStr = item.Value;
                    }
                    else if (item.Name == "obligate")
                    {
                        obligateStr = item.Value;
                    }
                    else if (item.Name == "logfliesize")
                    {
                        if (string.IsNullOrEmpty(item.Value))
                            logfliesize = 10;
                        else
                        {
                            int temp = 10;
                            if (int.TryParse(item.Value, out temp))
                            {
                                logfliesize = temp;
                            }
                            else
                                logfliesize = 10;
                        }

                    }
                }
            }
        }
    }


    /// <summary>
    /// 自动清除日志处理类
    /// </summary>
    public class AsyDispose
    {

        #region log.xml
//<?xml version = "1.0" encoding="utf-8" ?>
//<config>
//  <!--配置文件夹的名称(中间用英文逗号隔开)-->
//  <folder>log,test</folder>
//  <!--配置文件后缀(中间用英文逗号隔开)-->
//  <postfix>.log,.txt</postfix>
//  <!--预留时间-->
//  <obligate>30</obligate>
//  <!--单个日志文件最大容量,单位M,默认10M-->
//  <logfliesize>10</logfliesize>
//</config>
        #endregion

        //string xmlPath = System.AppDomain.CurrentDomain.BaseDirectory + @"/log.xml";
        /// <summary>
        /// 文件夹名称
        /// </summary>
        public string folderstr { get; set; }
        /// <summary>
        /// 文件尾缀
        /// </summary>
        public string postfixStr { get; set; }
        /// <summary>
        /// 保留天数
        /// </summary>
        public string obligateStr { get; set; }
        public void LogDeal(bool isStop, string xmlPath)
        {
            if (System.IO.File.Exists(xmlPath))
            {
                //异步执行
                if (!string.IsNullOrEmpty(LogConfig.folderstr) && !string.IsNullOrEmpty(LogConfig.postfixStr) && !string.IsNullOrEmpty(LogConfig.obligateStr))
                {
                    OptLogFile(folderstr, postfixStr, obligateStr);
                }
            }
        }

        public bool isParms { get; set; }

        internal void OptLogFile(string folderstr, string postfixStr, string obligateStr)
        {
            int obligateDu = 0;
            if (int.TryParse(obligateStr, out obligateDu) && obligateDu <= 0)
            {
                obligateDu = 30;
            }

            string pathSource = System.AppDomain.CurrentDomain.BaseDirectory;
            string[] folderArr = null;
            string[] pathList = null;
            if (!string.IsNullOrEmpty(folderstr))
            {
                folderArr = folderstr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                pathList = new string[folderArr.Length];
                for (int itfo = 0; itfo < folderArr.Length; itfo++)
                {
                    pathList[itfo] = pathSource + "\\" + folderArr[itfo];
                }

                foreach (string path in pathList)
                {
                    string[] postfixArr = postfixStr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    if (Directory.Exists(path))
                    {
                        DirectoryInfo dyinfo = new DirectoryInfo(path);
                        foreach (FileInfo fi in dyinfo.GetFiles())
                        {
                            foreach (string fix in postfixArr)
                            {
                                if (fi.Extension.Contains(fix)
                                    && (DateTime.Now - fi.LastWriteTime).Days > obligateDu)
                                {
                                    File.Delete(path + "\\" + fi.Name);
                                    LogHelper.LogInfo("记录删除日志:"+ path + "\\" + fi.Name + "(" + fi.LastWriteTime + ")");
                                    continue;
                                }

                                if (fi.Name.Contains("AsyDispose") && fi.Length > 200 * 1024)
                                {
                                    File.Delete(path + "\\" + fi.Name);
                                }
                            }
                        }
                    }
                }

                //if (isParms)
                //{
                //    System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName("lis.client.LogDispose");
                //    foreach (System.Diagnostics.Process p in ps)
                //    {
                //        p.Kill();
                //    }
                //}
            }

        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • VersionHelper是啥呢?先看看具体的函数长啥样: 其实跟之前说的VersionHelper差不多里面就干...
    APP4x阅读 441评论 0 0
  • 转载自:http://blog.sina.com.cn/s/blog_416656f70102vwld.html本...
    SkTj阅读 1,051评论 0 0
  • 本文介绍了对 Linux IO 子系统性能进行优化时需要考虑的因素,以及一些 IO 性能检测工具。 本文的大部分内...
    superme_阅读 732评论 0 1
  • 索引什么时候会失效? 失效的常见场景与原因[https://bbs.huaweicloud.com/blogs/3...
    Florence9阅读 957评论 0 1
  • 1. redis介绍 Redis 是一种基于内存的数据库,对数据的读写操作都是在内存中完成,因此读写速度非常快,常...
    小pig阅读 363评论 0 0