-
Notifications
You must be signed in to change notification settings - Fork 8
P2: OpenTelemetry integration — trace SQL parsing in distributed systems #451
Copy link
Copy link
Closed
Labels
Description
Problem
GoSQLX has no observability integration. In production microservices, teams need to trace SQL parsing duration, statement complexity, and dialect distribution alongside their application traces. Currently, GoSQLX is a black box from an observability perspective.
Proposed API
import (
"go.opentelemetry.io/otel"
"github.com/ajitpratap0/GoSQLX/pkg/integration/otel"
)
// Option 1: Wrap the gosqlx package with tracing
tracer := otel.Tracer("gosqlx")
tracedGosqlx := gosqlxotel.New(tracer)
ast, err := tracedGosqlx.Parse(ctx, sql)
// Emits span: gosqlx.parse
// Span attributes:
// gosqlx.dialect = "postgresql"
// gosqlx.statement_count = 1
// gosqlx.statement_type = "select"
// gosqlx.has_subquery = true
// gosqlx.token_count = 47
// gosqlx.parse_duration_ms = 0.12
// Option 2: ParseOptions with tracer injection (no wrapper needed)
ast, err := gosqlx.ParseWithOptions(sql, gosqlx.ParseOptions{
Tracer: otel.Tracer("gosqlx"),
Context: ctx,
})Span Attributes to Emit
gosqlx.dialect (string) — postgresql, mysql, etc.
gosqlx.statement_type (string) — select, insert, update, delete, merge, etc.
gosqlx.statement_count (int) — for ParseMultiple
gosqlx.token_count (int) — tokenizer output size
gosqlx.has_subquery (bool) — complexity signal
gosqlx.has_cte (bool) — complexity signal
gosqlx.has_window (bool) — complexity signal
gosqlx.table_count (int) — number of tables referenced
gosqlx.complexity_score (int) — advisor complexity rating
gosqlx.error (string) — parse error if any
Package Structure
pkg/integration/
├── otel/
│ ├── tracer.go — TracedParser wrapper
│ ├── attributes.go — Span attribute extraction from AST
│ └── tracer_test.go — Unit tests with in-memory tracer
└── gorm/
└── hooks.go — GORM pre-query hook (separate issue)
Design Principles
- Optional dependency: OTel packages are NOT in the main go.mod. The
pkg/integration/otelsub-package adds its owngo.modwith OTel as a dependency. Zero overhead if not used. - Context propagation: All traced calls require a
context.Context; trace context is extracted automatically - No instrumentation overhead when disabled: Zero allocation path when no tracer is configured
Acceptance Criteria
-
pkg/integration/otelpackage with TracedParser wrapper - Span attributes cover: dialect, statement type, token count, complexity signals
- OTel dependency in sub-module (not in main go.mod)
- Tests using in-memory span exporter
- Example in
examples/otel-tracing/ - Benchmark: zero overhead when tracer not configured (<1ns)
Reactions are currently unavailable