package main import ( "context" "fmt" "sync" "time" "github.com/darkit/goproxy/examples/plugin" ) // StatsPlugin 统计插件 // 用于收集和记录系统运行时统计数据 type StatsPlugin struct { plugin.Plugin // 嵌入接口,确保类型检查 name string // 插件名称 version string // 插件版本 description string // 插件描述 author string // 插件作者 pluginType plugin.PluginType // 插件类型 enabled bool // 是否启用 stats map[string]int64 startTime time.Time mu sync.RWMutex tickerStop chan bool ticker *time.Ticker config map[string]interface{} } // StatsParams 统计请求参数结构体 // 允许通过结构体传递参数,简化调用 type StatsParams struct { Name string `json:"name"` // 统计项名称 Value int64 `json:"value"` // 统计值 BytesReceived int64 `json:"bytesReceived"` // 接收字节数 BytesSent int64 `json:"bytesSent"` // 发送字节数 IsError bool `json:"isError"` // 是否为错误请求 } // Plugin 导出的插件变量 var Plugin = &StatsPlugin{ name: "StatsPlugin", version: "1.0.0", description: "系统运行时统计插件", author: "开发者", pluginType: plugin.PluginTypeUtils, // 指定为工具类插件 enabled: true, stats: make(map[string]int64), tickerStop: make(chan bool), } // Name 返回插件名称 func (p *StatsPlugin) Name() string { return p.name } // Version 返回插件版本 func (p *StatsPlugin) Version() string { return p.version } // Description 返回插件描述 func (p *StatsPlugin) Description() string { return p.description } // Author 返回插件作者 func (p *StatsPlugin) Author() string { return p.author } // Type 返回插件类型 func (p *StatsPlugin) Type() plugin.PluginType { return p.pluginType } // IsEnabled 返回插件是否启用 func (p *StatsPlugin) IsEnabled() bool { return p.enabled } // SetEnabled 设置插件启用状态 func (p *StatsPlugin) SetEnabled(enabled bool) { p.enabled = enabled } // GetOperationInfo 获取操作的参数信息 func (p *StatsPlugin) GetOperationInfo(operation string) (map[string]interface{}, error) { return map[string]interface{}{}, nil } // GetAllOperations 获取所有操作及其参数信息 func (p *StatsPlugin) GetAllOperations() map[string]map[string]interface{} { return map[string]map[string]interface{}{} } // Init 初始化插件 func (p *StatsPlugin) Init(ctx context.Context, config map[string]interface{}) error { p.config = config // 初始化统计指标 p.mu.Lock() p.stats["requests"] = 0 p.stats["errors"] = 0 p.stats["bytes_sent"] = 0 p.stats["bytes_received"] = 0 p.mu.Unlock() fmt.Println("统计插件初始化完成") return nil } // Start 启动插件 func (p *StatsPlugin) Start(ctx context.Context) error { p.startTime = time.Now() // 启动定时统计任务 interval := 60 * time.Second // 默认60秒 // 从配置中获取统计间隔 if intervalSec, ok := p.config["interval_seconds"].(float64); ok { interval = time.Duration(intervalSec) * time.Second } p.ticker = time.NewTicker(interval) go func() { for { select { case <-p.ticker.C: p.logStats() case <-p.tickerStop: p.ticker.Stop() return case <-ctx.Done(): p.ticker.Stop() return } } }() fmt.Println("统计插件已启动") return nil } // Stop 停止插件 func (p *StatsPlugin) Stop(ctx context.Context) error { if p.ticker != nil { p.tickerStop <- true } // 输出最终统计信息 p.logStats() fmt.Println("统计插件已停止") return nil } // 以下方法将被自动注册为可通过Execute调用的操作 // IncrementStat 增加统计值 // 会被自动注册为"incrementstat"操作 func (p *StatsPlugin) IncrementStat(name string, value int64) error { p.mu.Lock() defer p.mu.Unlock() if _, exists := p.stats[name]; exists { p.stats[name] += value } else { p.stats[name] = value } return nil } // GetStat 获取统计值 // 会被自动注册为"getstat"操作 func (p *StatsPlugin) GetStat(name string) (int64, error) { p.mu.RLock() defer p.mu.RUnlock() if value, exists := p.stats[name]; exists { return value, nil } return 0, fmt.Errorf("统计项 %s 不存在", name) } // RecordRequest 记录请求 // 会被自动注册为"recordrequest"操作 func (p *StatsPlugin) RecordRequest(ctx context.Context, params StatsParams) error { p.IncrementStat("requests", 1) p.IncrementStat("bytes_received", params.BytesReceived) p.IncrementStat("bytes_sent", params.BytesSent) if params.IsError { p.IncrementStat("errors", 1) } return nil } // ResetStats 重置统计数据 // 会被自动注册为"resetstats"操作 func (p *StatsPlugin) ResetStats() error { p.mu.Lock() defer p.mu.Unlock() p.stats = make(map[string]int64) p.stats["requests"] = 0 p.stats["errors"] = 0 p.stats["bytes_sent"] = 0 p.stats["bytes_received"] = 0 p.startTime = time.Now() return nil } // GenerateStatsReport 生成统计报告 // 会被自动注册为"generatestatsreport"操作 func (p *StatsPlugin) GenerateStatsReport() (map[string]interface{}, error) { p.mu.RLock() defer p.mu.RUnlock() uptime := time.Since(p.startTime).Seconds() report := map[string]interface{}{ "uptime_seconds": uptime, "stats": p.stats, } if uptime > 0 && p.stats["requests"] > 0 { report["requests_per_second"] = float64(p.stats["requests"]) / uptime report["error_rate"] = float64(p.stats["errors"]) * 100 / float64(p.stats["requests"]) } return report, nil } // GetAllStats 获取所有统计数据 // 会被自动注册为"getallstats"操作 func (p *StatsPlugin) GetAllStats() (map[string]int64, error) { p.mu.RLock() defer p.mu.RUnlock() // 创建一个副本 statsCopy := make(map[string]int64, len(p.stats)) for k, v := range p.stats { statsCopy[k] = v } // 添加运行时间 statsCopy["uptime_seconds"] = int64(time.Since(p.startTime).Seconds()) return statsCopy, nil } // logStats 记录当前统计信息 // 不会被注册为操作,因为它是内部方法 func (p *StatsPlugin) logStats() { p.mu.RLock() defer p.mu.RUnlock() uptime := time.Since(p.startTime).Seconds() fmt.Printf("===== 系统统计信息 =====\n") fmt.Printf("运行时间: %.2f 秒\n", uptime) fmt.Printf("总请求数: %d\n", p.stats["requests"]) fmt.Printf("错误数: %d\n", p.stats["errors"]) fmt.Printf("发送字节: %d\n", p.stats["bytes_sent"]) fmt.Printf("接收字节: %d\n", p.stats["bytes_received"]) if uptime > 0 && p.stats["requests"] > 0 { fmt.Printf("平均请求/秒: %.2f\n", float64(p.stats["requests"])/uptime) fmt.Printf("错误率: %.2f%%\n", float64(p.stats["errors"])*100/float64(p.stats["requests"])) } fmt.Printf("=======================\n") } // GetAvailableOperations 获取可用操作列表 // 这是一个帮助方法,列出所有可通过Execute调用的操作 func (p *StatsPlugin) GetAvailableOperations() []string { // 返回硬编码的操作列表,而不是调用不存在的方法 return []string{ "incrementstat", "getstat", "recordrequest", "resetstats", "generatestatsreport", "getallstats", } } // main 函数是必须的,但不会被调用 func main() { // 不会被执行,仅用于编译插件 }