首页 > 学院 > 开发设计 > 正文

[C#]简易日志记录,线程安全

2019-11-14 16:31:58
字体:
来源:转载
供稿:网友

在实际项目开发中,会涉及日志记录问题,比较常用的有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();            }        }    }}

代码效果:

image

才疏学浅,如有纰漏,敬请指出,希望有所帮助!谢谢 大笑


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表