diff options
Diffstat (limited to 'plugins/status/plugin.go')
-rw-r--r-- | plugins/status/plugin.go | 92 |
1 files changed, 68 insertions, 24 deletions
diff --git a/plugins/status/plugin.go b/plugins/status/plugin.go index 6fbe67cf..693440bf 100644 --- a/plugins/status/plugin.go +++ b/plugins/status/plugin.go @@ -18,10 +18,13 @@ const ( ) type Plugin struct { - registry map[string]Checker - server *fiber.App - log logger.Logger - cfg *Config + // plugins which needs to be checked just as Status + statusRegistry map[string]Checker + // plugins which needs to send Readiness status + readyRegistry map[string]Readiness + server *fiber.App + log logger.Logger + cfg *Config } func (c *Plugin) Init(log logger.Logger, cfg config.Configurer) error { @@ -34,7 +37,9 @@ func (c *Plugin) Init(log logger.Logger, cfg config.Configurer) error { return errors.E(op, errors.Disabled, err) } - c.registry = make(map[string]Checker) + c.readyRegistry = make(map[string]Readiness) + c.statusRegistry = make(map[string]Checker) + c.log = log return nil } @@ -49,6 +54,7 @@ func (c *Plugin) Serve() chan error { }) c.server.Use("/health", c.healthHandler) + c.server.Use("/ready", c.readinessHandler) go func() { err := c.server.Listen(c.cfg.Address) @@ -69,10 +75,11 @@ func (c *Plugin) Stop() error { return nil } -// Reset named service. -func (c *Plugin) Status(name string) (Status, error) { +// status returns a Checker interface implementation +// Reset named service. This is not an Status interface implementation +func (c *Plugin) status(name string) (Status, error) { const op = errors.Op("checker_plugin_status") - svc, ok := c.registry[name] + svc, ok := c.statusRegistry[name] if !ok { return Status{}, errors.E(op, errors.Errorf("no such service: %s", name)) } @@ -80,16 +87,34 @@ func (c *Plugin) Status(name string) (Status, error) { return svc.Status(), nil } -// CollectTarget collecting services which can provide Status. -func (c *Plugin) CollectTarget(name endure.Named, r Checker) error { - c.registry[name.Name()] = r +// ready used to provide a readiness check for the plugin +func (c *Plugin) ready(name string) (Status, error) { + const op = errors.Op("checker_plugin_ready") + svc, ok := c.readyRegistry[name] + if !ok { + return Status{}, errors.E(op, errors.Errorf("no such service: %s", name)) + } + + return svc.Ready(), nil +} + +// CollectCheckerImpls collects services which can provide Status. +func (c *Plugin) CollectCheckerImpls(name endure.Named, r Checker) error { + c.statusRegistry[name.Name()] = r + return nil +} + +// CollectReadinessImpls collects services which can provide Readiness check. +func (c *Plugin) CollectReadinessImpls(name endure.Named, r Readiness) error { + c.readyRegistry[name.Name()] = r return nil } // Collects declares services to be collected. func (c *Plugin) Collects() []interface{} { return []interface{}{ - c.CollectTarget, + c.CollectReadinessImpls, + c.CollectCheckerImpls, } } @@ -109,6 +134,35 @@ type Plugins struct { const template string = "Service: %s: Status: %d\n" +func (c *Plugin) readinessHandler(ctx *fiber.Ctx) error { + const op = errors.Op("checker_plugin_readiness_handler") + plugins := &Plugins{} + err := ctx.QueryParser(plugins) + if err != nil { + return errors.E(op, err) + } + + if len(plugins.Plugins) == 0 { + ctx.Status(http.StatusOK) + _, _ = ctx.WriteString("No plugins provided in query. Query should be in form of: ready?plugin=plugin1&plugin=plugin2 \n") + return nil + } + + // iterate over all provided plugins + for i := 0; i < len(plugins.Plugins); i++ { + // check if the plugin exists + if plugin, ok := c.readyRegistry[plugins.Plugins[i]]; ok { + st := plugin.Ready() + _, _ = ctx.WriteString(fmt.Sprintf(template, plugins.Plugins[i], st.Code)) + } else { + _, _ = ctx.WriteString(fmt.Sprintf("Service: %s not found", plugins.Plugins[i])) + } + } + + ctx.Status(http.StatusOK) + return nil +} + func (c *Plugin) healthHandler(ctx *fiber.Ctx) error { const op = errors.Op("checker_plugin_health_handler") plugins := &Plugins{} @@ -123,26 +177,16 @@ func (c *Plugin) healthHandler(ctx *fiber.Ctx) error { return nil } - failed := false // iterate over all provided plugins for i := 0; i < len(plugins.Plugins); i++ { // check if the plugin exists - if plugin, ok := c.registry[plugins.Plugins[i]]; ok { + if plugin, ok := c.statusRegistry[plugins.Plugins[i]]; ok { st := plugin.Status() - if st.Code >= 500 { - failed = true - continue - } else if st.Code >= 100 && st.Code <= 400 { - _, _ = ctx.WriteString(fmt.Sprintf(template, plugins.Plugins[i], st.Code)) - } + _, _ = ctx.WriteString(fmt.Sprintf(template, plugins.Plugins[i], st.Code)) } else { _, _ = ctx.WriteString(fmt.Sprintf("Service: %s not found", plugins.Plugins[i])) } } - if failed { - ctx.Status(http.StatusInternalServerError) - return nil - } ctx.Status(http.StatusOK) return nil |