Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,7 @@ packages:
github.com/jaegertracing/jaeger/internal/storage/v2/api/tracestore:
config:
all: true
github.com/jaegertracing/jaeger/internal/storage/v2/clickhouse:
interfaces:
Conn: {}
Batch: {}
22 changes: 22 additions & 0 deletions internal/storage/v2/clickhouse/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2025 The Jaeger Authors.
// SPDX-License-Identifier: Apache-2.0

package clickhouse

import "context"

// Conn is an abstract interface representing a connection to ClickHouse.
// It is based on the driver.Conn interface in the github.com/ClickHouse/clickhouse-go package,
// primarily used for preparing Batch operations for executing ClickHouse queries.
// see https://github.com/ClickHouse/clickhouse-go/blob/main/lib/driver/driver.go#L52
type Conn interface {
PrepareBatch(ctx context.Context, query string) (Batch, error)
}

// Batch is an abstract interface representing a Batch for bulk operations.
// It is based on the conn_batch.Batch interface in the https://github.com/ClickHouse/clickhouse-go/blob/main/conn_batch.go
// providing methods to append data to the Batch (Append) and send the Batch to ClickHouse (Send).
type Batch interface {
Append(v ...any) error
Send() error
}
229 changes: 229 additions & 0 deletions internal/storage/v2/clickhouse/mocks/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions internal/storage/v2/clickhouse/package_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) 2025 The Jaeger Authors.
// SPDX-License-Identifier: Apache-2.0

package clickhouse

import (
"testing"

"github.com/jaegertracing/jaeger/internal/testutils"
)

func TestMain(m *testing.M) {
testutils.VerifyGoLeaks(m)
}
46 changes: 46 additions & 0 deletions internal/storage/v2/clickhouse/tracestore/writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2025 The Jaeger Authors.
// SPDX-License-Identifier: Apache-2.0

package tracestore

import (
"context"
"fmt"

"go.opentelemetry.io/collector/pdata/ptrace"

"github.com/jaegertracing/jaeger/internal/storage/v2/clickhouse"
"github.com/jaegertracing/jaeger/internal/storage/v2/clickhouse/tracestore/dbmodel"
)

const insertTrace = "INSERT INTO traces"

type Writer struct {
client clickhouse.Conn
}

func (tw *Writer) WriteTraces(ctx context.Context, td ptrace.Traces) error {
var err error
batch, err := tw.client.PrepareBatch(ctx, insertTrace)
if err != nil {
return fmt.Errorf("error closing ClickHouse batch: %w", err)
}

// The dbmodel.ToDBModel is now based on the ch-go library.
// It will be deprecated in favor of a new function based on the clickhouse-go library.
// For more information, see https://github.com/jaegertracing/jaeger/pull/7149.
traces := dbmodel.ToDBModel(td)

for range traces {
// TODO Maybe AppendStruct is a better choice.
err := batch.Append()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not complete. The batch.Append call should resemble the following:

err := batch.Append(
			spanRow.StartTime,
			spanRow.TraceId,
			spanRow.SpanId,
			spanRow.ParentSpanId,
			spanRow.TraceState,
			spanRow.ServiceName,
			spanRow.Name,
			spanRow.Kind,
			spanRow.Duration,
			spanRow.StatusCode,
			spanRow.StatusMessage,
			spanRow.Attributes.BoolKeys,
			spanRow.Attributes.BoolValues,
			spanRow.Attributes.DoubleKeys,
			spanRow.Attributes.DoubleValues,
			spanRow.Attributes.IntKeys,
			spanRow.Attributes.IntValues,
			spanRow.Attributes.StrKeys,
			spanRow.Attributes.StrValues,
			spanRow.Attributes.BytesKeys,
			spanRow.Attributes.BytesValues,

			scopeRow.Name,
			scopeRow.Version,
			scopeRow.Attributes.BoolKeys,
			scopeRow.Attributes.BoolValues,
			scopeRow.Attributes.DoubleKeys,
			scopeRow.Attributes.DoubleValues,
			scopeRow.Attributes.IntKeys,
			scopeRow.Attributes.IntValues,
			scopeRow.Attributes.StrKeys,
			scopeRow.Attributes.StrValues,
			scopeRow.Attributes.BytesKeys,
			scopeRow.Attributes.BytesValues,

			resourceRow.Attributes.BoolKeys,
			resourceRow.Attributes.BoolValues,
			resourceRow.Attributes.DoubleKeys,
			resourceRow.Attributes.DoubleValues,
			resourceRow.Attributes.IntKeys,
			resourceRow.Attributes.IntValues,
			resourceRow.Attributes.StrKeys,
			resourceRow.Attributes.StrValues,
			resourceRow.Attributes.BytesKeys,
			resourceRow.Attributes.BytesValues,

			eventsRow.Names,
			eventsRow.Timestamps,
			eventsAllAttrRow.BoolAttrs,
			eventsAllAttrRow.DoubleAttrs,
			eventsAllAttrRow.IntAttrs,
			eventsAllAttrRow.StrAttrs,
			eventsAllAttrRow.BytesAttrs,

			linksRow.TraceIds,
			linksRow.SpanIds,
			linksRow.TraceStates,
			linksAllAttrRow.BoolAttrs,
			linksAllAttrRow.DoubleAttrs,
			linksAllAttrRow.IntAttrs,
			linksAllAttrRow.StrAttrs,
			linksAllAttrRow.BytesAttrs,
		)

However, to keep this PR small and simple, adding the batch.Append logic with all these fields would be too large of a change. Therefore, it's better to add the complete batch.Append implementation in a subsequent PR.

if err != nil {
return fmt.Errorf("failed to append trace data to ClickHouse batch: %w", err)
}
}
err = batch.Send()
if err != nil {
return fmt.Errorf("failed to send data to Clickhouse: %w", err)
}
return nil
}
Loading
Loading