asp.net c# 异步日志通用类(4)

版权声明:转载博主原创文章,请注明文章来源地址! https://blog.csdn.net/qq_38428623/article/details/77411673

在之前的日志调用中用到了委托实现,现在把委托去掉,效率又有一定的提高了,说的不好听从高大上(委托)到原始的调用,代码如下:

/*********************************************
 * CLR 版本:       4.0.30319.42000
 * 类 名 称:       Logger
 * 机器名称:       MS-20170310FLQY
 * 命名空间:       Utils
 * 文 件 名:       Logger
 * 创建时间:       2017/5/12 10:16:17
 * 作    者:       Choj
 * 说    明:     
 * 修改时间:
 * 修 改 人:
 * 
*********************************************/

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Utils
{
    /// <summary>
    /// 异步日志实现类
    /// </summary>
    public class Logger
    {
        #region 属性
        /// <summary>
        /// 实例化
        /// </summary>
        public static Logger Instance = new Logger();
        /// <summary>
        /// 日志保存的路径
        /// </summary>
        string LogPath = ConfigurationManager.AppSettings["LogPath"];
        /// <summary>
        /// 文件夹路径
        /// </summary>
        string LogDir = ConfigurationManager.AppSettings["LogDir"];
        /// <summary>
        /// 文件夹路径
        /// </summary>
        string LogDateFormat = ConfigurationManager.AppSettings["LogDateFormat"] ?? "yyyyMMddHH";
        #endregion

        #region 构造函数
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public Logger()
        { }

        /// <summary>
        /// 够着函数
        /// </summary>
        /// <param name="LogDir">日志的文件夹</param>
        public Logger(string LogDir)
        {
            this.LogDir = LogDir;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="path"></param>
        /// <param name="LogDir"></param>
        public Logger(string path, string LogDir)
        {
            this.LogPath = path;
            this.LogDir = LogDir;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="LogDir">日志路径</param>
        /// <param name="logDateFormat">文件格式</param>
        public Logger(string path, string logDir, string logDateFormat)
        {
            this.LogPath = path;
            this.LogDir = logDir;
            this.LogDateFormat = logDateFormat;
        }
        #endregion

        #region 错误日志记录
        /// <summary>
        /// 添加错误日志
        /// </summary>
        /// <param name="ex">错误的信息</param>
        /// <param name="parms">其他的参数</param>
        public void Error(Exception ex, params object[] parms)
        {
            var strMsg = new StringBuilder();
            strMsg.AppendFormat("\r\n");
            strMsg.AppendFormat("Message:{0}", ex.Message);
            strMsg.AppendFormat("\r\n");
            strMsg.AppendFormat("StackTrace:{0}", ex.StackTrace);
            strMsg.AppendFormat("\r\n");
            strMsg.AppendFormat("source:{0}", ex.Source);
            strMsg.AppendFormat("\r\n");
            strMsg.AppendFormat("InnerException:{0}", ex.InnerException);
            strMsg.AppendFormat("\r\n");

            AddQueue(strMsg.ToString(), "Error", parms);
        }

        /// <summary>
        /// 调试日志
        /// </summary>
        /// <param name="msg">信息</param>
        /// <param name="parms">其他的参数</param>
        public void Debug(string msg, params object[] parms)
        {
            AddQueue(msg, "Debug", parms);
        }

        /// <summary>
        /// 调试日志
        /// </summary>
        /// <param name="msg">信息</param>
        /// <param name="parms">其他的参数</param>
        public void Info(string msg, params object[] parms)
        {
            AddQueue(msg, "Info", parms);
        }

        /// <summary>
        /// 警告
        /// </summary>
        /// <param name="msg">信息</param>
        /// <param name="parms">其他的参数</param>
        public void Warn(string msg, params object[] parms)
        {
            AddQueue(msg, "Warn", parms);
        }

        /// <summary>
        /// 错误
        /// </summary>
        /// <param name="msg">信息</param>
        /// <param name="parms">其他的参数</param>
        public void Error(string msg, params object[] parms)
        {
            AddQueue(msg, "Error", parms);
        }

        /// <summary>
        /// 致命错误
        /// </summary>
        /// <param name="msg">信息</param>
        /// <param name="parms">其他的参数</param>
        public void Fatal(string msg, params object[] parms)
        {
            AddQueue(msg, "Fatal", parms);
        }
        #endregion

        #region 添加日志到队列
        /// <summary>
        /// 添加日志到队列
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="level"></param>
        /// <param name="parms"></param>
        private void AddQueue(string msg, string level, params object[] parms)
        {
            QueueHelper<LogEntity>.Instance.Enqueue(new LogEntity()
            {
                Level = level,
                Msg = msg,
                Parms = parms
            });
        }
        #endregion

        #region 保存日志信息
        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            ThreadPool.QueueUserWorkItem(o =>
            {
                while (true)
                {
                    var queue = QueueHelper<LogEntity>.Instance.Dequeue();

                    if (queue != null)
                    {
                        #region 基本的设置
                        var fileName = System.DateTime.Now.ToString(LogDateFormat) + ".log";
                        string path = LogPath;
                        if (string.IsNullOrEmpty(path))
                        {
                            path = System.AppDomain.CurrentDomain.BaseDirectory;
                        }
                        path = string.Format("{0}\\Log\\{1}\\{2}\\", path, queue.Level, LogDir);

                        while (path.Contains(@"\\"))
                        {
                            path = path.Replace(@"\\", @"\");
                        }
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }
                        string filePath = path + fileName;
                        #endregion

                        using (var sw = new StreamWriter(filePath, true))
                        {
                            var strMsg = new StringBuilder();
                            strMsg.AppendFormat(DateTime.Now.ToString());
                            strMsg.Append("\r\n");
                            strMsg.AppendFormat("{0}", queue.Msg);
                            if (queue.Parms != null)
                            {//--- 其他的参数 ---
                                foreach (var parm in queue.Parms)
                                {
                                    strMsg.Append("\r\n");
                                    strMsg.Append(parm);
                                }
                            }
                            strMsg.Append("\r\n");

                            sw.WriteLine(strMsg.ToString());
                        }
                    }
                }
            });
        }
        #endregion
    }
    /// <summary>
    /// 保存日志
    /// </summary>
    public class LogEntity
    {
        private string msg;
        /// <summary>
        /// 日志基本信息
        /// </summary>
        public string Msg
        {
            get { return msg; }
            set { msg = value; }
        }
        private string level;
        /// <summary>
        /// 日志等级
        /// </summary>
        public string Level
        {
            get { return level; }
            set { level = value; }
        }
        private object[] parms;
        /// <summary>
        /// 其他的参数
        /// </summary>
        public object[] Parms
        {
            get { return parms; }
            set { parms = value; }
        }
    }
}

测试代码:

Utils.Logger.Instance.Init();

            var sw = new Stopwatch();
            sw.Start();

            for (int i = 0; i < 10000; i++)
            {
                Utils.Logger.Instance.Debug("Logger测试");
            }

            sw.Stop();
            Console.WriteLine("Logger 日志循环10000次,总耗时:" + sw.ElapsedMilliseconds);

            sw = new Stopwatch();
            sw.Start();

            Parallel.For(0, 100, (i) =>
            {
                for (int j = 0; j < 100; j++)
                {
                    Utils.Logger.Instance.Debug("Logger测试");
                }
            });

            sw.Stop();
            Console.WriteLine("Logger 并行循环10000次,总耗时:" + sw.ElapsedMilliseconds);

            Console.ReadKey();

这个效率感觉应该还是可以了,但是优化的还有很多,但是思想基本就是这样了,日志的保存根据自己的需要可以自己添加对应的功能,比如保存到mongodb(nosql),或者关系数据库中


1000000的数据测试的代码和结果:

Utils.Logger.Instance.Init();

            var sw = new Stopwatch();
            sw.Start();

            for (int i = 0; i < 1000000; i++)
            {
                Utils.Logger.Instance.Debug("Logger测试");
            }

            sw.Stop();
            Console.WriteLine("Logger 日志循环1000000次,总耗时:" + sw.ElapsedMilliseconds);

            sw = new Stopwatch();
            sw.Start();

            Parallel.For(0, 100, (i) =>
            {
                for (int j = 0; j < 10000; j++)
                {
                    Utils.Logger.Instance.Debug("Logger测试");
                }
            });

            sw.Stop();
            Console.WriteLine("Logger 并行循环1000000次,总耗时:" + sw.ElapsedMilliseconds);

            Console.ReadKey();


猜你喜欢

转载自blog.csdn.net/qq_38428623/article/details/77411673