可替代log4j日志的c#简单日志类队列实现类代码分享

代码如下:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

namespace LogisTrac
{
    /// <summary>
    /// 日志类
    /// 队列 可年/月/周/日/大小分割
    /// 调用方法:
    ///  Log.Instance.LogDirectory=@"C:\"; 默认为程序运行目录
    ///  Log.Instance.FileNamePrefix="cxd";默认为log_
    ///  Log.Instance.CurrentMsgType = MsgLevel.Debug;默认为Error
    ///  Log.Instance.logFileSplit = LogFileSplit.Daily; 日志拆分类型LogFileSplit.Sizely 大小
    ///  Log.Instance.MaxFileSize = 5; 默认大小为2M,只有LogFileSplit.Sizely的时候配置有效
    ///  Log.Instance.LogWrite("aa");
    ///  Log.Instance.LogWrite("aa", MsgLevel.Debug);
    /// </summary>
    public class Log : IDisposable
    {
        private static Log _instance = null;
        private static readonly object _synObject = new object();

/// <summary>
        ///单例
        /// </summary>
        public static Log Instance
        {
            get
            {
                if (null == _instance)
                {
                    lock (_synObject)
                    {
                        if (null == _instance)
                        {
                            _instance = new Log();
                        }
                    }
                }
                return _instance;
            }
        }

/// <summary>
        /// 日志对象的缓存队列
        /// </summary>
        private static Queue<Msg> _msgs;

/// <summary>
        /// 日志写入线程的控制标记  ture写中|false没有写
        /// </summary>
        private  bool _state;

private  string _logDirectory = AppDomain.CurrentDomain.BaseDirectory;

/// <summary>
        /// 日志文件存放目录
        /// </summary>
        public  string LogDirectory
        {
            get { return _logDirectory; }
            set { _logDirectory = value; }
        }

private  LogFileSplit _logFileSplit = LogFileSplit.Sizely;
        /// <summary>
        /// 日志拆分类型
        /// </summary>
        public  LogFileSplit logFileSplit
        {
            get { return _logFileSplit; }
            set { _logFileSplit = value; }
        }

private MsgLevel _currentLogLevel = MsgLevel.Error;

/// <summary>
        /// 当前日志记录等级
        /// </summary>
        public MsgLevel CurrentMsgType
        {
            get { return _currentLogLevel; }
            set { _currentLogLevel = value; }
        }

/// <summary>
        /// 当前负责记录日志文件的名称
        /// </summary>
        private  string _currentFileName="1.log";

private  string _fileNamePrefix = "log_";

/// <summary>
        /// 日志的前缀名称,默认为log_
        /// </summary>
        public string FileNamePrefix
        {
            get { return _fileNamePrefix; }
            set { _fileNamePrefix = value; }
        }

/// <summary>
        /// 日志文件生命周期的时间标记
        /// </summary>
        private  DateTime _CurrentFileTimeSign = new DateTime();

private  int _maxFileSize = 2;

/// <summary>
        /// 单个日志文件默认大小(单位:兆)
        /// </summary>
        public  int MaxFileSize
        {
            get { return _maxFileSize; }
            set { _maxFileSize = value; }
        }

/// <summary>
        /// 文件后缀号
        /// </summary>
        private  int _fileSymbol = 0;

/// <summary>
        /// 当前文件大小(单位:B)
        /// </summary>
        private  long _fileSize = 0;

/// <summary>
        /// 日志文件写入流对象
        /// </summary>
        private StreamWriter _writer;

/// <summary>
        /// 创建日志对象的新实例,根据指定的日志文件路径和指定的日志文件创建类型
        /// </summary>
        private Log()
        {
            if (_msgs == null)
            {
                GetCurrentFilename();
                _state = true;
                _msgs = new Queue<Msg>();
                Thread thread = new Thread(work);
                thread.Start();
            }
        }

//日志文件写入线程执行的方法
        private void work()
        {
            while (true)
            {
                //判断队列中是否存在待写入的日志
                if (_msgs.Count > 0)
                {
                    Msg msg = null;
                    lock (_msgs)
                    {
                        msg = _msgs.Dequeue();

if (msg != null)
                        {
                            FileWrite(msg);
                        }
                    }
                }
                else
                {
                    //判断是否已经发出终止日志并关闭的消息
                    if (_state)
                    {
                        Thread.Sleep(1);
                    }
                    else
                    {
                        FileClose();
                    }
                }
            }
        }

/// <summary>
        /// 根据日志类型获取日志文件名,并同时创建文件到期的时间标记
        /// 通过判断文件的到期时间标记将决定是否创建新文件。
        /// </summary>
        /// <returns></returns>
        private
            void  GetCurrentFilename()
        {
            DateTime now = DateTime.Now;
            string format = "";
            switch (_logFileSplit)
            {
                case LogFileSplit.Daily:
                    _CurrentFileTimeSign = new DateTime(now.Year, now.Month, now.Day);
                    _CurrentFileTimeSign = _CurrentFileTimeSign.AddDays(1);
                    format = now.ToString("yyyyMMdd'.log'");
                    break;
                case LogFileSplit.Weekly:
                    _CurrentFileTimeSign = new DateTime(now.Year, now.Month, now.Day);
                    _CurrentFileTimeSign = _CurrentFileTimeSign.AddDays(7);
                    format = now.ToString("yyyyMMdd'.log'");
                    break;
                case LogFileSplit.Monthly:
                    _CurrentFileTimeSign = new DateTime(now.Year, now.Month, 1);
                    _CurrentFileTimeSign = _CurrentFileTimeSign.AddMonths(1);
                    format = now.ToString("yyyyMM'.log'");
                    break;
                case LogFileSplit.Annually:
                    _CurrentFileTimeSign = new DateTime(now.Year, 1, 1);
                    _CurrentFileTimeSign = _CurrentFileTimeSign.AddYears(1);
                    format = now.ToString("yyyy'.log'");
                    break;
                default:
                    _fileSymbol++;
                    format = _fileSymbol.ToString() + ".log";
                    break;
            }
            if (File.Exists(Path.Combine(LogDirectory, _currentFileName)))
            {
                _fileSize = new FileInfo(Path.Combine(LogDirectory, _currentFileName)).Length;
            }
            else
            {
                _fileSize = 0;
            }
            _currentFileName=_fileNamePrefix + format.Trim();
        }

//写入日志文本到文件的方法
        private void FileWrite(Msg msg)
        {
            try
            {
                if (_writer == null)
                {
                    FileOpen();

}

if (_writer != null)
                {
                    //判断文件到期标志,如果当前文件到期则关闭当前文件创建新的日志文件
                    if ((_logFileSplit != LogFileSplit.Sizely && DateTime.Now >= _CurrentFileTimeSign)||
                        (_logFileSplit == LogFileSplit.Sizely && ((double)_fileSize / 1048576) > _maxFileSize))
                    {
                        GetCurrentFilename();
                        FileClose();
                        FileOpen();
                    }
                    _writer.Write(msg.datetime);
                    _writer.Write('\t');
                    _writer.Write(msg.type);
                    _writer.Write('\t');
                    _writer.WriteLine(msg.text);                   
                    _fileSize+=System.Text.Encoding.UTF8.GetBytes(msg.ToString()).Length;  
                    _writer.Flush();
                }
            }
            catch (Exception e)
            {
                Console.Out.Write(e);
            }
        }

//打开文件准备写入
        private void FileOpen()
        {
            _writer = new StreamWriter(LogDirectory + _currentFileName, true, Encoding.UTF8);
        }

//关闭打开的日志文件
        private void FileClose()
        {
            if (_writer != null)
            {
                _writer.Flush();
                _writer.Close();
                _writer.Dispose();
                _writer = null;
            }
        }

/// <summary>
        /// 写入新日志,根据指定的日志对象Msg
        /// </summary>
        /// <param name="msg">日志内容对象</param>
        private void LogWrite(Msg msg)
        {
            if (msg.type < CurrentMsgType)
                return;
            if (_msgs != null)
            {
                lock (_msgs)
                {
                    _msgs.Enqueue(msg);
                }
            }
        }

/// <summary>
        /// 写入新日志,根据指定的日志内容和信息类型,采用当前时间为日志时间写入新日志
        /// </summary>
        /// <param name="text">日志内容</param>
        /// <param name="type">信息类型</param>
        public void LogWrite(string text, MsgLevel type)
        {
            LogWrite(new Msg(text, type));
        }

/// <summary>
        /// 写入新日志,根据指定的日志内容
        /// </summary>
        /// <param name="text">日志内容</param>
        public void LogWrite(string text)
        {
            LogWrite(text, MsgLevel.Debug);
        }

/// <summary>
        /// 写入新日志,根据指定的日志时间、日志内容和信息类型写入新日志
        /// </summary>
        /// <param name="dt">日志时间</param>
        /// <param name="text">日志内容</param>
        /// <param name="type">信息类型</param>
        public void LogWrite(DateTime dt, string text, MsgLevel type)
        {
            LogWrite(new Msg(dt, text, type));
        }

/// <summary>
        /// 写入新日志,根据指定的异常类和信息类型写入新日志
        /// </summary>
        /// <param name="e">异常对象</param>
        /// <param name="type">信息类型</param>
        public void LogWrite(Exception e)
        {
            LogWrite(new Msg(e.Message, MsgLevel.Error));
        }

/// <summary>
        /// 销毁日志对象
        /// </summary>
        public void Dispose()
        {
            _state = false;
        }
    }

/// <summary>
    /// 一个日志记录的对象
    /// </summary>
    public class Msg
    {

/// <summary>
        /// 创建新的日志记录实例;日志记录的内容为空,消息类型为MsgType.Unknown,日志时间为当前时间
        /// </summary>
        public Msg()
            : this("", MsgLevel.Debug)
        {
        }

/// <summary>
        /// 创建新的日志记录实例;日志事件为当前时间
        /// </summary>
        /// <param name="t">日志记录的文本内容</param>
        /// <param name="p">日志记录的消息类型</param>
        public Msg(string t, MsgLevel p)
            : this(DateTime.Now, t, p)
        {
        }

/// <summary>
        /// 创建新的日志记录实例;
        /// </summary>
        /// <param name="dt">日志记录的时间</param>
        /// <param name="t">日志记录的文本内容</param>
        /// <param name="p">日志记录的消息类型</param>
        public Msg(DateTime dt, string t, MsgLevel p)
        {
            datetime = dt;
            type = p;
            text = t;
        }

/// <summary>
        /// 日志记录的时间
        /// </summary>
        public DateTime datetime { get; set; }

/// <summary>
        ///日志记录的内容
        /// </summary>
        public string text { get; set; }

/// <summary>
        /// 日志等级
        /// </summary>
        public MsgLevel type { get; set; }

public new string ToString()
        {
            return datetime.ToString(CultureInfo.InvariantCulture) + "\t" + text + "\n";
        }
    }

/// <summary>
    /// 日志文件拆分的枚举
    /// </summary>
    /// <remarks>日志类型枚举指示日志文件创建的方式,如果日志比较多可考虑每天创建一个日志文件
    /// 如果日志量比较小可考虑每周、每月或每年创建一个日志文件</remarks>
    public enum LogFileSplit
    {
        /// <summary>
        /// 此枚举指示每天创建一个新的日志文件
        /// </summary>
        Daily,

/// <summary>
        /// 此枚举指示每周创建一个新的日志文件
        /// </summary>
        Weekly,

/// <summary>
        /// 此枚举指示每月创建一个新的日志文件
        /// </summary>
        Monthly,

/// <summary>
        /// 此枚举指示每年创建一个新的日志文件
        /// </summary>
        Annually,

/// <summary>
        /// 日志文件大小超过指定的创建一个新的日志文件,MaxFileSize指定大小
        /// </summary>
        Sizely
    }

/// <summary>
    /// 日志等级类型 Debug=0 Infor Warn Error
    /// </summary>
    public enum MsgLevel
    {
        /// <summary>
        /// 调试信息
        /// </summary>
        Debug = 0,

/// <summary>
        /// 指示普通信息类型的日志记录
        /// </summary>
        Infor,

/// <summary>
        /// 指示警告信息类型的日志记录
        /// </summary>
        Warn,

/// <summary>
        /// 指示错误信息类型的日志记录
        /// </summary>
        Error
    }

}

