一个简单的Log类

Posted elvis-luo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个简单的Log类相关的知识,希望对你有一定的参考价值。

经常在运行程序时需要在某些地方记录log,之前想用Log4Net,但又感觉要附带一个dll,想要只带一个exe文件运行,干脆自己写个简单的类了。

需要满足的条件:被多个线程调用;时间的准确性不重要,知道先后关系就行;不想阻塞线程,毕竟干活才是主要目的,为了不太在意时间的log而阻塞等待有点不划算。

然后开始:1.需要静态类,默认存储在当前目录下,可指定log文件名;2.需要一个用来写入到文件的方法。

public static class LogWriter

   static string logPath ="Log_"+ DateTime.Now.ToString("yyyyMMdd") + ".txt";    
   private static void WriteLine_Helper(string str)
        
            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(logPath, true))
            
                writer.WriteLine(DateTime.Now.ToString("yyyy/MM/dd  HH:mm:ss    ") + str);
                writer.Close();
            
        

然后,直接写的话会存在同时访问的问题,在不使用锁进行阻塞的前提下,这里使用两个List存储消息队列,并用一个bool变量UseList1来标识当前存储到的List,当存储List1的时候,建立线程将List2中的内容写入到log并清除list2中的消息,然后取反UseList1,将消息存储到List2队列,此时将List1中的消息写入log并清除list1中的消息,最后检查list1和list2中是否还有消息,如果有则继续写入。

static List<string> list1 = new List<string>();
static List<string> list2 = new List<string>();
static bool UseList1 = false;
static bool isUsed = false;

public static void WriteLine(string str)     //将消息放进List中
        
            if (UseList1)    //如果当前正在使用List1写入log,就将消息放入list2
            
                list2.Add(str);
            
            else
            
                list1.Add(str);
            

            if (!isUsed)    //如果没开启线程,则开启线程
            
                isUsed = true;
                Thread t = new Thread(WriteList);
                t.Start();
            
        
private static void WriteList()   //将list中的消息写入log
        
            if (UseList1)   //如果正在使用list1,则将list1的消息写入log
            
                Write(list1);
                list1.Clear();  //list1的消息写入完成后清除list1消息
                UseList1 = false;   //取反UseList1,之后消息写入List2
                Write(list2);   //将list2中的消息写入log
                list2.Clear();   //清除list2中的消息
            
            else
            
                Write(list2);
                list2.Clear();
                UseList1 = true;
                Write(list1);
                list1.Clear();
            
            isClear();   //检查在写入log期间是否有新增消息,如果有则继续写
            isUsed = false;
        

private static void Write(List<string> list)   //将list中的消息写入log文件
        
            for (int i = 0; i < list.Count; i++)
            
                WriteLine_Helper(list[i]);
            
        

public static void isClear()   //检查是否list1和list2中是否还有消息未写入
        
            if (list1.Count>0 || list2.Count>0)
            
                WriteList();
            
        

实践发现写log频率高的时候的确log消息会滞后几秒,应该是频繁建立线程和频繁的打开和关闭文件造成的。可以建立一个线程等待消息,增加一个list计数,当list中消息达到一定数量的时候再打开文件写入log,减少文件的打开和操作次数,不过对于只是偶尔看看状态用的log,不折腾了。。。

以上是关于一个简单的Log类的主要内容,如果未能解决你的问题,请参考以下文章

Python之自定义封装一个简单的Log类

简单实用的Log4net帮助类

slf4j的简单用法以及与log4j的区别

我的Android进阶之旅------&gt;Android关于Log的一个简单封装

Log4j2 简单使用

升级你的Logger(注解+动态代理)