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();
                //    }
                //}
            }

        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容

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