Path: blob/main/pkg/traces/automaticloggingprocessor/automaticloggingprocessor_test.go
4095 views
package automaticloggingprocessor12import (3"context"4"testing"5"time"67"github.com/grafana/agent/pkg/logs"8"github.com/grafana/agent/pkg/util"9"github.com/prometheus/common/model"10"github.com/stretchr/testify/assert"11"github.com/stretchr/testify/require"12"go.opentelemetry.io/collector/component/componenttest"13"go.opentelemetry.io/collector/pdata/pcommon"14"go.opentelemetry.io/collector/pdata/ptrace"15"gopkg.in/yaml.v3"16)1718func TestSpanKeyVals(t *testing.T) {19tests := []struct {20spanName string21spanAttrs map[string]interface{}22spanStart time.Time23spanEnd time.Time24cfg AutomaticLoggingConfig25expected []interface{}26}{27{28expected: []interface{}{29"span", "",30"dur", "0ns",31"status", ptrace.StatusCode(1),32},33},34{35spanName: "test",36expected: []interface{}{37"span", "test",38"dur", "0ns",39"status", ptrace.StatusCode(1),40},41},42{43expected: []interface{}{44"span", "",45"dur", "0ns",46"status", ptrace.StatusCode(1),47},48},49{50spanStart: time.Unix(0, 0),51spanEnd: time.Unix(0, 10),52expected: []interface{}{53"span", "",54"dur", "10ns",55"status", ptrace.StatusCode(1),56},57},58{59spanStart: time.Unix(0, 10),60spanEnd: time.Unix(0, 100),61expected: []interface{}{62"span", "",63"dur", "90ns",64"status", ptrace.StatusCode(1),65},66},67{68spanAttrs: map[string]interface{}{69"xstr": "test",70},71expected: []interface{}{72"span", "",73"dur", "0ns",74"status", ptrace.StatusCode(1),75},76},77{78spanAttrs: map[string]interface{}{79"xstr": "test",80},81cfg: AutomaticLoggingConfig{82SpanAttributes: []string{"xstr"},83},84expected: []interface{}{85"span", "",86"dur", "0ns",87"status", ptrace.StatusCode(1),88"xstr", "test",89},90},91{92cfg: AutomaticLoggingConfig{93Overrides: OverrideConfig{94SpanNameKey: "a",95DurationKey: "c",96StatusKey: "d",97},98},99expected: []interface{}{100"a", "",101"c", "0ns",102"d", ptrace.StatusCode(1),103},104},105}106107for _, tc := range tests {108tc.cfg.Backend = BackendStdout109tc.cfg.Spans = true110p, err := newTraceProcessor(&automaticLoggingProcessor{}, &tc.cfg)111require.NoError(t, err)112113span := ptrace.NewSpan()114span.SetName(tc.spanName)115span.Attributes().FromRaw(tc.spanAttrs)116span.SetStartTimestamp(pcommon.NewTimestampFromTime(tc.spanStart))117span.SetEndTimestamp(pcommon.NewTimestampFromTime(tc.spanEnd))118span.Status().SetCode(ptrace.StatusCodeOk)119120actual := p.(*automaticLoggingProcessor).spanKeyVals(span)121assert.Equal(t, tc.expected, actual)122}123}124125func TestProcessKeyVals(t *testing.T) {126tests := []struct {127processAttrs map[string]interface{}128svc string129cfg AutomaticLoggingConfig130expected []interface{}131}{132{133expected: []interface{}{134"svc", "",135},136},137{138processAttrs: map[string]interface{}{139"xstr": "test",140},141expected: []interface{}{142"svc", "",143},144},145{146processAttrs: map[string]interface{}{147"xstr": "test",148},149cfg: AutomaticLoggingConfig{150ProcessAttributes: []string{"xstr"},151},152expected: []interface{}{153"svc", "",154"xstr", "test",155},156},157}158159for _, tc := range tests {160tc.cfg.Backend = BackendStdout161tc.cfg.Spans = true162p, err := newTraceProcessor(&automaticLoggingProcessor{}, &tc.cfg)163require.NoError(t, err)164165process := pcommon.NewResource()166process.Attributes().Sort().FromRaw(tc.processAttrs)167168actual := p.(*automaticLoggingProcessor).processKeyVals(process, tc.svc)169assert.Equal(t, tc.expected, actual)170}171}172173func TestBadConfigs(t *testing.T) {174tests := []struct {175cfg *AutomaticLoggingConfig176}{177{178cfg: &AutomaticLoggingConfig{},179},180{181cfg: &AutomaticLoggingConfig{182Backend: "blarg",183Spans: true,184},185},186{187cfg: &AutomaticLoggingConfig{188Backend: "logs",189},190},191{192cfg: &AutomaticLoggingConfig{193Backend: "loki",194},195},196{197cfg: &AutomaticLoggingConfig{198Backend: "stdout",199},200},201}202203for _, tc := range tests {204p, err := newTraceProcessor(&automaticLoggingProcessor{}, tc.cfg)205require.Error(t, err)206require.Nil(t, p)207}208}209210func TestLogToStdoutSet(t *testing.T) {211cfg := &AutomaticLoggingConfig{212Backend: BackendStdout,213Spans: true,214}215216p, err := newTraceProcessor(&automaticLoggingProcessor{}, cfg)217require.NoError(t, err)218require.True(t, p.(*automaticLoggingProcessor).logToStdout)219220err = p.Start(context.Background(), componenttest.NewNopHost())221require.NoError(t, err)222223cfg = &AutomaticLoggingConfig{224Backend: BackendLogs,225Spans: true,226}227228p, err = newTraceProcessor(&automaticLoggingProcessor{}, cfg)229require.NoError(t, err)230require.False(t, p.(*automaticLoggingProcessor).logToStdout)231}232233func TestDefaults(t *testing.T) {234cfg := &AutomaticLoggingConfig{235Spans: true,236}237238p, err := newTraceProcessor(&automaticLoggingProcessor{}, cfg)239require.NoError(t, err)240require.Equal(t, BackendStdout, p.(*automaticLoggingProcessor).cfg.Backend)241require.Equal(t, defaultTimeout, p.(*automaticLoggingProcessor).cfg.Timeout)242require.True(t, p.(*automaticLoggingProcessor).logToStdout)243244require.Equal(t, defaultLogsTag, p.(*automaticLoggingProcessor).cfg.Overrides.LogsTag)245require.Equal(t, defaultServiceKey, p.(*automaticLoggingProcessor).cfg.Overrides.ServiceKey)246require.Equal(t, defaultSpanNameKey, p.(*automaticLoggingProcessor).cfg.Overrides.SpanNameKey)247require.Equal(t, defaultStatusKey, p.(*automaticLoggingProcessor).cfg.Overrides.StatusKey)248require.Equal(t, defaultDurationKey, p.(*automaticLoggingProcessor).cfg.Overrides.DurationKey)249require.Equal(t, defaultTraceIDKey, p.(*automaticLoggingProcessor).cfg.Overrides.TraceIDKey)250}251252func TestLokiNameMigration(t *testing.T) {253logsConfig := &logs.Config{254Configs: []*logs.InstanceConfig{{Name: "default"}},255}256257input := util.Untab(`258backend: loki259loki_name: default260overrides:261loki_tag: traces262`)263expect := util.Untab(`264backend: logs_instance265logs_instance_name: default266overrides:267logs_instance_tag: traces268`)269270var cfg AutomaticLoggingConfig271require.NoError(t, yaml.Unmarshal([]byte(input), &cfg))272require.NoError(t, cfg.Validate(logsConfig))273274bb, err := yaml.Marshal(cfg)275require.NoError(t, err)276require.YAMLEq(t, expect, string(bb))277}278279func TestLabels(t *testing.T) {280tests := []struct {281name string282labels []string283keyValues []interface{}284expectedLabels model.LabelSet285}{286{287name: "happy case",288labels: []string{"loki", "svc"},289keyValues: []interface{}{"loki", "loki", "svc", "gateway", "duration", "1s"},290expectedLabels: map[model.LabelName]model.LabelValue{291"loki": "loki",292"svc": "gateway",293},294},295{296name: "happy case with dots",297labels: []string{"loki", "service.name"},298keyValues: []interface{}{"loki", "loki", "service.name", "gateway", "duration", "1s"},299expectedLabels: map[model.LabelName]model.LabelValue{300"loki": "loki",301"service_name": "gateway",302},303},304{305name: "no labels",306labels: []string{},307keyValues: []interface{}{"loki", "loki", "svc", "gateway", "duration", "1s"},308expectedLabels: map[model.LabelName]model.LabelValue{},309},310{311name: "label not present in keyValues",312labels: []string{"loki", "svc"},313keyValues: []interface{}{"loki", "loki", "duration", "1s"},314expectedLabels: map[model.LabelName]model.LabelValue{315"loki": "loki",316},317},318{319name: "label value is not type string",320labels: []string{"loki"},321keyValues: []interface{}{"loki", 42, "duration", "1s"},322expectedLabels: map[model.LabelName]model.LabelValue{323"loki": "42",324},325},326{327name: "stringifies value if possible",328labels: []string{"status"},329keyValues: []interface{}{"status", ptrace.StatusCode(1)},330expectedLabels: map[model.LabelName]model.LabelValue{331"status": model.LabelValue(ptrace.StatusCode(1).String()),332},333},334{335name: "no keyValues",336labels: []string{"status"},337keyValues: []interface{}{},338expectedLabels: map[model.LabelName]model.LabelValue{},339},340}341342for _, tc := range tests {343t.Run(tc.name, func(t *testing.T) {344cfg := &AutomaticLoggingConfig{345Spans: true,346Labels: tc.labels,347}348p, err := newTraceProcessor(&automaticLoggingProcessor{}, cfg)349require.NoError(t, err)350351ls := p.(*automaticLoggingProcessor).spanLabels(tc.keyValues)352assert.Equal(t, tc.expectedLabels, ls)353})354}355}356357358