C#实现线程安全的简易日志记录方法

作者:shichen2014 时间:2023-12-20 22:45:17 

一般在实际项目的开发中,会要求涉及日志记录的问题,比较常用的有Log4Net,NLog等几个,而小项目小工具的话,则无需费此大驾。而譬如串口开发的话,需要记录串口过来的数据等等,这时候就要考虑日志记录上线程的问题。对此,为了方便后续使用,封装了下代码:


using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;

namespace CSharpUtilHelpV2
{
 /// <summary>
 /// 日志类型枚举
 /// </summary>
 public enum LogType
 {
   /// <summary>
   /// 一般输出
   /// </summary>
   Trace,
   /// <summary>
   /// 警告
   /// </summary>
   Warning,
   /// <summary>
   /// 错误
   /// </summary>
   Error,
   /// <summary>
   /// SQL
   /// </summary>
   SQL
 }
 /// <summary>
 /// 基于.NET 2.0日志工具类
 /// </summary>
 public class LogToolV2
 {
   private static readonly Thread LogTask;
   private static readonly ThreadSafeQueueV2<string> LogColQueue;//自定义线程安全的Queue
   private static readonly object SyncRoot;
   private static readonly string FilePath;
   private static readonly long BackFileSize_MB = 2;//超过2M就开始备份日志文件
   static LogToolV2()
   {
     SyncRoot = new object();
     FilePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "Log\\";
     LogTask = new Thread(WriteLog);
     LogColQueue = new ThreadSafeQueueV2<string>();
     LogTask.Start();
     Debug.WriteLine("Log Start......");
   }
   /// <summary>
   /// 记录日志
   /// </summary>
   /// <param name="msg">日志内容</param>
   public static void Log(string msg)
   {
     string _msg = string.Format("{0} : {2}", DateTime.Now.ToString("HH:mm:ss"), msg);
     LogColQueue.Enqueue(msg);
   }
   /// <summary>
   /// 记录日志
   /// </summary>
   /// <param name="msg">日志内容</param>
   /// <param name="type">日志类型</param>
   public static void Log(string msg, LogType type)
   {
     string _msg = string.Format("{0} {1}: {2}", DateTime.Now.ToString("HH:mm:ss"), type, msg);
     LogColQueue.Enqueue(_msg);
   }
   /// <summary>
   /// 记录日志
   /// </summary>
   /// <param name="ex">异常</param>
   public static void Log(Exception ex)
   {
     if (ex != null)
     {
       string _newLine = Environment.NewLine;
       StringBuilder _builder = new StringBuilder();
       _builder.AppendFormat("{0}: {1}{2}", DateTime.Now.ToString("HH:mm:ss"), ex.Message, _newLine);
       _builder.AppendFormat("{0}{1}", ex.GetType(), _newLine);
       _builder.AppendFormat("{0}{1}", ex.Source, _newLine);
       _builder.AppendFormat("{0}{1}", ex.TargetSite, _newLine);
       _builder.AppendFormat("{0}{1}", ex.StackTrace, _newLine);
       LogColQueue.Enqueue(_builder.ToString());
     }
   }
   private static void WriteLog()
   {
     while (true)
     {
       if (LogColQueue.Count() > 0)
       {
         string _msg = LogColQueue.Dequeue();
         Monitor.Enter(SyncRoot);
         if (!CreateDirectory()) continue;
         string _path = string.Format("{0}{1}.log", FilePath, DateTime.Now.ToString("yyyyMMdd"));
         Monitor.Exit(SyncRoot);
         lock (SyncRoot)
         {
           if (CreateFile(_path))
             ProcessWriteLog(_path, _msg);//写入日志到文本
         }
         ProcessBackLog(_path);//日志备份
       }
     }
   }
   private static void ProcessBackLog(string path)
   {
     lock (SyncRoot)
     {
       if (FileToolV2.GetMBSize(path) > BackFileSize_MB)
       {
         FileToolV2.CopyToBak(path);
       }
     }
   }
   private static void ProcessWriteLog(string path, string msg)
   {
     try
     {
       StreamWriter _sw = File.AppendText(path);
       _sw.WriteLine(msg);
       _sw.Flush();
       _sw.Close();
     }
     catch (Exception ex)
     {
       Debug.WriteLine(string.Format("写入日志失败,原因:{0}", ex.Message));
     }
   }
   private static bool CreateFile(string path)
   {
     bool _result = true;
     try
     {
       if (!File.Exists(path))
       {
         FileStream _files = File.Create(path);
         _files.Close();
       }
     }
     catch (Exception)
     {
       _result = false;
     }
     return _result;
   }
   private static bool CreateDirectory()
   {
     bool _result = true;
     try
     {
       if (!Directory.Exists(FilePath))
       {
         Directory.CreateDirectory(FilePath);
       }
     }
     catch (Exception)
     {
       _result = false;
     }
     return _result;
   }

}
}

