From a78782e1ff6f11e624a1b08268d7051c78536925 Mon Sep 17 00:00:00 2001 From: James Ryans <46216691+james-ryans@users.noreply.github.com> Date: Thu, 2 May 2024 03:20:21 +0700 Subject: [PATCH] [jaeger-v2] Define an internal interface of storage v2 spanstore (#5399) ## Which problem is this PR solving? - Part of #5334 ## Description of the changes - An API design of Storage V2 spanstore and its proto file. - For the detailed discussion and how we arrived to this design, please take a look at https://docs.google.com/document/d/1IvUcDsdRxMPK-xTUE32w3NSAGTkUcmnDQttN6ijUnWs/edit?usp=sharing ## How was this change tested? - This PR hasn't been tested yet since it only contains interfaces and no actual implementation to be tested. ## Checklist - [x] I have read https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md - [x] I have signed all commits - [ ] I have added unit tests for the new functionality - [x] I have run lint and test steps successfully - for `jaeger`: `make lint test` - for `jaeger-ui`: `yarn lint` and `yarn test` --------- Signed-off-by: James Ryans --- storage_v2/empty_test.go | 14 ++++++ storage_v2/factory.go | 21 +++++++++ storage_v2/spanstore/empty_test.go | 14 ++++++ storage_v2/spanstore/factory.go | 20 +++++++++ storage_v2/spanstore/reader.go | 71 ++++++++++++++++++++++++++++++ storage_v2/spanstore/writer.go | 19 ++++++++ 6 files changed, 159 insertions(+) create mode 100644 storage_v2/empty_test.go create mode 100644 storage_v2/factory.go create mode 100644 storage_v2/spanstore/empty_test.go create mode 100644 storage_v2/spanstore/factory.go create mode 100644 storage_v2/spanstore/reader.go create mode 100644 storage_v2/spanstore/writer.go diff --git a/storage_v2/empty_test.go b/storage_v2/empty_test.go new file mode 100644 index 000000000000..1802ccdc52e3 --- /dev/null +++ b/storage_v2/empty_test.go @@ -0,0 +1,14 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package storage_v2 + +import ( + "testing" + + "github.com/jaegertracing/jaeger/pkg/testutils" +) + +func TestMain(m *testing.M) { + testutils.VerifyGoLeaks(m) +} diff --git a/storage_v2/factory.go b/storage_v2/factory.go new file mode 100644 index 000000000000..e7515549e05d --- /dev/null +++ b/storage_v2/factory.go @@ -0,0 +1,21 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package storage_v2 + +import ( + "context" +) + +// Factory is a general factory interface to be reused across different storage factories. +// It lives within the OTEL collector extension component's lifecycle. +// The Initialize and Close functions supposed to be called from the +// OTEL component's Start and Shutdown functions. +type FactoryBase interface { + // Initialize performs internal initialization of the factory, + // such as opening connections to the backend store. + Initialize(ctx context.Context) error + + // Close closes the resources held by the factory + Close(ctx context.Context) error +} diff --git a/storage_v2/spanstore/empty_test.go b/storage_v2/spanstore/empty_test.go new file mode 100644 index 000000000000..50d2cb2753a7 --- /dev/null +++ b/storage_v2/spanstore/empty_test.go @@ -0,0 +1,14 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package spanstore + +import ( + "testing" + + "github.com/jaegertracing/jaeger/pkg/testutils" +) + +func TestMain(m *testing.M) { + testutils.VerifyGoLeaks(m) +} diff --git a/storage_v2/spanstore/factory.go b/storage_v2/spanstore/factory.go new file mode 100644 index 000000000000..3701a97ccdaf --- /dev/null +++ b/storage_v2/spanstore/factory.go @@ -0,0 +1,20 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package spanstore + +import ( + "github.com/jaegertracing/jaeger/storage_v2" +) + +// Factory defines an interface for a factory that can create implementations of +// different span storage components. +type Factory interface { + storage_v2.FactoryBase + + // CreateTraceReader creates a spanstore.Reader. + CreateTraceReader() (Reader, error) + + // CreateTraceWriter creates a spanstore.Writer. + CreateTraceWriter() (Writer, error) +} diff --git a/storage_v2/spanstore/reader.go b/storage_v2/spanstore/reader.go new file mode 100644 index 000000000000..b7e9f78ca093 --- /dev/null +++ b/storage_v2/spanstore/reader.go @@ -0,0 +1,71 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package spanstore + +import ( + "context" + "time" + + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/ptrace" + + spanstore_v1 "github.com/jaegertracing/jaeger/storage/spanstore" +) + +// ErrTraceNotFound is returned by Reader's GetTrace if no data is found for given trace ID. +var ErrTraceNotFound = spanstore_v1.ErrTraceNotFound + +// Reader finds and loads traces and other data from storage. +type Reader interface { + // GetTrace retrieves the trace with a given id. + // + // If no spans are stored for this trace, it returns ErrTraceNotFound. + GetTrace(ctx context.Context, traceID pcommon.TraceID) (ptrace.Traces, error) + + // GetServices returns all service names known to the backend from spans + // within its retention period. + GetServices(ctx context.Context) ([]string, error) + + // GetOperations returns all operation names for a given service + // known to the backend from spans within its retention period. + GetOperations(ctx context.Context, query OperationQueryParameters) ([]Operation, error) + + // FindTraces returns all traces matching query parameters. There's currently + // an implementation-dependent ambiguity whether all query filters (such as + // multiple tags) must apply to the same span within a trace, or can be satisfied + // by different spans. + // + // If no matching traces are found, the function returns (nil, nil). + FindTraces(ctx context.Context, query TraceQueryParameters) ([]ptrace.Traces, error) + + // FindTraceIDs does the same search as FindTraces, but returns only the list + // of matching trace IDs. + // + // If no matching traces are found, the function returns (nil, nil). + FindTraceIDs(ctx context.Context, query TraceQueryParameters) ([]pcommon.TraceID, error) +} + +// TraceQueryParameters contains parameters of a trace query. +type TraceQueryParameters struct { + ServiceName string + OperationName string + Tags map[string]string + StartTimeMin time.Time + StartTimeMax time.Time + DurationMin time.Duration + DurationMax time.Duration + NumTraces int +} + +// OperationQueryParameters contains parameters of query operations, empty spanKind means get operations for all kinds of span. +type OperationQueryParameters struct { + ServiceName string + SpanKind string +} + +// Operation contains operation name and span kind +type Operation struct { + Name string + SpanKind string +} diff --git a/storage_v2/spanstore/writer.go b/storage_v2/spanstore/writer.go new file mode 100644 index 000000000000..cbccaf7c258e --- /dev/null +++ b/storage_v2/spanstore/writer.go @@ -0,0 +1,19 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package spanstore + +import ( + "context" + + "go.opentelemetry.io/collector/pdata/ptrace" +) + +// Writer writes spans to storage. +type Writer interface { + // WriteTrace writes a batch of spans to storage. Idempotent. + // Implementations are not required to support atomic transactions, + // so if any of the spans fail to be written an error is returned. + // Compatible with OTLP Exporter API. + WriteTraces(ctx context.Context, td ptrace.Traces) error +}