Skip to content

feat: OpenTelemetry instrumentation#1394

Open
joschi wants to merge 20 commits into
golang-migrate:masterfrom
joschi:feat-opentelemetry-instrumentation
Open

feat: OpenTelemetry instrumentation#1394
joschi wants to merge 20 commits into
golang-migrate:masterfrom
joschi:feat-opentelemetry-instrumentation

Conversation

@joschi
Copy link
Copy Markdown
Contributor

@joschi joschi commented Apr 19, 2026

Adds end-to-end OpenTelemetry observability to golang-migrate. Zero breaking changes — all instrumentation is automatic when a global SDK provider is configured.

Note

This PR is based on #1132 and requires the changes from that PR to work.

What's instrumented

Core (migrate.go)

Every public entry point emits an INTERNAL span with shared attributes (db.system.name, migrate.source):

Span Attributes
migrate.up / migrate.down migrate.direction
migrate.migrate / migrate.force migrate.version
migrate.steps migrate.direction, migrate.steps
migrate.run
migrate.run_migration migrate.version, migrate.target_version, migrate.direction, migrate.identifier
migrate.drop

Metrics (OpenTelemetry metric instruments):

Metric Type Unit
migrate.migrations.applied Int64Counter {migration}
migrate.migrations.failed Int64Counter {migration}
migrate.migration.run.duration Float64Histogram s

Database drivers — transparent wrapper (database/oteldriver.go)

database.NewOTelDriver wraps any database.Driver and emits CLIENT spans for every operation (db.lock, db.unlock, db.run, db.set_version, db.version, db.drop). Applied automatically inside all four New* constructors.

Source drivers — transparent wrapper (source/oteldriver.go)

source.NewOTelDriver wraps any source.Driver and emits INTERNAL spans for source.read_up and source.read_down. Applied automatically in all constructors. os.ErrNotExist is not treated as an error (expected "no migration here" signal).

Per-driver instrumentation

Library-native OTel instrumentation using the appropriate contrib package:

Driver(s) Library Approach
clickhouse, cockroachdb, firebird, mysql, pgx, pgx/v5, postgres, ql, redshift, snowflake, sqlite, sqlite3, sqlserver, yugabytedb otelsql otelsql.Open wraps the registered SQL driver
sqlcipher otelsql Same, via ExecerContext adapter (go-sqlcipher/v4 only implements deprecated driver.Execer)
cassandra otelgocql otelgocql.NewSessionWithTracing
mongodb otelmongo options.Client().SetMonitor(otelmongo.NewMonitor())
spanner otelgrpc option.WithGRPCDialOption(grpc.WithStatsHandler(otelgrpc.NewClientHandler()))
aws_s3 otelaws otelaws.AppendMiddlewares(&cfg.APIOptions)also migrates aws_s3 from SDK v1 → v2
bitbucket, github, github_ee, gitlab otelhttp otelhttp.NewTransport injected as the HTTP client transport
google_cloud_storage otelgrpc Same as spanner

