Documentation ¶
Overview ¶
Package feature provides feature flagging capabilities for InfluxDB servers. This document describes this package and how it is used to control experimental features in `influxd`.
Flags are configured in `flags.yml` at the top of this repository. Running `make flags` generates Go code based on this configuration to programmatically test flag values in a given request context. Boolean flags are the most common case, but integers, floats and strings are supported for more complicated experiments.
The `Flagger` interface is the crux of this package. It computes a map of feature flag values for a given request context. The default implementation always returns the flag default configured in `flags.yml`. The override implementation allows an operator to override feature flag defaults at startup. Changing these overrides requires a restart.
In `influxd`, a `Flagger` instance is provided to a `Handler` middleware configured to intercept all API requests and annotate their request context with a map of feature flags.
A flag can opt in to be exposed externally in `flags.yml`. If exposed, this flag will be included in the response from the `/api/v2/flags` endpoint. This allows the UI and other API clients to control their behavior according to the flag in addition to the server itself.
A concrete example to illustrate the above:
I have a feature called "My Feature" that will involve turning on new code in both the UI and the server.
First, I add an entry to `flags.yml`.
```yaml
- name: My Feature description: My feature is awesome key: myFeature default: false expose: true contact: My Name
```
My flag type is inferred to be boolean by my default of `false` when I run `make flags` and the `feature` package now includes `func MyFeature() BoolFlag`.
I use this to control my backend code with ¶
```go
if feature.MyFeature.Enabled(ctx) { // new code... } else { // new code... }
```
and the `/api/v2/flags` response provides the same information to the frontend.
```json
{ "myFeature": false }
```
While `false` by default, I can turn on my experimental feature by starting my server with a flag override.
``` env INFLUXD_FEATURE_FLAGS="{\"flag1\":\value1\",\"key2\":\"value2\"}" influxd ```
``` influxd --feature-flags flag1=value1,flag2=value2 ```
Index ¶
- func Annotate(ctx context.Context, f Flagger, flags ...Flag) (context.Context, error)
- func ExposedFlagsFromContext(ctx context.Context, byKey ByKeyFn) map[string]interface{}
- func FlagsFromContext(ctx context.Context) map[string]interface{}
- func NewFlagsHandler(errorHandler HTTPErrorHandler, byKey ByKeyFn) http.Handler
- func NewHandler(log *zap.Logger, flagger Flagger, flags []Flag, next http.Handler) http.Handler
- type Base
- type BoolFlag
- func AppMetrics() BoolFlag
- func DefaultMonacoSelectionToEof() BoolFlag
- func EnforceOrganizationDashboardLimits() BoolFlag
- func GroupWindowAggregateTranspose() BoolFlag
- func InjectLatestSuccessTime() BoolFlag
- func MakeBoolFlag(name, key, owner string, defaultValue bool, lifetime Lifetime, expose bool) BoolFlag
- func MemoryOptimizedFill() BoolFlag
- func MemoryOptimizedSchemaMutation() BoolFlag
- func NewDashboardAutorefresh() BoolFlag
- func NewLabelPackage() BoolFlag
- func QueryTracing() BoolFlag
- func RefreshSingleCell() BoolFlag
- func TimeFilterFlags() BoolFlag
- type ByKeyFn
- type Flag
- type Flagger
- type FloatFlag
- type HTTPErrorHandler
- type HTTPProxy
- type Handler
- type IntFlag
- type Lifetime
- type ProxyEnabler
- type StringFlag
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExposedFlagsFromContext ¶
ExposedFlagsFromContext returns the filtered map of exposed flags attached to the context by Annotate, or nil if none is found.
func FlagsFromContext ¶
FlagsFromContext returns the map of flags attached to the context by Annotate, or nil if none is found.
func NewFlagsHandler ¶
func NewFlagsHandler(errorHandler HTTPErrorHandler, byKey ByKeyFn) http.Handler
NewFlagsHandler returns a handler that returns the map of computed feature flags on the request context.
Types ¶
type Base ¶
type Base struct {
// contains filtered or unexported fields
}
flag base type.
func MakeBase ¶
func MakeBase(name, key, owner string, defaultValue interface{}, lifetime Lifetime, expose bool) Base
MakeBase constructs a flag flag.
type BoolFlag ¶
type BoolFlag struct { Base // contains filtered or unexported fields }
BoolFlag implements Flag for boolean values.
func AppMetrics ¶
func AppMetrics() BoolFlag
AppMetrics - Send UI Telementry to Tools cluster - should always be false in OSS
func DefaultMonacoSelectionToEof ¶ added in v2.0.5
func DefaultMonacoSelectionToEof() BoolFlag
DefaultMonacoSelectionToEof - Positions the cursor at the end of the line(s) when using the monaco editor
func EnforceOrganizationDashboardLimits ¶
func EnforceOrganizationDashboardLimits() BoolFlag
EnforceOrganizationDashboardLimits - Enforces the default limit params for the dashboards api when orgs are set
func GroupWindowAggregateTranspose ¶
func GroupWindowAggregateTranspose() BoolFlag
GroupWindowAggregateTranspose - Enables the GroupWindowAggregateTransposeRule for all enabled window aggregates
func InjectLatestSuccessTime ¶
func InjectLatestSuccessTime() BoolFlag
InjectLatestSuccessTime - Inject the latest successful task run timestamp into a Task query extern when executing.
func MakeBoolFlag ¶
func MakeBoolFlag(name, key, owner string, defaultValue bool, lifetime Lifetime, expose bool) BoolFlag
MakeBoolFlag returns a string flag with the given Base and default.
func MemoryOptimizedFill ¶
func MemoryOptimizedFill() BoolFlag
MemoryOptimizedFill - Enable the memory optimized fill()
func MemoryOptimizedSchemaMutation ¶
func MemoryOptimizedSchemaMutation() BoolFlag
MemoryOptimizedSchemaMutation - Enable the memory optimized schema mutation functions
func NewDashboardAutorefresh ¶ added in v2.1.0
func NewDashboardAutorefresh() BoolFlag
NewDashboardAutorefresh - Enables the new dashboard autorefresh controls in the UI
func NewLabelPackage ¶
func NewLabelPackage() BoolFlag
NewLabelPackage - Enables the refactored labels api
func QueryTracing ¶
func QueryTracing() BoolFlag
QueryTracing - Turn on query tracing for queries that are sampled
func RefreshSingleCell ¶ added in v2.0.5
func RefreshSingleCell() BoolFlag
RefreshSingleCell - Refresh a single cell on the dashboard rather than the entire dashboard
func TimeFilterFlags ¶ added in v2.0.2
func TimeFilterFlags() BoolFlag
TimeFilterFlags - Filter task run list based on before and after flags
type Flag ¶
type Flag interface { // Key returns the programmatic backend identifier for the flag. Key() string // Default returns the type-agnostic zero value for the flag. // Type-specific flag implementations may expose a typed default // (e.g. BoolFlag includes a boolean Default field). Default() interface{} // Expose the flag. Expose() bool }
Flag represents a generic feature flag with a key and a default.
type Flagger ¶
type Flagger interface { // Flags returns a map of flag keys to flag values. // // If an authorization is present on the context, it may be used to compute flag // values according to the affiliated user ID and its organization and other mappings. // Otherwise, they should be computed generally or return a default. // // One or more flags may be provided to restrict the results. // Otherwise, all flags should be computed. Flags(context.Context, ...Flag) (map[string]interface{}, error) }
Flagger returns flag values.
func DefaultFlagger ¶
func DefaultFlagger() Flagger
DefaultFlagger returns a flagger that always returns default values.
type FloatFlag ¶
type FloatFlag struct { Base // contains filtered or unexported fields }
FloatFlag implements Flag for float values.
type HTTPErrorHandler ¶
type HTTPErrorHandler interface {
HandleHTTPError(ctx context.Context, err error, w http.ResponseWriter)
}
HTTPErrorHandler is an influxdb.HTTPErrorHandler. It's defined here instead of referencing the other interface type, because we want to try our best to avoid cyclical dependencies when feature package is used throughout the codebase.
type HTTPProxy ¶
type HTTPProxy struct {
// contains filtered or unexported fields
}
HTTPProxy is an HTTP proxy that's guided by a feature flag. If the feature flag presented to it is enabled, it will perform the proxying behavior. Otherwise it will be a no-op.
func NewHTTPProxy ¶
NewHTTPProxy returns a new Proxy.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler is a middleware that annotates the context with a map of computed feature flags. To accurately compute identity-scoped flags, this middleware should be executed after any authorization middleware has annotated the request context with an authorizer.
type IntFlag ¶
type IntFlag struct { Base // contains filtered or unexported fields }
IntFlag implements Flag for integer values.
type Lifetime ¶
type Lifetime int
Lifetime represents the intended lifetime of the feature flag.
The zero value is Temporary, the most common case, but Permanent is included to mark special cases where a flag is not intended to be removed, e.g. enabling debug tracing for an organization.
TODO(gavincabbage): This may become a stale date, which can then
be used to trigger a notification to the contact when the flag has become stale, to encourage flag cleanup.
func (*Lifetime) UnmarshalYAML ¶
UnmarshalYAML implements yaml.Unmarshaler and interprets a case-insensitive text representation as a lifetime constant.
type ProxyEnabler ¶
ProxyEnabler is a boolean feature flag.
type StringFlag ¶
type StringFlag struct { Base // contains filtered or unexported fields }
StringFlag implements Flag for string values.
func MakeStringFlag ¶
func MakeStringFlag(name, key, owner string, defaultValue string, lifetime Lifetime, expose bool) StringFlag
MakeStringFlag returns a string flag with the given Base and default.