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
|