Imports System.IO Imports System.Text Imports System.Collections.Concurrent Public Module Logger Private ReadOnly logDirectory As String = "c:\\logs" Private ReadOnly maxLogSizeBytes As Long = 10 * 1024 * 1024 ' 每个文件最大10MB Private ReadOnly logRetentionDays As Integer = 1 Private ReadOnly logLock As New Object() Private ReadOnly logQueue As New ConcurrentQueue(Of String)() Private ReadOnly logWritingTask As Task Public Enum LogLevel Info Warn [Error] Debug End Enum ''' ''' 初始化日志写入任务 ''' Sub New() logWritingTask = Task.Run(AddressOf ProcessLogQueue) End Sub ''' ''' 异步写入带等级的日志 ''' Public Sub WriteLog(level As LogLevel, message As String) Dim logEntry As String = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} [{level.ToString().ToUpper()}] {message}" logQueue.Enqueue(logEntry) End Sub ''' ''' 定期从队列中取出日志并写入文件 ''' Private Async Sub ProcessLogQueue() While True ' 确保日志写入任务不会频繁创建线程 If logQueue.IsEmpty Then Await Task.Delay(500) ' 等待一段时间再检查队列 End If ' 使用 TryDequeue 从队列中获取 logEntry Dim logEntry As String = Nothing If logQueue.TryDequeue(logEntry) Then WriteLogToFile(logEntry) End If End While End Sub ''' ''' 写入日志到文件 ''' Private Sub WriteLogToFile(logEntry As String) Try SyncLock logLock If Not Directory.Exists(logDirectory) Then Directory.CreateDirectory(logDirectory) End If CleanupOldLogs() Dim todayFile As String = Path.Combine(logDirectory, $"{Date.Today:yyyy-MM-dd}.log") If File.Exists(todayFile) Then Dim fileInfo As New FileInfo(todayFile) If fileInfo.Length > maxLogSizeBytes Then BackupAndClear(todayFile) End If End If Using sw As New StreamWriter(todayFile, append:=True, encoding:=Encoding.UTF8) sw.WriteLine(logEntry) End Using End SyncLock Catch ' 忽略日志写入错误 End Try End Sub ''' ''' 清理过期的日志文件 ''' Private Sub CleanupOldLogs() Try Dim files = Directory.GetFiles(logDirectory) For Each file In files Dim fileName = Path.GetFileNameWithoutExtension(file) Dim dateStr = fileName.Split("_"c).FirstOrDefault() If Date.TryParse(dateStr, Nothing) Then Dim fileDate = Date.Parse(dateStr) If (Date.Today - fileDate).Days >= logRetentionDays Then file.Remove(file) End If End If Next Catch ' 忽略清理错误 End Try End Sub ''' ''' 备份并清空日志文件 ''' Private Sub BackupAndClear(filePath As String) Try Dim bakFile As String = filePath.Replace(".log", $"_{DateTime.Now:HHmmss}.bak") File.Copy(filePath, bakFile, overwrite:=True) File.WriteAllText(filePath, "") ' 清空日志内容 Catch ' 忽略备份错误 End Try End Sub ''' ''' 快捷方法:写 Info 日志 ''' Public Sub Info(message As String) 'WriteLog(LogLevel.Info, message) End Sub ''' ''' 快捷方法:写 Warning 日志 ''' Public Sub Warn(message As String) 'WriteLog(LogLevel.Warn, message) End Sub ''' ''' 快捷方法:写 Error 日志 ''' Public Sub [Error](message As String) 'WriteLog(LogLevel.Error, message) End Sub ''' ''' 快捷方法:写 Debug 日志 ''' Public Sub Debug(message As String) 'WriteLog(LogLevel.Debug, message) End Sub End Module