Files
goproxy/examples/plugin/manager/plugin_manager.go
DarkiT 9f78cb483b 增强插件系统:添加插件执行功能
- 在插件接口和基本插件实现中新增 Execute 方法,支持插件功能的动态执行。
- 更新各个插件(如日志插件、统计插件、存储插件等)以实现 Execute 方法,允许通过操作名称和参数执行特定功能。
- 在插件管理器中添加 ExecutePlugin、ExecutePluginsByType 和 ExecuteAllPlugins 方法,便于批量执行插件操作。
- 示例程序中更新插件调用方式,展示如何使用 Execute 方法进行操作。

此更新提升了插件系统的灵活性和可扩展性,便于开发者动态管理和执行插件功能。
2025-03-14 11:31:32 +08:00

273 lines
7.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"context"
"fmt"
"runtime"
"github.com/darkit/goproxy/examples/plugin"
)
// 这是内置插件的示例实现
// LogPlugin 日志插件
type LogPlugin struct {
name string
version string
description string
author string
pluginType plugin.PluginType
enabled bool
level string
}
// 创建内置日志插件 - 示例1明确指定插件类型
func NewLogPlugin() *LogPlugin {
return &LogPlugin{
name: "InternalLogPlugin",
version: "1.0.0",
description: "内置日志插件,在不支持动态加载插件的平台上使用",
author: "开发者",
pluginType: plugin.PluginTypeUtils, // 明确指定为工具类插件
enabled: true,
level: "info",
}
}
// 创建内置日志插件 - 示例2使用默认插件类型通用插件
func NewDefaultLogPlugin() *LogPlugin {
return &LogPlugin{
name: "DefaultLogPlugin",
version: "1.0.0",
description: "使用默认类型的内置日志插件示例",
author: "开发者",
pluginType: plugin.PluginTypeGeneral, // 自动设置为通用插件类型
enabled: true,
level: "info",
}
}
// 实现Plugin接口
func (p *LogPlugin) Name() string {
return p.name
}
func (p *LogPlugin) Version() string {
return p.version
}
func (p *LogPlugin) Description() string {
return p.description
}
func (p *LogPlugin) Author() string {
return p.author
}
// Type 实现插件类型方法
func (p *LogPlugin) Type() plugin.PluginType {
return p.pluginType
}
func (p *LogPlugin) IsEnabled() bool {
return p.enabled
}
func (p *LogPlugin) SetEnabled(enabled bool) {
p.enabled = enabled
}
func (p *LogPlugin) Init(ctx context.Context, config map[string]interface{}) error {
if level, ok := config["level"].(string); ok {
p.level = level
}
fmt.Printf("内置日志插件[%s]已初始化,日志级别: %s, 插件类型: %s\n", p.name, p.level, p.Type())
return nil
}
func (p *LogPlugin) Start(ctx context.Context) error {
fmt.Printf("内置日志插件[%s]已启动\n", p.name)
return nil
}
func (p *LogPlugin) Stop(ctx context.Context) error {
fmt.Printf("内置日志插件[%s]已停止\n", p.name)
return nil
}
// Execute 实现Execute方法以满足Plugin接口
func (p *LogPlugin) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
switch action {
case "log":
// 需要参数: message
message, ok := params["message"].(string)
if !ok {
return nil, fmt.Errorf("缺少必需参数: message")
}
p.Log(message)
return true, nil
case "setLevel":
// 需要参数: level
level, ok := params["level"].(string)
if !ok {
return nil, fmt.Errorf("缺少必需参数: level")
}
p.level = level
return true, nil
case "getLevel":
// 不需要参数,返回当前日志级别
return p.level, nil
case "getStatus":
// 返回插件状态信息
status := map[string]interface{}{
"name": p.name,
"version": p.version,
"level": p.level,
"enabled": p.enabled,
"type": p.Type(),
}
return status, nil
default:
return nil, fmt.Errorf("未知的操作: %s", action)
}
}
// Log 记录日志
func (p *LogPlugin) Log(message string) {
fmt.Printf("[%s][%s] %s\n", p.name, p.level, message)
}
func main() {
// 创建插件管理器
pluginsDir := "./plugins"
pm := plugin.NewPluginManager(pluginsDir)
// 检查当前系统是否支持动态加载插件
if pm.IsDynamicLoadingSupported() {
fmt.Printf("当前系统(%s)支持动态加载插件\n", runtime.GOOS)
} else {
fmt.Printf("当前系统(%s)不支持动态加载插件\n", runtime.GOOS)
// 在不支持动态加载的系统上注册内置插件
// 示例1注册明确指定类型的插件
logPlugin := NewLogPlugin()
pm.RegisterPlugin(logPlugin)
// 示例2注册使用默认类型的插件
defaultLogPlugin := NewDefaultLogPlugin()
pm.RegisterPlugin(defaultLogPlugin)
fmt.Println("已注册两个内置插件以展示不同的插件类型设置方式")
}
// 加载插件
fmt.Println("正在加载插件...")
if err := pm.LoadPlugins(); err != nil {
fmt.Printf("加载插件失败: %v\n", err)
}
// 配置插件
logPluginConfig := map[string]interface{}{
"level": "debug",
}
if err := pm.SetPluginConfig("InternalLogPlugin", logPluginConfig); err != nil {
fmt.Printf("配置插件失败: %v\n", err)
}
// 初始化插件
ctx := context.Background()
fmt.Println("正在初始化插件...")
if err := pm.InitPlugins(ctx); err != nil {
fmt.Printf("初始化插件失败: %v\n", err)
}
// 启动插件
fmt.Println("正在启动插件...")
if err := pm.StartPlugins(ctx); err != nil {
fmt.Printf("启动插件失败: %v\n", err)
}
// 获取并打印所有插件信息
fmt.Println("\n已加载的插件列表:")
plugins := pm.GetPluginInfos()
for i, info := range plugins {
status := "启用"
if !info.Enabled {
status = "禁用"
}
fmt.Printf("[%d] %s (v%s) - %s [%s]\n作者: %s\n类型: %s\n",
i, info.Name, info.Version, info.Description, status, info.Author, info.Type)
// 打印插件配置
if len(info.Config) > 0 {
fmt.Println("配置:")
for k, v := range info.Config {
fmt.Printf(" %s: %v\n", k, v)
}
}
fmt.Println()
}
// 使用第一个启用的插件(这里只是示例)
if len(plugins) > 0 {
for _, info := range plugins {
if info.Enabled {
fmt.Printf("正在使用插件: %s (类型: %s)\n", info.Name, info.Type)
if p, ok := pm.GetPlugin(info.Name); ok {
// 这里可以根据插件类型执行特定操作
if logPlugin, ok := p.(*LogPlugin); ok {
logPlugin.Log("这是一条测试日志消息")
// 改用Execute方法调用
logPlugin.Execute(ctx, "log", map[string]interface{}{
"message": "这是一条测试日志消息",
})
}
}
break
}
}
}
// 按类型获取和使用插件
fmt.Println("\n按类型获取插件:")
// 获取工具类插件
utilsPlugins := pm.GetPluginsByType(plugin.PluginTypeUtils)
fmt.Printf("找到 %d 个工具类插件\n", len(utilsPlugins))
for _, p := range utilsPlugins {
fmt.Printf("工具类插件: %s\n", p.Name())
if logPlugin, ok := p.(*LogPlugin); ok {
logPlugin.Log("通过类型获取到的日志插件记录消息")
// 改用Execute方法调用
logPlugin.Execute(ctx, "log", map[string]interface{}{
"message": "通过类型获取到的日志插件记录消息",
})
}
}
// 获取通用类型插件
generalPlugins := pm.GetPluginsByType(plugin.PluginTypeGeneral)
fmt.Printf("找到 %d 个通用类型插件\n", len(generalPlugins))
for _, p := range generalPlugins {
fmt.Printf("通用类型插件: %s\n", p.Name())
if logPlugin, ok := p.(*LogPlugin); ok {
logPlugin.Log("通过类型获取到的通用类型插件记录消息")
// 改用Execute方法调用
logPlugin.Execute(ctx, "log", map[string]interface{}{
"message": "通过类型获取到的通用类型插件记录消息",
})
}
}
// 停止插件
fmt.Println("\n正在停止插件...")
if err := pm.StopPlugins(ctx); err != nil {
fmt.Printf("停止插件失败: %v\n", err)
}
fmt.Println("示例结束")
}