Skip to content

Commit

Permalink
feat(http): add config option to disable metrics endpoint in influxd
Browse files Browse the repository at this point in the history
  • Loading branch information
danxmoran committed Mar 15, 2021
1 parent 8ba7f34 commit 2689c32
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 35 deletions.
10 changes: 10 additions & 0 deletions cmd/influxd/launcher/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ type InfluxdOpts struct {
SessionRenewDisabled bool

ProfilingDisabled bool
MetricsDisabled bool

NatsPort int
NatsMaxPayloadBytes int
Expand Down Expand Up @@ -189,6 +190,7 @@ func newOpts(viper *viper.Viper) *InfluxdOpts {
SessionRenewDisabled: false,

ProfilingDisabled: false,
MetricsDisabled: false,

StoreType: BoltStore,
SecretStore: BoltStore,
Expand Down Expand Up @@ -519,5 +521,13 @@ func (o *InfluxdOpts) bindCliOpts() []cli.Opt {
Desc: "Don't expose debugging information over HTTP at /debug/pprof",
Default: o.ProfilingDisabled,
},

// Metrics config
{
DestP: &o.MetricsDisabled,
Flag: "metrics-disabled",
Desc: "Don't expose metrics over HTTP at /metrics",
Default: o.MetricsDisabled,
},
}
}
4 changes: 2 additions & 2 deletions cmd/influxd/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -915,12 +915,12 @@ func (m *Launcher) run(ctx context.Context, opts *InfluxdOpts) (err error) {
)

httpLogger := m.log.With(zap.String("service", "http"))
m.httpServer.Handler = http.NewHandlerFromRegistry(
m.httpServer.Handler = http.NewRootHandler(
"platform",
m.reg,
http.WithLog(httpLogger),
http.WithAPIHandler(platformHandler),
http.WithPprofEnabled(!opts.ProfilingDisabled),
http.WithMetrics(m.reg, !opts.MetricsDisabled),
)

if opts.LogLevel == zap.DebugLevel {
Expand Down
68 changes: 37 additions & 31 deletions http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"

"github.com/go-chi/chi"
"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/kit/prom"
kithttp "github.com/influxdata/influxdb/v2/kit/transport/http"
"github.com/influxdata/influxdb/v2/pprof"
Expand Down Expand Up @@ -39,17 +40,31 @@ type Handler struct {

type (
handlerOpts struct {
log *zap.Logger
apiHandler http.Handler
healthHandler http.Handler
metricsHandler http.Handler
readyHandler http.Handler
pprofEnabled bool
log *zap.Logger
apiHandler http.Handler
healthHandler http.Handler
readyHandler http.Handler
pprofEnabled bool

// NOTE: Track the registry even if metricsExposed = false
// so we can report HTTP metrics via telemetry.
metricsRegistry *prom.Registry
metricsExposed bool
}

HandlerOptFn func(opts *handlerOpts)
)

func (o *handlerOpts) metricsHTTPHandler() http.Handler {
if !o.metricsExposed || o.metricsRegistry == nil {
handlerFunc := func(rw http.ResponseWriter, r *http.Request) {
kithttp.WriteErrorResponse(r.Context(), rw, influxdb.EForbidden, "metrics disabled")
}
return http.HandlerFunc(handlerFunc)
}
return o.metricsRegistry.HTTPHandler()
}

func WithLog(l *zap.Logger) HandlerOptFn {
return func(opts *handlerOpts) {
opts.log = l
Expand All @@ -68,34 +83,23 @@ func WithPprofEnabled(enabled bool) HandlerOptFn {
}
}

func WithHealthHandler(h http.Handler) HandlerOptFn {
return func(opts *handlerOpts) {
opts.healthHandler = h
}
}

func WithMetricsHandler(h http.Handler) HandlerOptFn {
return func(opts *handlerOpts) {
opts.metricsHandler = h
}
}

func WithReadyHandler(h http.Handler) HandlerOptFn {
func WithMetrics(reg *prom.Registry, exposed bool) HandlerOptFn {
return func(opts *handlerOpts) {
opts.readyHandler = h
opts.metricsRegistry = reg
opts.metricsExposed = exposed
}
}

// NewHandlerFromRegistry creates a new handler with the given name,
// and sets the /metrics endpoint to use the metrics from the given registry,
// after self-registering h's metrics.
func NewHandlerFromRegistry(name string, reg *prom.Registry, opts ...HandlerOptFn) *Handler {
// NewRootHandler creates a new handler with the given name and registers any root-level
// (non-API) routes enabled by the caller.
func NewRootHandler(name string, opts ...HandlerOptFn) *Handler {
opt := handlerOpts{
log: zap.NewNop(),
healthHandler: http.HandlerFunc(HealthHandler),
metricsHandler: reg.HTTPHandler(),
readyHandler: ReadyHandler(),
pprofEnabled: false,
log: zap.NewNop(),
healthHandler: http.HandlerFunc(HealthHandler),
readyHandler: ReadyHandler(),
pprofEnabled: false,
metricsRegistry: nil,
metricsExposed: false,
}
for _, o := range opts {
o(&opt)
Expand All @@ -113,7 +117,7 @@ func NewHandlerFromRegistry(name string, reg *prom.Registry, opts ...HandlerOptF
r.Use(
kithttp.Metrics(name, h.requests, h.requestDur),
)
r.Mount(MetricsPath, opt.metricsHandler)
r.Mount(MetricsPath, opt.metricsHTTPHandler())
r.Mount(ReadyPath, opt.readyHandler)
r.Mount(HealthPath, opt.healthHandler)
r.Mount(DebugPath, pprof.NewHTTPHandler(opt.pprofEnabled))
Expand All @@ -130,7 +134,9 @@ func NewHandlerFromRegistry(name string, reg *prom.Registry, opts ...HandlerOptF

h.r = r

reg.MustRegister(h.PrometheusCollectors()...)
if opt.metricsRegistry != nil {
opt.metricsRegistry.MustRegister(h.PrometheusCollectors()...)
}
return h
}

Expand Down
4 changes: 2 additions & 2 deletions http/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ func TestHandler_ServeHTTP(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
reg := prom.NewRegistry(zaptest.NewLogger(t))
h := NewHandlerFromRegistry(
h := NewRootHandler(
tt.fields.name,
reg,
WithLog(tt.fields.log),
WithAPIHandler(tt.fields.handler),
WithMetrics(reg, true),
)

tt.args.r.Header.Set("User-Agent", "ua1")
Expand Down

0 comments on commit 2689c32

Please sign in to comment.