2024-08-15 03:53:20 -07:00
|
|
|
package breaker
|
2024-06-25 05:16:30 +02:00
|
|
|
|
|
|
|
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 {
|
2024-10-11 10:34:41 +03:00
|
|
|
logger := logging.WithName("circuit-breaker")
|
2024-06-25 05:16:30 +02:00
|
|
|
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)
|
|
|
|
}
|