一个简单的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,不折腾了。。。

原文地址:https://www.cnblogs.com/Elvis-Luo/p/11470538.html

时间: 2024-08-28 10:52:45

一个简单的Log类的相关文章

Python+Selenium进阶版(八)- Python自定义封装一个简单的Log类

目标:如何写一个Python日志类,用来输出不同级别的日志信息到本地文件夹下的日志文件里. 练习场景: 我们需要封装一个简单的日志类,主要有以下内容: 1.生成的日志文件格式是 年月日分秒.log 2.生成的XXX.log文件存储在项目根目录下Logs文件夹下 3.这个日志类,支持INFO,ERROR两种日志级别 4.日志里,每行日志输出,时间日期+执行类名称+日志级别+日志描述 解决思路: 1.在根目录下新建一个Logs的文件夹,获取这个Log的相对路径: 2.日志的保存命名,需要系统时间:

一个简单的购物类网站

最近给学校做了一个购物类的网站:捐赠网站;模式和淘宝是一样的:选择商品->选择数量->填写留言(评价)->付款(支付宝付款);逻辑比较简单. 接下来的几天,我将就编程中遇到的一些问题和体会说说.下面列出了想说的几点; 1.html 文档对象模型 DOM: 2.安全验证方面:比如客户端向服务器传输数据时怎么保证数据的安全性;

LayaBox开发实战之实现一个简单的模板类

1.首先UI设计:记得导出 2.然后查看layaUI.max.all.js中是否生成对应UI的JS代码: var FeedBackUI=(function(_super){ function FeedBackUI(){ this.btn_close=null; this.FeedBackText=null; this.button_submit=null; this.button_cancel=null; FeedBackUI.__super.call(this); } CLASS$(FeedB

一个简单的数组类操作

要求定义一个数组类,动态分配数组大小,并实现反转与排序操作. 代码如下: class Array { private int a[] = null; private int foot=0; public Array(int len) { if (len > 0) this.a = new int[len]; else this.a = new int[1]; } public boolean add(int i){ if(this.foot<this.a.length){ this.a[foo

一个简单网络服务器类的实现

网络服务器,顾名思义是一个可以接受连接的host,我们要实现的网络服务器类是一个 1.能够实现多个连接 2.仅仅通过继承或实现网络服务器类(或接口)的处理就能实现不同的连接功能 3.当服务器关闭时,已有建立的私有连接不被中断,但服务器不在接受新的连接 针对以上功能我们分解一下要实现的模块: 1.多线程实现多个连接,当serverSocket accept到一个连接请求时,开启一个独立的线程 2.实现这个,要求上面新建线程能被网络服务器锁管理 3.服务器不接受其他连接,可以用线程中断做,私有连接能

一个简单的c++类的定义和实例化

#include "iostream" #include <string> using namespace std; class mycoach { private: string name; short age = 0; public: void coachgreeting(string _name, int _age) { name = _name; age = _age; cout << "大家好,我是" << name &

7.qfilesystemmodel rowcount 为什么为0? 一个简单的model类的例子

任务: 1.新建一个空的mainwindow项目 2.debug下编译得到一个文件夹,应用程序输出这个文件夹中的文件(不显示文件夹中的文件夹) 3.使用QFileSystemModel完成. 本例显示结果: Makefile Makefile.Debug Makefile.Release ui_mainwindow (debug和release是文件夹,不在应用程序输出中) mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #inclu

C++一个简单的手柄类模板

#ifndef HANDLE_H #define HANDLE_H #include "Animal.h" template <typename T> class Handle{ public: Handle(T *ptr); Handle(const Handle &other); Handle &operator = (const Handle &other); ~Handle(); T *operator->(); private: T

C++的一个简单的句柄类模板

#ifndef HANDLE_H #define HANDLE_H #include "Animal.h" template <typename T> class Handle{ public: Handle(T *ptr); Handle(const Handle &other); Handle &operator = (const Handle &other); ~Handle(); T *operator->(); private: T