测试代码如下:


using CSharpUtilHelpV2;
using System;
using System.Diagnostics;
using System.Threading;

namespace LogUtilHelpV2Test
{
 class Program
 {
   static void Main(string[] args)
   {
     try
     {
       Debug.WriteLine("-------------");
       Action _writeLog = delegate()
       {
         for (int i = 0; i < 10000; i++)
           LogToolV2.Log(Guid.NewGuid().ToString(), LogType.Trace);
       };
       Thread _wireteLogTask1 = new Thread(new ThreadStart(_writeLog));
       _wireteLogTask1.Start();

Thread _wireteLogTask2 = new Thread(new ThreadStart(_writeLog));
       _wireteLogTask2.Start();

//throw new Exception("test  aaa bb cc");
     }
     catch (Exception ex)
     {
       LogToolV2.Log(ex);
       Console.WriteLine(ex.Message.Trim());
     }
     finally
     {
       Console.WriteLine("ok");
       Console.ReadLine();
     }
   }
 }
}

代码运行效果如下所示:

C#实现线程安全的简易日志记录方法

感兴趣的读者可以自己测试运行一下,希望能对大家起到一点帮助!

标签:C#,线程,安全,日志,记录,方法
0
投稿

猜你喜欢

  • springcloud整合openfeign使用实例详解

    2022-10-05 08:51:52
  • maven报错:Failed to execute goal on project问题及解决

    2021-09-30 09:58:36
  • SpringBoot整合WebSocket实现聊天室流程全解

    2021-07-03 23:35:21
  • C#数组初始化简析

    2022-01-02 11:55:12
  • MybatisPlus使用@TableId主键id自增长无效的解决

    2023-01-30 15:59:41
  • SpringMVC中转发与重定向的区别浅析

    2023-10-15 23:13:36
  • Android Apk反编译及加密教程

    2022-01-13 01:01:25
  • C#实现简单记事本程序

    2022-07-20 23:52:37
  • C#提取PPT文本和图片的实现方法

    2022-10-28 08:02:59
  • spring mvc利用ajax向controller传递对象的方法示例

    2022-10-22 15:06:13
  • 详解Android中Drawable方法

    2021-06-12 12:40:05
  • Maven的使用之继承与聚合

    2023-08-14 21:47:14
  • SpringCloud Alibaba 基本开发框架搭建过程

    2023-04-21 03:23:43
  • 一篇文章带你深入了解Java线程池

    2021-11-22 21:59:42
  • 如何用C#实现SAGA分布式事务

    2022-11-29 20:34:49
  • 如何把JAR发布到maven中央仓库的几种方法

    2022-11-08 11:07:06
  • Java基础之练习打印三角形

    2023-08-25 05:39:33
  • 如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    2023-02-12 21:25:59
  • C#中fixed关键字的作用总结

    2023-07-17 09:43:44
  • 如何使用Java爬虫批量爬取图片

    2023-01-11 16:19:54
  • asp之家 软件编程 m.aspxhome.com