Not instrumented: neo4j (v1 driver has no OTel API; v5 migration is a separate effort), rqlite (gorqlite's HTTP client is unexported — no injection point).

Attributes

Attribute keys follow semconv v1.39.0 (db.system.name per the rename from db.system). Numeric version attributes (migrate.version, migrate.target_version) are recorded as Int64 to avoid overflow on 32-bit platforms.

Error handling in spans

When a span is set to error status, database.Error values are sanitized: only the underlying OrigErr is used as the span status description, preventing migration SQL/query excerpts from leaking into traces. The full error (including query context) is still attached via RecordError for diagnostic use.

Trace topology

migrate.up                              INTERNAL
  db.lock                               CLIENT
  db.version                            CLIENT
  source.read_up (version N)            INTERNAL
  migrate.run_migration (version N)     INTERNAL
    db.set_version (dirty=true)         CLIENT
      [otelsql/otelgocql/… child]
    db.run                              CLIENT
      [otelsql/otelgocql/… child]
    db.set_version (dirty=false)        CLIENT
  db.unlock                             CLIENT

Dependency changes

  • Added: go.opentelemetry.io/otel + SDK (v1.40.0), github.com/XSAM/otelsql (v0.41.0), otelgocql, otelmongo, otelaws, otelhttp, otelgrpc
  • Upgraded: go.mongodb.org/mongo-driver v1.7.5 → v1.17.9, aws-sdk-go-v2 v1.x
  • otelgrpc, google.golang.org/grpc, google.golang.org/api/option promoted from indirect to direct
  • Minimum Go version: 1.24

joschi and others added 14 commits April 12, 2026 22:59
Emit traces and metrics via the OTel API (no SDK init in library code).
Global providers are used, so there is zero overhead when the host
application has not configured OTel, and automatic telemetry when it has.

Traces
- One parent span per public operation: migrate.up, migrate.down,
  migrate.migrate, migrate.steps, migrate.run, migrate.drop, migrate.force
- One child span per individual migration: migrate.run_migration
- Common attributes: db.system, migrate.source, migrate.direction,
  migrate.version, migrate.target_version, migrate.identifier
- ErrNoChange and ErrNilVersion do not produce error spans

Metrics
- migrate.migrations.applied  (Int64Counter,   {migration})
- migrate.migrations.failed   (Int64Counter,   {migration})
- migrate.migration.run.duration (Float64Histogram, s)

New files
- otel.go       tracer/meter factories, otelInstruments struct
- otel_test.go  9 tests using in-memory SDK exporters

Dependencies
- go.opentelemetry.io/otel v1.40.0 (direct)
- go.opentelemetry.io/otel/metric v1.40.0 (direct)
- go.opentelemetry.io/otel/trace v1.40.0 (direct)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add OTel wrapper types for database.Driver and source.Driver that emit
child spans for every driver operation, auto-wired into all 4 public
constructors so users get driver-level spans with zero code changes.

Database driver spans (SpanKind: CLIENT):
  db.lock, db.unlock, db.run, db.set_version, db.version, db.drop
  Attributes: db.system, migrate.version, migrate.dirty (SetVersion)

Source driver spans (SpanKind: INTERNAL):
  source.read_up, source.read_down
  Attributes: migrate.source, migrate.version
  os.ErrNotExist is treated as a non-error (expected sentinel)

Both wrappers expose Unwrap() Driver following the errors.Unwrap
convention, allowing test code and wrapping libraries to reach the
inner driver without losing type identity.

Also fixes a pre-existing context propagation bug in runMigrations:
the child context from otelTracer.Start was discarded (assigned to _),
causing all database driver spans to attach to the parent operation
span instead of the per-migration migrate.run_migration span.

Updates:
- database/oteldriver.go: new OTelDriver for database.Driver
- database/oteldriver_test.go: unit tests for db wrapper
- source/oteldriver.go: new OTelDriver for source.Driver
- source/oteldriver_test.go: unit tests for source wrapper
- migrate.go: fix childCtx propagation; wrap drivers in constructors
- migrate_test.go: add sourceStub/databaseStub helpers for Unwrap
- otel_test.go: add TestOtelTraceTopology end-to-end topology test
- README.md: document driver-level span tables and attributes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use github.com/XSAM/otelsql to add low-level SQL span instrumentation
to the clickhouse, cockroachdb, mysql, and sqlite drivers. Each driver's
Open() method now wraps the underlying sql.Driver via otelsql.Open(),
producing child spans for every SQL operation (Exec, Query, Begin,
Commit, Rollback) that automatically nest under the migrate-level
db.* spans from the OTelDriver wrapper.

The db.system attribute is set per driver:
  - clickhouse: "clickhouse"
  - cockroachdb: "cockroachdb"  (uses postgres wire protocol)
  - mysql:       "mysql"
  - sqlite:      "sqlite"

WithInstance callers who supply a pre-built *sql.DB retain their
existing behaviour unchanged; otelsql wrapping applies only when the
driver opens its own connection via Open().

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add github.com/XSAM/otelsql instrumentation to all database/sql-based
drivers so every SQL operation (queries, execs, transactions) emits a
child span under the migrate-level spans from the OTel wrappers.

Instrumented drivers (otelsql.Open / otelsql.OpenDB):
  - firebird     (db.system=firebird)
  - pgx/v4       (db.system=postgresql)
  - pgx/v5       (db.system=postgresql)
  - postgres     (db.system=postgresql)
  - ql           (db.system=ql)
  - redshift      (db.system=redshift)
  - snowflake    (db.system=snowflake)
  - sqlite3      (db.system=sqlite)
  - sqlserver    (db.system=mssql; both sql.Open and sql.OpenDB MSI paths)
  - yugabytedb   (db.system=yugabytedb)

Previously instrumented (committed separately):
  - clickhouse, cockroachdb, mysql, sqlite

Excluded drivers (not using database/sql):
  - cassandra (gocql), mongodb (mongo.Client), neo4j (neo4j.Driver),
    rqlite (gorqlite), spanner (cloud.google.com/go/spanner)

sqlcipher is intentionally excluded: go-sqlcipher/v4 does not implement
driver.ExecerContext, causing database/sql to fall back to Prepare+Exec
which only prepares the first statement in a multi-statement query.
This breaks NoTxWrap mode (BEGIN; ...; COMMIT; migrations). The driver
must be kept with plain sql.Open until upstream adds ExecerContext.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
go-sqlcipher/v4 implements the deprecated driver.Execer interface but
not driver.ExecerContext. Without ExecerContext, database/sql falls back
to Prepare+Exec which only compiles the first statement in a
multi-statement query (SQLite's sqlite3_prepare_v2 behaviour), breaking
NoTxWrap migrations such as "BEGIN; CREATE TABLE ...; COMMIT;".

Add execerContextDriver and execerContextConn adapter types that promote
driver.Execer → driver.ExecerContext at the driver level. The wrapped
driver is registered once under a private name and then passed to
otelsql.Open so SQL-level spans are emitted with db.system="sqlite".

All sqlcipher tests including TestNoTxWrap pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… tracing

Replace cluster.CreateSession() with otelgocql.NewSessionWithTracing()
so every gocql query, batch operation, and connection attempt emits an
OpenTelemetry span as a child of the surrounding migrate-level spans.

The otelgocql observer pattern instruments the cluster before the
session is created, meaning the *gocql.Session returned is a standard
unmodified session — all tracing is transparent.

Note: WithInstance() accepts a pre-existing *gocql.Session and cannot
retroactively add observers; callers that construct their own session
should set QueryObserver/BatchObserver/ConnectObserver on the cluster
before calling cluster.CreateSession() using otelgocql directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace raw attribute.String("db.system", ...) calls with typed constants
from go.opentelemetry.io/otel/semconv/v1.40.0. Semconv v1.40.0 renamed
the attribute key from db.system to db.system.name and updated several
values to match the canonical OTel semantic conventions spec.

Attribute key change (all drivers):
  db.system → db.system.name

Attribute value changes:
  firebird:   "firebird"  → semconv.DBSystemNameFirebirdSQL     ("firebirdsql")
  sqlserver:  "mssql"     → semconv.DBSystemNameMicrosoftSQLServer ("microsoft.sql_server")
  redshift:   "redshift"  → semconv.DBSystemNameAWSRedshift     ("aws.redshift")

Values unchanged but now constants:
  clickhouse → DBSystemNameClickHouse, cockroachdb → DBSystemNameCockroachDB,
  mysql → DBSystemNameMySQL, postgresql → DBSystemNamePostgreSQL,
  sqlite → DBSystemNameSQLite

No semconv constant defined for: ql, snowflake, yugabytedb — these use
DBSystemNameKey.String("...") to at least use the correct attribute key.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…migration

The test was checking for attribute key "db.system" but semconv v1.40.0
renamed it to "db.system.name" (DBSystemNameKey). Update the lookup and
the assertion message to match the new key.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Migrate the S3 source driver from github.com/aws/aws-sdk-go (v1) to
github.com/aws/aws-sdk-go-v2, then instrument all S3 API calls using
go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws.

Key changes:
- Replace github.com/aws/aws-sdk-go/service/s3/s3iface.S3API with a
  local s3APIClient interface (ListObjects + GetObject), which enables
  SDK v2 compatibility and keeps WithInstance testable with a fake
- session.NewSession() + s3.New(sess) → awsconfig.LoadDefaultConfig(ctx)
  + s3.NewFromConfig(cfg)
- otelaws.AppendMiddlewares(&cfg.APIOptions) instruments the aws.Config
  so every S3 operation emits an OTel span automatically
- ListObjectsWithContext / GetObjectWithContext → ListObjects / GetObject
- aws.StringValue → aws.ToString; s3.Object (v1) → types.Object (v2)
- Update s3_test.go fakeS3 to implement the new SDK v2 interface

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wrap every outgoing HTTP client with otelhttp.NewTransport so that all
API calls made by the source drivers produce child OTel spans.

bitbucket:  cl.HttpClient.Transport = otelhttp.NewTransport(http.DefaultTransport)
            go-bitbucket uses a plain http.Client; auth headers are
            injected per-request, not via a custom transport.

github:     no-auth path: replace nil (DefaultClient) with an
            otelhttp-wrapped client.
            oauth2 path: inject the otelhttp-wrapped base client via
            context.WithValue(ctx, oauth2.HTTPClient, base) so the
            chain is oauth2.Transport → otelhttp.Transport → DefaultTransport.

github_ee:  wrap the whole BasicAuthTransport:
            otelhttp.NewTransport(tr) so the chain is
            otelhttp.Transport → BasicAuthTransport → http.Transport(TLS).

gitlab:     pass &http.Client{Transport: otelhttp.NewTransport(...)}
            to gitlab.NewClient instead of nil.

httpfs is not instrumented here: it wraps an http.FileSystem interface
which is a file-system abstraction (e.g. http.Dir, embed.FS) and makes
no outgoing HTTP requests. Transport instrumentation belongs in the
http.FileSystem implementation provided by the caller.

Upgrade otelhttp v0.61.0 → v0.68.0 (aligns with otel v1.43.0).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo
and attach otelmongo.NewMonitor() as a CommandMonitor on the client
options in Open():

  options.Client().ApplyURI(dsn).SetMonitor(otelmongo.NewMonitor())

This causes every MongoDB command (find, insert, update, delete,
aggregate, runCommand, …) to emit an OTel span as a child of the
surrounding migrate operation span.

WithInstance() accepts a pre-built *mongo.Client and cannot
retroactively attach a monitor; callers that use WithInstance()
directly should set the monitor themselves when constructing the client.

Also upgrades go.mongodb.org/mongo-driver v1.7.5 → v1.17.9 (required
by the otelmongo contrib package).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc
stats handler instrumentation to both Google Cloud drivers.

database/spanner: pass option.WithGRPCDialOption(grpc.WithStatsHandler(
otelgrpc.NewClientHandler())) to sdb.NewDatabaseAdminClient and
spanner.NewClient so all DDL admin and data RPCs emit OTel spans.

source/google_cloud_storage: same option injected into storage.NewClient
so GCS object list and read operations appear as child spans.

Both drivers use the stats handler approach (grpc.WithStatsHandler) rather
than the deprecated interceptor API, consistent with otelgrpc guidance.

otelgrpc and google.golang.org/grpc promoted from indirect to direct deps.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three bugs found in code review:

1. otelAttrs() in migrate.go used the pre-semconv-v1.40.0 key "db.system"
   while every other file in this branch uses DBSystemNameKey ("db.system.name").
   Fix: import semconv and call semconv.DBSystemNameKey.String(...).

2. Migrate.otelMeter was stored in the struct after construction but never
   accessed again — the meter is only needed to create otelInstruments.
   Fix: remove the otelMeter field; use a local variable in newCommon().

3. migrationRunDuration histogram was recorded (with a ~0 duration) even
   when migr.Body == nil, polluting the histogram for schema-only migrations
   that have no SQL to execute.
   Fix: move the Record call inside the if migr.Body != nil block so the
   metric is only emitted when a database Run actually occurred.

Simplification: tracerName and meterName constants in otel.go had identical
values. Replace both with a single instrumentationName constant.

Update otel_test.go to reference instrumentationName and remove the now-
deleted otelMeter field access.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@joschi joschi marked this pull request as ready for review April 19, 2026 20:19
Copilot AI review requested due to automatic review settings April 19, 2026 20:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds end-to-end OpenTelemetry observability across migrate operations and driver interactions, leveraging the OTel API so telemetry is automatically emitted when host applications configure global providers.

Changes:

  • Introduces core OTel helpers and adds tracing/metrics around public migrate operations.
  • Adds transparent OTel wrappers for database.Driver and source.Driver, plus per-driver native instrumentation (otelsql/otelhttp/otelgrpc/otelaws/otelmongo/otelgocql).
  • Propagates context.Context across driver APIs and updates CLI, tests, and examples accordingly (including aws_s3 SDK v1 → v2).

Reviewed changes

Copilot reviewed 89 out of 90 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
README.md Documents new OpenTelemetry behavior and usage.
otel.go Adds shared tracer/meter setup and metric instruments.
internal/cli/main.go Passes context into migrate construction/close.
internal/cli/commands.go Passes context through CLI command execution.
source/driver.go Adds context.Context to the source driver interface and Open.
source/migration.go Threads context through Migrations helpers.
source/oteldriver.go Adds OTel spans for ReadUp/ReadDown.
source/oteldriver_test.go Tests source OTel wrapper span emission/attributes.
source/testing/testing.go Updates shared source-driver test helpers for context.
source/stub/stub.go Updates stub source driver for context-based interface.
source/stub/stub_test.go Updates stub source tests for context.
source/pkger/pkger.go Updates pkger source driver for context API.
source/pkger/pkger_test.go Updates pkger tests for context.
source/iofs/iofs.go Updates iofs driver for context API.
source/iofs/example_test.go Updates iofs example to pass context.
source/httpfs/driver.go Updates httpfs driver Open signature for context.
source/httpfs/driver_test.go Updates httpfs tests for context.
source/httpfs/partial_driver.go Updates httpfs partial driver for context API.
source/httpfs/partial_driver_test.go Updates httpfs partial driver tests for context.
source/google_cloud_storage/storage.go Adds ctx propagation and gRPC OTel instrumentation for GCS source.
source/google_cloud_storage/storage_test.go Updates GCS source test for context.
source/godoc_vfs/vfs.go Updates godoc_vfs source driver for context API.
source/godoc_vfs/vfs_test.go Updates godoc_vfs tests for context.
source/godoc_vfs/vfs_example_test.go Updates godoc_vfs example for context.
source/go_bindata/go-bindata.go Updates bindata source driver for context API.
source/go_bindata/go-bindata_test.go Updates bindata tests for context.
source/github/github.go Adds ctx propagation and otelhttp-instrumented HTTP client.
source/github/github_test.go Updates GitHub source tests for context.
source/github_ee/github_ee.go Adds ctx propagation and otelhttp instrumentation.
source/github_ee/github_ee_test.go Updates GitHub EE source tests for context.
source/gitlab/gitlab.go Adds ctx propagation and otelhttp instrumentation.
source/gitlab/gitlab_test.go Updates GitLab source tests for context.
source/bitbucket/bitbucket.go Adds ctx propagation and otelhttp instrumentation.
source/bitbucket/bitbucket_test.go Updates Bitbucket source tests for context.
source/aws_s3/s3.go Migrates aws_s3 source to AWS SDK v2 + otelaws + ctx propagation.
source/aws_s3/s3_test.go Updates aws_s3 tests for SDK v2 and context.
database/driver.go Adds context.Context to the database driver interface and Open.
database/driver_test.go Updates database driver tests for context.
database/oteldriver.go Adds OTel CLIENT spans for database driver operations.
database/oteldriver_test.go Tests database OTel wrapper span emission/attributes.
database/testing/testing.go Updates shared database-driver test helpers for context.
database/testing/migrate_testing.go Updates migrate-through-db-driver tests for context.
database/stub/stub.go Updates stub database driver for context API.
database/stub/stub_test.go Updates stub database tests for context.
database/cassandra/cassandra.go Adds ctx propagation and otelgocql instrumentation.
database/cassandra/cassandra_test.go Updates Cassandra DB tests for context.
database/clickhouse/clickhouse.go Adds ctx propagation and otelsql instrumentation.
database/clickhouse/clickhouse_test.go Updates ClickHouse DB tests for context.
database/cockroachdb/cockroachdb_test.go Updates CockroachDB DB tests for context.
database/firebird/firebird.go Adds ctx propagation and otelsql instrumentation.
database/firebird/firebird_test.go Updates Firebird DB tests for context.
database/mongodb/mongodb.go Adds ctx propagation and otelmongo instrumentation.
database/mongodb/mongodb_test.go Updates MongoDB DB tests for context.
database/mysql/mysql.go Adds ctx propagation and otelsql instrumentation.
database/mysql/mysql_test.go Updates MySQL DB tests for context.
database/neo4j/neo4j.go Adds ctx propagation (no per-driver OTel due to driver constraints).
database/neo4j/neo4j_test.go Updates Neo4j DB tests for context.
database/ql/ql.go Adds ctx propagation and otelsql instrumentation.
database/ql/ql_test.go Updates ql DB tests for context.
database/redshift/redshift.go Adds ctx propagation and otelsql instrumentation.
database/rqlite/rqlite.go Adds ctx propagation to rqlite DB driver APIs.
database/rqlite/rqlite_test.go Updates rqlite DB tests for context.
database/snowflake/snowflake.go Adds ctx propagation and otelsql instrumentation.
database/spanner/spanner.go Adds ctx propagation and otelgrpc instrumentation.
database/spanner/spanner_test.go Updates Spanner DB tests for context.
database/sqlcipher/sqlcipher_test.go Updates sqlcipher DB tests for context.
database/sqlite/sqlite.go Adds ctx propagation and otelsql instrumentation.
database/sqlite/sqlite_test.go Updates sqlite DB tests for context.
database/sqlite3/sqlite3.go Adds ctx propagation and otelsql instrumentation.
database/sqlite3/sqlite3_test.go Updates sqlite3 DB tests for context.
database/sqlserver/sqlserver_test.go Updates SQLServer DB tests for context.
database/yugabytedb/yugabytedb_test.go Updates YugabyteDB DB tests for context.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread database/mysql/mysql.go Outdated
Comment thread source/google_cloud_storage/storage.go
Comment thread README.md
Comment thread README.md Outdated
Comment thread database/spanner/spanner.go
joschi and others added 4 commits April 19, 2026 22:59
…tibilities

- github.com/aws/aws-sdk-go-v2/feature/s3/manager: v1.11.33 -> v1.22.15
- github.com/snowflakedb/gosnowflake: v1.6.19 -> v1.19.1

Both packages used AWS SDK v2 fields (ContentLength, BucketKeyEnabled,
PartNumber) that changed from value types to pointer types in newer SDK
versions, causing build failures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- database/mysql: use PingContext(ctx) instead of Ping() in WithInstance
  so cancellations and timeouts propagate consistently
- source/google_cloud_storage: store *storage.Client in struct, close it
  in Close() and on loadMigrations error to prevent resource leaks
- database/spanner: return error instead of log.Fatal when NewClient
  fails; close adminClient on error to avoid resource leak; remove
  unused log import
- README: fix attribute key db.system -> db.system.name (semconv v1.40)
- README: add context import and pass ctx to migrate.New in OTel example
  so the snippet compiles with the updated API

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The go directive was unintentionally bumped to 1.25.0 as a side-effect
of adding OTel dependencies. Root causes identified and resolved:

- github.com/XSAM/otelsql v0.42.0 → v0.41.0 (required go 1.25)
- go.opentelemetry.io/otel and related packages v1.43.0 → v1.40.0
  (v1.42.0+ requires go 1.25)
- go.opentelemetry.io/contrib/instrumentation/* v0.68.0 → v0.64.0
  (v0.65.0+ requires go 1.25)
- semconv import path updated from v1.40.0 → v1.39.0 (semconv/v1.40.0
  sub-package only exists in otel module v1.43.0+; v1.39.0 provides
  identical db.system.name attribute key)
- golang.org/x/{net,sync,sys,term,text} pinned to last Go 1.24
  compatible versions (v0.50.0, v0.19.0, v0.41.0, v0.40.0, v0.34.0)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 89 out of 90 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread source/oteldriver.go
Comment thread source/oteldriver_test.go
Comment thread database/oteldriver.go
Comment thread migrate.go
Comment thread source/pkger/pkger.go
Comment thread source/google_cloud_storage/storage.go
Comment thread otel.go
Comment thread README.md Outdated
Comment thread migrate.go
- otel_test.go: extract span name string literals into constants
  (spanNameUp, spanNameDown, spanNameRunMigration) to fix goconst
- database/mongodb/mongodb_test.go: replace deprecated DecodeBytes()
  with Raw() (SA1019/staticcheck)
- database/sqlcipher/sqlcipher.go: add nolint:staticcheck on intentional
  driver.Execer usages; the deprecated interface is required because
  go-sqlcipher/v4 does not implement ExecerContext
- database/oteldriver_test.go: remove unused *dStub.Stub second return
  value from newTestDriver and update all call sites (unparam)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 19, 2026

Coverage Status

coverage: 56.328% (+1.9%) from 54.432% — joschi:feat-opentelemetry-instrumentation into golang-migrate:master

- README.md: fix db.system → db.system.name in database span table
- otel.go: call otel.Handle(err) on instrument creation errors instead
  of silently discarding them (doc comment already promised this)
- migrate.go: use attribute.Int64 for uint version fields to avoid
  int overflow on 32-bit platforms
- migrate.go: sanitize database.Error in otelSpanSetError to avoid
  leaking migration SQL into trace span status descriptions
- database/oteldriver.go: same SQL-leak fix in endSpan; add errors import
- source/oteldriver.go: use attribute.Int64 for uint version fields
- source/oteldriver_test.go: assert span.Status().Code != codes.Error
  directly rather than comparing full sdktrace.Status struct
- source/pkger/pkger.go: fix import grouping (stdlib before third-party)
- source/google_cloud_storage/storage.go: merge context into stdlib group

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants