diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 13eb6ef..f7b4abf 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: + go-version: - "1.22" - "1.23" - "1.24" @@ -24,7 +24,7 @@ jobs: uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} - + - name: Install dependencies run: go mod tidy -diff diff --git a/operation_name_go124.go b/operation_name_go124.go new file mode 100644 index 0000000..98726ed --- /dev/null +++ b/operation_name_go124.go @@ -0,0 +1,22 @@ +//go:build go1.24 +// +build go1.24 + +package otelpgx + +import ( + "strings" +) + +// sqlOperationName attempts to get the first 'word' from a given SQL query, which usually +// is the operation name (e.g. 'SELECT'). +func (t *Tracer) sqlOperationName(stmt string) string { + if t.spanNameFunc != nil { + return t.spanNameFunc(stmt) + } + + for word := range strings.FieldsSeq(stmt) { + return strings.ToUpper(word) + } + + return sqlOperationUnknown +} diff --git a/operation_name_legacy.go b/operation_name_legacy.go new file mode 100644 index 0000000..45442e2 --- /dev/null +++ b/operation_name_legacy.go @@ -0,0 +1,33 @@ +//go:build !go1.24 +// +build !go1.24 + +package otelpgx + +import ( + "strings" + "unicode" +) + +// sqlOperationName attempts to get the first 'word' from a given SQL query, which usually +// is the operation name (e.g. 'SELECT'). +func (t *Tracer) sqlOperationName(stmt string) string { + // If a custom function is provided, use that. Otherwise, fall back to the + // default implementation. This allows users to override the default + // behavior without having to reimplement it. + if t.spanNameFunc != nil { + return t.spanNameFunc(stmt) + } + + stmt = strings.TrimSpace(stmt) + end := strings.IndexFunc(stmt, unicode.IsSpace) + if end < 0 && len(stmt) > 0 { + // No space found, use the whole statement. + end = len(stmt) + } else if end < 0 { + // Fall back to a fixed value to prevent creating lots of tracing operations + // differing only by the amount of whitespace in them (in case we'd fall back + // to the full query or a cut-off version). + return sqlOperationUnknown + } + return strings.ToUpper(stmt[:end]) +} diff --git a/tracer.go b/tracer.go index 670d0f0..d70b91d 100644 --- a/tracer.go +++ b/tracer.go @@ -6,9 +6,7 @@ import ( "errors" "fmt" "runtime/debug" - "strings" "time" - "unicode" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgconn" @@ -186,31 +184,6 @@ func (t *Tracer) recordOperationDuration(ctx context.Context, pgxOperation strin } } -// sqlOperationName attempts to get the first 'word' from a given SQL query, which usually -// is the operation name (e.g. 'SELECT'). -func (t *Tracer) sqlOperationName(stmt string) string { - // If a custom function is provided, use that. Otherwise, fall back to the - // default implementation. This allows users to override the default - // behavior without having to reimplement it. - if t.spanNameFunc != nil { - return t.spanNameFunc(stmt) - } - - // NOTE: Can convert to FieldsSeq in go 1.24+ which avoids allocations. - stmt = strings.TrimSpace(stmt) - end := strings.IndexFunc(stmt, unicode.IsSpace) - if end < 0 && len(stmt) > 0 { - // No space found, use the whole statement. - end = len(stmt) - } else if end < 0 { - // Fall back to a fixed value to prevent creating lots of tracing operations - // differing only by the amount of whitespace in them (in case we'd fall back - // to the full query or a cut-off version). - return sqlOperationUnknown - } - return strings.ToUpper(stmt[:end]) -} - // connectionAttributesFromConfig returns a SpanStartOption that contains // attributes from the given connection config. func connectionAttributesFromConfig(config *pgx.ConnConfig) trace.SpanStartOption {