支持异步写入的日志类,支持Framework2.0
因为工作需要需要在XP上运行一个C#编写的Winform插件,我就用Framework2.0,因为存在接口交互所以想保留交易过程的入参出参。
考虑到插件本身实施的因素,就没有使用Log4、NLog等成熟的日志插件。在网上搜索了一个是通过TextWriterTraceListener实现的,但是实际使用
过程中发现并没实现我想要的功能,于是乎自己重新造了个轮子,如果大家有需要可以参考下。
/// <summary>
/// 日志类型
/// </summary>
public enum LogType
{
Error,
Trace,
Info
} /// <summary>
/// 日志类
/// 支持同步和异步
/// </summary>
public sealed class Logger
{ #region 变量|常量 /// <summary>
/// 用于Trace的组织输出的类别名称
/// </summary>
private const string error = "\r\n***********************EXCEPTION {0}***********************"; /// <summary>
/// 跟踪
/// </summary>
private const string trace = "\r\n*************************TRACE {0}*******************************"; /// <summary>
/// 信息
/// </summary>
private const string info = "\r\n****************************INFO {0}********************************"; /// <summary>
/// 1 仅控制台输出
/// 2 仅日志输出
/// 3 控制台+日志输出
/// </summary>
private static readonly int flag = ; //可以修改成从配置文件读取 #endregion #region 委托 private delegate void AsyncLogException(Exception ex);
private delegate void AyyncLog(string msg, LogType type);
private delegate void AsyncLogSqlCommand(SqlCommand cmd);
private delegate void AsyncLogSql(string sql, params SqlParameter[] parameter); private static void BeginError(Exception ex)
{
if (null != ex)
{
string path = GetLogPath(LogType.Error);
//输出日志头
WriteLog(path, string.Format(error, DateTime.Now));
while (null != ex)
{
WriteLog(path, string.Format("{0} {1}\r\n{2}\r\nSource:{3}", ex.GetType().Name, ex.Message, ex.StackTrace, ex.Source));
ex = ex.InnerException;
}
}
} private static void BeginTrace(string msg, LogType type)
{
if (string.IsNullOrEmpty(msg)) return;
string path = GetLogPath(type);
//输出日志头
WriteLog(path, string.Format(trace, DateTime.Now));
//输出日志内容
WriteLog(path, msg);
}
#endregion #region IO操作
/// <summary>
/// 获取日志类型对应的日志存储环境
/// </summary>
/// <param name="type">日志类型</param>
/// <returns></returns>
private static string GetLogPath(LogType type)
{
DateTime time = DateTime.Now;
string subdir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
subdir = Path.Combine(subdir, type.ToString());
subdir = Path.Combine(subdir, time.ToString("yyyyMM"));
if (!Directory.Exists(subdir))
{
Directory.CreateDirectory(subdir);
}
string result = Path.Combine(subdir, time.ToString("yyyyMMdd") + ".log");
return result;
} /// <summary>
/// 写入日志
/// </summary>
/// <param name="path">日志环境</param>
/// <param name="text">写入的文本值</param>
private static void WriteLog(string path, string text)
{
string filePath = Path.GetDirectoryName(path);
if (Directory.Exists(filePath) == false)
{
Directory.CreateDirectory(filePath);
}
if (File.Exists(path))
{
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(text + "\n");
sw.Flush();
sw.Close();
}
}
else
{
StreamWriter sr = File.CreateText(path);
sr.WriteLine(text + "\n");
sr.Flush();
sr.Close();
}
}
#endregion #region 发布的方法
/// <summary>
/// 写入异常日志
/// </summary>
/// <param name="ex">异常对象</param>
/// <param name="isAsync">是否异步,默认异步</param>
public static void Error(Exception ex, bool isAsync = true)
{
if (isAsync)
new AsyncLogException(BeginError).BeginInvoke(ex, null, null);
else
BeginError(ex);
} /// <summary>
/// 写入错误日志
/// </summary>
/// <param name="msg">错误信息</param>
/// <param name="isAsync">是否异步,默认异步</param>
public static void Error(string msg, bool isAsync = false)
{
if (isAsync)
new AyyncLog(BeginTrace).BeginInvoke(msg, LogType.Error, null, null);
else
BeginTrace(msg, LogType.Error);
} /// <summary>
/// 异步跟踪日志
/// </summary>
/// <param name="msg"></param>
public static void Trace(string msg, bool isAsync = true)
{
if (isAsync)
new AyyncLog(BeginTrace).BeginInvoke(msg, LogType.Trace, null, null);
else
BeginTrace(msg, LogType.Trace);
} /// <summary>
/// 写入日志信息,日志类型为info
/// </summary>
/// <param name="msg">日志信息</param>
/// <param name="isAsync">是否异步,默认异步</param>
public static void Info(string msg, bool isAsync = true)
{
if (isAsync)
new AyyncLog(BeginTrace).BeginInvoke(msg, LogType.Info, null, null);
else
BeginTrace(msg, LogType.Info);
}
#endregion }
}
调用代码:
private void button1_Click_1(object sender, EventArgs e)
{
Logger.Info("测试");
}
运行效果如下:

