opentelemetry-instrumentation-trilogy 0.65.1 → 0.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28156d3d671c7047006f609431a9733c8d5b9a5100f9786e933e8107ec16d335
4
- data.tar.gz: fe6a2fbfb58876ca5c5f833fb1cb794a0a727f969ec4e773458b0c0f5bb0b9ca
3
+ metadata.gz: 61673a70660a205354946b86bedb7ee5a3aa2cfd7af0aebab52b3c10e80b8c63
4
+ data.tar.gz: 6db4aa4e8c9cf0b62093d39b8e71a27f66735702271ac33426a755fce2240bd9
5
5
  SHA512:
6
- metadata.gz: e77db5dfec5ea2d319c47e420f7a54d0e1592421af6536d1e01b12b8b9c50c4d385f3f1a4ddd4f75a9138385b07cc2b0d70aa94a7b68afa5d3fd10a586054525
7
- data.tar.gz: b820cbb445b9f798e4779dda675cc773bec5aa5c9113e686b8bef896e0fca793274e9f52854de9e86c572ac32ad9021e0bcca2586ac4bd290476b31b082963c1
6
+ metadata.gz: 216d40455f51acf894bb5aecf79abc6050d972598509b19e0356ce1c01bef1c57da6f12045d2be745ffc9411ef449817a594bd312aa01ee357b35f0836c7a84e
7
+ data.tar.gz: d5b67b6383b4a21e9932ef6123d617a92d8f13763c6df1163ae749106503e4667a17329ff7213e8baa7eee3909e7bb5679392045a407978fdc3472376e0463cd
data/CHANGELOG.md CHANGED
@@ -1,136 +1,152 @@
1
1
  # Release History: opentelemetry-instrumentation-trilogy
2
2
 
3
- ### v0.65.1 / 2025-12-03
3
+ ## v0.69.0 / 2026-05-21
4
4
 
