支持异步写入的日志类,支持Framework2.0

因为工作需要需要在XP上运行一个C#编写的Winform插件,我就用Framework2.0,因为存在接口交互所以想保留交易过程的入参出参。

考虑到插件本身实施的因素,就没有使用Log4、NLog等成熟的日志插件。在网上搜索了一个是通过TextWriterTraceListener实现的,但是实际使用

过程中发现并没实现我想要的功能,于是乎自己重新造了个轮子,如果大家有需要可以参考下。

  1   /// <summary>
  2     /// 日志类型
  3     /// </summary>
  4     public enum LogType
  5     {
  6         Error,
  7         Trace,
  8         Info
  9     }
 10 
 11     /// <summary>
 12     /// 日志类
 13     /// 支持同步和异步
 14     /// </summary>
 15     public sealed class Logger
 16     {
 17 
 18         #region 变量|常量
 19 
 20         /// <summary>
 21         /// 用于Trace的组织输出的类别名称
 22         /// </summary>
 23         private const string error = "
***********************EXCEPTION {0}***********************";
 24 
 25         /// <summary>
 26         /// 跟踪
 27         /// </summary>
 28         private const string trace = "
*************************TRACE {0}*******************************";
 29 
 30         /// <summary>
 31         /// 信息
 32         /// </summary>
 33         private const string info = "
****************************INFO {0}********************************";
 34 
 35         /// <summary>
 36         /// 1   仅控制台输出
 37         /// 2   仅日志输出
 38         /// 3   控制台+日志输出
 39         /// </summary>
 40         private static readonly int flag = 2;         //可以修改成从配置文件读取
 41 
 42         #endregion
 43 
 44         #region 委托
 45 
 46         private delegate void AsyncLogException(Exception ex);
 47         private delegate void AyyncLog(string msg, LogType type);
 48         private delegate void AsyncLogSqlCommand(SqlCommand cmd);
 49         private delegate void AsyncLogSql(string sql, params SqlParameter[] parameter);
 50 
 51         private static void BeginError(Exception ex)
 52         {
 53             if (null != ex)
 54             {
 55                 string path = GetLogPath(LogType.Error);
 56                 //输出日志头
 57                 WriteLog(path, string.Format(error, DateTime.Now));
 58                 while (null != ex)
 59                 {
 60                     WriteLog(path, string.Format("{0} {1}
{2}
Source:{3}", ex.GetType().Name, ex.Message, ex.StackTrace, ex.Source));
 61                     ex = ex.InnerException;
 62                 }
 63             }
 64         }
 65 
 66         private static void BeginTrace(string msg, LogType type)
 67         {
 68             if (string.IsNullOrEmpty(msg)) return;
 69             string path = GetLogPath(type);
 70             //输出日志头
 71             WriteLog(path, string.Format(trace, DateTime.Now));
 72             //输出日志内容
 73             WriteLog(path, msg);
 74         }
 75         #endregion
 76 
 77         #region IO操作
 78         /// <summary>
 79         /// 获取日志类型对应的日志存储环境
 80         /// </summary>
 81         /// <param name="type">日志类型</param>
 82         /// <returns></returns>
 83         private static string GetLogPath(LogType type)
 84         {
 85             DateTime time = DateTime.Now;
 86             string subdir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
 87             subdir = Path.Combine(subdir, type.ToString());
 88             subdir = Path.Combine(subdir, time.ToString("yyyyMM"));
 89             if (!Directory.Exists(subdir))
 90             {
 91                 Directory.CreateDirectory(subdir);
 92             }
 93             string result = Path.Combine(subdir, time.ToString("yyyyMMdd") + ".log");
 94             return result;
 95         }
 96 
 97         /// <summary>
 98         /// 写入日志
 99         /// </summary>
100         /// <param name="path">日志环境</param>
101         /// <param name="text">写入的文本值</param>
102         private static void WriteLog(string path, string text)
103         {
104             string filePath = Path.GetDirectoryName(path);
105             if (Directory.Exists(filePath) == false)
106             {
107                 Directory.CreateDirectory(filePath);
108             }
109             if (File.Exists(path))
110             {
111                 using (StreamWriter sw = File.AppendText(path))
112                 {
113                     sw.WriteLine(text + "
");
114                     sw.Flush();
115                     sw.Close();
116                 }
117             }
118             else
119             {
120                 StreamWriter sr = File.CreateText(path);
121                 sr.WriteLine(text + "
");
122                 sr.Flush();
123                 sr.Close();
124             }
125         }
126         #endregion
127 
128         #region 发布的方法
129         /// <summary>
130         /// 写入异常日志
131         /// </summary>
132         /// <param name="ex">异常对象</param>
133         /// <param name="isAsync">是否异步,默认异步</param>
134         public static void Error(Exception ex, bool isAsync = true)
135         {
136             if (isAsync)
137                 new AsyncLogException(BeginError).BeginInvoke(ex, null, null);
138             else
139                 BeginError(ex);
140         }
141 
142         /// <summary>
143         /// 写入错误日志
144         /// </summary>
145         /// <param name="msg">错误信息</param>
146         /// <param name="isAsync">是否异步,默认异步</param>
147         public static void Error(string msg, bool isAsync = false)
148         {
149             if (isAsync)
150                 new AyyncLog(BeginTrace).BeginInvoke(msg, LogType.Error, null, null);
151             else
152                 BeginTrace(msg, LogType.Error);
153         }
154 
155         /// <summary>
156         /// 异步跟踪日志
157         /// </summary>
158         /// <param name="msg"></param>
159         public static void Trace(string msg, bool isAsync = true)
160         {
161             if (isAsync)
162                 new AyyncLog(BeginTrace).BeginInvoke(msg, LogType.Trace, null, null);
163             else
164                 BeginTrace(msg, LogType.Trace);
165         }
166 
167 
168         /// <summary>
169         /// 写入日志信息,日志类型为info
170         /// </summary>
171         /// <param name="msg">日志信息</param>
172         /// <param name="isAsync">是否异步,默认异步</param>
173         public static void Info(string msg, bool isAsync = true)
174         {
175             if (isAsync)
176                 new AyyncLog(BeginTrace).BeginInvoke(msg, LogType.Info, null, null);
177             else
178                 BeginTrace(msg, LogType.Info);
179         }
180         #endregion
181 
182     }
183 }
View Code

调用代码:

private void button1_Click_1(object sender, EventArgs e)
{
     Logger.Info("测试"); 
}

运行效果如下:

原文地址:https://www.cnblogs.com/hunanzp/p/7815197.html