支持异步写入的日志类,支持Framework2.0的更多相关文章
- C#写文本日志帮助类(支持多线程)
代码: using System; using System.Configuration; using System.IO; using System.Threading.Tasks; namespa ...
- python日志,支持彩色打印和文件大小切片写入和写入mongodb
1.项目中使用了自定义的ColorHandler和MongoHandler,使用了内置的RotatingFileHandler和三方库的ConcurrentRotatingFileHandler. 支 ...
- Android开发调试日志工具类[支持保存到SD卡]
直接上代码: package com.example.callstatus; import java.io.File; import java.io.FileWriter; import java.i ...
- C#写文本日志帮助类(支持多线程)改进版(不适用于ASP.NET程序)
由于iis的自动回收机制,不适用于ASP.NET程序 代码: using System; using System.Collections.Concurrent; using System.Confi ...
- BAE3.0还不支持本地写入文件
BAE3.0对比2.0做了很大的改动,对于安装应用方面也方便了很多,普通的应用表面上(下文就是讲为什么说表面上)不需要做什么适配.比如wp博客,直接修改wp-config.php,把数据库信息填一下就 ...
- TNetHttpClient支持异步访问(Delphi 10.1 Berlin,红鱼儿的博客)
Delphi 10.1进一步改进自Delphi 10带来的Http访问控件TNetHttpClient,支持异步访问,同时增加ConnectionTimeout及ResponseTimeout两个超时 ...
- 支持异步同步的分布式CommandBus MSMQ实现
支持异步同步的分布式CommandBus MSMQ实现 先上一张本文所描述的适用场景图 分布式场景,共3台server: 前端Server Order App Server Warehouse App ...
- LogStation 支持浏览器实时查看日志
我们在logback 分布式日志汇总中已经将日志输出到了all.logs,LogStation支持浏览器实时查看日志,适合研发和运维彼此独立的场景:研发没有服务器权限,却想看日志实时输出.再配合ngi ...
- Java - IO System类支持和缓冲流
System类的支持和缓冲流 System类对IO的支持 在System类中,为了支持IO操作提供了三个常量: 错误输出: public static final PrintStream err; 输 ...
随机推荐
- XP Sp3 开机就要激活,否则无法登录windows桌面
参考网页:https://www.reddit.com/r/sysadmin/comments/5m9240/activating_windows_xp_in_2017_still_possible/ ...
- 201771010126 王燕《面向对象程序设计(Java)》第十六周学习总结
实验十六 线程技术 实验时间 2017-12-8 1.实验目的与要求 (1) 掌握线程概念: ‐多线程 是进程执行过中产生的多条线索. 是进程执行过中产生的多条线索. 是进程执行过中产生的多条线索. ...
- Golang实现requests库
Golang实现requests库 简单的封装下,方便使用,像python的requests库一样. Github地址 Github 支持 GET.POST.PUT.DELETE applicatio ...
- Qt5和VS2017建立开发环境,安装后新建项目找不到Qt选项!!!
最近开发win驱动和Qt5测试程序,需要建立Qt5和VS2017开发环境---对于Qt5和VS2017安装这里不做多余叙述. 参考资源很多,讲解也不错!! 这里切入正题:在VS2017中安转Qt vs ...
- hive-issue-inserting-records-to-partitioned-table
hive-issue-inserting-records-to-partitioned-table Hi Sam, Recently we upgraded our cluster from HDP2 ...
- excel写入操作
字典列表类型数据写入excel. #导入xlwt库 import xlwt import os # 步骤1:获取excel文件的绝对路径 dirPath = os.path.join(os.getcw ...
- Python练手例子(9)
49.使用lambda来创建匿名函数. #python3.7 MAXIMUM = lambda x,y : (x > y) * x + (x < y) * y MINIMUM = lamb ...
- 关于using namespace std
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~关于using namespace std ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- grunt 插件
一个简单的 grunt 插件, 作用是 把 css 文件中的 /images/ 替换成指定的 url path, 以实现 图片 cdn 路劲改造 插件项目文件结构 grunt-contrib-s ...
- go 使用 c接口
在使用go语言时, 有时为了方便可以直接调用c语言的接口与库, 不需要重复编写. 那就来说说在go语言里面如何调用c的接口 首先编写好c语言的源文件与头文件,这里举一个简单的例子,实现一个字符串大小写 ...