(0)

相关推荐

  • log4j详细的常用配置说明介绍

    很多屌丝都觉得log4j不好用,因为它不输出到IDE的控制台,哈哈,其实都是配置惹的祸,下面看我怎么一步步配置到控制台的,log4j的输出级别和输出模式相信屌丝们都知道的,这里不多说了,直接看代码注释: # All,TRACE,DEBUG,INFO,WARN,ERROR,FITAL,OFF #全局项目日志配置 log4j.rootLogger=ERROR #指定的包下所有的日志(只输出项目com包下的日志) log4j.logger.com=DEBUG,yin,dailly_rolling_fi

  • Java log4j详细教程

    一:Log4j入门简介学习 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务器.NT的事件记录器.UNIX Syslog守护进程等:我们也可以控制每一条日志的输出格式:通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程.最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码. 此外,通过Log4j其他语言接口,您可以在C.C++..Net.PL/SQL程序中

  • 很详细的Log4j配置步骤

    1. 配置文件 Log4J配置文件的基本格式如下:  复制代码 代码如下: #配置根Logger log4j.rootLogger = [ level ] , appenderName1 , appenderName2 , - #配置日志信息输出目的地Appender log4j.appender.appenderName = fully.qualified.name.of.appender.class log4j.appender.appenderName.option1 = value1 -

  • log4j使用教程详解(怎么使用log4j2)

    1. 去官方下载log4j 2,导入jar包,基本上你只需要导入下面两个jar包就可以了(xx是乱七八糟的版本号): log4j-core-xx.jar log4j-api-xx.jar 2. 导入到你的项目中:这个就不说了. 3. 开始使用: 我们知道,要在某个类中使用log4j记录日志,只需要申明下面的成员变量(其实不一定要是成员变量,只是为了方便调用而已) 复制代码 代码如下: private static Logger logger = LogManager.getLogger(MyAp

  • log4j 详解异步日志的配置和测试

     log4j 详解异步日志的配置和测试 日志可以帮助我们分析故障原因,做些数据挖掘的工作.最简单的日志方法,就是自己写个写文件的方法,在需要打日志的时候调用下,但是这显然不可能在实际工程上用.还有个问题,就是频繁地打日志,会增加磁盘I/O,使得系统性能下降.这里用log4j这个库来部署一个含有日志管理的轻量级的系统,主要支持日志的异步写和等级分类的功能,完成最低限度的日志需求. 首先,我们建立一个Maven工程,并且在pom.xml文件里面引入log4j的依赖: <dependency> &l

  • log4j的配置文件详细解析

    1.Log4j的优点Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送地:我们也可以控制每一条日志的输出格式:通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程.最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码. log4j的好处在于:(1) 通过修改配置文件,就可以决定log信息的目的地--控制台.文件.GUI组件.甚至是套接口服务器.NT的事件记录器.UNIX Syslog守护进程等. (2) 通过修

  • 深入浅析java web log4j 配置及在web项目中配置Log4j的技巧

    在上篇文章给大家介绍了Java log4j详细教程,本文给大家介绍java web log4j配置及web项目中配置log4j的技巧.具体详情请看下文吧. 首先给大家提供log4j.jar下载:http://logging.apache.org/log4j/1.2/download.html 一.java web项目使用log4j 1.在web.xml文件中添加 <!-- 配置log4j --> <context-param> <param-name>webAppRoo

  • log4j的使用详细解析

    1 Log4j配置说明 1.1 配置文件Log4j可以通过java程序动态设置,该方式明显缺点是:如果需要修改日志输出级别等信息,则必须修改java文件,然后重新编译,很是麻烦: log4j也可以通过配置文件的方式进行设置,目前支持两种格式的配置文件: •xml文件•properties文件(推荐)下面是一个log4j配置文件的完整内容: 复制代码 代码如下: log4j.rootCategory=INFO, stdoutlog4j.rootLogger=info, stdout ### std

  • log4j 文件输出

    写一个动态生成Properties(log4j.properties加载到内存中的形式)的类,指定,可实现动态修改任何东西! ====================== 目录不可以创建,但是log文件是自动创建得呢 log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=C:\bea\user_projects\domain\log ============================== 你可

  • 使用Log4j为项目配置日志输出应用详解以及示例演示的实现分析

    Log4j组件构成  Log4j由三个重要的组件构成: 1.日志信息的优先级(Logger) 2.日志信息的输出目的地(Appender) 3.日志信息的输出格式(Layout). 概要: 日志信息的优先级从高到低有ERROR.WARN. INFO.DEBUG,分别用来指定这条日志信息的重要程度: 日志信息的输出目的地指定了日志将打印到控制台还是文件中: 而输出格式则控制了日志信息的显示内容. Log4j介绍 Log4j是 Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信

  • java自定义日志输出文件(log4j日志文件输出多个自定义日志文件)

    log4j输出多个自定义日志文件 如果在实际应用中需要输出独立的日志文件,怎样才能把所需的内容从原有日志中分离,形成单独的日志文件呢? 先看一个常见的log4j.properties文件,它是在控制台和test.log文件中记录日志: 复制代码 代码如下: log4j.rootLogger=DEBUG, stdout, logfile log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layo

随机推荐