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

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

    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

测试代码:

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();
            }
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

代码效果:

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

[C#]简易日志记录,线程安全,布布扣,bubuko.com

时间: 2024-10-24 08:13:35

[C#]简易日志记录,线程安全的相关文章

网站访客 简易日志记录

摘要 header 查看header 模拟header php中的使用 IP接口 接口介绍 PHP访问接口并解析 简易方式 略繁方式 解析JSON数据 记录器 操作系统信息 获取浏览器信息 核心 最终效果 总结 摘要 百度站长统计,一个不错的工具.各种信息也能超级详细的被记录下来,可以从下图上略知一二.但是实际上其详细程度远远不止如此.百度统计支持一级域名,以及二级域名的绑定.所以很方便. 但也不是对于所有的服务器都支持,比如我没有给服务器绑定域名,所以自然就没法用了.但是如果我还想获得一些访客

日志记录.02_线程处理

为了在业务系统中方便记录日志,可以建立一个线程类,专用于记录日志 Type TCustomLogThread = class(TThread) 为了保证线程记录日志的有效性和安全性,在线程中可以添加一个临界区来进行保护,当高频记录日志时,可有效的保护日志记录安全 Var FCS:TRTLCriticalSection;     --WinApi.Windows.pas --创建 --释放 InitializeCriticalSection(FCS);              DeleteCri

巧用CurrentThread.Name来统一标识日志记录

先看下面的日志: 2017/5/21 18:00:01 [OrderQuery_180001914_C72FF]请求支付中心参数:{"order_no":"KB201705210000165","sign":"e6c3559cd4b36458b180f15bfcd9b5a5"} 2017/5/21 18:00:01 [OrderQuery_180001914_C72FF]支付中心验签通过. 2017/5/21 18:00:01

转:使用log4net完成程序异常日志记录(使用SQLite数据库记录和普通文本记录)

http://www.cnblogs.com/kyo-yo/archive/2010/06/11/use-log4net-to-log-exception.html 在前端时间开发的时候由于需要将异常保存到数据库中,所以就到网上搜了下专门的日志记录工具,一搜果然很多,比如:log4net,NLog,EntLib Logging等等,但是还是log4net名气最大,所以就下载下来试用了一番,果然很方便,其涵盖了所有常用的日志记录方式具体的可以看下表: AdoNetAppender 将日志记录到数据

Java学习-007-Log4J 日志记录配置文件详解及实例源代码

此文主要讲述在初学 Java 时,常用的 Log4J 日志记录配置文件详解及实例源代码整理.希望能对初学 Java 编程的亲们有所帮助.若有不足之处,敬请大神指正,不胜感激!源代码测试通过日期为:2015-1-30 13:54:02,请知悉. 所需的 jar 包下载链接为:http://yunpan.cn/cKE56sxqtQCfP  访问密码 63d8 有关 Log4J 日志文件中日志级别及文件配置的详细情况,在 Log4J 的配置文件(xml.properties)中有详细的介绍,敬请参阅!

巧用CurrentThread.Name来统一标识日志记录(完结篇)

上一篇文章<巧用CurrentThread.Name来统一标识日志记录(续)>所述就是<巧用CurrentThread.Name来统一标识日志记录>里改用当前线程名统一记日志后的问题. 我在csdn里也提问了(here and here),很遗憾最终没有查到原因.不过,很欣赏@sp1234大哥中肯的意见: 设计软件,面向业务来设计,例如用一个自定义的变量来保存参数.这样不管这问题中不同的过程被调用时在同一个线程还是不同线程,变量的值都是一致的. 如果“高大上”到过分技术层面,由于我

Log4Net日志记录介绍

原文地址 : http://www.cnblogs.com/wolf-sun/p/3347373.html#3009010 简介 log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具.     log4net是Apache软件基金会Apache Logging Services工程的一部分.Apache日志服务工程致力于为程序调试和审计提供跨语言的日志服务.(f:百度百科) 原理 Log4

利用大数据技术实现日志记录与分析

整体思路 整体分三步: 1.记录日志 1.记录日志采用UDP协议写入大数据平台,大数据平台采用Hive表来存储日志信息. 2.写入日志的工作,封装了一个Auto.Lib3.Dealer.Log.dll,这个dll要依赖ZooKeeperNet.dll 和 log4net.dll.这三个dll文件地址如下: dll文件 TFS上路径 Auto.Lib3.Dealer.Log.dll $/dealer/MCH/CommonLib/Auto.Lib3.Logging.dll ZooKeeperNet.

springmvc+log4j操作日志记录,详细配置

没有接触过的,先了解一下:log4j教程 部分内容来:log4j教程 感谢! 需要导入包: log包:log4j-12.17.jar 第一步:web.xml配置 <!-- log4j配置,文件路径,因为是跟随项目启动 --> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/log4j.xml</param-value>