当前位置: 首页 > news >正文

C# 超高速高性能写日志

原理

使用列队先缓存到内存,独立线程从列队中使用log4net写到磁盘上。

日志写入列队

public void EnqueueMessage(string message, FlashLogLevel level, Exception ex = null)
{if ((level == FlashLogLevel.Debug && _log.IsDebugEnabled)|| (level == FlashLogLevel.Error && _log.IsErrorEnabled)|| (level == FlashLogLevel.Fatal && _log.IsFatalEnabled)|| (level == FlashLogLevel.Info && _log.IsInfoEnabled)|| (level == FlashLogLevel.Warn && _log.IsWarnEnabled)){_que.Enqueue(new FlashLogMessage{Message = "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff") + "]\r\n" + message,Level = level,Exception = ex});// 通知线程往磁盘中写日志_mre.Set();}
}

队列写入日志

/// <summary>
/// 另一个线程记录日志,只在程序初始化时调用一次
/// </summary>
public void Register()
{Thread t = new Thread(new ThreadStart(WriteLog));t.IsBackground = false;t.Start();
}/// <summary>
/// 从队列中写日志至磁盘
/// </summary>
private void WriteLog()
{while (true){// 等待信号通知_mre.WaitOne();FlashLogMessage msg;// 判断是否有内容需要如磁盘 从列队中获取内容,并删除列队中的内容while (_que.Count > 0 && _que.TryDequeue(out msg)){// 判断日志等级,然后写日志switch (msg.Level){case FlashLogLevel.Debug:_log.Debug(msg.Message, msg.Exception);break;case FlashLogLevel.Info:_log.Info(msg.Message, msg.Exception);break;case FlashLogLevel.Error:_log.Error(msg.Message, msg.Exception);break;case FlashLogLevel.Warn:_log.Warn(msg.Message, msg.Exception);break;case FlashLogLevel.Fatal:_log.Fatal(msg.Message, msg.Exception);break;}}// 重新设置信号_mre.Reset();          Thread.Sleep(1);}
}

应用注意事项

需要在程序启动时注册,如asp.net 程序中在Global.asax中的Application_Start注册。

注册示例

public class MvcApplication : System.Web.HttpApplication
{protected void Application_Start(){AreaRegistration.RegisterAllAreas();FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);FlashLogger.Instance().Register();}
}

 使用

调用FlashLogger的静态方法

FlashLogger.Debug("Debug");
FlashLogger.Debug("Debug", new Exception("testexception"));
FlashLogger.Info("Info");
FlashLogger.Fatal("Fatal");
FlashLogger.Error("Error");
FlashLogger.Warn("Warn", new Exception("testexception"));

参考链接

C# 超高速高性能写日志icon-default.png?t=O83Ahttps://mp.weixin.qq.com/s?__biz=MzA4MTQyNDk4OA==&mid=2456958300&idx=2&sn=9c949a184d13e23f98e82417ac729421&chksm=895b198dcdf167e226da852887a430b409d74997d18ded44e20858db53fd841448fe11b93d96&mpshare=1&scene=1&srcid=1226pYPjHUCOMZmnq7FMGk86&sharer_shareinfo=ece2905c127436a9b5eae1003db433fd&sharer_shareinfo_first=0628f372cfaf61c028e18d6a8c508f50&exportkey=n_ChQIAhIQuA3e9zi0waukFDFCW1r%2ByhKfAgIE97dBBAEAAAAAAMFpCyDDdf4AAAAOpnltbLcz9gKNyK89dVj0uQI27swsOvYg368rEF3G9%2B72QxoOEAPAtRnBP0T8TmPbvTWYGbNG6ug7Za3ehBxruqhkk%2Bki%2BwUlj9NyGj7PzmMFO%2FJsij6UBGY3Vpgu3wKdrwe08W%2F0g4%2FAHVYW85it%2FEy104f1SNm0dtnV7sKSaTu8QbO%2FhqanrBe6n1u5q0B816ezwmh2m4RyMqxtUucoo0a2cOBvnIpfgO5pA%2F1KZ1naNd73ubHBMDQ2dU8E8SSQH2quniORgpyMqyOMK19GbsFh9Yh6xu1qsmX3iE5Ei%2F3G3JxxHvWaTR5uV5%2Fousn%2Fly4ctUTgA1mNvArHHHabEgtbFAVFrP5W&acctmode=0&pass_ticket=%2BHWz3yc2o8iZ6T2jkz0Pa27SKjP5Jc%2BuBoHv%2FE7tlB6avrF01Uh8JTBFsqDxKGA6&wx_header=0#rd

