144 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			VB.net
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			VB.net
		
	
	
	
	
	
| 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
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 初始化日志写入任务
 | |
|     ''' </summary>
 | |
|     Sub New()
 | |
|         logWritingTask = Task.Run(AddressOf ProcessLogQueue)
 | |
|     End Sub
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 异步写入带等级的日志
 | |
|     ''' </summary>
 | |
|     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
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 定期从队列中取出日志并写入文件
 | |
|     ''' </summary>
 | |
|     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
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 写入日志到文件
 | |
|     ''' </summary>
 | |
|     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
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 清理过期的日志文件
 | |
|     ''' </summary>
 | |
|     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
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 备份并清空日志文件
 | |
|     ''' </summary>
 | |
|     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
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 快捷方法:写 Info 日志
 | |
|     ''' </summary>
 | |
|     Public Sub Info(message As String)
 | |
|         'WriteLog(LogLevel.Info, message)
 | |
|     End Sub
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 快捷方法:写 Warning 日志
 | |
|     ''' </summary>
 | |
|     Public Sub Warn(message As String)
 | |
|         'WriteLog(LogLevel.Warn, message)
 | |
|     End Sub
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 快捷方法:写 Error 日志
 | |
|     ''' </summary>
 | |
|     Public Sub [Error](message As String)
 | |
|         'WriteLog(LogLevel.Error, message)
 | |
|     End Sub
 | |
| 
 | |
|     ''' <summary>
 | |
|     ''' 快捷方法:写 Debug 日志
 | |
|     ''' </summary>
 | |
|     Public Sub Debug(message As String)
 | |
|         'WriteLog(LogLevel.Debug, message)
 | |
|     End Sub
 | |
| End Module
 |