Path: blob/main/pkg/traces/servicegraphprocessor/processor_test.go
4095 views
package servicegraphprocessor12import (3"bytes"4"context"5"os"6"testing"7"time"89"github.com/grafana/agent/pkg/traces/contextkeys"10"github.com/prometheus/client_golang/prometheus"11"github.com/prometheus/client_golang/prometheus/testutil"12"github.com/stretchr/testify/assert"13"github.com/stretchr/testify/require"14"go.opentelemetry.io/collector/consumer"15"go.opentelemetry.io/collector/pdata/ptrace"16)1718const (19traceSamplePath = "testdata/trace-sample.json"20unpairedTraceSamplePath = "testdata/unpaired-trace-sample.json"21)2223func TestConsumeMetrics(t *testing.T) {24for _, tc := range []struct {25name string26sampleDataPath string27cfg *Config28expectedMetrics string29}{30{31name: "happy case",32sampleDataPath: traceSamplePath,33cfg: &Config{34Wait: time.Hour,35},36expectedMetrics: happyCaseExpectedMetrics,37},38{39name: "unpaired spans",40sampleDataPath: unpairedTraceSamplePath,41cfg: &Config{42Wait: -time.Millisecond,43},44expectedMetrics: `45# HELP traces_service_graph_unpaired_spans_total Total count of unpaired spans46# TYPE traces_service_graph_unpaired_spans_total counter47traces_service_graph_unpaired_spans_total{client="",server="db"} 248traces_service_graph_unpaired_spans_total{client="app",server=""} 349traces_service_graph_unpaired_spans_total{client="lb",server=""} 350`,51},52{53name: "max items in storeMap is reached",54sampleDataPath: traceSamplePath,55cfg: &Config{56Wait: -time.Millisecond,57MaxItems: 1, // Configure max number of items in storeMap to 1. Only one edge will be processed.58},59expectedMetrics: droppedSpansCaseMetrics,60},61{62name: `success codes`,63sampleDataPath: traceSamplePath,64cfg: &Config{65Wait: -time.Millisecond,66SuccessCodes: &successCodes{67http: []int64{404},68},69},70expectedMetrics: successCodesCaseMetrics,71},72} {73t.Run(tc.name, func(t *testing.T) {74p := newProcessor(&mockConsumer{}, tc.cfg)75close(p.closeCh) // Don't collect any edges, leave that to the test.7677reg := prometheus.NewRegistry()78ctx := context.WithValue(context.Background(), contextkeys.PrometheusRegisterer, reg)7980err := p.Start(ctx, nil)81require.NoError(t, err)8283traces := traceSamples(t, tc.sampleDataPath)84err = p.ConsumeTraces(context.Background(), traces)85require.NoError(t, err)8687collectMetrics(p)8889assert.Eventually(t, func() bool {90return testutil.GatherAndCompare(reg, bytes.NewBufferString(tc.expectedMetrics)) == nil91}, time.Second, time.Millisecond*100)92err = testutil.GatherAndCompare(reg, bytes.NewBufferString(tc.expectedMetrics))93require.NoError(t, err)94})95}96}9798func traceSamples(t *testing.T, path string) ptrace.Traces {99b, err := os.ReadFile(path)100require.NoError(t, err)101102decoder := &ptrace.JSONUnmarshaler{}103traces, err := decoder.UnmarshalTraces(b)104require.NoError(t, err)105106return traces107}108109// helper function to force collection of all metrics110func collectMetrics(p *processor) {111p.store.mtx.Lock()112defer p.store.mtx.Unlock()113114for h := p.store.l.Front(); h != nil; h = p.store.l.Front() {115edge := h.Value.(*edge)116p.collectEdge(edge)117delete(p.store.m, edge.key)118p.store.l.Remove(h)119}120}121122type mockConsumer struct{}123124func (m *mockConsumer) Capabilities() consumer.Capabilities { return consumer.Capabilities{} }125126func (m *mockConsumer) ConsumeTraces(context.Context, ptrace.Traces) error { return nil }127128const (129happyCaseExpectedMetrics = `130# HELP traces_service_graph_request_client_seconds Time for a request between two nodes as seen from the client131# TYPE traces_service_graph_request_client_seconds histogram132traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.01"} 0133traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.02"} 0134traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.04"} 0135traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.08"} 0136traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.16"} 0137traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.32"} 0138traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.64"} 0139traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="1.28"} 2140traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="2.56"} 3141traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="5.12"} 3142traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="10.24"} 3143traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="20.48"} 3144traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="+Inf"} 3145traces_service_graph_request_client_seconds_sum{client="app",server="db"} 4.4146traces_service_graph_request_client_seconds_count{client="app",server="db"} 3147traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.01"} 0148traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.02"} 0149traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.04"} 0150traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.08"} 0151traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.16"} 0152traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.32"} 0153traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.64"} 0154traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="1.28"} 0155traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="2.56"} 2156traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="5.12"} 3157traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="10.24"} 3158traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="20.48"} 3159traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="+Inf"} 3160traces_service_graph_request_client_seconds_sum{client="lb",server="app"} 7.8161traces_service_graph_request_client_seconds_count{client="lb",server="app"} 3162# HELP traces_service_graph_request_failed_total Total count of failed requests between two nodes163# TYPE traces_service_graph_request_failed_total counter164traces_service_graph_request_failed_total{client="lb",server="app"} 2165# HELP traces_service_graph_request_server_seconds Time for a request between two nodes as seen from the server166# TYPE traces_service_graph_request_server_seconds histogram167traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.01"} 0168traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.02"} 0169traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.04"} 0170traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.08"} 0171traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.16"} 0172traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.32"} 0173traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.64"} 0174traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="1.28"} 1175traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="2.56"} 3176traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="5.12"} 3177traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="10.24"} 3178traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="20.48"} 3179traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="+Inf"} 3180traces_service_graph_request_server_seconds_sum{client="app",server="db"} 5181traces_service_graph_request_server_seconds_count{client="app",server="db"} 3182traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.01"} 0183traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.02"} 0184traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.04"} 0185traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.08"} 0186traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.16"} 0187traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.32"} 0188traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.64"} 0189traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="1.28"} 1190traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="2.56"} 2191traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="5.12"} 3192traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="10.24"} 3193traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="20.48"} 3194traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="+Inf"} 3195traces_service_graph_request_server_seconds_sum{client="lb",server="app"} 6.2196traces_service_graph_request_server_seconds_count{client="lb",server="app"} 3197# HELP traces_service_graph_request_total Total count of requests between two nodes198# TYPE traces_service_graph_request_total counter199traces_service_graph_request_total{client="app",server="db"} 3200traces_service_graph_request_total{client="lb",server="app"} 3201`202droppedSpansCaseMetrics = `203# HELP traces_service_graph_dropped_spans_total Total count of dropped spans204# TYPE traces_service_graph_dropped_spans_total counter205traces_service_graph_dropped_spans_total{client="",server="app"} 2206traces_service_graph_dropped_spans_total{client="",server="db"} 3207traces_service_graph_dropped_spans_total{client="app",server=""} 3208traces_service_graph_dropped_spans_total{client="lb",server=""} 2209# HELP traces_service_graph_request_client_seconds Time for a request between two nodes as seen from the client210# TYPE traces_service_graph_request_client_seconds histogram211traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.01"} 0212traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.02"} 0213traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.04"} 0214traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.08"} 0215traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.16"} 0216traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.32"} 0217traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.64"} 0218traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="1.28"} 0219traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="2.56"} 1220traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="5.12"} 1221traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="10.24"} 1222traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="20.48"} 1223traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="+Inf"} 1224traces_service_graph_request_client_seconds_sum{client="lb",server="app"} 2.5225traces_service_graph_request_client_seconds_count{client="lb",server="app"} 1226# HELP traces_service_graph_request_failed_total Total count of failed requests between two nodes227# TYPE traces_service_graph_request_failed_total counter228traces_service_graph_request_failed_total{client="lb",server="app"} 1229# HELP traces_service_graph_request_server_seconds Time for a request between two nodes as seen from the server230# TYPE traces_service_graph_request_server_seconds histogram231traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.01"} 0232traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.02"} 0233traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.04"} 0234traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.08"} 0235traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.16"} 0236traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.32"} 0237traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.64"} 0238traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="1.28"} 1239traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="2.56"} 1240traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="5.12"} 1241traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="10.24"} 1242traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="20.48"} 1243traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="+Inf"} 1244traces_service_graph_request_server_seconds_sum{client="lb",server="app"} 1245traces_service_graph_request_server_seconds_count{client="lb",server="app"} 1246# HELP traces_service_graph_request_total Total count of requests between two nodes247# TYPE traces_service_graph_request_total counter248traces_service_graph_request_total{client="lb",server="app"} 1249`250// has only one failed span instead of 2251successCodesCaseMetrics = `252# HELP traces_service_graph_request_client_seconds Time for a request between two nodes as seen from the client253# TYPE traces_service_graph_request_client_seconds histogram254traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.01"} 0255traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.02"} 0256traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.04"} 0257traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.08"} 0258traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.16"} 0259traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.32"} 0260traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="0.64"} 0261traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="1.28"} 2262traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="2.56"} 3263traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="5.12"} 3264traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="10.24"} 3265traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="20.48"} 3266traces_service_graph_request_client_seconds_bucket{client="app",server="db",le="+Inf"} 3267traces_service_graph_request_client_seconds_sum{client="app",server="db"} 4.4268traces_service_graph_request_client_seconds_count{client="app",server="db"} 3269traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.01"} 0270traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.02"} 0271traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.04"} 0272traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.08"} 0273traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.16"} 0274traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.32"} 0275traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="0.64"} 0276traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="1.28"} 0277traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="2.56"} 2278traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="5.12"} 3279traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="10.24"} 3280traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="20.48"} 3281traces_service_graph_request_client_seconds_bucket{client="lb",server="app",le="+Inf"} 3282traces_service_graph_request_client_seconds_sum{client="lb",server="app"} 7.8283traces_service_graph_request_client_seconds_count{client="lb",server="app"} 3284# HELP traces_service_graph_request_failed_total Total count of failed requests between two nodes285# TYPE traces_service_graph_request_failed_total counter286traces_service_graph_request_failed_total{client="lb",server="app"} 1287# HELP traces_service_graph_request_server_seconds Time for a request between two nodes as seen from the server288# TYPE traces_service_graph_request_server_seconds histogram289traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.01"} 0290traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.02"} 0291traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.04"} 0292traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.08"} 0293traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.16"} 0294traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.32"} 0295traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="0.64"} 0296traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="1.28"} 1297traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="2.56"} 3298traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="5.12"} 3299traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="10.24"} 3300traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="20.48"} 3301traces_service_graph_request_server_seconds_bucket{client="app",server="db",le="+Inf"} 3302traces_service_graph_request_server_seconds_sum{client="app",server="db"} 5303traces_service_graph_request_server_seconds_count{client="app",server="db"} 3304traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.01"} 0305traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.02"} 0306traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.04"} 0307traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.08"} 0308traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.16"} 0309traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.32"} 0310traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="0.64"} 0311traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="1.28"} 1312traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="2.56"} 2313traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="5.12"} 3314traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="10.24"} 3315traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="20.48"} 3316traces_service_graph_request_server_seconds_bucket{client="lb",server="app",le="+Inf"} 3317traces_service_graph_request_server_seconds_sum{client="lb",server="app"} 6.2318traces_service_graph_request_server_seconds_count{client="lb",server="app"} 3319# HELP traces_service_graph_request_total Total count of requests between two nodes320# TYPE traces_service_graph_request_total counter321traces_service_graph_request_total{client="app",server="db"} 3322traces_service_graph_request_total{client="lb",server="app"} 3323`324)325326327