news 2026/6/15 18:37:58

NtLogV4

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
NtLogV4
public class NtLogV4 //可能无法使用 { private Queue<LogContentV4> buffer = new Queue<LogContentV4>(); public string LogPath { get; } private string curfilepath = string.Empty; private string errorLgFile = string.Empty; //定义从Exception到Fault这5个层级为Error private Task task; //不要删除,多线程写日志时会用到 private Stopwatch watcher = new Stopwatch(); private long maxms, minms, lastms; private volatile bool IsWriting = false; public bool Writing { get { return IsWriting; } } /// <summary> /// 平均耗时 /// </summary> public long AverageConsum { get { return (maxms + minms + lastms) / 3; } } public NtLogV4() { this.LogPath = AppDomain.CurrentDomain.BaseDirectory; ////创建日志文件夹 this.LogPath = CreateLogDirectory(); MakeLogFileName(); maxms = minms = lastms = 0; } public void Enqueue(LogContentV4 log) { this.buffer.Enqueue(log); } public void Enqueue(ref List<LogContentV4> logs) { foreach (LogContentV4 log in logs) { this.buffer.Enqueue(log); } } public void Enqueue(Queue<LogContentV4> rlogs) { foreach (LogContentV4 log in rlogs) { this.buffer.Enqueue(log); } } public void Enqueue(ref Queue<LogContentV4> rlogs) { while (rlogs.Count > 0) { this.buffer.Enqueue(rlogs.Dequeue()); } } public void OnLogging(ref Queue<LogContentV4> logs) { for (int i = 0; i < logs.Count; i++) { this.buffer.Enqueue(logs.Dequeue()); } this.UpdatePathFileName(); if (this.IsWriting == false && this.buffer.Count > 0) { WriteLogByThreadV5(); } } private static string CreateLogDirectory() { string path = AppDomain.CurrentDomain.BaseDirectory; // 获取当前应用程序域的名称(通常是程序集名称) string assemblyName = AppDomain.CurrentDomain.FriendlyName; // 去掉路径和扩展名,只保留文件名 assemblyName = Path.GetFileNameWithoutExtension(assemblyName); // 组合成完整的路径 path = System.IO.Path.Combine(path, assemblyName + "Log"); //TempLog.logging(path); //创建日志文件夹 Directory.CreateDirectory(path); return path; } private void UpdatePathFileName() { string path = AppDomain.CurrentDomain.BaseDirectory; // 获取当前应用程序域的名称(通常是程序集名称) string assemblyName = AppDomain.CurrentDomain.FriendlyName; // 去掉路径和扩展名,只保留文件名 assemblyName = Path.GetFileNameWithoutExtension(assemblyName); // 组合成完整的路径 path = System.IO.Path.Combine(path, assemblyName + "Log"); //TempLog.logging(path); //创建日志文件夹 Directory.CreateDirectory(path); string dn = DateTime.Now.ToString("yyyy-MM-dd"); this.curfilepath = Path.Combine(this.LogPath, assemblyName + dn + ".log"); this.errorLgFile = Path.Combine(this.LogPath, assemblyName + dn + "err.log"); } private void MakeLogFileName() { // 获取当前应用程序域的名称(通常是程序集名称) string assemblyName = AppDomain.CurrentDomain.FriendlyName; // 去掉路径和扩展名,只保留文件名 assemblyName = Path.GetFileNameWithoutExtension(assemblyName); string dn = DateTime.Now.ToString("yyyy-MM-dd"); this.curfilepath = Path.Combine(this.LogPath, assemblyName + dn + ".log"); this.errorLgFile = Path.Combine(this.LogPath, assemblyName + dn + "err.log"); } public void WriteLogFile() { using (StreamWriter writer = new StreamWriter(this.curfilepath, true)) // true表示追加模式 { foreach (var cnt in this.buffer) { writer.WriteLine(cnt.ToString()); } } } public void WriteErrorLog() { using (StreamWriter writer = new StreamWriter(this.errorLgFile, true)) // true表示追加模式 { foreach (LogContentV4 cnt in this.buffer) { if (cnt._Level >= LogLevel.Warning) writer.WriteLine(LogContentV4X.TraceDetail(cnt)); } } } //发现它仍然阻塞主线程 //注意只有一个线程写,不能多个线程同时写文件。 //请注意,Buffer.Remove(cnt) 在循环中可能会导致问题,因为从集合中移除元素会改变集合的大小,从而可能导致迭代器失效。为了避免这个问题,可以先收集需要删除的元素,然后在循环结束后统一删除它们。 public void WriteLogByThreadV5() { this.watcher.Start(); this.IsWriting = true; Queue<LogContentV4> errlogs = new Queue<LogContentV4>(); // 使用Task.Run在后台线程中执行文件写入操作 this.task = Task.Run(() => { //FileStream可以设置成独享锁定模式,防止 线程互斥 using (FileStream fs1 = new FileStream(this.curfilepath, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer = new StreamWriter(fs1)) { //foreach (var cnt in queue) //{ // writer.WriteLine(cnt.ToString()); // ; // if (cnt.Level >= LogLevel.Warning) // errlogs.Enqueue(cnt); //} while (this.buffer.Count > 0) { var tmp = this.buffer.Dequeue(); writer.WriteLine(tmp.ToString()); if (tmp._Level >= LogLevel.Warning) errlogs.Enqueue(tmp); } } } //如果没有errlog就不写 if (errlogs.Count > 0) { using (FileStream fs2 = new FileStream(this.errorLgFile, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer2 = new StreamWriter(fs2)) { for (int i = 0; i < errlogs.Count; i++) { writer2.WriteLine(LogContentV4X.TraceDetail(errlogs.Dequeue())); } } } } //Buffer没有上锁是希望它尽快完成操作,但有风险 }); this.watcher.Stop(); this.IsWriting = false; if (this.lastms > 0 && this.lastms > this.maxms) { this.maxms = this.lastms; } if (this.lastms > 0 && this.minms == 0) this.minms = this.lastms; if (this.lastms > 0 && this.lastms < this.minms) { this.minms = this.lastms; } this.lastms = watcher.ElapsedMilliseconds; } public void WriteLogByThreadV8() { this.watcher.Start(); this.IsWriting = true; Queue<LogContentV4> errlogs = new Queue<LogContentV4>(); // 使用Task.Run在后台线程中执行文件写入操作 this.task = Task.Run(() => { //刷新文件路径 MakeLogFileName(); //FileStream可以设置成独享锁定模式,防止 线程互斥 using (FileStream fs1 = new FileStream(this.curfilepath, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer = new StreamWriter(fs1)) { //foreach (var cnt in queue) //{ // writer.WriteLine(cnt.ToString()); // ; // if (cnt.Level >= LogLevel.Warning) // errlogs.Enqueue(cnt); //} while (this.buffer.Count > 0) { var tmp = this.buffer.Dequeue(); writer.WriteLine(tmp.ToString()); if (tmp._Level >= LogLevel.Warning) errlogs.Enqueue(tmp); } } } //如果没有errlog就不写 if (errlogs.Count > 0) { using (FileStream fs2 = new FileStream(this.errorLgFile, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer2 = new StreamWriter(fs2)) { for (int i = 0; i < errlogs.Count; i++) { writer2.WriteLine(LogContentV4X.TraceDetailV2(errlogs.Dequeue())); } } } } //Buffer没有上锁是希望它尽快完成操作,但有风险 }); this.watcher.Stop(); this.IsWriting = false; if (this.lastms > 0 && this.lastms > this.maxms) { this.maxms = this.lastms; } if (this.lastms > 0 && this.minms == 0) this.minms = this.lastms; if (this.lastms > 0 && this.lastms < this.minms) { this.minms = this.lastms; } this.lastms = watcher.ElapsedMilliseconds; } public void WriteLogByThreadV8(Queue<LogContentV4> logqueue) { Enqueue(logqueue); this.watcher.Start(); this.IsWriting = true; Queue<LogContentV4> errlogs = new Queue<LogContentV4>(); // 使用Task.Run在后台线程中执行文件写入操作 this.task = Task.Run(() => { //刷新文件路径 MakeLogFileName(); //FileStream可以设置成独享锁定模式,防止 线程互斥 using (FileStream fs1 = new FileStream(this.curfilepath, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer = new StreamWriter(fs1)) { //foreach (var cnt in queue) //{ // writer.WriteLine(cnt.ToString()); // ; // if (cnt.Level >= LogLevel.Warning) // errlogs.Enqueue(cnt); //} while (this.buffer.Count > 0) { var tmp = this.buffer.Dequeue(); writer.WriteLine(tmp.ToString()); if (tmp._Level >= LogLevel.Warning) errlogs.Enqueue(tmp); } } } //如果没有errlog就不写 if (errlogs.Count > 0) { using (FileStream fs2 = new FileStream(this.errorLgFile, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer2 = new StreamWriter(fs2)) { for (int i = 0; i < errlogs.Count; i++) { writer2.WriteLine(LogContentV4X.TraceDetailV2(errlogs.Dequeue())); } } } } //Buffer没有上锁是希望它尽快完成操作,但有风险 }); this.watcher.Stop(); this.IsWriting = false; if (this.lastms > 0 && this.lastms > this.maxms) { this.maxms = this.lastms; } if (this.lastms > 0 && this.minms == 0) this.minms = this.lastms; if (this.lastms > 0 && this.lastms < this.minms) { this.minms = this.lastms; } this.lastms = watcher.ElapsedMilliseconds; } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 17:21:18

