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

C# WinForms 日志实现与封装

C# WinForms 日志实现与封装

下面我将为您实现一个完整的、可重用的日志系统,适用于WinForms应用程序。这个实现包括文件日志、控制台日志和WinForms文本框日志输出,并提供了简单的接口供后续项目直接引用。

1. 创建日志接口和基础实现

首先,我们定义一个日志接口,然后提供几种实现方式。

using System;namespace WinFormsLogger
{// 日志级别枚举public enum LogLevel{Debug,Info,Warning,Error,Fatal}// 日志接口public interface ILogger{void Log(LogLevel level, string message);void Debug(string message);void Info(string message);void Warning(string message);void Error(string message);void Fatal(string message);}// 抽象基类提供默认实现public abstract class LoggerBase : ILogger{public virtual void Debug(string message) => Log(LogLevel.Debug, message);public virtual void Info(string message) => Log(LogLevel.Info, message);public virtual void Warning(string message) => Log(LogLevel.Warning, message);public virtual void Error(string message) => Log(LogLevel.Error, message);public virtual void Fatal(string message) => Log(LogLevel.Fatal, message);public abstract void Log(LogLevel level, string message);protected virtual string FormatMessage(LogLevel level, string message){return $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} [{level}] {message}";}}
}

2. 实现具体的日志记录器

2.1 文件日志记录器

