Skip to content

Commit 573d7ad

Browse files
mahadzaryab1amol-verma-allen
authored andcommitted
[grpc][v2] Implement v2 gRPC trace writer (jaegertracing#6919)
## Which problem is this PR solving? - Towards jaegertracing#6789 ## Description of the changes - This PR implements the v2 gRPC trace writer using OTEL's gRPC exporter client. ## How was this change tested? - Added unit tests ## Checklist - [x] I have read https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md - [x] I have signed all commits - [x] 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`: `npm run lint` and `npm run test` --------- Signed-off-by: Mahad Zaryab <mahadzaryab1@gmail.com> Signed-off-by: amol-verma-allen <amol.verma@allen.in>
1 parent f5b146a commit 573d7ad

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (c) 2025 The Jaeger Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package grpc
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"go.opentelemetry.io/collector/pdata/ptrace"
11+
"go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp"
12+
"google.golang.org/grpc"
13+
14+
"github.com/jaegertracing/jaeger/internal/storage/v2/api/tracestore"
15+
)
16+
17+
var _ tracestore.Writer = (*TraceWriter)(nil)
18+
19+
type TraceWriter struct {
20+
client ptraceotlp.GRPCClient
21+
}
22+
23+
// NewTraceWriter creates a TraceWriter that exports traces to a remote gRPC storage server.
24+
//
25+
// The provided gRPC connection is used exclusively for sending trace data to the backend.
26+
// To prevent recursive trace generation, this connection should not have instrumentation enabled.
27+
func NewTraceWriter(conn *grpc.ClientConn) *TraceWriter {
28+
return &TraceWriter{
29+
client: ptraceotlp.NewGRPCClient(conn),
30+
}
31+
}
32+
33+
func (tw *TraceWriter) WriteTraces(ctx context.Context, td ptrace.Traces) error {
34+
req := ptraceotlp.NewExportRequestFromTraces(td)
35+
_, err := tw.client.Export(ctx, req)
36+
if err != nil {
37+
return fmt.Errorf("failed to export traces: %w", err)
38+
}
39+
return nil
40+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright (c) 2025 The Jaeger Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package grpc
5+
6+
import (
7+
"context"
8+
"net"
9+
"testing"
10+
11+
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
13+
"go.opentelemetry.io/collector/pdata/ptrace"
14+
"go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp"
15+
"google.golang.org/grpc"
16+
"google.golang.org/grpc/credentials/insecure"
17+
)
18+
19+
type testWriterServer struct {
20+
ptraceotlp.UnimplementedGRPCServer
21+
22+
err error
23+
}
24+
25+
func (s *testWriterServer) Export(
26+
context.Context,
27+
ptraceotlp.ExportRequest,
28+
) (ptraceotlp.ExportResponse, error) {
29+
return ptraceotlp.NewExportResponse(), s.err
30+
}
31+
32+
func startWriterServer(t *testing.T, testServer *testWriterServer) *grpc.ClientConn {
33+
listener, err := net.Listen("tcp", ":0")
34+
require.NoError(t, err)
35+
36+
server := grpc.NewServer()
37+
ptraceotlp.RegisterGRPCServer(server, testServer)
38+
39+
go func() {
40+
server.Serve(listener)
41+
}()
42+
43+
conn, err := grpc.NewClient(
44+
listener.Addr().String(),
45+
grpc.WithTransportCredentials(insecure.NewCredentials()),
46+
)
47+
require.NoError(t, err)
48+
49+
t.Cleanup(
50+
func() {
51+
conn.Close()
52+
server.Stop()
53+
listener.Close()
54+
},
55+
)
56+
57+
return conn
58+
}
59+
60+
func TestTraceWriter_WriteTraces(t *testing.T) {
61+
tests := []struct {
62+
name string
63+
serverErr error
64+
expectedErr string
65+
}{
66+
{
67+
name: "no error",
68+
},
69+
{
70+
name: "server error",
71+
serverErr: assert.AnError,
72+
expectedErr: "failed to export traces",
73+
},
74+
}
75+
76+
for _, test := range tests {
77+
t.Run(test.name, func(t *testing.T) {
78+
server := &testWriterServer{err: test.serverErr}
79+
conn := startWriterServer(t, server)
80+
81+
writer := NewTraceWriter(conn)
82+
err := writer.WriteTraces(context.Background(), ptrace.NewTraces())
83+
if test.expectedErr == "" {
84+
require.NoError(t, err)
85+
} else {
86+
require.ErrorContains(t, err, test.expectedErr)
87+
}
88+
})
89+
}
90+
}

0 commit comments

Comments
 (0)