602 lines
13 KiB
Markdown
602 lines
13 KiB
Markdown
# logger.dll 使用教程
|
||
## 1. 创建DLL工具实例
|
||
### 加载DLL文件
|
||
```gotemplate
|
||
package logs
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"os"
|
||
"runtime"
|
||
"syscall"
|
||
"unsafe"
|
||
)
|
||
|
||
// LoggerDLL 封装 logger.dll 操作
|
||
type LoggerDLL struct {
|
||
dll *syscall.LazyDLL
|
||
createLogger *syscall.LazyProc
|
||
createContext *syscall.LazyProc
|
||
logInfo *syscall.LazyProc
|
||
logError *syscall.LazyProc
|
||
logWarning *syscall.LazyProc
|
||
logSuccess *syscall.LazyProc
|
||
freeString *syscall.LazyProc
|
||
closeAllLoggers *syscall.LazyProc
|
||
}
|
||
|
||
// LoggerConfig logger配置结构
|
||
type LoggerConfig struct {
|
||
LogDir string `json:"log_dir"`
|
||
SplitType int `json:"split_type"`
|
||
RotateType int `json:"rotate_type"`
|
||
MaxSize int64 `json:"max_size"`
|
||
MaxCount int `json:"max_count"`
|
||
Level int `json:"level"`
|
||
EnableCaller bool `json:"enable_caller"`
|
||
DefaultTaskType string `json:"default_task_type"`
|
||
}
|
||
|
||
var loggerDLLInstance *LoggerDLL
|
||
var loggerHandle string
|
||
var loggerContextHandle string
|
||
|
||
// ensureLoggerDLL 确保logger DLL已加载
|
||
func ensureLoggerDLL() (*LoggerDLL, error) {
|
||
if loggerDLLInstance != nil {
|
||
return loggerDLLInstance, nil
|
||
}
|
||
|
||
// 检查是否在Windows平台
|
||
if runtime.GOOS != "windows" {
|
||
return nil, fmt.Errorf("logger DLL only supported on Windows platform")
|
||
}
|
||
|
||
// logger.dll 位于 dll/logger.dll
|
||
//dllPath := filepath.Join("modules", "logs", "logger.dll")
|
||
dllPath := "D:\\www\\wwwroot\\planA\\modules\\logs\\logger.dll"
|
||
|
||
// 检查文件是否存在
|
||
if _, err := os.Stat(dllPath); os.IsNotExist(err) {
|
||
// 尝试从当前目录查找
|
||
if _, err := os.Stat("logger.dll"); err == nil {
|
||
dllPath = "logger.dll"
|
||
} else {
|
||
return nil, fmt.Errorf("logger DLL not found at %s", dllPath)
|
||
}
|
||
}
|
||
|
||
dll := syscall.NewLazyDLL(dllPath)
|
||
|
||
loggerDLLInstance = &LoggerDLL{
|
||
dll: dll,
|
||
createLogger: dll.NewProc("CreateLogger"),
|
||
createContext: dll.NewProc("CreateContextWithTaskType"),
|
||
logInfo: dll.NewProc("LogInfo"),
|
||
logError: dll.NewProc("LogError"),
|
||
logWarning: dll.NewProc("LogWarning"),
|
||
logSuccess: dll.NewProc("LogSuccess"),
|
||
freeString: dll.NewProc("FreeString"),
|
||
closeAllLoggers: dll.NewProc("CloseAllLoggers"),
|
||
}
|
||
|
||
return loggerDLLInstance, nil
|
||
}
|
||
|
||
// cStr 将 C 字符串指针转换为 Go 字符串
|
||
func cStr(ptr uintptr) string {
|
||
if ptr == 0 {
|
||
return ""
|
||
}
|
||
var b []byte
|
||
for {
|
||
c := *(*byte)(unsafe.Pointer(ptr))
|
||
if c == 0 {
|
||
break
|
||
}
|
||
b = append(b, c)
|
||
ptr++
|
||
}
|
||
return string(b)
|
||
}
|
||
|
||
// InitializeLogger 初始化logger
|
||
func InitializeLogger(logDir string) error {
|
||
m, err := ensureLoggerDLL()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 确保日志目录存在
|
||
if err := os.MkdirAll(logDir, 0755); err != nil {
|
||
return fmt.Errorf("创建日志目录失败: %v", err)
|
||
}
|
||
|
||
// 创建logger配置
|
||
config := LoggerConfig{
|
||
LogDir: logDir,
|
||
SplitType: 1, // SplitByDay
|
||
RotateType: 0, // RotateBySize
|
||
MaxSize: 100 * 1024 * 1024, // 100MB
|
||
MaxCount: 10,
|
||
Level: 1, // LevelInfo - 只显示INFO及以上级别的日志
|
||
EnableCaller: true,
|
||
DefaultTaskType: "main",
|
||
}
|
||
|
||
configJSON, err := json.Marshal(config)
|
||
if err != nil {
|
||
return fmt.Errorf("序列化配置失败: %v", err)
|
||
}
|
||
|
||
// 调用CreateLogger
|
||
configPtr, _ := syscall.BytePtrFromString(string(configJSON))
|
||
ret, _, _ := m.createLogger.Call(uintptr(unsafe.Pointer(configPtr)))
|
||
|
||
if ret == 0 {
|
||
return fmt.Errorf("创建logger失败")
|
||
}
|
||
|
||
// 获取logger句柄
|
||
handle := cStr(ret)
|
||
loggerHandle = handle
|
||
|
||
// 释放返回的字符串
|
||
m.freeString.Call(ret)
|
||
|
||
// 创建默认上下文
|
||
return createLoggerContext("main")
|
||
}
|
||
|
||
// createLoggerContext 创建带任务类型的logger上下文
|
||
func createLoggerContext(taskType string) error {
|
||
m, err := ensureLoggerDLL()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if loggerHandle == "" {
|
||
return fmt.Errorf("logger未初始化")
|
||
}
|
||
|
||
handlePtr, _ := syscall.BytePtrFromString(loggerHandle)
|
||
taskTypePtr, _ := syscall.BytePtrFromString(taskType)
|
||
|
||
ret, _, _ := m.createContext.Call(
|
||
uintptr(unsafe.Pointer(handlePtr)),
|
||
uintptr(unsafe.Pointer(taskTypePtr)),
|
||
)
|
||
|
||
if ret == 0 {
|
||
return fmt.Errorf("创建logger上下文失败")
|
||
}
|
||
|
||
// 获取上下文句柄
|
||
loggerContextHandle = cStr(ret)
|
||
|
||
// 释放返回的字符串
|
||
m.freeString.Call(ret)
|
||
|
||
return nil
|
||
}
|
||
|
||
// SetLogTaskType 设置当前日志任务类型
|
||
func SetLogTaskType(taskType string) error {
|
||
return createLoggerContext(taskType)
|
||
}
|
||
|
||
// LogInfo 记录信息日志
|
||
func LogInfo(message string) error {
|
||
m, err := ensureLoggerDLL()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if loggerContextHandle == "" {
|
||
return fmt.Errorf("logger上下文未初始化")
|
||
}
|
||
|
||
ctxPtr, _ := syscall.BytePtrFromString(loggerContextHandle)
|
||
msgPtr, _ := syscall.BytePtrFromString(message)
|
||
|
||
m.logInfo.Call(
|
||
uintptr(unsafe.Pointer(ctxPtr)),
|
||
uintptr(unsafe.Pointer(msgPtr)),
|
||
)
|
||
|
||
return nil
|
||
}
|
||
|
||
// LogError 记录错误日志
|
||
func LogError(message string) error {
|
||
m, err := ensureLoggerDLL()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if loggerContextHandle == "" {
|
||
return fmt.Errorf("logger上下文未初始化")
|
||
}
|
||
|
||
ctxPtr, _ := syscall.BytePtrFromString(loggerContextHandle)
|
||
msgPtr, _ := syscall.BytePtrFromString(message)
|
||
|
||
m.logError.Call(
|
||
uintptr(unsafe.Pointer(ctxPtr)),
|
||
uintptr(unsafe.Pointer(msgPtr)),
|
||
)
|
||
|
||
return nil
|
||
}
|
||
|
||
// LogWarning 记录警告日志
|
||
func LogWarning(message string) error {
|
||
m, err := ensureLoggerDLL()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if loggerContextHandle == "" {
|
||
return fmt.Errorf("logger上下文未初始化")
|
||
}
|
||
|
||
ctxPtr, _ := syscall.BytePtrFromString(loggerContextHandle)
|
||
msgPtr, _ := syscall.BytePtrFromString(message)
|
||
|
||
m.logWarning.Call(
|
||
uintptr(unsafe.Pointer(ctxPtr)),
|
||
uintptr(unsafe.Pointer(msgPtr)),
|
||
)
|
||
|
||
return nil
|
||
}
|
||
|
||
// LogSuccess 记录成功日志
|
||
func LogSuccess(message string) error {
|
||
m, err := ensureLoggerDLL()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if loggerContextHandle == "" {
|
||
return fmt.Errorf("logger上下文未初始化")
|
||
}
|
||
|
||
ctxPtr, _ := syscall.BytePtrFromString(loggerContextHandle)
|
||
msgPtr, _ := syscall.BytePtrFromString(message)
|
||
|
||
m.logSuccess.Call(
|
||
uintptr(unsafe.Pointer(ctxPtr)),
|
||
uintptr(unsafe.Pointer(msgPtr)),
|
||
)
|
||
|
||
return nil
|
||
}
|
||
|
||
// CloseLogger 关闭logger
|
||
func CloseLogger() error {
|
||
m, err := ensureLoggerDLL()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
ret, _, _ := m.closeAllLoggers.Call()
|
||
if ret == 0 {
|
||
return fmt.Errorf("关闭logger失败")
|
||
}
|
||
|
||
m.freeString.Call(ret)
|
||
|
||
loggerHandle = ""
|
||
loggerContextHandle = ""
|
||
loggerDLLInstance = nil
|
||
|
||
return nil
|
||
}
|
||
|
||
// GetLoggerHandle 获取当前logger句柄(用于外部调用)
|
||
func GetLoggerHandle() string {
|
||
return loggerContextHandle
|
||
}
|
||
|
||
// IsLoggerInitialized 检查logger是否已初始化
|
||
func IsLoggerInitialized() bool {
|
||
return loggerHandle != "" && loggerContextHandle != ""
|
||
}
|
||
|
||
// SetConsoleOutput 设置控制台输出开关
|
||
func SetConsoleOutput(enabled bool) {
|
||
if enabled {
|
||
os.Setenv("LOG_CONSOLE", "true")
|
||
} else {
|
||
os.Setenv("LOG_CONSOLE", "false")
|
||
}
|
||
}
|
||
|
||
// LogWithLevel 带级别的日志记录,可以精确控制显示
|
||
func LogWithLevel(level, message string, showConsole bool) {
|
||
if !IsLoggerInitialized() {
|
||
return
|
||
}
|
||
|
||
switch level {
|
||
case "ERROR":
|
||
LogError(message)
|
||
case "WARNING":
|
||
LogWarning(message)
|
||
case "SUCCESS":
|
||
LogSuccess(message)
|
||
case "INFO":
|
||
LogInfo(message)
|
||
default:
|
||
LogInfo(message)
|
||
}
|
||
}
|
||
|
||
// LogOnlyFile 仅写入文件,不输出到控制台
|
||
func LogOnlyFile(level, message string) {
|
||
// 临时禁用控制台输出
|
||
os.Setenv("LOG_CONSOLE", "false")
|
||
LogWithLevel(level, message, false)
|
||
}
|
||
|
||
// LogConsoleAndFile 同时输出到控制台和文件
|
||
func LogConsoleAndFile(level, message string) {
|
||
// 临时启用控制台输出
|
||
os.Setenv("LOG_CONSOLE", "true")
|
||
LogWithLevel(level, message, true)
|
||
}
|
||
|
||
```
|
||
|
||
# 接口详情
|
||
## 创建日志器--CreateLogger
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.CreateLogger(configJSON)
|
||
```
|
||
### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--|--|--|--------------|
|
||
| configJSON | string | 是 | 配置信息JSON字符串 |
|
||
#### 配置JSON结构
|
||
```json
|
||
{
|
||
"log_dir": "/path/to/logs",
|
||
"split_type": 0,
|
||
"rotate_type": 0,
|
||
"max_size": 104857600,
|
||
"max_count": 30,
|
||
"level": 1,
|
||
"enable_caller": true,
|
||
"default_task_type": "main"
|
||
}
|
||
```
|
||
#### 参数说明:
|
||
```text
|
||
log_dir: 日志目录路径
|
||
split_type: 分片方式(0=按月,1=按天,2=按小时,3=按分钟,4=按秒)
|
||
rotate_type: 轮转方式(0=按大小,1=按数量)
|
||
max_size: 最大文件大小(字节),仅在rotate_type=0时有效
|
||
max_count: 最大文件数量,仅在rotate_type=1时有效
|
||
level: 日志级别(0=SUCCESS,1=INFO,2=WARNING,3=ERROR)
|
||
enable_caller: 是否启用调用者信息
|
||
default_task_type: 默认任务类型
|
||
```
|
||
### 响应示例
|
||
```json
|
||
"错误: 创建日志目录失败: permission denied"
|
||
```
|
||
|
||
## 创建带任务类型的上下文--CreateContextWithTaskType
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.CreateContextWithTaskType(loggerHandle, taskType)
|
||
```
|
||
### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--|--|--|--------------|
|
||
| loggerHandle | string | 是 | 日志器句柄 |
|
||
| taskType | string | 是 | 任务类型 |
|
||
### 响应示例
|
||
```json
|
||
"ctx_1645497600000000000"
|
||
```
|
||
#### 错误响应示例
|
||
```json
|
||
"错误: 无效的logger句柄"
|
||
```
|
||
|
||
## 记录信息日志--LogInfo
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.LogInfo(ctxHandle, message)
|
||
```
|
||
### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--|--|--|--------------|
|
||
| ctxHandle | string | 是 | 上下文句柄 |
|
||
| message | string | 是 | 日志消息 |
|
||
### 响应示例
|
||
```text
|
||
无返回值,日志将写入到对应的日志文件中。
|
||
```
|
||
|
||
## 记录错误日志--LogError
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.LogError(ctxHandle, message)
|
||
```
|
||
### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--|--|--|--------------|
|
||
| ctxHandle | string | 是 | 上下文句柄 |
|
||
| message | string | 是 | 日志消息 |
|
||
### 响应示例
|
||
```text
|
||
无返回值,日志将写入到对应的日志文件中。
|
||
```
|
||
|
||
## 记录警告日志--LogWarning
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.LogWarning(ctxHandle, message)
|
||
```
|
||
### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--|--|--|--------------|
|
||
| ctxHandle | string | 是 | 上下文句柄 |
|
||
| message | string | 是 | 日志消息 |
|
||
### 响应示例
|
||
```text
|
||
无返回值,日志将写入到对应的日志文件中。
|
||
```
|
||
|
||
## 记录成功日志--LogSuccess
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.LogSuccess(ctxHandle, message)
|
||
```
|
||
### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--|--|--|--------------|
|
||
| ctxHandle | string | 是 | 上下文句柄 |
|
||
| message | string | 是 | 日志消息 |
|
||
### 响应示例
|
||
```text
|
||
无返回值,日志将写入到对应的日志文件中。
|
||
```
|
||
|
||
## 获取日志条目--GetLogs
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.GetLogs(loggerHandle, configJSON)
|
||
```
|
||
### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--|--|--|-----------|
|
||
| loggerHandle | string | 是 | 日志器句柄 |
|
||
| configJSON | string | 是 | 查询配置JSON |
|
||
#### 查询配置JSON结构
|
||
```json
|
||
{
|
||
"level": 1,
|
||
"task_type": "main",
|
||
"start_time": "2024-01-01 00:00:00",
|
||
"end_time": "2024-01-31 23:59:59",
|
||
"max_entries": 1000
|
||
}
|
||
```
|
||
#### 参数说明:
|
||
```text
|
||
level: 日志级别(-1表示所有级别)
|
||
task_type: 任务类型(空字符串表示所有任务类型)
|
||
start_time: 开始时间(格式: 2006-01-02 15:04:05)
|
||
end_time: 结束时间(格式: 2006-01-02 15:04:05)
|
||
max_entries: 最大返回条目数(0表示使用默认值1000)
|
||
```
|
||
### 响应示例
|
||
```json
|
||
{
|
||
"count": 125,
|
||
"entries": [
|
||
{
|
||
"timestamp": "2024-01-15 10:30:45.123",
|
||
"level": "INFO",
|
||
"task_type": "main",
|
||
"caller": "logger.go:256",
|
||
"message": "系统启动完成"
|
||
},
|
||
{
|
||
"timestamp": "2024-01-15 10:31:15.456",
|
||
"level": "ERROR",
|
||
"task_type": "backup",
|
||
"caller": "backup.go:89",
|
||
"message": "备份文件失败: 磁盘空间不足"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
### 错误响应示例
|
||
```json
|
||
{"error": "无效的logger句柄"}
|
||
```
|
||
|
||
## 获取日志文件列表--GetLogFiles
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.GetLogFiles(loggerHandle)
|
||
```
|
||
### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--|--|--|-----------|
|
||
| loggerHandle | string | 是 | 日志器句柄 |
|
||
### 响应示例
|
||
```json
|
||
{
|
||
"count": 8,
|
||
"files": [
|
||
{
|
||
"level": "INFO",
|
||
"task_type": "main",
|
||
"file_name": "INFO-main-2024-01.logs",
|
||
"file_size": 1048576,
|
||
"mod_time": "2024-01-15 10:30:45"
|
||
},
|
||
{
|
||
"level": "ERROR",
|
||
"task_type": "backup",
|
||
"file_name": "ERROR-backup-2024-01.logs",
|
||
"file_size": 51200,
|
||
"mod_time": "2024-01-15 10:31:15"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
### 错误响应示例
|
||
```json
|
||
{"error": "无效的logger句柄"}
|
||
```
|
||
|
||
## 获取版本信息--GetVersion
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.GetVersion()
|
||
```
|
||
### 请求参数
|
||
```text
|
||
无参数
|
||
```
|
||
### 响应示例
|
||
```json
|
||
"v1"
|
||
```
|
||
|
||
## 关闭所有日志器--CloseAllLoggers
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.CloseAllLoggers()
|
||
```
|
||
### 请求参数
|
||
```text
|
||
无参数
|
||
```
|
||
### 响应示例
|
||
```json
|
||
"成功关闭所有logger"
|
||
```
|
||
### 错误响应示例
|
||
```json
|
||
"关闭了5个logger,其中1个出错,最后错误: close file error"
|
||
```
|
||
|
||
## 释放C字符串内存--FreeString
|
||
### 请求信息
|
||
```gotemplate
|
||
dll.FreeString(str)
|
||
```
|
||
### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--|--|--|-----------|
|
||
| str | string | 是 | 需要释放的字符串 | |