完整代码

using log4net;
using log4net.Config;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace Emrys.FlashLog
{public sealed class FlashLogger{/// <summary>/// 记录消息Queue/// </summary>private readonly ConcurrentQueue<FlashLogMessage> _que;/// <summary>/// 信号/// </summary>private readonly ManualResetEvent _mre;/// <summary>/// 日志/// </summary>private readonly ILog _log;/// <summary>/// 日志/// </summary>private static FlashLogger _flashLog = new FlashLogger();private FlashLogger(){var configFile = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config"));if (!configFile.Exists){throw new Exception("未配置log4net配置文件!");}// 设置日志配置文件路径XmlConfigurator.Configure(configFile);_que = new ConcurrentQueue<FlashLogMessage>();_mre = new ManualResetEvent(false);_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);}/// <summary>/// 实现单例/// </summary>/// <returns></returns>public static FlashLogger Instance(){return _flashLog;}/// <summary>/// 另一个线程记录日志,只在程序初始化时调用一次/// </summary>public void Register(){Thread t = new Thread(new ThreadStart(WriteLog));t.IsBackground = false;t.Start();}/// <summary>/// 从队列中写日志至磁盘/// </summary>private void WriteLog(){while (true){// 等待信号通知_mre.WaitOne();FlashLogMessage msg;// 判断是否有内容需要如磁盘 从列队中获取内容,并删除列队中的内容while (_que.Count > 0 && _que.TryDequeue(out msg)){// 判断日志等级,然后写日志switch (msg.Level){case FlashLogLevel.Debug:_log.Debug(msg.Message, msg.Exception);break;case FlashLogLevel.Info:_log.Info(msg.Message, msg.Exception);break;case FlashLogLevel.Error:_log.Error(msg.Message, msg.Exception);break;case FlashLogLevel.Warn:_log.Warn(msg.Message, msg.Exception);break;case FlashLogLevel.Fatal:_log.Fatal(msg.Message, msg.Exception);break;}}// 重新设置信号_mre.Reset();Thread.Sleep(1);}}/// <summary>/// 写日志/// </summary>/// <param name="message">日志文本</param>/// <param name="level">等级</param>/// <param name="ex">Exception</param>public void EnqueueMessage(string message, FlashLogLevel level, Exception ex = null){if ((level == FlashLogLevel.Debug && _log.IsDebugEnabled)|| (level == FlashLogLevel.Error && _log.IsErrorEnabled)|| (level == FlashLogLevel.Fatal && _log.IsFatalEnabled)|| (level == FlashLogLevel.Info && _log.IsInfoEnabled)|| (level == FlashLogLevel.Warn && _log.IsWarnEnabled)){_que.Enqueue(new FlashLogMessage{Message = "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff") + "]\r\n" + message,Level = level,Exception = ex});// 通知线程往磁盘中写日志_mre.Set();}}public static void Debug(string msg, Exception ex = null){Instance().EnqueueMessage(msg, FlashLogLevel.Debug, ex);}public static void Error(string msg, Exception ex = null){Instance().EnqueueMessage(msg, FlashLogLevel.Error, ex);}public static void Fatal(string msg, Exception ex = null){Instance().EnqueueMessage(msg, FlashLogLevel.Fatal, ex);}public static void Info(string msg, Exception ex = null){Instance().EnqueueMessage(msg, FlashLogLevel.Info, ex);}public static void Warn(string msg, Exception ex = null){Instance().EnqueueMessage(msg, FlashLogLevel.Warn, ex);}}/// <summary>/// 日志等级/// </summary>public enum FlashLogLevel{Debug,Info,Error,Warn,Fatal}/// <summary>/// 日志内容/// </summary>public class FlashLogMessage{public string Message { get; set; }public FlashLogLevel Level { get; set; }public Exception Exception { get; set; }}
}

特此记录

anlog

2024年12月27日

相关文章:

C# 超高速高性能写日志

原理 使用列队先缓存到内存&#xff0c;独立线程从列队中使用log4net写到磁盘上。 日志写入列队 public void EnqueueMessage(string message, FlashLogLevel level, Exception ex null) {if ((level FlashLogLevel.Debug && _log.IsDebugEnabled)|| (level Flas…...

阿里云人工智能ACA(五)——深度学习基础

一、深度学习概述 1. 深度学习概念 1-1. 深度学习基本概念 深度学习是机器学习的一个分支基于人工神经网络&#xff08;模仿人脑结构&#xff09;通过多层网络自动学习特征能够处理复杂的模式识别问题 1-2. 深度学习的优点与缺点 优点 强大的特征学习能力可以处理复杂问题…...

入职体检尿潜血3+能通过吗,什么原因引起

在许多行业入职体检中&#xff0c;尿液检测是一个重要的组成部分。尿潜血&#xff08;也称为尿中血红蛋白&#xff09;是尿液常规检查中一种常见的指标&#xff0c;其结果可以反映出身体的健康状况。当检测结果为“尿潜血3”时&#xff0c;很多人会感到困惑&#xff0c;尤其是在…...

vue最新源码探索分析

我在github上fork了最新版本vue3.5版本的源码并做了大幅删除&#xff0c;保留最核心的代码&#xff0c;有兴趣的可以看看&#xff0c;欢迎大家提出PR 仓库地址 https://github.com/greatanimalion/core 本项目vue版本3.5.13 为了方便查看与分析&#xff0c;减少心智负担 已…...

Kivy App开发之打包apk

Kivy项目可以为windows,max os,安卓,IOS等平台创建运行python的程序包。本文介绍如何将程序打包成apk并在安卓系统上安卓运行。 打包apk的方法主要有三种 使用Kivy Launcher,添加项目文件夹(必须包含main.py文件和android.txt文件),启动Kivy Launcher后就会运行,要生成a…...

【Java 数据结构】LinkedList 类 和 模拟实现链表

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 目录 1. 什么是 LinkedList &#xff1f; 2 LinkedList 的使用 2.1 LinkedList 的构造 2.2 LinkedList 的常用方法 2.3 LinkedList 的遍历 3. 单链表的模拟实现…...

VS2022 中的 /MT /MTd /MD /MDd 选项

我们有时编译时,需要配置这个 运行库,指定C/C++运行时库的链接方式。 如下图 那么这些选项的含义是什么? /MT:静态链接多线程库 /MT选项代表“Multi-threaded Static”,即多线程静态库。选择此选项时,编译器会从运行时库中选择多线程静态连接库来解释程序中的代码,…...

产品初探Devops!以及AI如何赋能Devops?

DevOps源自Development&#xff08;开发&#xff09;和Operations&#xff08;运维&#xff09;的组合&#xff0c;是一种新的软件工程理念&#xff0c;旨在打破传统软件工程方法中“开发->测试->运维”的割裂模式&#xff0c;强调端到端高效一致的交付流程&#xff0c;实…...

两种不同的LuaBehaviour生命周期绑定

在学习xLua时&#xff0c;发现xLua和LoxodonFramework的LuaBehaviour稍微有些不同&#xff0c;其中一个点是在调用DoString方法时的区别 1. xLua的版本中 直接使用Lua脚本环境进行绑定&#xff0c;这时候的Lua脚本调用生命周期函数是这样的 直接在Lua脚本中写函数就行 2. Lo…...

Effective C++ 条款31:将文件间的编译依存关系降至最低

文章目录 条款31&#xff1a;将文件间的编译依存关系降至最低最小化编译依赖关系的最佳实践通过减少编译依赖的好处总结 条款31&#xff1a;将文件间的编译依存关系降至最低 为了减少编译依赖关系&#xff0c;应该将接口与实现分离&#xff0c;并尽量减少头文件之间的依赖。这…...

python数据分析之爬虫基础:scrapy详解

一、爬虫工程化 在之前的爬虫学习中基本已经掌握了爬虫这门技术的大多数技术点&#xff0c;但是我们现在写的代码还很流程化&#xff0c;很难进行商用&#xff0c;想要爬虫达到商用级别&#xff0c;必须要对我们现在编写的爬虫进行大刀阔斧式的重组&#xff0c;以达到工程化的…...

openwrt 负载均衡方法 openwrt负载均衡本地源接口

openwrt 负载均衡方法 openwrt负载均衡本地源接口_mob6454cc647bdb的技术博客_51CTO博客 本人注重原理分析&#xff0c;要求对其原理掌握&#xff0c;否则按教程操作&#xff0c;你怕是什么都学不会&#xff0c;仔细看&#xff0c;认真记比较好。 首先确认一下基本细节 1、路由…...

Linux高级--3.3.2.6高并发编程之“内存屏障”“CPU屏障”“编译屏障”

一、内存屏障 在 Linux C 语言编程 中&#xff0c;内存屏障&#xff08;Memory Barrier&#xff09; 是一种用于控制内存访问顺序的技术。它主要用于多处理器系统中&#xff0c;确保某些操作按预期顺序执行&#xff0c;避免 CPU 和编译器对内存访问进行优化&#xff0c;从而影…...

【含开题报告+文档+PPT+源码】基于SpringBoot的智能安全与急救知识科普系统设计与实现

开题报告 在全球范围内&#xff0c;安全与急救知识的普及已成为提升公众安全素养、减少意外伤害发生率、提高突发事件应对能力的重要举措。尤其是在当今社会&#xff0c;人们面临的生活、工作环境日益复杂&#xff0c;交通事故、火灾、溺水、突发疾病等各种意外事件的发生概率…...

EMQX5.X版本性能配置调优参数

EMQX 主配置文件为 emqx.conf&#xff0c;根据安装方式其所在位置有所不同&#xff1a; 安装方式配置文件所在位置DEB 或 RPM 包安装/etc/emqx/emqx.confDocker 容器/opt/emqx/etc/emqx.conf解压缩包安装./etc/emqx.conf EMQ X 消息服务器默认占用的 TCP 端口包括: 端口 说明…...

电脑配置maven-3.6.1版本

不要使用太高的版本。 apache-maven-3.6.1-bin.zip 下载这个的maven压缩包 使用3.6.1版本。 解压缩放在本地软甲目录下面&#xff1a; 配置系统环境变量 在系统环境下面配置MAVEN_HOME 点击path 新增一条 在cmd中输入 mvn -v 检查maven的版本 配置阿里云镜像和本地的仓库 …...

水电站视频智能监控系统方案设计与技术应用方案

一、背景需求 水电站作为国家重要的能源基地&#xff0c;其安全运行对于保障能源供应和社会稳定具有重要意义。然而&#xff0c;传统的人工监控方式存在着诸多问题&#xff0c;如人力成本高、监控范围有限、反应不及时等。因此&#xff0c;水电站急需引进一种先进的视频智能监控…...

React 组件通信完整指南 以及 自定义事件发布订阅系统

React 组件通信完整指南 1. 父子组件通信 1.1 父组件向子组件传递数据 // 父组件 function ParentComponent() {const [data, setData] useState(Hello from parent);return <ChildComponent message{data} />; }// 子组件 function ChildComponent({ message }) {re…...

华为 AI Agent:企业内部管理的智能变革引擎(11/30)

一、华为 AI Agent 引领企业管理新潮流 在当今数字化飞速发展的时代&#xff0c;企业内部管理的高效性与智能化成为了决定企业竞争力的关键因素。华为&#xff0c;作为全球领先的科技巨头&#xff0c;其 AI Agent 技术在企业内部管理中的应用正掀起一场全新的变革浪潮。 AI Ag…...

【Pandas】pandas Series empty

Pandas2.2 Series Attributes 方法描述Series.index每个数据点的标签或索引Series.array对象底层的数据数组Series.values以NumPy数组的形式访问Series中的数据值Series.dtype用于获取 Pandas Series 中数据的类型&#xff08;dtype&#xff09;Series.shape用于获取 Pandas …...

深入理解 MySQL 事务:从基础到实战,一篇吃透

在开发和运维 MySQL 数据库的过程中&#xff0c;事务&#xff08;Transaction&#xff09; 是绕不开的核心知识点&#xff0c;它是保证数据库数据安全、一致、可靠的基石。无论是电商下单、银行转账、支付结算&#xff0c;还是日常的业务数据操作&#xff0c;都离不开事务的支撑…...

从make clean到build.prop:揭秘Android系统属性生成的完整链条

从make clean到build.prop&#xff1a;揭秘Android系统属性生成的完整链条 当你通过adb shell getprop ro.build.display.id查看设备版本号时&#xff0c;是否好奇过这个字符串背后的生成逻辑&#xff1f;在Android编译系统中&#xff0c;从Makefile执行到最终生成build.prop文…...

3分钟搞定Windows和Office激活:KMS_VL_ALL_AIO智能脚本使用指南

3分钟搞定Windows和Office激活&#xff1a;KMS_VL_ALL_AIO智能脚本使用指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为系统激活烦恼吗&#xff1f;Windows提示许可证过期&#xff0c…...

BEYOND REALITY Z-Image新手入门:三步生成你的第一张8K写真人像

BEYOND REALITY Z-Image新手入门&#xff1a;三步生成你的第一张8K写真人像 1. 为什么选择BEYOND REALITY Z-Image&#xff1f; 在当前的AI图像生成领域&#xff0c;写实人像一直是最具挑战性的任务之一。传统模型往往难以平衡细节精度与自然感&#xff0c;生成的图片要么过于…...

日期时间格式化中的字母代码解析与应用实例

1. 日期时间格式化字母代码入门指南 第一次接触日期时间格式化时&#xff0c;看到那些神秘的字母组合是不是一头雾水&#xff1f;yy、MM、dd这些看起来简单的代码&#xff0c;在实际使用中却藏着不少门道。作为处理时间数据的基础技能&#xff0c;掌握这些字母代码的含义和用法…...

AI辅助开发新范式:让快马AI优化你的17.143.cv模型推理管线

AI辅助开发新范式&#xff1a;让快马AI优化你的17.143.cv模型推理管线 最近在做一个实时视频流人物动作识别的项目&#xff0c;用到了17.143.cv库中的姿态估计模型。开发过程中遇到了两个比较棘手的问题&#xff1a;一是模型在某些帧上的推理速度不够理想&#xff0c;影响了实…...

颠覆传统:智能网页捕获工具重新定义长截图体验

颠覆传统&#xff1a;智能网页捕获工具重新定义长截图体验 【免费下载链接】full-page-screen-capture-chrome-extension One-click full page screen captures in Google Chrome 项目地址: https://gitcode.com/gh_mirrors/fu/full-page-screen-capture-chrome-extension …...

Janus-Pro-7B开发环境搭建:Ubuntu20.04系统配置全攻略

Janus-Pro-7B开发环境搭建&#xff1a;Ubuntu20.04系统配置全攻略 从零开始&#xff0c;手把手带你搭建Janus-Pro-7B多模态AI开发环境 如果你刚接触Janus-Pro-7B这个强大的多模态模型&#xff0c;可能会被环境配置的各种问题困扰。别担心&#xff0c;今天我就带你一步步在Ubunt…...

PyTorch 2.8镜像环境配置:CUDA 12.4与cuDNN 8+版本兼容性验证指南

PyTorch 2.8镜像环境配置&#xff1a;CUDA 12.4与cuDNN 8版本兼容性验证指南 1. 镜像环境概述 PyTorch 2.8深度学习镜像是一个经过深度优化的通用计算环境&#xff0c;专为现代AI工作负载设计。这个镜像最显著的特点是完美适配了NVIDIA最新的CUDA 12.4和cuDNN 8版本&#xff…...

Kandinsky-5.0-I2V-Lite-5s Web工具深度解析:非聊天页,专注图生视频的生产级界面

Kandinsky-5.0-I2V-Lite-5s Web工具深度解析&#xff1a;非聊天页&#xff0c;专注图生视频的生产级界面 1. 工具概述 Kandinsky-5.0-I2V-Lite-5s是一款专为图生视频任务设计的轻量级AI模型&#xff0c;它通过简洁直观的Web界面&#xff0c;让用户能够快速将静态图片转化为动…...