using System;
using System.IO;namespace WinFormsLogger
{public class FileLogger : LoggerBase{private readonly string _logFilePath;private readonly object _lock = new object();public FileLogger(string logFilePath){_logFilePath = logFilePath;// 确保日志目录存在var dir = Path.GetDirectoryName(_logFilePath);if (!string.IsNullOrEmpty(dir) Directory.CreateDirectory(dir);}public override void Log(LogLevel level, string message){lock (_lock){File.AppendAllText(_logFilePath, FormatMessage(level, message) + Environment.NewLine);}}}
}

2.2 控制台日志记录器

using System;namespace WinFormsLogger
{public class ConsoleLogger : LoggerBase{public override void Log(LogLevel level, string message){var originalColor = Console.ForegroundColor;try{Console.ForegroundColor = GetLevelColor(level);Console.WriteLine(FormatMessage(level, message));}finally{Console.ForegroundColor = originalColor;}}private ConsoleColor GetLevelColor(LogLevel level){return level switch{LogLevel.Debug => ConsoleColor.Gray,LogLevel.Info => ConsoleColor.White,LogLevel.Warning => ConsoleColor.Yellow,LogLevel.Error => ConsoleColor.Red,LogLevel.Fatal => ConsoleColor.DarkRed,_ => ConsoleColor.White};}}
}

2.3 WinForms文本框日志记录器

using System;
using System.Windows.Forms;namespace WinFormsLogger
{public class TextBoxLogger : LoggerBase{private readonly TextBox _textBox;private readonly int _maxLines;public TextBoxLogger(TextBox textBox, int maxLines = 1000){_textBox = textBox ?? throw new ArgumentNullException(nameof(textBox));_maxLines = maxLines;}public override void Log(LogLevel level, string message){if (_textBox.InvokeRequired){_textBox.Invoke(new Action(() => Log(level, message)));return;}var formattedMessage = FormatMessage(level, message);_textBox.AppendText(formattedMessage + Environment.NewLine);// 限制最大行数if (_textBox.Lines.Length > _maxLines){var lines = _textBox.Lines;var newLines = new string[Math.Min(_maxLines, lines.Length)];Array.Copy(lines, lines.Length - newLines.Length, newLines, 0, newLines.Length);_textBox.Lines = newLines;}_textBox.ScrollToCaret();}}
}

2.4 复合日志记录器(可同时记录到多个目标)

using System;
using System.Collections.Generic;namespace WinFormsLogger
{public class CompositeLogger : LoggerBase{private readonly List<ILogger> _loggers = new List<ILogger>();public void AddLogger(ILogger logger){if (logger == null) throw new ArgumentNullException(nameof(logger));_loggers.Add(logger);}public override void Log(LogLevel level, string message){foreach (var logger in _loggers){logger.Log(level, message);}}}
}

3. 日志管理器(便于全局访问)

using System;namespace WinFormsLogger
{public static class LogManager{private static ILogger _logger = new ConsoleLogger(); // 默认使用控制台日志public static ILogger Logger{get => _logger;set => _logger = value ?? throw new ArgumentNullException(nameof(value));}public static void Debug(string message) => Logger.Debug(message);public static void Info(string message) => Logger.Info(message);public static void Warning(string message) => Logger.Warning(message);public static void Error(string message) => Logger.Error(message);public static void Fatal(string message) => Logger.Fatal(message);}
}

4. 使用示例

4.1 在WinForms项目中初始化日志系统

using System;
using System.Windows.Forms;
using WinFormsLogger;namespace YourWinFormsApp
{public partial class MainForm : Form{public MainForm(){InitializeComponent();InitializeLogging();}private void InitializeLogging(){// 创建复合日志记录器var compositeLogger = new CompositeLogger();// 添加文件日志记录器compositeLogger.AddLogger(new FileLogger("logs/application.log"));// 添加控制台日志记录器(调试时有用)compositeLogger.AddLogger(new ConsoleLogger());// 添加文本框日志记录器(假设你的窗体上有一个名为txtLog的TextBox)compositeLogger.AddLogger(new TextBoxLogger(txtLog));// 设置为全局日志记录器LogManager.Logger = compositeLogger;LogManager.Info("日志系统初始化完成");}private void btnDoSomething_Click(object sender, EventArgs e){try{LogManager.Debug("开始执行某些操作...");// 你的业务逻辑代码LogManager.Info("操作成功完成");}catch (Exception ex){LogManager.Error($"操作失败: {ex.Message}");}}}
}

4.2 在其他类中使用日志

using WinFormsLogger;namespace YourWinFormsApp
{public class SomeService{public void PerformTask(){LogManager.Info("开始执行任务...");try{// 业务逻辑LogManager.Debug("任务执行中...");}catch (Exception ex){LogManager.Error($"任务执行出错: {ex}");throw;}LogManager.Info("任务完成");}}
}

5. 高级功能扩展

如果您需要更高级的功能,可以考虑以下扩展:

5.1 日志文件滚动

修改FileLogger类,实现日志文件按日期或大小滚动:

public class RollingFileLogger : LoggerBase
{private readonly string _logDirectory;private readonly string _logFileBaseName;private readonly long _maxFileSize;private readonly int _maxBackupFiles;private readonly object _lock = new object();private string _currentLogFilePath;public RollingFileLogger(string logDirectory, string logFileBaseName, long maxFileSize = 10 * 1024 * 1024, // 默认10MBint maxBackupFiles = 10){_logDirectory = logDirectory;_logFileBaseName = logFileBaseName;_maxFileSize = maxFileSize;_maxBackupFiles = maxBackupFiles;Directory.CreateDirectory(_logDirectory);_currentLogFilePath = GetCurrentLogFilePath();}private string GetCurrentLogFilePath(){return Path.Combine(_logDirectory, $"{_logFileBaseName}_{DateTime.Now:yyyyMMdd}.log");}public override void Log(LogLevel level, string message){lock (_lock){var currentDate = DateTime.Now.Date;var newLogFilePath = GetCurrentLogFilePath();// 如果日期变化或文件过大,滚动日志if (newLogFilePath != _currentLogFilePath || (File.Exists(_currentLogFilePath) && new FileInfo(_currentLogFilePath).Length > _maxFileSize)){RollLogFiles();_currentLogFilePath = newLogFilePath;}File.AppendAllText(_currentLogFilePath, FormatMessage(level, message) + Environment.NewLine);}}private void RollLogFiles(){// 实现日志文件滚动逻辑// ...}
}

5.2 异步日志记录

using System;
using System.Threading.Tasks;namespace WinFormsLogger
{public class AsyncLogger : LoggerBase{private readonly ILogger _innerLogger;private readonly TaskQueue _taskQueue;public AsyncLogger(ILogger innerLogger){_innerLogger = innerLogger ?? throw new ArgumentNullException(nameof(innerLogger));_taskQueue = new TaskQueue();}public override void Log(LogLevel level, string message){_taskQueue.Enqueue(() => _innerLogger.Log(level, message));}// 简单的任务队列实现private class TaskQueue{private readonly object _lock = new object();private Task _lastTask = Task.CompletedTask;public void Enqueue(Action action){lock (_lock){_lastTask = _lastTask.ContinueWith(_ => action(), TaskContinuationOptions.ExecuteSynchronously);}}}}
}

6. 打包为可重用的类库

要将这个日志系统打包为可重用的类库:

  1. 创建一个新的"类库(.NET Framework)"或"类库(.NET Standard)"项目
  2. 将上述代码文件添加到项目中
  3. 编译生成DLL
  4. 在其他WinForms项目中引用此DLL

总结

这个日志系统提供了以下特点:

  1. 灵活:支持多种日志输出目标(文件、控制台、文本框)
  2. 可扩展:可以轻松添加新的日志记录器实现
  3. 线程安全:所有日志记录器都考虑了线程安全
  4. 简单易用:通过LogManager静态类提供全局访问
  5. 可重用:可以打包为独立的类库供多个项目使用

相关文章:

  • 益阳做网站怎么便宜重庆seo博客
  • 兰州手机网站制作公司宁波网络优化seo
  • jsp做网站下载图片深圳优化seo排名
  • 网站建设企业宣传微博seo营销
  • 响应式网站模仿优化网络推广外包
  • asp.net做三个网站网站建设的系统流程图
  • Flink状态和容错-基础篇
  • Golang Kratos 系列:领域层model定义是自洽还是直接依赖第三方(三)
  • 帮助装修公司拓展客户资源的微信装修小程序怎么做?
  • 重点解析(软件工程)
  • MonkeyOCR在Win习题部署指南和报错提醒
  • 谷歌 Gemini 2.5 系列模型:性能、功能与应用全方位解析​
  • 深入理解RAG:大语言模型时代的知识增强架构
  • pyqt多界面
  • 人机协作新篇章:艾利特按摩机器人如何重塑健康生活
  • 【JS】整理常复用的JS函数合集
  • python有哪些常用的GUI(图形用户界面)库及选择指南
  • SpringCloud系列(34)--使用Hystrix进行服务熔断
  • c++ 类型擦除技术
  • 使用预训练权重在YOLO模型上训练新数据集的完整指南
  • 数字图像处理——滤波器核(kernel)
  • Jetson家族横向对比:如何选择你的边缘计算设备
  • Rust 项目实战:多线程 Web 服务器
  • 前端后端文件下载防抖实现方案
  • 基于大模型预测的化脓性阑尾炎诊疗方案研究报告
  • 【微信小程序】9、用户拒绝授权地理位置后再次请求授权