From e243d4dee3af158178fb77944ff6bf556b2707d7 Mon Sep 17 00:00:00 2001 From: Pavel <177363085+pkcll@users.noreply.github.com> Date: Tue, 7 Jul 2026 00:06:03 -0400 Subject: [PATCH] fix(workflows): cap get-secrets histogram buckets in MetricViews platform_engine_get_secrets_duration_ms used OTel default 16 buckets; add an explicit 8-bucket view next to the other platform_engine views. Co-authored-by: Cursor --- .../workflows/monitoring/metric_views_test.go | 47 +++++++++++++++++++ .../workflows/monitoring/monitoring.go | 7 +++ 2 files changed, 54 insertions(+) create mode 100644 core/services/workflows/monitoring/metric_views_test.go diff --git a/core/services/workflows/monitoring/metric_views_test.go b/core/services/workflows/monitoring/metric_views_test.go new file mode 100644 index 00000000000..0418705907e --- /dev/null +++ b/core/services/workflows/monitoring/metric_views_test.go @@ -0,0 +1,47 @@ +package monitoring_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/metric" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + + "github.com/smartcontractkit/chainlink/v2/core/services/workflows/monitoring" +) + +func TestMetricViews_getSecretsDurationBuckets(t *testing.T) { + t.Parallel() + + wantBoundaries := []float64{0, 10, 50, 100, 250, 500, 1000} + + reader := sdkmetric.NewManualReader() + mp := sdkmetric.NewMeterProvider( + sdkmetric.WithReader(reader), + sdkmetric.WithView(monitoring.MetricViews()...), + ) + t.Cleanup(func() { _ = mp.Shutdown(context.Background()) }) + + hist, err := mp.Meter("test").Int64Histogram( + "platform_engine_get_secrets_duration_ms", + metric.WithUnit("ms"), + ) + require.NoError(t, err) + hist.Record(context.Background(), 75) + + var rm metricdata.ResourceMetrics + require.NoError(t, reader.Collect(context.Background(), &rm)) + + require.Len(t, rm.ScopeMetrics, 1) + require.Len(t, rm.ScopeMetrics[0].Metrics, 1) + require.Equal(t, "platform_engine_get_secrets_duration_ms", rm.ScopeMetrics[0].Metrics[0].Name) + + data, ok := rm.ScopeMetrics[0].Metrics[0].Data.(metricdata.Histogram[int64]) + require.True(t, ok) + require.Len(t, data.DataPoints, 1) + assert.Equal(t, wantBoundaries, data.DataPoints[0].Bounds) + assert.Len(t, data.DataPoints[0].Bounds, 7, "expected 7 boundaries (8 Prometheus buckets including +Inf)") +} diff --git a/core/services/workflows/monitoring/monitoring.go b/core/services/workflows/monitoring/monitoring.go index 5117be7a23d..16111755a6b 100644 --- a/core/services/workflows/monitoring/monitoring.go +++ b/core/services/workflows/monitoring/monitoring.go @@ -490,6 +490,13 @@ func MetricViews() []sdkmetric.View { Boundaries: []float64{0, 0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30, 60}, }}, ), + // Default OTel buckets (16) for this instrument; Capabilities dashboards use p50/p90. + sdkmetric.NewView( + sdkmetric.Instrument{Name: "platform_engine_get_secrets_duration_ms"}, + sdkmetric.Stream{Aggregation: sdkmetric.AggregationExplicitBucketHistogram{ + Boundaries: []float64{0, 10, 50, 100, 250, 500, 1000}, + }}, + ), } }