asp.net c# 异步日志通用类(3)
2017-08-19 14:05
381 查看
通过测试,发现验证是否要保存日志验证很慢,我试了好多种方法验证都还是不理想,所以把删除了,只能按需调用方法就行 了,示例代码如下:
/*********************************************
* 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";
/// <summary>
/// 委托
/// </summary>
/// <p
c105
aram name="msg">信息</param>
/// <param name="fileName">文件名</param>
/// <param name="parms">其他的参数</param>
delegate void LogException(string msg, string fileName, params object[] parms);
#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");
new LogException(AddQueue).BeginInvoke(strMsg.ToString(), "Error", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 调试日志
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Debug(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Debug", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 调试日志
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Info(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Info", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 警告
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Warn(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Warn", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 错误
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Error(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Error", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 致命错误
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Fatal(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Fatal", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 异步回调
/// </summary>
/// <param name="result">异步调用</param>
static void CallBack(IAsyncResult result)
{
var handler = ((AsyncResult)result).AsyncDelegate as LogException;
if (handler != null)
{
handler.EndInvoke(result);
}
}
#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();
快是快多了,但是要是按需写入日志就没有办法实现了,有时间在研究一下,怎么验证效率才会更高
/*********************************************
* 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";
/// <summary>
/// 委托
/// </summary>
/// <p
c105
aram name="msg">信息</param>
/// <param name="fileName">文件名</param>
/// <param name="parms">其他的参数</param>
delegate void LogException(string msg, string fileName, params object[] parms);
#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");
new LogException(AddQueue).BeginInvoke(strMsg.ToString(), "Error", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 调试日志
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Debug(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Debug", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 调试日志
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Info(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Info", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 警告
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Warn(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Warn", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 错误
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Error(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Error", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 致命错误
/// </summary>
/// <param name="msg">信息</param>
/// <param name="parms">其他的参数</param>
public void Fatal(string msg, params object[] parms)
{
new LogException(AddQueue).BeginInvoke(msg, "Fatal", parms, new AsyncCallback(CallBack), null);
}
/// <summary>
/// 异步回调
/// </summary>
/// <param name="result">异步调用</param>
static void CallBack(IAsyncResult result)
{
var handler = ((AsyncResult)result).AsyncDelegate as LogException;
if (handler != null)
{
handler.EndInvoke(result);
}
}
#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();
快是快多了,但是要是按需写入日志就没有办法实现了,有时间在研究一下,怎么验证效率才会更高
相关文章推荐
- asp.net c# 异步日志通用类(4)
- asp.net c# 异步日志通用类(1)
- asp.net c# 异步日志通用类(2)
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
- Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库 自定义日志记录功能,按日记录,很方便 C#常量和字段以及各种方法的语法总结 类型,对象,线程栈,托管堆在运行时的关系,以及clr如何调用静态方法,实例方法,和虚方法 asp.net webapi 自定义身份验证
- 有简易通用权限管理后台的快速C# ASP.NET开发的例子应用程序卖给了曾长期开发JAVA银行程序的大哥
- 回答网友的问题,有C# ASP.NET 通用权权限系统源码下载收费
- 【商业版】C# ASP.NET 通用权限管理系统组件源码中的数据库访问组件可以全面支持Access单机数据库了
- 【商业版】C# ASP.NET 通用权限管理系统组件源码中的数据库访问组件可以全面支持Access单机数据库了
- 【商业版】C# ASP.NET 通用权限管理系统组件源码中的数据库访问组件可以全面支持Access单机数据库了
- C#ASP.NET 通用扩展函数之 LogicSugar 简单好用
- 回答网友的问题,有C# ASP.NET 通用权权限系统源码下载收费
- C# ASP.NET 最常用的通用权限的3个方法例子展示(每个功能一行代码实现)
- C#、ASP.NET通用扩展工具类之TypeParse
- C#写文本日志帮助类(支持多线程)改进版(不适用于ASP.NET程序)
- C# ASP.NET 通用权限管理系统组件源码中WCF例子程序客户端运行详细配置参考
- 感谢付费客户不覺流年似水(271558528) 对C#ASP.NET通用权限管理组件的改进意见,已修正
- C# ASP.NET 最常用的通用权限的3个方法例子展示(每个功能一行代码实现)
- C# ASP.NET走火入魔通用权限管理
- ASP.NET(C#)通用数据库类