‘早年写的一个日志函数,有时间优化以下,比如支持内存缓冲,定时异步写入,写入到数据库,等。
‘20240706 加入了 OutputDebugString 函数,暂时先简陋的实现一下远程实时调试。
‘日志输出到 DgbView 控制台参考:
‘vb6使用 OutputDebugString 配合 debugview 工具进行调试输出
‘https://vb6.pro/vi/1233
‘20240706 加入了网页版远程调试,并支持日志级别控制,完善了代码逻辑和命名规范。
‘用法:
‘先设置一个 WebUserCode 的值,可以是你喜欢的任意字符串
‘仅支持 字母和数字 组合,然后到 http://log.vb6.pro 去填写这个值
‘也可以在网站得到一个随机字符串再回来这里设置 WebUserCode
‘设置好之后,就可以在网站实时看到本模块的 WebView 函数提交的日志了
以下代码复制到一个单独的模块文件,命名为 LogTools.bas
Option Explicit
'作者:邓伟
'联系:QQ 215879458
'网站:http://vb6.pro
'说明:原创模块,转载请保留本注释块
'早年写的一个日志函数,有时间优化以下,比如支持内存缓冲,定时异步写入等。
'20240706 加入了 OutputDebugString 函数,暂时先简陋的实现一下远程实时调试。
'日志输出到 DbgView 控制台参考:
'vb6使用 OutputDebugString 配合 debugview 工具进行调试输出
'https://vb6.pro/vi/1233
'20240706 加入了网页版远程调试,并支持日志级别控制,完善了代码逻辑和命名规范。
'用法:
'先设置一个 WebUserCode 的值,可以是你喜欢的任意字符串
'仅支持 字母和数字 组合,然后到 http://log.vb6.pro 去填写这个值
'也可以在网站得到一个随机字符串再回来这里设置 WebUserCode
'设置好之后,就可以在网站实时看到本模块的 WebView 函数提交的日志了
'日志级别
Enum EnumLogLevel
Info = 0
Warn = 1
Danger = 2
Error = 3
Debugger = 4
Custom = 5
End Enum
'日志文件名规则
Enum EnumLogFileNameRule
None = 0
ByMonth = 1
ByDay = 2
byUser = 3
End Enum
'当前设置的日志控制级别,级别值越高,日志输出越少
Public LogLevelControl As EnumLogLevel
'设置全局的通道开关,可代替 save 函数的开关参数
Public SendToFormView As Boolean
Public SendToDbgView As Boolean
Public SendToWebView As Boolean
'用于回显到任意窗体,任何 Form 窗体把 listbox set 给这个对象就可以输出
'比如:Set LogTools.FormListBox = List1
Public FormListBox As VB.ListBox
Public FormListBoxMaxItem As Long
'日志文件根目录,为空则使用当前程序的目录
Public LogDir As String
'日志文件子目录,一般用于区分业务模块的日志
Public LogSubDir As String
'日志文件名称规则,默认按月份细分,也可以按日,或者用户定义
Public LogFileNameRule As EnumLogFileNameRule
'日志文件名称用户定义,支持任意细分深层目录和文件名
Public LogFileNameByUer As String
'设置网页调试使用的用户识别码
Public WebUserCode As String
Private Const WEB_URL As String = "http://log.vb6.pro/submit"
Public DebugPring As Boolean
Dim FileNumber
Dim LogData As String
Dim LevelData
Private Declare Sub OutputDebugString Lib "kernel32" Alias "OutputDebugStringA" (ByVal lpOutputString As String)
'MakeSureDirectoryPathExists 支持长路径自动创建 多级文件夹
Private Declare Function MakeSureDirectoryPathExists Lib "imagehlp.dll" (ByVal DirPath As String) As Long
Public Function FormView(LogStr As String, Optional LogLevel As EnumLogLevel) As String
'用途:日志输出到窗体的列表控件
If FormListBox Is Nothing Then Exit Function
If MakeLogData(LogStr, LogLevel) = False Then Exit Function
FormListBox.AddItem LogData, 0
'移除超出最大条目数量
If FormListBoxMaxItem < 9 Then FormListBoxMaxItem = 999
If FormListBox.ListCount > FormListBoxMaxItem Then FormListBox.RemoveItem FormListBoxMaxItem
FormView = LogData
End Function
Public Function WebView(LogStr As String, Optional LogLevel As EnumLogLevel) As String
'用途:日志输出到网页控制台
If WebUserCode = "" Then Exit Function
If MakeLogData(LogStr, LogLevel) = False Then Exit Function
Static HttpClient As Object
' 创建 WinHttpRequest 对象
Set HttpClient = CreateObject("WinHttp.WinHttpRequest.5.1")
'采用异步提交,不管成功与否。避免请求等待浪费时间
With HttpClient
'Sub SetTimeouts(ResolveTimeout As Long, ConnectTimeout As Long, SendTimeout As Long, ReceiveTimeout As Long)
.Open "POST", WEB_URL & "?code=" & WebUserCode, True
.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.Send "log=" & LogData
' Debug.Print .ResponseText
End With
WebView = LogData
End Function
Public Function DbgView(LogStr As String, Optional LogLevel As EnumLogLevel) As String
'用途:日志输出到 DbgView 控制台
'加个前缀,方便 debugview 工具进行筛选过滤本类消息
If MakeLogData(LogStr, LogLevel) = False Then Exit Function
OutputDebugString "来自VB6日志的数据:" & LogData
DbgView = LogData
End Function
Public Function Save(ByVal LogStr As String, Optional LogLevel As EnumLogLevel, _
Optional ToFormView As Boolean, _
Optional ToDbgView As Boolean, _
Optional ToWebView As Boolean) As String
'用途:日志输出到文件,支持其他通道开关
Dim LogPath As String
Dim LogFile As String
'默认值处理
If LogSubDir = "" Then LogSubDir = "system"
If LogFileNameByUer = "" Then LogFileNameByUer = "vb"
If LogFileNameRule = None Then LogFileNameRule = ByDay
If MakeLogData(LogStr, LogLevel) = False Then Exit Function
Select Case LogFileNameRule
Case EnumLogFileNameRule.ByMonth
LogPath = Format$(Now, "yyyy") & "\"
LogFile = "\" & Format$(Now, "yyyyMM") & ".txt"
Case EnumLogFileNameRule.ByDay
LogPath = Format$(Now, "yyyy") & "\" & Format$(Now, "MM") & "\"
LogFile = Format$(Now, "yyyyMMdd") & ".txt"
Case Else
LogPath = Format$(Now, "yyyy") & "\" & Format$(Now, "MM") & "\"
LogFile = LogFileNameByUer & ".txt"
End Select
LogPath = "\logs\" + LogSubDir + "\" + LogPath
If LogDir = "" Then
LogPath = App.Path & LogPath
Else
LogPath = LogDir & LogPath
End If
If Dir(LogPath, vbDirectory) = "" Then '判断文件夹是否存在
MakeSureDirectoryPathExists LogPath '创建文件夹
End If
FileNumber = FreeFile
Open LogPath & LogFile For Append As #FileNumber
Print #FileNumber, LogData
Close #FileNumber
'
If SendToDbgView = True Or ToDbgView = True Then DbgView LogStr
If SendToWebView = True Or ToWebView = True Then WebView LogStr
If SendToFormView = True Or ToFormView = True Then FormView LogStr
Save = LogData
End Function
Private Function MakeLogData(LogStr As String, LogLevel As EnumLogLevel) As Boolean
If IsEmpty(LogStr) = True Then Exit Function
'判断日志控制级别
If LogLevel < LogLevelControl Then Exit Function
'ok
If IsEmpty(LevelData) = True Then
LevelData = Array("INFO", "WARN", "DANGER", "ERROR")
End If
LogData = "[" & Now & "] [" & LevelData(LogLevel) & "] " & LogStr
If App.LogMode = 0 And DebugPring = True Then Debug.Print LogData
MakeLogData = True
End Function
用法:既可以试试通过调试工具实时观察日志,又可以自动按分类目录写入日志文件。
在任意需要调试信息的地方直接调用模块方法:
'通道1:写入磁盘文件,一般用于部署正式版的时候写日志文件
LogTools.Save "存储这个消息到磁盘日志文件"
LogTools.Save "这是一个调试信息", debug,是否输出到窗体,是否输出到DbgView,是否输出到网页
'通道2:输出日志到DdbView软件,实时显示,用于调试,可过滤前置关键词
LogTools.DbgView "这是一个调试的危险消息",Danger
'通道3:输出日志到网页控制台界面,走webosckt实时显示,用于调试,无需软件,直接浏览器观看
LogTools.WebView "这是一个调试的警告消息",Warn
'通道4:输出日志到vb窗口界面的listbox控件,走对象实时显示,用于调试观看
LogTools.FormView "这是一个调试的错误日志消息",Error
'这里是其他代码
‘参考:
‘vb6使用 OutputDebugString 配合 debugview 工具进行调试输出 – VB6.PRO
https://vb6.pro/vi/1233
Views: 260
One Comment