diff --git a/datasource/jaeger/jaeger.go b/datasource/jaeger/jaeger.go index fa4df2f4..bb9146bd 100644 --- a/datasource/jaeger/jaeger.go +++ b/datasource/jaeger/jaeger.go @@ -7,8 +7,6 @@ import ( "github.com/K-Phoen/sdk" ) -// TODO: support "Trace to logs" settings - var _ datasource.Datasource = Jaeger{} type Jaeger struct { @@ -16,6 +14,7 @@ type Jaeger struct { } type Option func(datasource *Jaeger) +type TraceToLogsOption func(settings map[string]interface{}) func New(name string, url string, options ...Option) Jaeger { jaeger := &Jaeger{ diff --git a/datasource/jaeger/options.go b/datasource/jaeger/options.go index ee165551..3b24f5f4 100644 --- a/datasource/jaeger/options.go +++ b/datasource/jaeger/options.go @@ -73,3 +73,56 @@ func WithNodeGraph() Option { } } } + +// TraceToLogs defines how to navigate from a trace span to the selected datasource logs. +func TraceToLogs(logsDatasourceUID string, options ...TraceToLogsOption) Option { + settings := map[string]interface{}{ + "datasourceUid": logsDatasourceUID, + } + + for _, opt := range options { + opt(settings) + } + + return func(datasource *Jaeger) { + datasource.builder.JSONData.(map[string]interface{})["tracesToLogs"] = settings + } +} + +// Tags defines tags that will be used in the Loki query. +// Default tags: 'cluster', 'hostname', 'namespace', 'pod'. +func Tags(tags ...string) TraceToLogsOption { + return func(settings map[string]interface{}) { + settings["tags"] = tags + } +} + +// SpanStartShift shifts the start time of the span. +// Default 0 (Time units can be used here, for example: 5s, 1m, 3h) +func SpanStartShift(shift time.Duration) TraceToLogsOption { + return func(settings map[string]interface{}) { + settings["spanStartTimeShift"] = shift.String() + } +} + +// SpanEndShift shifts the start time of the span. +// Default 0 (Time units can be used here, for example: 5s, 1m, 3h) +func SpanEndShift(shift time.Duration) TraceToLogsOption { + return func(settings map[string]interface{}) { + settings["spanEndTimeShift"] = shift.String() + } +} + +// FilterByTrace filters logs by Trace ID. Appends '|=' to the query. +func FilterByTrace() TraceToLogsOption { + return func(settings map[string]interface{}) { + settings["filterByTraceID"] = true + } +} + +// FilterBySpan filters logs by Trace ID. Appends '|=' to the query. +func FilterBySpan() TraceToLogsOption { + return func(settings map[string]interface{}) { + settings["filterBySpanID"] = true + } +} diff --git a/datasource/jaeger/options_test.go b/datasource/jaeger/options_test.go index 7c01761e..367030ee 100644 --- a/datasource/jaeger/options_test.go +++ b/datasource/jaeger/options_test.go @@ -84,3 +84,28 @@ func TestWithNodeGraph(t *testing.T) { req.Equal(true, jsonData["nodeGraph"].(map[string]interface{})["enabled"]) } + +func TestTraceToLogs(t *testing.T) { + req := require.New(t) + + lokiDatasourceUID := "lala" + datasource := New("", "", TraceToLogs( + lokiDatasourceUID, + Tags("pod", "namespace"), + SpanStartShift(2*time.Second), + SpanEndShift(1*time.Second), + FilterByTrace(), + FilterBySpan(), + )) + + jsonData := datasource.builder.JSONData.(map[string]interface{}) + traceToLogsSettings := jsonData["tracesToLogs"].(map[string]interface{}) + + req.NotEmpty(traceToLogsSettings) + req.Equal(lokiDatasourceUID, traceToLogsSettings["datasourceUid"]) + req.ElementsMatch([]string{"pod", "namespace"}, traceToLogsSettings["tags"]) + req.Equal("2s", traceToLogsSettings["spanStartTimeShift"]) + req.Equal("1s", traceToLogsSettings["spanEndTimeShift"]) + req.Equal(true, traceToLogsSettings["filterByTraceID"]) + req.Equal(true, traceToLogsSettings["filterBySpanID"]) +}