1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 07:26:55 +00:00
kyverno/pkg/breaker/breaker.go

67 lines
1.6 KiB
Go
Raw Permalink Normal View History

package breaker
import (
"context"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/metrics"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
sdkmetric "go.opentelemetry.io/otel/metric"
)
type Breaker interface {
Do(context.Context, func(context.Context) error) error
}
type breaker struct {
name string
drops sdkmetric.Int64Counter
total sdkmetric.Int64Counter
open func(context.Context) bool
}
func NewBreaker(name string, open func(context.Context) bool) *breaker {
logger := logging.WithName("circuit-breaker")
meter := otel.GetMeterProvider().Meter(metrics.MeterName)
drops, err := meter.Int64Counter(
"kyverno_breaker_drops",
sdkmetric.WithDescription("track the number of times the breaker failed open and dropped"),
)
if err != nil {
logger.Error(err, "Failed to create instrument, kyverno_breaker_drops")
}
total, err := meter.Int64Counter(
"kyverno_breaker_total",
sdkmetric.WithDescription("track number of times the breaker was invoked"),
)
if err != nil {
logger.Error(err, "Failed to create instrument, kyverno_breaker_total")
}
return &breaker{
name: name,
drops: drops,
total: total,
open: open,
}
}
func (b *breaker) Do(ctx context.Context, inner func(context.Context) error) error {
attributes := sdkmetric.WithAttributes(
attribute.String("circuit_name", b.name),
)
if b.total != nil {
b.total.Add(ctx, 1, attributes)
}
if b.open != nil && b.open(ctx) {
if b.drops != nil {
b.drops.Add(ctx, 1, attributes)
}
return nil
}
if inner == nil {
return nil
}
return inner(ctx)
}