Documentation
¶
Overview ¶
Package circuitbreakingcfg builds a circuitbreaking.CircuitBreaker from configuration. There is one implementation and so no provider to name: what is configured here is the trip threshold and the breaker's identity.
The name is the load-bearing field. It is the breaker's identity in every log line it writes and the value of the attribute on every counter it records, so an unnamed breaker gets a numbered placeholder — enough to keep two of them out of one series, and no help to whoever reads that series later. The instrument names are exported here for the dashboards that query them.
EnsureCircuitBreaker is the other half of this package: it substitutes a noop for a nil breaker and says so through the caller's logger, because a component that believes it is protected and is not is exactly what circuitbreaking exists to prevent.
Index ¶
- Constants
- func EnsureCircuitBreaker(breaker circuitbreaking.CircuitBreaker, opts ...Option) circuitbreaking.CircuitBreaker
- func NewCircuitBreaker(ctx context.Context, cfg *Config, opts ...Option) (circuitbreaking.CircuitBreaker, error)
- func RegisterCircuitBreaker(i do.Injector)
- type Config
- type Option
Constants ¶
const ( // DefaultName is what a breaker with no configured name is defaulted to. It // is a placeholder, not an identity: see NewCircuitBreaker. DefaultName = "UNKNOWN" // The instruments every breaker records into. They do not carry the // breaker's name — that is NameAttributeKey — so that "how often is anything // tripping" is one series to read rather than one per breaker, and so a // breaker nobody named cannot create an instrument nobody expected. // // They are exported for the same reason the attribute key is: a dashboard // querying them has to spell them, and a constant is better than a string // repeated across a query builder and a test. TrippedCounterName = "circuit_breaker_tripped" FailedCounterName = "circuit_breaker_failed" ResetCounterName = "circuit_breaker_reset" )
const NameAttributeKey = "circuit_breaker.name"
NameAttributeKey is the metric attribute carrying which breaker a measurement came from. It is exported because a dashboard querying these counters has to spell it, and a constant is better than a string repeated in a query builder.
Variables ¶
This section is empty.
Functions ¶
func EnsureCircuitBreaker ¶
func EnsureCircuitBreaker(breaker circuitbreaking.CircuitBreaker, opts ...Option) circuitbreaking.CircuitBreaker
EnsureCircuitBreaker ensures a valid CircuitBreaker is made available.
Substituting a noop is worth saying out loud — a component that believes it is protected and is not is the whole failure mode this package exists to prevent — so pass WithLogger and hear about it. It used to say so through a bare slog.Info, which meant a library writing to whatever the process had made global rather than to the logger the caller configured, in the format the caller configured it in.
func NewCircuitBreaker ¶
func NewCircuitBreaker(ctx context.Context, cfg *Config, opts ...Option) (circuitbreaking.CircuitBreaker, error)
NewCircuitBreaker provides a CircuitBreaker from config.
func RegisterCircuitBreaker ¶
RegisterCircuitBreaker registers a CircuitBreaker with the injector.
Types ¶
type Config ¶
type Config struct {
Name string `env:"NAME" json:"name,omitempty" yaml:"name,omitempty"`
ErrorRate float64 `` /* 135-byte string literal not displayed */
MinimumSampleThreshold uint64 `` /* 146-byte string literal not displayed */
}
func (*Config) EnsureDefaults ¶
func (cfg *Config) EnsureDefaults()
func (*Config) NewCircuitBreaker ¶
func (cfg *Config) NewCircuitBreaker(ctx context.Context, opts ...Option) (circuitbreaking.CircuitBreaker, error)
NewCircuitBreaker provides a CircuitBreaker.
Name it. A breaker's name is its identity in every measurement it records and every line it logs, and an unnamed one gets a numbered placeholder — enough to keep two of them from adding into the same series, and no help at all to whoever is looking at the series later.
type Option ¶
type Option func(*options)
Option customizes how a CircuitBreaker is provided.
The observability dependencies are options rather than parameters because both are genuinely optional: an absent logger logs nowhere and an absent metrics provider records nothing. Requiring them positionally made a caller that wanted neither name both anyway, usually as noops.
There is no tracer provider here. A circuit breaker's decisions are counters and log lines, not spans — it has nothing to trace.
func WithLogger ¶
WithLogger attaches a logger. An absent logger logs nowhere.
func WithMetricAttributes ¶
WithMetricAttributes attaches a fixed set of attributes to every metric the circuit breaker emits. It is used to distinguish breakers that share counter names (for example, tagging a per-key breaker with its partition).
func WithMetricsProvider ¶
WithMetricsProvider attaches a metrics provider for the breaker's tripped, failed, and reset counters. An absent provider records nothing.
func WithPillars ¶
func WithPillars(p *observability.Pillars) Option
WithPillars attaches a logger and metrics provider in one go, for the common case where a caller has already built them together. A nil Pillars attaches nothing. The pillars' tracer provider is ignored — see Option.
It is applied in order with the individual options, so a caller can hand over its pillars and then override one of them.