- 在插件接口和基本插件实现中新增 Execute 方法,支持插件功能的动态执行。 - 更新各个插件(如日志插件、统计插件、存储插件等)以实现 Execute 方法,允许通过操作名称和参数执行特定功能。 - 在插件管理器中添加 ExecutePlugin、ExecutePluginsByType 和 ExecuteAllPlugins 方法,便于批量执行插件操作。 - 示例程序中更新插件调用方式,展示如何使用 Execute 方法进行操作。 此更新提升了插件系统的灵活性和可扩展性,便于开发者动态管理和执行插件功能。
198 lines
4.8 KiB
Go
198 lines
4.8 KiB
Go
package main
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"path/filepath"
|
||
"time"
|
||
|
||
"github.com/darkit/goproxy/examples/plugin"
|
||
)
|
||
|
||
// LoggerPlugin 日志插件
|
||
// 提供文件日志和控制台日志功能
|
||
type LoggerPlugin struct {
|
||
*plugin.BasePlugin // 嵌入基本插件结构
|
||
logFile *os.File // 日志文件
|
||
logger *log.Logger // 日志记录器
|
||
config map[string]interface{} // 配置
|
||
}
|
||
|
||
// Plugin 导出的插件变量
|
||
// 注意:变量名必须是Plugin,大小写敏感
|
||
// 使用方式1: 明确指定插件类型
|
||
var Plugin = &LoggerPlugin{
|
||
BasePlugin: plugin.NewBasePlugin(
|
||
"LoggerPlugin",
|
||
"1.0.0",
|
||
"简单的日志记录插件",
|
||
"开发者",
|
||
plugin.PluginTypeUtils, // 明确指定为工具类插件
|
||
),
|
||
}
|
||
|
||
// 使用方式2: 使用默认插件类型(通用插件)
|
||
// 如果您不关心插件类型或想使用默认的通用插件类型,可以使用以下方式:
|
||
//
|
||
// var Plugin = &LoggerPlugin{
|
||
// BasePlugin: plugin.NewBasePluginWithDefaultType(
|
||
// "LoggerPlugin",
|
||
// "1.0.0",
|
||
// "简单的日志记录插件",
|
||
// "开发者",
|
||
// ), // 将自动使用 PluginTypeGeneral 类型
|
||
// }
|
||
|
||
// Init 初始化插件
|
||
func (p *LoggerPlugin) Init(ctx context.Context, config map[string]interface{}) error {
|
||
p.config = config
|
||
|
||
// 获取日志文件路径
|
||
logPath, ok := config["log_path"].(string)
|
||
if !ok {
|
||
// 使用默认路径
|
||
logPath = "logs"
|
||
}
|
||
|
||
// 确保日志目录存在
|
||
if err := os.MkdirAll(logPath, 0o755); err != nil {
|
||
return fmt.Errorf("创建日志目录失败: %v", err)
|
||
}
|
||
|
||
// 创建日志文件
|
||
logFilePath := filepath.Join(logPath, fmt.Sprintf("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, "[LoggerPlugin] ", log.LstdFlags)
|
||
|
||
p.logger.Println("日志插件初始化完成")
|
||
fmt.Printf("日志插件初始化完成,日志文件: %s,插件类型: %s\n", logFilePath, p.Type())
|
||
|
||
return nil
|
||
}
|
||
|
||
// Start 启动插件
|
||
func (p *LoggerPlugin) Start(ctx context.Context) error {
|
||
if p.logger == nil {
|
||
return fmt.Errorf("插件未初始化")
|
||
}
|
||
|
||
p.logger.Println("日志插件已启动")
|
||
fmt.Println("日志插件已启动")
|
||
return nil
|
||
}
|
||
|
||
// Stop 停止插件
|
||
func (p *LoggerPlugin) 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
|
||
}
|
||
|
||
// Execute 执行插件功能
|
||
func (p *LoggerPlugin) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
|
||
switch action {
|
||
case "log":
|
||
// 需要参数: level, message
|
||
level, ok := params["level"].(string)
|
||
if !ok {
|
||
return nil, fmt.Errorf("缺少必需参数: level")
|
||
}
|
||
message, ok := params["message"].(string)
|
||
if !ok {
|
||
return nil, fmt.Errorf("缺少必需参数: message")
|
||
}
|
||
p.Log(level, message)
|
||
return true, nil
|
||
|
||
case "info":
|
||
// 需要参数: message
|
||
message, ok := params["message"].(string)
|
||
if !ok {
|
||
return nil, fmt.Errorf("缺少必需参数: message")
|
||
}
|
||
p.Info(message)
|
||
return true, nil
|
||
|
||
case "warn":
|
||
// 需要参数: message
|
||
message, ok := params["message"].(string)
|
||
if !ok {
|
||
return nil, fmt.Errorf("缺少必需参数: message")
|
||
}
|
||
p.Warn(message)
|
||
return true, nil
|
||
|
||
case "error":
|
||
// 需要参数: message
|
||
message, ok := params["message"].(string)
|
||
if !ok {
|
||
return nil, fmt.Errorf("缺少必需参数: message")
|
||
}
|
||
p.Error(message)
|
||
return true, nil
|
||
|
||
case "getLoggerStatus":
|
||
// 不需要参数
|
||
status := map[string]interface{}{
|
||
"initialized": p.logger != nil,
|
||
"config": p.config,
|
||
}
|
||
return status, nil
|
||
|
||
default:
|
||
return nil, fmt.Errorf("未知的操作: %s", action)
|
||
}
|
||
}
|
||
|
||
// Log 记录日志
|
||
func (p *LoggerPlugin) Log(level, message string) {
|
||
if p.logger == nil {
|
||
fmt.Printf("[%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 *LoggerPlugin) Info(message string) {
|
||
p.Log("INFO", message)
|
||
}
|
||
|
||
// Warn 记录警告日志
|
||
func (p *LoggerPlugin) Warn(message string) {
|
||
p.Log("WARN", message)
|
||
}
|
||
|
||
// Error 记录错误日志
|
||
func (p *LoggerPlugin) Error(message string) {
|
||
p.Log("ERROR", message)
|
||
}
|
||
|
||
// main 函数是必须的,但不会被调用
|
||
func main() {
|
||
// 不会被执行,仅用于编译插件
|
||
}
|