Files
windows_lock_vb/Yjpp36/service/Logger.vb
2025-05-19 14:06:21 +08:00

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