基于Go语言的动态插件系统,支持热插拔和动态加载插件。
This commit is contained in:
330
plugins/defaultlogger/default_logger_plugin.go
Normal file
330
plugins/defaultlogger/default_logger_plugin.go
Normal file
@@ -0,0 +1,330 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/darkit/plugins"
|
||||
)
|
||||
|
||||
// DefaultLoggerPlugin 默认日志插件
|
||||
// 提供文件日志和控制台日志功能,使用默认插件类型
|
||||
type DefaultLoggerPlugin struct {
|
||||
*plugins.BasePlugin // 嵌入基本插件结构
|
||||
logFile *os.File // 日志文件
|
||||
logger *log.Logger // 日志记录器
|
||||
config map[string]interface{} // 配置
|
||||
}
|
||||
|
||||
// Plugin 导出的插件变量
|
||||
// 注意:变量名必须是Plugin,大小写敏感
|
||||
// 这个插件使用默认的通用插件类型(PluginTypeGeneral)
|
||||
var Plugin plugins.IPlugin = &DefaultLoggerPlugin{
|
||||
BasePlugin: plugins.NewBasePluginWithDefaultType(
|
||||
"DefaultLoggerPlugin",
|
||||
"1.0.0",
|
||||
"使用默认通用类型的日志记录插件",
|
||||
"开发者",
|
||||
), // 将自动使用 PluginTypeGeneral 类型
|
||||
}
|
||||
|
||||
// Init 初始化插件
|
||||
func (p *DefaultLoggerPlugin) Init(ctx context.Context, config map[string]interface{}) error {
|
||||
p.config = config
|
||||
|
||||
// 获取日志文件路径
|
||||
logPath, ok := config["log_path"].(string)
|
||||
if !ok {
|
||||
// 使用默认路径
|
||||
logPath = "logs/default"
|
||||
}
|
||||
|
||||
// 确保日志目录存在
|
||||
if err := os.MkdirAll(logPath, 0o755); err != nil {
|
||||
return fmt.Errorf("创建日志目录失败: %v", err)
|
||||
}
|
||||
|
||||
// 创建日志文件
|
||||
logFilePath := filepath.Join(logPath, fmt.Sprintf("default_app_%s.log", time.Now().Format("2006-01-02")))
|
||||
logFile, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("打开日志文件失败: %v", err)
|
||||
}
|
||||
|
||||
p.logFile = logFile
|
||||
p.logger = log.New(logFile, "[DefaultLoggerPlugin] ", log.LstdFlags)
|
||||
|
||||
p.logger.Println("默认日志插件初始化完成")
|
||||
fmt.Printf("默认日志插件初始化完成,日志文件: %s,插件类型: %s\n", logFilePath, p.Type())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start 启动插件
|
||||
func (p *DefaultLoggerPlugin) Start(ctx context.Context) error {
|
||||
if p.logger == nil {
|
||||
return fmt.Errorf("插件未初始化")
|
||||
}
|
||||
|
||||
p.logger.Println("默认日志插件已启动")
|
||||
fmt.Println("默认日志插件已启动")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop 停止插件
|
||||
func (p *DefaultLoggerPlugin) Stop(ctx context.Context) error {
|
||||
if p.logger != nil {
|
||||
p.logger.Println("默认日志插件正在停止")
|
||||
}
|
||||
|
||||
if p.logFile != nil {
|
||||
if err := p.logFile.Close(); err != nil {
|
||||
return fmt.Errorf("关闭日志文件失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("默认日志插件已停止")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Log 记录日志
|
||||
func (p *DefaultLoggerPlugin) Log(level, message string) {
|
||||
if p.logger == nil {
|
||||
fmt.Printf("[DEFAULT][%s] %s\n", level, message)
|
||||
return
|
||||
}
|
||||
|
||||
logMsg := fmt.Sprintf("[%s] %s", level, message)
|
||||
p.logger.Println(logMsg)
|
||||
|
||||
// 如果配置了同时输出到控制台
|
||||
if consoleOutput, ok := p.config["console_output"].(bool); ok && consoleOutput {
|
||||
fmt.Println(logMsg)
|
||||
}
|
||||
}
|
||||
|
||||
// Info 记录信息日志
|
||||
func (p *DefaultLoggerPlugin) Info(message string) {
|
||||
p.Log("INFO", message)
|
||||
}
|
||||
|
||||
// Warn 记录警告日志
|
||||
func (p *DefaultLoggerPlugin) Warn(message string) {
|
||||
p.Log("WARN", message)
|
||||
}
|
||||
|
||||
// Error 记录错误日志
|
||||
func (p *DefaultLoggerPlugin) Error(message string) {
|
||||
p.Log("ERROR", message)
|
||||
}
|
||||
|
||||
// GetOperationInfo 获取操作的参数信息
|
||||
func (p *DefaultLoggerPlugin) GetOperationInfo(operation string) (*plugins.OperationInfo, error) {
|
||||
switch operation {
|
||||
case "log":
|
||||
return &plugins.OperationInfo{
|
||||
Name: "log",
|
||||
Description: "记录日志",
|
||||
Params: []plugins.OperationParamInfo{
|
||||
{
|
||||
Name: "level",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Default: "INFO",
|
||||
Description: "日志级别,可选值:INFO, WARN, ERROR",
|
||||
},
|
||||
{
|
||||
Name: "message",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Default: "",
|
||||
Description: "日志消息",
|
||||
},
|
||||
},
|
||||
Extra: map[string]interface{}{
|
||||
"category": "日志操作",
|
||||
},
|
||||
}, nil
|
||||
case "info":
|
||||
return &plugins.OperationInfo{
|
||||
Name: "info",
|
||||
Description: "记录信息日志",
|
||||
Params: []plugins.OperationParamInfo{
|
||||
{
|
||||
Name: "message",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Default: "",
|
||||
Description: "日志消息",
|
||||
},
|
||||
},
|
||||
Extra: map[string]interface{}{
|
||||
"category": "日志操作",
|
||||
},
|
||||
}, nil
|
||||
case "warn":
|
||||
return &plugins.OperationInfo{
|
||||
Name: "warn",
|
||||
Description: "记录警告日志",
|
||||
Params: []plugins.OperationParamInfo{
|
||||
{
|
||||
Name: "message",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Default: "",
|
||||
Description: "日志消息",
|
||||
},
|
||||
},
|
||||
Extra: map[string]interface{}{
|
||||
"category": "日志操作",
|
||||
},
|
||||
}, nil
|
||||
case "error":
|
||||
return &plugins.OperationInfo{
|
||||
Name: "error",
|
||||
Description: "记录错误日志",
|
||||
Params: []plugins.OperationParamInfo{
|
||||
{
|
||||
Name: "message",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Default: "",
|
||||
Description: "日志消息",
|
||||
},
|
||||
},
|
||||
Extra: map[string]interface{}{
|
||||
"category": "日志操作",
|
||||
},
|
||||
}, nil
|
||||
case "console":
|
||||
return &plugins.OperationInfo{
|
||||
Name: "console",
|
||||
Description: "向控制台打印日志",
|
||||
Params: []plugins.OperationParamInfo{
|
||||
{
|
||||
Name: "level",
|
||||
Type: "string",
|
||||
Required: false,
|
||||
Default: "INFO",
|
||||
Description: "日志级别,可选值:INFO, WARN, ERROR",
|
||||
},
|
||||
{
|
||||
Name: "message",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Default: "",
|
||||
Description: "日志消息",
|
||||
},
|
||||
},
|
||||
Extra: map[string]interface{}{
|
||||
"category": "控制台操作",
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("插件 %s 不支持 %s 操作", p.Name(), operation)
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllOperations 获取所有操作及其参数信息
|
||||
func (p *DefaultLoggerPlugin) GetAllOperations() []*plugins.OperationInfo {
|
||||
operations := []*plugins.OperationInfo{}
|
||||
|
||||
// 添加所有支持的操作
|
||||
ops := []string{"log", "info", "warn", "error", "console"}
|
||||
for _, op := range ops {
|
||||
info, _ := p.GetOperationInfo(op)
|
||||
operations = append(operations, info)
|
||||
}
|
||||
|
||||
return operations
|
||||
}
|
||||
|
||||
// Execute 实现执行插件功能的方法
|
||||
func (p *DefaultLoggerPlugin) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
|
||||
switch action {
|
||||
case "log":
|
||||
// 获取参数
|
||||
level, ok := params["level"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("缺少日志级别参数或类型错误")
|
||||
}
|
||||
message, ok := params["message"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("缺少日志消息参数或类型错误")
|
||||
}
|
||||
|
||||
// 记录日志
|
||||
p.Log(level, message)
|
||||
return map[string]interface{}{"success": true, "message": "日志已记录"}, nil
|
||||
|
||||
case "info":
|
||||
// 获取参数
|
||||
message, ok := params["message"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("缺少日志消息参数或类型错误")
|
||||
}
|
||||
|
||||
// 记录信息日志
|
||||
p.Info(message)
|
||||
return map[string]interface{}{"success": true, "message": "信息日志已记录"}, nil
|
||||
|
||||
case "warn":
|
||||
// 获取参数
|
||||
message, ok := params["message"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("缺少日志消息参数或类型错误")
|
||||
}
|
||||
|
||||
// 记录警告日志
|
||||
p.Warn(message)
|
||||
return map[string]interface{}{"success": true, "message": "警告日志已记录"}, nil
|
||||
|
||||
case "error":
|
||||
// 获取参数
|
||||
message, ok := params["message"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("缺少日志消息参数或类型错误")
|
||||
}
|
||||
|
||||
// 记录错误日志
|
||||
p.Error(message)
|
||||
return map[string]interface{}{"success": true, "message": "错误日志已记录"}, nil
|
||||
|
||||
case "console":
|
||||
// 获取参数
|
||||
level := "INFO" // 默认级别
|
||||
if levelParam, ok := params["level"].(string); ok && levelParam != "" {
|
||||
level = levelParam
|
||||
}
|
||||
|
||||
message, ok := params["message"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("缺少日志消息参数或类型错误")
|
||||
}
|
||||
|
||||
// 强制输出到控制台,无论配置如何
|
||||
formattedMsg := fmt.Sprintf("[控制台][%s] %s", level, message)
|
||||
fmt.Println(formattedMsg)
|
||||
|
||||
// 同时也记录到日志文件
|
||||
p.Log(level, fmt.Sprintf("[Web控制台] %s", message))
|
||||
|
||||
return map[string]interface{}{
|
||||
"success": true,
|
||||
"message": "日志已输出到控制台",
|
||||
"console_output": formattedMsg,
|
||||
}, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("不支持的操作: %s", action)
|
||||
}
|
||||
}
|
||||
|
||||
// main 函数是必须的,但不会被调用
|
||||
func main() {
|
||||
// 不会被执行,仅用于编译插件
|
||||
}
|
||||
Reference in New Issue
Block a user