diff --git a/common/xfer/plugin_spec.go b/common/xfer/plugin_spec.go index 41f203cf1..93c040538 100644 --- a/common/xfer/plugin_spec.go +++ b/common/xfer/plugin_spec.go @@ -25,6 +25,8 @@ type PluginSpec struct { // Interfaces is a list of things this plugin can be used for (e.g. "reporter") Interfaces []string `json:"interfaces"` + + Status string `json:"status,omitempty"` } // PluginSpecs is a set of plugin specs keyed on ID. Clients must use diff --git a/probe/plugins/registry.go b/probe/plugins/registry.go index ef55a0678..7dc7b4d22 100644 --- a/probe/plugins/registry.go +++ b/probe/plugins/registry.go @@ -171,6 +171,24 @@ func (r *Registry) Implementers(iface string, f func(p *Plugin)) { }) } +// Name implements the Reporter interface +func (r *Registry) Name() string { return "plugins" } + +// Report implements the Reporter interface +func (r *Registry) Report() (report.Report, error) { + rpt := report.MakeReport() + r.Implementers("reporter", func(plugin *Plugin) { + pluginReport, err := plugin.Report() + if err != nil { + log.Errorf("plugins: error getting report from %s: %v", plugin.ID, err) + pluginReport = report.MakeReport() + } + pluginReport.Plugins = pluginReport.Plugins.Add(plugin.PluginSpec) + rpt = rpt.Merge(pluginReport) + }) + return rpt, nil +} + // Close shuts down the registry. It can still be used after this, but will be // out of date. func (r *Registry) Close() { @@ -219,7 +237,8 @@ type handshakeResponse struct { // handshake tries the handshake with this plugin. func (p *Plugin) handshake(ctx context.Context, expectedAPIVersion string, params url.Values) func() (bool, error) { - return func() (bool, error) { + return func() (ok bool, err error) { + defer func() { p.setStatus(err) }() var resp handshakeResponse if err := p.get("/", params, &resp); err != nil { return err == context.Canceled, fmt.Errorf("plugins: error loading plugin %s: %v", p.socket, err) @@ -243,9 +262,18 @@ func (p *Plugin) handshake(ctx context.Context, expectedAPIVersion string, param func (p *Plugin) Report() (report.Report, error) { result := report.MakeReport() err := p.get("/report", nil, &result) + p.setStatus(err) return result, err } +func (p *Plugin) setStatus(err error) { + if err == nil { + p.Status = "ok" + } else { + p.Status = fmt.Sprintf("error: %v", err) + } +} + // TODO(paulbellamy): better error handling on wrong status codes func (p *Plugin) get(path string, params url.Values, result interface{}) error { ctx, cancel := context.WithTimeout(p.context, pluginTimeout) diff --git a/probe/plugins/reporter.go b/probe/plugins/reporter.go deleted file mode 100644 index a85f16b42..000000000 --- a/probe/plugins/reporter.go +++ /dev/null @@ -1,25 +0,0 @@ -package plugins - -import ( - log "github.com/Sirupsen/logrus" - - "github.com/weaveworks/scope/probe" - "github.com/weaveworks/scope/report" -) - -// Reporter implements the Reporter interface for a plugin registry. -func Reporter(pluginRegistry *Registry) probe.Reporter { - return probe.ReporterFunc("plugins", func() (report.Report, error) { - rpt := report.MakeReport() - pluginRegistry.Implementers("reporter", func(plugin *Plugin) { - pluginReport, err := plugin.Report() - if err != nil { - log.Errorf("plugins: error getting report from %s: %v", plugin.ID, err) - return - } - pluginReport.Plugins = pluginReport.Plugins.Add(plugin.PluginSpec) - rpt = rpt.Merge(pluginReport) - }) - return rpt, nil - }) -} diff --git a/prog/probe.go b/prog/probe.go index 2d56fd04c..86a0c3d4e 100644 --- a/prog/probe.go +++ b/prog/probe.go @@ -206,7 +206,7 @@ func probeMain() { } } - p.AddReporter(plugins.Reporter(pluginRegistry)) + p.AddReporter(pluginRegistry) if *httpListen != "" { go func() {