1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00
kyverno/pkg/webhooks/handlers/metrics.go
Charles-Edouard Brétéché a597d65a33
chore: bump otel deps (#9442)
* chore: bump otel deps

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix semconv version

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
2024-01-19 09:36:28 +00:00

105 lines
4.2 KiB
Go

package handlers
import (
"context"
"net/http"
"strings"
"time"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/metrics"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
)
func (inner AdmissionHandler) WithMetrics(logger logr.Logger, metricsConfig config.MetricsConfiguration, attrs ...attribute.KeyValue) AdmissionHandler {
return inner.withMetrics(logger, metricsConfig, attrs...).WithTrace("METRICS")
}
func (inner AdmissionHandler) withMetrics(logger logr.Logger, metricsConfig config.MetricsConfiguration, attrs ...attribute.KeyValue) AdmissionHandler {
meter := otel.GetMeterProvider().Meter(metrics.MeterName)
requestsMetric, err := meter.Int64Counter(
"kyverno_admission_requests",
metric.WithDescription("can be used to track the number of admission requests encountered by Kyverno in the cluster"),
)
if err != nil {
logger.Error(err, "Failed to create instrument, kyverno_admission_requests_total")
}
durationMetric, err := meter.Float64Histogram(
"kyverno_admission_review_duration_seconds",
metric.WithDescription("can be used to track the latencies (in seconds) associated with the entire individual admission review. For example, if an incoming request trigger, say, five policies, this metric will track the e2e latency associated with the execution of all those policies"),
)
if err != nil {
logger.Error(err, "Failed to create instrument, kyverno_admission_review_duration_seconds")
}
return func(ctx context.Context, logger logr.Logger, request AdmissionRequest, startTime time.Time) AdmissionResponse {
response := inner(ctx, logger, request, startTime)
namespace := request.Namespace
if metricsConfig.CheckNamespace(namespace) {
operation := strings.ToLower(string(request.Operation))
attributes := []attribute.KeyValue{
attribute.String("resource_kind", request.Kind.Kind),
attribute.String("resource_namespace", namespace),
attribute.String("resource_request_operation", operation),
attribute.Bool("request_allowed", response.Allowed),
}
attributes = append(attributes, attrs...)
if durationMetric != nil {
defer func() {
latency := int64(time.Since(startTime))
durationInSeconds := float64(latency) / float64(1000*1000*1000)
durationMetric.Record(ctx, durationInSeconds, metric.WithAttributes(attributes...))
}()
}
if requestsMetric != nil {
requestsMetric.Add(ctx, 1, metric.WithAttributes(attributes...))
}
}
return response
}
}
func (inner HttpHandler) WithMetrics(logger logr.Logger, attrs ...attribute.KeyValue) HttpHandler {
return inner.withMetrics(logger, attrs...).WithTrace("METRICS")
}
func (inner HttpHandler) withMetrics(logger logr.Logger, attrs ...attribute.KeyValue) HttpHandler {
meter := otel.GetMeterProvider().Meter(metrics.MeterName)
requestsMetric, err := meter.Int64Counter(
"kyverno_http_requests",
metric.WithDescription("can be used to track the number of http requests"),
)
if err != nil {
logger.Error(err, "Failed to create instrument, kyverno_http_requests")
}
durationMetric, err := meter.Float64Histogram(
"kyverno_http_requests_duration_seconds",
metric.WithDescription("can be used to track the latencies (in seconds) associated with the entire individual http request."),
)
if err != nil {
logger.Error(err, "Failed to create instrument, kyverno_http_requests_duration_seconds")
}
return func(writer http.ResponseWriter, request *http.Request) {
startTime := time.Now()
attributes := []attribute.KeyValue{
// semconv.HTTPHostKey.String(request.Host),
semconv.HTTPMethodKey.String(request.Method),
semconv.HTTPURLKey.String(request.RequestURI),
}
attributes = append(attributes, attrs...)
if requestsMetric != nil {
requestsMetric.Add(request.Context(), 1, metric.WithAttributes(attributes...))
}
if durationMetric != nil {
defer func() {
latency := int64(time.Since(startTime))
durationInSeconds := float64(latency) / float64(1000*1000*1000)
durationMetric.Record(request.Context(), durationInSeconds, metric.WithAttributes(attributes...))
}()
}
inner(writer, request)
}
}