增强插件系统:添加硬件插件类型及默认插件构造函数

- 在插件类型中新增硬件插件类型(PluginTypeHardware),以支持更多插件类型的扩展。
- 添加便捷的构造函数 NewBasePluginWithDefaultType 和 NewPluginWithDefaultType,简化插件创建过程,适用于不需要指定特殊类型的场景。
- 更新日志插件和统计插件的创建示例,展示如何使用默认插件类型。

此更新提升了插件系统的灵活性,便于开发者快速创建和管理插件。
This commit is contained in:
2025-03-14 11:14:47 +08:00
parent 098c721ee9
commit 0990e8c42c
7 changed files with 294 additions and 25 deletions

View File

@@ -1,22 +1,63 @@
#!/bin/bash
# 编译插件
go build -buildmode=plugin -o stats.so ./stats/stats.go
# 构建脚本,用于编译所有插件
# 检查编译结果
# 确保输出目录存在
mkdir -p dist
echo "===== 开始编译插件 ====="
# 编译带有明确类型的日志插件
echo "编译日志插件 (明确类型)..."
cd logger
go build -buildmode=plugin -o ../dist/logger.so
if [ $? -eq 0 ]; then
echo "插件编译成功: stats.so"
echo "日志插件编译成功"
else
echo "插件编译失败"
echo "日志插件编译失败"
exit 1
fi
fi
cd ..
go build -buildmode=plugin -o logger.so ./logger/logger.go
# 检查编译结果
# 编译使用默认类型的日志插件
echo "编译默认日志插件 (默认类型)..."
cd defaultlogger
go build -buildmode=plugin -o ../dist/defaultlogger.so
if [ $? -eq 0 ]; then
echo "插件编译成功: logger.so"
echo "默认日志插件编译成功"
else
echo "插件编译失败"
echo "默认日志插件编译失败"
exit 1
fi
fi
cd ..
# 编译统计插件
echo "编译统计插件..."
cd stats
go build -buildmode=plugin -o ../dist/stats.so
if [ $? -eq 0 ]; then
echo "统计插件编译成功!"
else
echo "统计插件编译失败!"
exit 1
fi
cd ..
# 编译存储插件
echo "编译存储插件..."
cd storage
go build -buildmode=plugin -o ../dist/storage.so
if [ $? -eq 0 ]; then
echo "存储插件编译成功!"
else
echo "存储插件编译失败!"
exit 1
fi
cd ..
echo "===== 所有插件编译完成 ====="
echo "插件文件保存在 dist 目录中:"
ls -la dist/
# 对于Windows系统添加.exe后缀
# go build -buildmode=plugin -o ../dist/plugin_name.dll

View File

@@ -0,0 +1,128 @@
package main
import (
"context"
"fmt"
"log"
"os"
"path/filepath"
"time"
"github.com/darkit/goproxy/examples/plugin"
)
// DefaultLoggerPlugin 默认日志插件
// 提供文件日志和控制台日志功能,使用默认插件类型
type DefaultLoggerPlugin struct {
*plugin.BasePlugin // 嵌入基本插件结构
logFile *os.File // 日志文件
logger *log.Logger // 日志记录器
config map[string]interface{} // 配置
}
// Plugin 导出的插件变量
// 注意变量名必须是Plugin大小写敏感
// 这个插件使用默认的通用插件类型PluginTypeGeneral
var Plugin = &DefaultLoggerPlugin{
BasePlugin: plugin.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)
}
// main 函数是必须的,但不会被调用
func main() {
// 不会被执行,仅用于编译插件
}

View File

@@ -22,16 +22,29 @@ type LoggerPlugin struct {
// Plugin 导出的插件变量
// 注意变量名必须是Plugin大小写敏感
// 使用方式1: 明确指定插件类型
var Plugin = &LoggerPlugin{
BasePlugin: plugin.NewBasePlugin(
"LoggerPlugin",
"1.0.0",
"简单的日志记录插件",
"开发者",
plugin.PluginTypeUtils, // 设置插件类型为工具插件
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
@@ -59,7 +72,7 @@ func (p *LoggerPlugin) Init(ctx context.Context, config map[string]interface{})
p.logger = log.New(logFile, "[LoggerPlugin] ", log.LstdFlags)
p.logger.Println("日志插件初始化完成")
fmt.Println("日志插件初始化完成,日志文件:", logFilePath)
fmt.Printf("日志插件初始化完成,日志文件: %s插件类型: %s\n", logFilePath, p.Type())
return nil
}

View File

@@ -23,17 +23,30 @@ type StatsPlugin struct {
// Plugin 导出的插件变量
var Plugin = &StatsPlugin{
BasePlugin: plugin.NewBasePlugin(
// 使用默认构造函数,不指定插件类型,将默认为通用插件
BasePlugin: plugin.NewBasePluginWithDefaultType(
"StatsPlugin",
"1.0.0",
"系统运行时统计插件",
"开发者",
plugin.PluginTypeUtils, // 设置为工具类插件
),
stats: make(map[string]int64),
tickerStop: make(chan bool),
}
// 为展示如何指定类型,我们也可以显式设置插件类型
// var Plugin = &StatsPlugin{
// BasePlugin: plugin.NewBasePlugin(
// "StatsPlugin",
// "1.0.0",
// "系统运行时统计插件",
// "开发者",
// plugin.PluginTypeUtils, // 明确指定为工具类插件
// ),
// stats: make(map[string]int64),
// tickerStop: make(chan bool),
// }
// Init 初始化插件
func (p *StatsPlugin) Init(ctx context.Context, config map[string]interface{}) error {
p.config = config