5
- * FIXED: Update gemspec dependencies to sql-processor
5
+ - ADDED: Add `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable support for span attributes (#2095)
6
6
 
7
- ### v0.65.0 / 2025-12-02
7
+ ## v0.68.0 / 2026-04-14
8
8
 
9
- * ADDED: Replace references sql-obfuscation -> sql-processor
9
+ - BREAKING CHANGE: Min Ruby Version 3.3 (#2125)
10
+ - ADDED: Min Ruby Version 3.3 (#2125)
11
+ - ADDED: Add release tag into source code url of gem metadata (#1984)
10
12
 
11
- ### v0.64.0 / 2025-10-22
13
+ ## v0.67.0 / 2026-03-17
12
14
 
13
- * BREAKING CHANGE: Min Ruby Version 3.2
15
+ - ADDED: Cache static span attributes in Trilogy instrumentation (#2089)
14
16
 
15
- * ADDED: Min Ruby Version 3.2
17
+ ## v0.66.0 / 2026-01-13
16
18
 
17
- ### v0.63.1 / 2025-09-30
19
+ - ADDED: Add SQL Comment Propagator
18
20
 
19
- * FIXED: Min OTel Ruby API 1.7
21
+ ## v0.65.1 / 2025-12-03
20
22
 
21
- ### v0.63.0 / 2025-09-30
23
+ - FIXED: Update gemspec dependencies to sql-processor
22
24
 
23
- * ADDED: Bump minimum API Version to 1.7
25
+ ## v0.65.0 / 2025-12-02
24
26
 
25
- ### v0.62.0 / 2025-09-25
27
+ - ADDED: Replace references sql-obfuscation -> sql-processor
26
28
 
27
- * ADDED: Trilogy: introduce record_exception setting
29
+ ## v0.64.0 / 2025-10-22
28
30
 
29
- ### v0.61.1 / 2025-04-16
31
+ - BREAKING CHANGE: Min Ruby Version 3.2
32
+ - ADDED: Min Ruby Version 3.2
30
33
 
31
- * refactor: Use SQL helpers for context attributes #1271
34
+ ## v0.63.1 / 2025-09-30
32
35
 
33
- ### v0.61.0 / 2025-01-16
36
+ - FIXED: Min OTel Ruby API 1.7
34
37
 
35
- * BREAKING CHANGE: Set minimum supported version to Ruby 3.1
38
+ ## v0.63.0 / 2025-09-30
36
39
 
37
- * ADDED: Set minimum supported version to Ruby 3.1
40
+ - ADDED: Bump minimum API Version to 1.7
38
41
 
39
- ### v0.60.0 / 2024-09-12
42
+ ## v0.62.0 / 2025-09-25
43
+
44
+ - ADDED: Trilogy: introduce record_exception setting
45
+
46
+ ## v0.61.1 / 2025-04-16
47
+
48
+ - refactor: Use SQL helpers for context attributes #1271
49
+
50
+ ## v0.61.0 / 2025-01-16
51
+
52
+ - BREAKING CHANGE: Set minimum supported version to Ruby 3.1
53
+ - ADDED: Set minimum supported version to Ruby 3.1
54
+
55
+ ## v0.60.0 / 2024-09-12
40
56
 
41
57
  - BREAKING CHANGE: Return message when sql is over the obfuscation limit. Fixes a bug where sql statements with prepended comments that hit the obfuscation limit would be sent raw.
42
58
 
43
- ### v0.59.3 / 2024-04-30
59
+ ## v0.59.3 / 2024-04-30
44
60
 
45
61
  - FIXED: Bundler conflict warnings
46
62
 
47
- ### v0.59.2 / 2024-02-20
63
+ ## v0.59.2 / 2024-02-20
48
64
 
49
65
  - FIXED: Dup string if frozen in trilogy query
50
66
 
51
- ### v0.59.1 / 2024-02-08
67
+ ## v0.59.1 / 2024-02-08
52
68
 
53
69
  - FIXED: Add missing requires for sql-helpers to mysql, pg, and trilogy instrumentation
54
70
 
55
- ### v0.59.0 / 2024-02-08
71
+ ## v0.59.0 / 2024-02-08
56
72
 
57
73
  - BREAKING CHANGE: Move shared sql behavior to helper gems
58
74
 
59
75
  - ADDED: Propagate context to Vitess
60
76
 
61
- ### v0.58.0 / 2024-01-06
77
+ ## v0.58.0 / 2024-01-06
62
78
 
63
79
  - BREAKING CHANGE: Change db.mysql.instance.address to db.instance.id
64
80
 
65
81
  - ADDED: Change db.mysql.instance.address to db.instance.id
66
82
  - FIXED: Trilogy only set db.instance.id attribute if there is a value
67
83
 
68
- ### v0.57.0 / 2023-10-27
84
+ ## v0.57.0 / 2023-10-27
69
85
 
70
86
  - ADDED: Instrument connect and ping
71
87
 
72
- ### v0.56.3 / 2023-08-03
88
+ ## v0.56.3 / 2023-08-03
73
89
 
74
90
  - FIXED: Remove inline linter rules
75
91
 
76
- ### v0.56.2 / 2023-07-14
92
+ ## v0.56.2 / 2023-07-14
77
93
 
78
94
  - ADDED: `db.user` attribute (recommended connection-level attribute)
79
95
 
80
- ### v0.56.1 / 2023-06-05
96
+ ## v0.56.1 / 2023-06-05
81
97
 
82
98
  - FIXED: Base config options
83
99
 
84
- ### v0.56.0 / 2023-06-02
100
+ ## v0.56.0 / 2023-06-02
85
101
 
86
102
  - BREAKING CHANGE: Separate logical MySQL host from connected host
87
103
 
88
104
  - ADDED: Separate logical MySQL host from connected host
89
105
 
90
- ### v0.55.1 / 2023-06-01
106
+ ## v0.55.1 / 2023-06-01
91
107
 
92
108
  - FIXED: Regex non-match with obfuscation limit (issue #486)
93
109
 
94
- ### v0.55.0 / 2023-05-31
110
+ ## v0.55.0 / 2023-05-31
95
111
 
96
112
  - BREAKING CHANGE: Add database name for trilogy traces
97
113
 
98
114
  - ADDED: Add database name for trilogy traces
99
115
 
100
- ### v0.54.0 / 2023-05-25
116
+ ## v0.54.0 / 2023-05-25
101
117
 
102
118
  - ADDED: Add Obfuscation Limit Option to Trilogy
103
119
 
104
- ### v0.53.0 / 2023-04-17
120
+ ## v0.53.0 / 2023-04-17
105
121
 
106
122
  - BREAKING CHANGE: Drop support for EoL Ruby 2.7
107
123
 
108
124
  - ADDED: Drop support for EoL Ruby 2.7
109
125
 
110
- ### v0.52.0 / 2023-03-06
126
+ ## v0.52.0 / 2023-03-06
111
127
 
112
128
  - ADDED: Add with_attributes context propagation to Trilogy instrumentation
113
129
  - ADDED: Add option to configure span name for trilogy
114
130
  - FIXED: Ensure encoding errors handled during SQL obfuscation for Trilogy
115
131
 
116
- ### v0.51.1 / 2023-01-14
132
+ ## v0.51.1 / 2023-01-14
117
133
 
118
134
  - DOCS: Fix gem homepage
119
135
  - DOCS: More gem documentation fixes
120
136
 
121
- ### v0.51.0 / 2022-06-09
137
+ ## v0.51.0 / 2022-06-09
122
138
 
123
139
  - Upgrading Base dependency version
124
140
  - FIXED: Broken test file requirements
125
141
 
126
- ### v0.50.2 / 2022-05-05
142
+ ## v0.50.2 / 2022-05-05
127
143
 
128
144
  - (No significant changes)
129
145
 
130
- ### v0.50.1 / 2022-01-07
146
+ ## v0.50.1 / 2022-01-07
131
147
 
132
148
  - FIXED: Trilogy Driver Options
133
149
 
134
- ### v0.50.0 / 2021-12-31
150
+ ## v0.50.0 / 2021-12-31
135
151
 
136
152
  - Initial release.
data/README.md CHANGED
@@ -51,18 +51,53 @@ OpenTelemetry::Instrumentation::Trilogy.with_attributes('pizzatoppings' => 'mush
51
51
  end
52
52
  ```
53
53
 
54
+ ## Compatibility
55
+
56
+ This gem requires Trilogy 2.11 or higher and will not work with a future Trilogy 3.x release.
57
+
58
+ ## Configuration Options
59
+
60
+ | Option | Default | Description |
61
+ | ------ | ------- | ----------- |
62
+ | `db_statement` | `:obfuscate` | Controls how SQL queries appear in spans. `:obfuscate` replaces literal values with `?`, `:include` records the raw SQL, `:omit` excludes the attribute entirely. |
63
+ | `obfuscation_limit` | `2000` | Maximum length of the obfuscated SQL statement. Statements exceeding this limit are truncated. |
64
+ | `peer_service` | `nil` | Deprecated with no replacement. Sets the `peer.service` attribute on spans (old semantic conventions only). |
65
+ | `propagator` | `'none'` | Propagator for injecting trace context into SQL comments. `'none'` disables propagation, `'tracecontext'` uses W3C Trace Context, `'vitess'` uses Vitess-style propagation (requires `opentelemetry-propagator-vitess` gem). |
66
+ | `record_exception` | `true` | Records exceptions as span events when an error occurs. |
67
+ | `span_name` | `:statement_type` | Controls span naming (old semantic conventions only). `:statement_type` uses the SQL operation (e.g., `SELECT`), `:db_name` uses the database name, `:db_operation_and_name` combines both. |
68
+
54
69
  ## Semantic Conventions
55
70
 
56
- This instrumentation generally uses [Database semantic conventions](https://opentelemetry.io/docs/specs/semconv/database/database-spans/).
71
+ This instrumentation generally uses [Database semantic conventions](https://opentelemetry.io/docs/specs/semconv/database/database-spans/). See the [Database semantic convention stability](#database-semantic-convention-stability) section for how to switch between stable and old conventions.
72
+
73
+ | Stable Attribute Name | Old Attribute Name | Type | Notes |
74
+ | - | - | - | - |
75
+ | `db.namespace` | `db.name` | String | Database name from connection_options |
76
+ | `db.query.text` | `db.statement` | String | The database query being executed; set according to the `db_statement` config option |
77
+ | `db.response.status_code` | — | String | The Trilogy error code, if available |
78
+ | `db.system.name` | `db.system` | String | DBMS product identifier; always `mysql` |
79
+ | `error.type` | — | String | The exception class name when the operation fails |
80
+ | `server.address` | `net.peer.name` | String | Database host from connection_options |
81
+ | `server.port` | — | Integer | Database port from connection_options |
82
+ | — | `db.instance.id` | String | Connected host, e.g. result of `SELECT @@hostname` |
83
+ | — | `db.user` | String | Database username from connection_options |
84
+ | — | `peer.service` | String | Configured via the `peer_service` config option |
85
+
86
+ ## Database semantic convention stability
87
+
88
+ In the OpenTelemetry ecosystem, database semantic conventions have now reached a stable state. However, the initial Trilogy instrumentation was introduced before this stability was achieved, which resulted in database attributes being based on an older version of the semantic conventions.
89
+
90
+ To facilitate the migration to stable semantic conventions, you can use the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This variable allows you to opt-in to the new stable conventions, ensuring compatibility and future-proofing your instrumentation.
91
+
92
+ When setting the value for `OTEL_SEMCONV_STABILITY_OPT_IN`, you can specify which conventions you wish to adopt:
93
+
94
+ - `database` - Emits the stable database and networking conventions and ceases emitting the old conventions previously emitted by the instrumentation.
95
+ - `database/dup` - Emits both the old and stable database and networking conventions, enabling a phased rollout of the stable semantic conventions.
96
+ - Default behavior (in the absence of either value) is to continue emitting the old database and networking conventions the instrumentation previously emitted.
97
+
98
+ During the transition from old to stable conventions, Trilogy instrumentation code comes in three patch versions: `dup`, `old`, and `stable`. These versions are identical except for the attributes they send. Any changes to Trilogy instrumentation should consider all three patches.
57
99
 
58
- | Attribute Name | Type | Notes |
59
- | - | - | - |
60
- | `db.instance.id` | String | The name of the DB host executing the query e.g. `SELECT @@hostname` |
61
- | `db.name` | String | The name of the database from connection_options |
62
- | `db.statement` | String | SQL statement being executed |
63
- | `db.user` | String | The username from connection_options |
64
- | `db.system` | String | `mysql` |
65
- | `net.peer.name` | String | The name of the remote host from connection_options |
100
+ For additional information on migration, please refer to our [documentation](https://opentelemetry.io/docs/specs/semconv/non-normative/db-migration/).
66
101
 
67
102
  ## How can I get involved?
68
103
 
@@ -7,7 +7,70 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module Trilogy
10
- # The Instrumentation class contains logic to detect and install the Trilogy instrumentation
10
+ # The {OpenTelemetry::Instrumentation::Trilogy::Instrumentation} class contains logic to detect and install the Trilogy instrumentation
11
+ #
12
+ # Installation and configuration of this instrumentation is done within the
13
+ # {https://www.rubydoc.info/gems/opentelemetry-sdk/OpenTelemetry/SDK#configure-instance_method OpenTelemetry::SDK#configure}
14
+ # block, calling {https://www.rubydoc.info/gems/opentelemetry-sdk/OpenTelemetry%2FSDK%2FConfigurator:use use()}
15
+ # or {https://www.rubydoc.info/gems/opentelemetry-sdk/OpenTelemetry%2FSDK%2FConfigurator:use_all use_all()}.
16
+ #
17
+ # ## Configuration keys and options
18
+ #
19
+ # ### `:db_statement`
20
+ #
21
+ # Controls how SQL queries appear in spans.
22
+ #
23
+ # - `:obfuscate` **(default)** - Replaces literal values with `?` to prevent
24
+ # sensitive data from being recorded.
25
+ # - `:include` - Records the raw SQL query as-is.
26
+ # - `:omit` - Excludes the SQL query attribute entirely.
27
+ #
28
+ # ### `:obfuscation_limit`
29
+ #
30
+ # Maximum length of the obfuscated SQL statement. Statements exceeding this limit
31
+ # are truncated. Default is `2000`.
32
+ #
33
+ # ### `:peer_service`
34
+ #
35
+ # Sets the `peer.service` attribute on spans. Default is `nil`.
36
+ # Only applies when using old semantic conventions. Deprecated with no replacement.
37
+ #
38
+ # ### `:propagator`
39
+ #
40
+ # Propagator for injecting trace context into SQL comments.
41
+ #
42
+ # - `'none'` **(default)** - Disables trace context propagation.
43
+ # - `'tracecontext'` - Uses W3C Trace Context format via SQL comments.
44
+ # - `'vitess'` - Uses Vitess-style propagation. Requires the
45
+ # `opentelemetry-propagator-vitess` gem.
46
+ #
47
+ # ### `:record_exception`
48
+ #
49
+ # Records exceptions as span events when an error occurs. Default is `true`.
50
+ #
51
+ # ### `:span_name`
52
+ #
53
+ # Controls how span names are generated. Only applies when using old semantic
54
+ # conventions; ignored for stable semantic conventions.
55
+ #
56
+ # - `:statement_type` **(default)** - Uses the SQL operation (e.g., `SELECT`).
57
+ # - `:db_name` - Uses the database name.
58
+ # - `:db_operation_and_name` - Combines the operation and database name.
59
+ #
60
+ # @example An explicit default configuration
61
+ # OpenTelemetry::SDK.configure do |c|
62
+ # c.use_all({
63
+ # 'OpenTelemetry::Instrumentation::Trilogy' => {
64
+ # db_statement: :obfuscate,
65
+ # obfuscation_limit: 2000,
66
+ # peer_service: nil,
67
+ # propagator: 'none',
68
+ # record_exception: true,
69
+ # span_name: :statement_type,
70
+ # },
71
+ # })
72
+ # end
73
+ #
11
74
  class Instrumentation < OpenTelemetry::Instrumentation::Base
12
75
  install do |config|
13
76
  require_dependencies
@@ -20,31 +83,63 @@ module OpenTelemetry
20
83
  end
21
84
 
22
85
  compatible do
23
- Gem::Requirement.create('>= 2.3', '< 3.0').satisfied_by?(Gem::Version.new(::Trilogy::VERSION))
86
+ Gem::Requirement.create('>= 2.11', '< 3.0').satisfied_by?(Gem::Version.new(::Trilogy::VERSION))
24
87
  end
25
88
 
26
89
  option :peer_service, default: nil, validate: :string
27
90
  option :db_statement, default: :obfuscate, validate: %I[omit include obfuscate]
28
91
  option :span_name, default: :statement_type, validate: %I[statement_type db_name db_operation_and_name]
29
92
  option :obfuscation_limit, default: 2000, validate: :integer
30
- option :propagator, default: nil, validate: :string
93
+ option :propagator, default: 'none', validate: %w[none tracecontext vitess]
31
94
  option :record_exception, default: true, validate: :boolean
32
95
 
33
- attr_reader :propagator
96
+ attr_reader :propagator, :semconv
34
97
 
35
98
  private
36
99
 
37
100
  def require_dependencies
38
- require_relative 'patches/client'
101
+ @semconv = determine_semconv
102
+
103
+ case @semconv
104
+ when :old
105
+ require_relative 'patches/old/client'
106
+ when :stable
107
+ require_relative 'patches/stable/client'
108
+ when :dup
109
+ require_relative 'patches/dup/client'
110
+ end
39
111
  end
40
112
 
41
113
  def patch_client
42
- ::Trilogy.prepend(Patches::Client)
114
+ case @semconv
115
+ when :old
116
+ ::Trilogy.prepend(Patches::Old::Client)
117
+ when :stable
118
+ ::Trilogy.prepend(Patches::Stable::Client)
119
+ when :dup
120
+ ::Trilogy.prepend(Patches::Dup::Client)
121
+ end
122
+ end
123
+
124
+ def determine_semconv
125
+ opt_in = ENV.fetch('OTEL_SEMCONV_STABILITY_OPT_IN', nil)
126
+ return :old if opt_in.nil?
127
+
128
+ opt_in_values = opt_in.split(',').map(&:strip)
129
+
130
+ if opt_in_values.include?('database/dup')
131
+ :dup
132
+ elsif opt_in_values.include?('database')
133
+ :stable
134
+ else
135
+ :old
136
+ end
43
137
  end
44
138
 
45
139
  def configure_propagator(config)
46
140
  propagator = config[:propagator]
47
141
  @propagator = case propagator
142
+ when 'tracecontext' then OpenTelemetry::Helpers::SqlProcessor::SqlCommenter.sql_query_propagator
48
143
  when 'vitess' then fetch_propagator(propagator, 'OpenTelemetry::Propagator::Vitess')
49
144
  when 'none', nil then nil
50
145
  else
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ require 'opentelemetry-helpers-mysql'
8
+ require 'opentelemetry-helpers-sql-processor'
9
+
10
+ module OpenTelemetry
11
+ module Instrumentation
12
+ module Trilogy
13
+ module Patches
14
+ module Dup
15
+ # Module to prepend to Trilogy for instrumentation (emits both old and stable semantic conventions)
16
+ module Client
17
+ def initialize(options = {})
18
+ @connection_options = options # This is normally done by Trilogy#initialize
19
+ @_otel_database_name = connection_options&.dig(:database)
20
+ @_otel_base_attributes = _build_otel_base_attributes.freeze
21
+
22
+ tracer.in_span(
23
+ 'connect',
24
+ attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
25
+ kind: :client,
26
+ record_exception: config[:record_exception]
27
+ ) do |span|
28
+ super
29
+ rescue StandardError => e
30
+ set_error_attributes(span, e)
31
+ raise
32
+ end
33
+ end
34
+
35
+ def ping(...)
36
+ tracer.in_span(
37
+ 'ping',
38
+ attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
39
+ kind: :client,
40
+ record_exception: config[:record_exception]
41
+ ) do |span|
42
+ super
43
+ rescue StandardError => e
44
+ set_error_attributes(span, e)
45
+ raise
46
+ end
47
+ end
48
+
49
+ def query(sql)
50
+ context_attributes = OpenTelemetry::Instrumentation::Trilogy.attributes
51
+
52
+ tracer.in_span(
53
+ OpenTelemetry::Helpers::MySQL.database_span_name(
54
+ sql,
55
+ context_attributes[OpenTelemetry::SemanticConventions::Trace::DB_OPERATION],
56
+ @_otel_database_name,
57
+ config
58
+ ),
59
+ attributes: client_attributes(sql).merge!(context_attributes),
60
+ kind: :client,
61
+ record_exception: config[:record_exception]
62
+ ) do |span, context|
63
+ if propagator && sql.frozen?
64
+ sql = +sql
65
+ propagator.inject(sql, context: context)
66
+ sql.freeze
67
+ elsif propagator
68
+ propagator.inject(sql, context: context)
69
+ end
70
+
71
+ super
72
+ rescue StandardError => e
73
+ set_error_attributes(span, e)
74
+ raise
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def _build_otel_base_attributes
81
+ database_user = connection_options&.dig(:username)
82
+ mysql_host = connection_options&.fetch(:host, nil) || 'unknown sock'
83
+ mysql_port = connection_options&.dig(:port)
84
+
85
+ # Include both old and stable attributes
86
+ attributes = {
87
+ # Old conventions
88
+ ::OpenTelemetry::SemanticConventions::Trace::DB_SYSTEM => 'mysql',
89
+ ::OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => mysql_host,
90
+ # Stable conventions
91
+ 'db.system.name' => 'mysql',
92
+ 'server.address' => mysql_host
93
+ }
94
+
95
+ attributes['server.port'] = mysql_port if mysql_port
96
+
97
+ # Database name (old: db.name, stable: db.namespace)
98
+ if @_otel_database_name
99
+ attributes[::OpenTelemetry::SemanticConventions::Trace::DB_NAME] = @_otel_database_name
100
+ attributes['db.namespace'] = @_otel_database_name
101
+ end
102
+
103
+ # db.user (old only - removed in stable)
104
+ attributes[::OpenTelemetry::SemanticConventions::Trace::DB_USER] = database_user if database_user
105
+
106
+ # peer.service (old only - not stable and not a db attribute)
107
+ attributes[::OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] unless config[:peer_service].nil?
108
+ attributes
109
+ end
110
+
111
+ def client_attributes(sql = nil)
112
+ attributes = @_otel_base_attributes.dup
113
+
114
+ # Old convention
115
+ attributes['db.instance.id'] = @connected_host unless @connected_host.nil?
116
+
117
+ if sql
118
+ case config[:db_statement]
119
+ when :obfuscate
120
+ obfuscated = OpenTelemetry::Helpers::SqlProcessor.obfuscate_sql(sql, obfuscation_limit: config[:obfuscation_limit], adapter: :mysql)
121
+ # Old convention
122
+ attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] = obfuscated
123
+ # Stable convention
124
+ attributes['db.query.text'] = obfuscated
125
+ when :include
126
+ # Old convention
127
+ attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] = sql
128
+ # Stable convention
129
+ attributes['db.query.text'] = sql
130
+ end
131
+ end
132
+
133
+ attributes
134
+ end
135
+
136
+ def set_error_attributes(span, error)
137
+ span.set_attribute('error.type', error.class.name)
138
+ span.set_attribute('db.response.status_code', error.error_code.to_s) if error.respond_to?(:error_code) && error.error_code
139
+ end
140
+
141
+ def tracer
142
+ Trilogy::Instrumentation.instance.tracer
143
+ end
144
+
145
+ def config
146
+ Trilogy::Instrumentation.instance.config
147
+ end
148
+
149
+ def propagator
150
+ Trilogy::Instrumentation.instance.propagator
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ require 'opentelemetry-helpers-mysql'
8
+ require 'opentelemetry-helpers-sql-processor'
9
+
10
+ module OpenTelemetry
11
+ module Instrumentation
12
+ module Trilogy
13
+ module Patches
14
+ module Old
15
+ # Module to prepend to Trilogy for instrumentation (old semantic conventions)
16
+ module Client
17
+ def initialize(options = {})
18
+ @connection_options = options # This is normally done by Trilogy#initialize
19
+ @_otel_database_name = connection_options&.dig(:database)
20
+ @_otel_base_attributes = _build_otel_base_attributes.freeze
21
+
22
+ tracer.in_span(
23
+ 'connect',
24
+ attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
25
+ kind: :client,
26
+ record_exception: config[:record_exception]
27
+ ) do
28
+ super
29
+ end
30
+ end
31
+
32
+ def ping(...)
33
+ tracer.in_span(
34
+ 'ping',
35
+ attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
36
+ kind: :client,
37
+ record_exception: config[:record_exception]
38
+ ) do
39
+ super
40
+ end
41
+ end
42
+
43
+ def query(sql)
44
+ context_attributes = OpenTelemetry::Instrumentation::Trilogy.attributes
45
+
46
+ tracer.in_span(
47
+ OpenTelemetry::Helpers::MySQL.database_span_name(
48
+ sql,
49
+ context_attributes[OpenTelemetry::SemanticConventions::Trace::DB_OPERATION],
50
+ @_otel_database_name,
51
+ config
52
+ ),
53
+ attributes: client_attributes(sql).merge!(context_attributes),
54
+ kind: :client,
55
+ record_exception: config[:record_exception]
56
+ ) do |_span, context|
57
+ if propagator && sql.frozen?
58
+ sql = +sql
59
+ propagator.inject(sql, context: context)
60
+ sql.freeze
61
+ elsif propagator
62
+ propagator.inject(sql, context: context)
63
+ end
64
+
65
+ super
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def _build_otel_base_attributes
72
+ database_user = connection_options&.dig(:username)
73
+
74
+ attributes = {
75
+ ::OpenTelemetry::SemanticConventions::Trace::DB_SYSTEM => 'mysql',
76
+ ::OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => connection_options&.fetch(:host, 'unknown sock') || 'unknown sock'
77
+ }
78
+
79
+ attributes[::OpenTelemetry::SemanticConventions::Trace::DB_NAME] = @_otel_database_name if @_otel_database_name
80
+ attributes[::OpenTelemetry::SemanticConventions::Trace::DB_USER] = database_user if database_user
81
+ attributes[::OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] unless config[:peer_service].nil?
82
+ attributes
83
+ end
84
+
85
+ def client_attributes(sql = nil)
86
+ attributes = @_otel_base_attributes.dup
87
+
88
+ attributes['db.instance.id'] = @connected_host unless @connected_host.nil?
89
+
90
+ if sql
91
+ case config[:db_statement]
92
+ when :obfuscate
93
+ attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] =
94
+ OpenTelemetry::Helpers::SqlProcessor.obfuscate_sql(sql, obfuscation_limit: config[:obfuscation_limit], adapter: :mysql)
95
+ when :include
96
+ attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] = sql
97
+ end
98
+ end
99
+
100
+ attributes
101
+ end
102
+
103
+ def tracer
104
+ Trilogy::Instrumentation.instance.tracer
105
+ end
106
+
107
+ def config
108
+ Trilogy::Instrumentation.instance.config
109
+ end
110
+
111
+ def propagator
112
+ Trilogy::Instrumentation.instance.propagator
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ require 'opentelemetry-helpers-mysql'
8
+ require 'opentelemetry-helpers-sql-processor'
9
+
10
+ module OpenTelemetry
11
+ module Instrumentation
12
+ module Trilogy
13
+ module Patches
14
+ module Stable
15
+ # Module to prepend to Trilogy for instrumentation (stable semantic conventions)
16
+ module Client
17
+ def initialize(options = {})
18
+ @connection_options = options # This is normally done by Trilogy#initialize
19
+ @_otel_database_name = connection_options&.dig(:database)
20
+ @_otel_base_attributes = _build_otel_base_attributes.freeze
21
+
22
+ tracer.in_span(
23
+ 'connect',
24
+ attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
25
+ kind: :client,
26
+ record_exception: config[:record_exception]
27
+ ) do |span|
28
+ super
29
+ rescue StandardError => e
30
+ set_error_attributes(span, e)
31
+ raise
32
+ end
33
+ end
34
+
35
+ def ping(...)
36
+ tracer.in_span(
37
+ 'ping',
38
+ attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
39
+ kind: :client,
40
+ record_exception: config[:record_exception]
41
+ ) do |span|
42
+ super
43
+ rescue StandardError => e
44
+ set_error_attributes(span, e)
45
+ raise
46
+ end
47
+ end
48
+
49
+ def query(sql)
50
+ context_attributes = OpenTelemetry::Instrumentation::Trilogy.attributes
51
+
52
+ tracer.in_span(
53
+ OpenTelemetry::Helpers::MySQL.database_span_name(
54
+ sql,
55
+ context_attributes[OpenTelemetry::SemanticConventions::Trace::DB_OPERATION],
56
+ @_otel_database_name,
57
+ config
58
+ ),
59
+ attributes: client_attributes(sql).merge!(context_attributes),
60
+ kind: :client,
61
+ record_exception: config[:record_exception]
62
+ ) do |span, context|
63
+ if propagator && sql.frozen?
64
+ sql = +sql
65
+ propagator.inject(sql, context: context)
66
+ sql.freeze
67
+ elsif propagator
68
+ propagator.inject(sql, context: context)
69
+ end
70
+
71
+ super
72
+ rescue StandardError => e
73
+ set_error_attributes(span, e)
74
+ raise
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def _build_otel_base_attributes
81
+ mysql_host = connection_options&.fetch(:host, nil) || 'unknown sock'
82
+ mysql_port = connection_options&.dig(:port)
83
+
84
+ attributes = {
85
+ 'db.system.name' => 'mysql',
86
+ 'server.address' => mysql_host
87
+ }
88
+
89
+ attributes['server.port'] = mysql_port if mysql_port
90
+
91
+ attributes['db.namespace'] = @_otel_database_name if @_otel_database_name
92
+ attributes
93
+ end
94
+
95
+ def client_attributes(sql = nil)
96
+ attributes = @_otel_base_attributes.dup
97
+
98
+ if sql
99
+ case config[:db_statement]
100
+ when :obfuscate
101
+ attributes['db.query.text'] =
102
+ OpenTelemetry::Helpers::SqlProcessor.obfuscate_sql(sql, obfuscation_limit: config[:obfuscation_limit], adapter: :mysql)
103
+ when :include
104
+ attributes['db.query.text'] = sql
105
+ end
106
+ end
107
+
108
+ attributes
109
+ end
110
+
111
+ def set_error_attributes(span, error)
112
+ span.set_attribute('error.type', error.class.name)
113
+ span.set_attribute('db.response.status_code', error.error_code.to_s) if error.respond_to?(:error_code) && error.error_code
114
+ end
115
+
116
+ def tracer
117
+ Trilogy::Instrumentation.instance.tracer
118
+ end
119
+
120
+ def config
121
+ Trilogy::Instrumentation.instance.config
122
+ end
123
+
124
+ def propagator
125
+ Trilogy::Instrumentation.instance.propagator
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -7,7 +7,7 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module Trilogy
10
- VERSION = '0.65.1'
10
+ VERSION = '0.69.0'
11
11
  end
12
12
  end
13
13
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-instrumentation-trilogy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.65.1
4
+ version: 0.69.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-12-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: opentelemetry-helpers-mysql
@@ -95,17 +94,18 @@ files:
95
94
  - lib/opentelemetry/instrumentation.rb
96
95
  - lib/opentelemetry/instrumentation/trilogy.rb
97
96
  - lib/opentelemetry/instrumentation/trilogy/instrumentation.rb
98
- - lib/opentelemetry/instrumentation/trilogy/patches/client.rb
97
+ - lib/opentelemetry/instrumentation/trilogy/patches/dup/client.rb
98
+ - lib/opentelemetry/instrumentation/trilogy/patches/old/client.rb
99
+ - lib/opentelemetry/instrumentation/trilogy/patches/stable/client.rb
99
100
  - lib/opentelemetry/instrumentation/trilogy/version.rb
100
101
  homepage: https://github.com/open-telemetry/opentelemetry-ruby-contrib
101
102
  licenses:
102
103
  - Apache-2.0
103
104
  metadata:
104
- changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.65.1/file/CHANGELOG.md
105
- source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/trilogy
105
+ changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.69.0/file/CHANGELOG.md
106
+ source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/opentelemetry-instrumentation-trilogy/v0.69.0/instrumentation/trilogy
106
107
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues
107
- documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.65.1
108
- post_install_message:
108
+ documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.69.0
109
109
  rdoc_options: []
