package plugin import ( "fmt" "sync" ) // Registry holds all registered collector plugins. type Registry struct { mu sync.RWMutex plugins map[string]Collector } // NewRegistry creates an empty plugin registry. func NewRegistry() *Registry { return &Registry{plugins: make(map[string]Collector)} } // Register adds a collector to the registry. Panics on duplicate name. func (r *Registry) Register(c Collector) { r.mu.Lock() defer r.mu.Unlock() name := c.Name() if _, exists := r.plugins[name]; exists { panic(fmt.Sprintf("plugin %q already registered", name)) } r.plugins[name] = c } // Get returns a collector by name, or an error if not found. func (r *Registry) Get(name string) (Collector, error) { r.mu.RLock() defer r.mu.RUnlock() c, ok := r.plugins[name] if !ok { return nil, fmt.Errorf("plugin %q not registered", name) } return c, nil } // List returns all registered plugin names. func (r *Registry) List() []string { r.mu.RLock() defer r.mu.RUnlock() names := make([]string, 0, len(r.plugins)) for name := range r.plugins { names = append(names, name) } return names }