asp.net c# 异步日志通用类(4)
来源:互联网 发布:python 单核可以子进程 编辑:程序博客网 时间:2024/06/10 16:45
在之前的日志调用中用到了委托实现,现在把委托去掉,效率又有一定的提高了,说的不好听从高大上(委托)到原始的调用,代码如下:
/********************************************* * 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();
阅读全文
0 0
- asp.net c# 异步日志通用类(4)
- asp.net c# 异步日志通用类(1)
- asp.net c# 异步日志通用类(2)
- asp.net c# 异步日志通用类(3)
- c# asp.net winform 调用存储过程的通用类
- asp.net c# 中的队列queue通用类
- C#通用类实现 读取xml控制Asp.net控件输入信息长度(TextBox,FileUpload)
- C#通用类实现 读取xml控制Asp.net控件输入信息长度(TextBox,FileUpload)
- c#异步编程(三)—ASP.NET MVC 异步控制器及EF异步操作
- c#异步编程(三)—ASP.NET MVC 异步控制器及EF异步操作
- C# 简易异步日志类
- Asp.Net cookies 通用类
- asp.net gridview通用类
- asp.net抓取通用类
- Asp.net通用缓存类
- .NET通用数据库访问组件,日志组件,C#相关工具
- asp.net生成高质量缩略图通用函数(c#代码)
- ASP.NET生成高质量缩略图通用函数(c#代码)
- 仿SDCycleScrollView(Swift版本)
- 应避免的11个最常见的设计误区(下)
- 51nod 1432 独木舟
- ccf认证路径解析90分运行错误
- MyBatis
- asp.net c# 异步日志通用类(4)
- 设计教育面临的最大问题
- 产品设计14招,招招有用(上)
- Java关键字final、static使用总结
- 【ftp】ftp服务器无法登录的解决办法
- Js中的window.parent ,window.top,window.self 详解
- 51NOD 1284 2 3 5 7的倍数
- 什么时候不能使用箭头函数
- wordpress如何简单的隐藏后台位置?