110
110
  require_paths:
111
111
  - lib
@@ -113,15 +113,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
- version: '3.2'
116
+ version: '3.3'
117
117
  required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  requirements:
119
119
  - - ">="
120
120
  - !ruby/object:Gem::Version
121
121
  version: '0'
122
122
  requirements: []
123
- rubygems_version: 3.4.19
124
- signing_key:
123
+ rubygems_version: 4.0.6
125
124
  specification_version: 4
126
125
  summary: Trilogy instrumentation for the OpenTelemetry framework
127
126
  test_files: []
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- require 'opentelemetry-helpers-mysql'
8
- require 'opentelemetry-helpers-sql-processor'
9
-
10
- module OpenTelemetry
11
- module Instrumentation
12
- module Trilogy
13
- module Patches
14
- # Module to prepend to Trilogy for instrumentation
15
- module Client
16
- def initialize(options = {})
17
- @connection_options = options # This is normally done by Trilogy#initialize
18
-
19
- tracer.in_span(
20
- 'connect',
21
- attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
22
- kind: :client,
23
- record_exception: config[:record_exception]
24
- ) do
25
- super
26
- end
27
- end
28
-
29
- def ping(...)
30
- tracer.in_span(
31
- 'ping',
32
- attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
33
- kind: :client,
34
- record_exception: config[:record_exception]
35
- ) do
36
- super
37
- end
38
- end
39
-
40
- def query(sql)
41
- tracer.in_span(
42
- OpenTelemetry::Helpers::MySQL.database_span_name(
43
- sql,
44
- OpenTelemetry::Instrumentation::Trilogy.attributes[
45
- OpenTelemetry::SemanticConventions::Trace::DB_OPERATION
46
- ],
47
- database_name,
48
- config
49
- ),
50
- attributes: client_attributes(sql).merge!(
51
- OpenTelemetry::Instrumentation::Trilogy.attributes
52
- ),
53
- kind: :client,
54
- record_exception: config[:record_exception]
55
- ) do |_span, context|
56
- if propagator && sql.frozen?
57
- sql = +sql
58
- propagator.inject(sql, context: context)
59
- sql.freeze
60
- elsif propagator
61
- propagator.inject(sql, context: context)
62
- end
63
-
64
- super
65
- end
66
- end
67
-
68
- private
69
-
70
- def client_attributes(sql = nil)
71
- attributes = {
72
- ::OpenTelemetry::SemanticConventions::Trace::DB_SYSTEM => 'mysql',
73
- ::OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => connection_options&.fetch(:host, 'unknown sock') || 'unknown sock'
74
- }
75
-
76
- attributes[::OpenTelemetry::SemanticConventions::Trace::DB_NAME] = database_name if database_name
77
- attributes[::OpenTelemetry::SemanticConventions::Trace::DB_USER] = database_user if database_user
78
- attributes[::OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] unless config[:peer_service].nil?
79
- attributes['db.instance.id'] = @connected_host unless @connected_host.nil?
80
-
81
- if sql
82
- case config[:db_statement]
83
- when :obfuscate
84
- attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] =
85
- OpenTelemetry::Helpers::SqlProcessor.obfuscate_sql(sql, obfuscation_limit: config[:obfuscation_limit], adapter: :mysql)
86
- when :include
87
- attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] = sql
88
- end
89
- end
90
-
91
- attributes
92
- end
93
-
94
- def database_name
95
- connection_options[:database]
96
- end
97
-
98
- def database_user
99
- connection_options[:username]
100
- end
101
-
102
- def tracer
103
- Trilogy::Instrumentation.instance.tracer
104
- end
105
-
106
- def config
107
- Trilogy::Instrumentation.instance.config
108
- end
109
-
110
- def propagator
111
- Trilogy::Instrumentation.instance.propagator
112
- end
113
- end
114
- end
115
- end
116
- end
117
- end