企业级CI/CD中解决Git版本识别问题的实战案例

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个CI/CD管道故障排查案例演示&#xff0c;模拟cannot identify version of git executable错误场景。要求&#xff1a;1. 设置Docker容器环境 2. 故意配置错误的PATH变量 3. …

作者头像 李华
网站建设 2026/6/15 11:47:10

Nacos数据库表结构升级实战:从版本冲突到平滑迁移的完整解决方案

Nacos数据库表结构升级实战&#xff1a;从版本冲突到平滑迁移的完整解决方案 【免费下载链接】nacos Nacos是由阿里巴巴开源的服务治理中间件&#xff0c;集成了动态服务发现、配置管理和服务元数据管理功能&#xff0c;广泛应用于微服务架构中&#xff0c;简化服务治理过程。 …

作者头像 李华
网站建设 2026/6/15 1:18:10

springboot基于vue的城科考务管理系统 在线考试报名系统_3y08p4z0

目录已开发项目效果实现截图开发技术系统开发工具&#xff1a;核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/6/15 13:17:08

springboot基于vue的大学学生社团管理系统开发与实现_zuo66yih

目录已开发项目效果实现截图开发技术系统开发工具&#xff1a;核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/6/15 13:39:15

网络地址转换(NAT)的场景分析及配置选用

作者&#xff1a;chen-trueqq.com仅供学习交流&#xff0c;如有错误恳请指出&#xff01;一、NAT常见分类根据设备实现和场景应用&#xff0c;NAT的分类方式有很多种。下面给出几种常见且工程上好用的分类方式&#xff08;不同方式彼此正交&#xff0c;可组合出现&#xff0c;比…

作者头像 李华
网站建设 2026/6/15 1:22:06

意图识别面试通关指南:从基础问答到场景落地

引言 意图识别&#xff08;Intent Recognition&#xff09;作为任务型对话系统&#xff08;Task-oriented Dialogue System&#xff09;的核心组件&#xff0c;一直是 NLP 算法岗面试的高频考点。本文整理了从基础概念到工程实践的常见面试题&#xff0c;助你从容应对。 第一部…

作者头像 李华