opentelemetry-instrumentation-trilogy 0.57.0 → 0.59.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: '09504a134e2dbff7d4b256525dc3b3633de98e89badfd6776ab673c8eea9f2ee'
4
- data.tar.gz: c33bef4cdb1a85edbd2060aa12e786efd379f67aee03ca0ef23a3d0141267c97
3
+ metadata.gz: 659855aedd21b5e568de5d42caddb847da28ede64dde5ea1c1122d5417b6f7bf
4
+ data.tar.gz: 4bd835b5ece9052f67c598c5b55ee2290f1e27675c252a1bdaf6e54583f9b961
5
5
  SHA512:
6
- metadata.gz: 695b8bfa62151a372159af269e5cc72a69d8c0ce8c336e9b07266cee91a090dbd7d6d8f01a07d6e4b3c95824ef39a19610d499866cc14f8a4452674b6ff965e7
7
- data.tar.gz: 5be93ffc2130b07a722b95c61b0a6fc7572a03f4979b23bfed6ef13b34a77ccb08fea86241c716ac6289bc59141e2003479d493ae64ea73c20b0a43441a99ecc
6
+ metadata.gz: a4e179492feb03fd83a5040a7c26570c6184fe850232b7318668687b6f7092047c825b6a2fb852362a8b860b56b86216cac72927da78d1e0fc8463e33af32511
7
+ data.tar.gz: 2495228e827b77ee3bfec6ed3733124364da88ddc8ae459b0cea62fdc3e0ed56aca06b6d09a3514782feb65f645c0fcebefb2f45d00e14a8335784aa34c995e0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Release History: opentelemetry-instrumentation-trilogy
2
2
 
3
+ ### v0.59.0 / 2024-02-08
4
+
5
+ * BREAKING CHANGE: Move shared sql behavior to helper gems
6
+
7
+ * ADDED: Propagate context to Vitess
8
+
9
+ ### v0.58.0 / 2024-01-06
10
+
11
+ * BREAKING CHANGE: Change db.mysql.instance.address to db.instance.id
12
+
13
+ * ADDED: Change db.mysql.instance.address to db.instance.id
14
+ * FIXED: Trilogy only set db.instance.id attribute if there is a value
15
+
3
16
  ### v0.57.0 / 2023-10-27
4
17
 
5
18
  * ADDED: Instrument connect and ping
data/README.md CHANGED
@@ -51,6 +51,19 @@ OpenTelemetry::Instrumentation::Trilogy.with_attributes('pizzatoppings' => 'mush
51
51
  end
52
52
  ```
53
53
 
54
+ ## Semantic Conventions
55
+
56
+ This instrumentation generally uses [Database semantic conventions](https://opentelemetry.io/docs/specs/semconv/database/database-spans/).
57
+
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 |
66
+
54
67
  ## How can I get involved?
55
68
 
56
69
  The `opentelemetry-instrumentation-trilogy` gem source is [on github][repo-github], along with related gems including `opentelemetry-api` and `opentelemetry-sdk`.
@@ -7,11 +7,28 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module Trilogy
10
+ # @api private
11
+ class NoopPropagator
12
+ EMPTY_LIST = [].freeze
13
+ private_constant(:EMPTY_LIST)
14
+
15
+ def inject(carrier, context: Context.current, setter: nil); end
16
+
17
+ def extract(carrier, context: Context.current, getter: nil)
18
+ context
19
+ end
20
+
21
+ def fields
22
+ EMPTY_LIST
23
+ end
24
+ end
25
+
10
26
  # The Instrumentation class contains logic to detect and install the Trilogy instrumentation
11
27
  class Instrumentation < OpenTelemetry::Instrumentation::Base
12
- install do |_config|
28
+ install do |config|
13
29
  require_dependencies
14
30
  patch_client
31
+ configure_propagator(config)
15
32
  end
16
33
 
17
34
  present do
@@ -26,6 +43,9 @@ module OpenTelemetry
26
43
  option :db_statement, default: :obfuscate, validate: %I[omit include obfuscate]
27
44
  option :span_name, default: :statement_type, validate: %I[statement_type db_name db_operation_and_name]
28
45
  option :obfuscation_limit, default: 2000, validate: :integer
46
+ option :propagator, default: nil, validate: :string
47
+
48
+ attr_reader :propagator
29
49
 
30
50
  private
31
51
 
@@ -36,6 +56,24 @@ module OpenTelemetry
36
56
  def patch_client
37
57
  ::Trilogy.prepend(Patches::Client)
38
58
  end
59
+
60
+ def configure_propagator(config)
61
+ propagator = config[:propagator]
62
+ @propagator = case propagator
63
+ when 'vitess' then fetch_propagator(propagator, 'OpenTelemetry::Propagator::Vitess')
64
+ when 'none', nil then NoopPropagator.new
65
+ else
66
+ OpenTelemetry.logger.warn "The #{propagator} propagator is unknown and cannot be configured"
67
+ NoopPropagator.new
68
+ end
69
+ end
70
+
71
+ def fetch_propagator(name, class_name, gem_suffix = name)
72
+ Kernel.const_get(class_name).sql_query_propagator
73
+ rescue NameError
74
+ OpenTelemetry.logger.warn "The #{name} propagator cannot be configured - please add opentelemetry-propagator-#{gem_suffix} to your Gemfile"
75
+ nil
76
+ end
39
77
  end
40
78
  end
41
79
  end
@@ -1,53 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
3
7
  module OpenTelemetry
4
8
  module Instrumentation
5
9
  module Trilogy
6
10
  module Patches
7
11
  # Module to prepend to Trilogy for instrumentation
8
- module Client # rubocop:disable Metrics/ModuleLength
9
- QUERY_NAMES = [
10
- 'set names',
11
- 'select',
12
- 'insert',
13
- 'update',
14
- 'delete',
15
- 'begin',
16
- 'commit',
17
- 'rollback',
18
- 'savepoint',
19
- 'release savepoint',
20
- 'explain',
21
- 'drop database',
22
- 'drop table',
23
- 'create database',
24
- 'create table'
25
- ].freeze
26
-
27
- QUERY_NAME_RE = Regexp.new("^(#{QUERY_NAMES.join('|')})", Regexp::IGNORECASE)
28
-
29
- COMPONENTS_REGEX_MAP = {
30
- single_quotes: /'(?:[^']|'')*?(?:\\'.*|'(?!'))/,
31
- double_quotes: /"(?:[^"]|"")*?(?:\\".*|"(?!"))/,
32
- numeric_literals: /-?\b(?:[0-9]+\.)?[0-9]+([eE][+-]?[0-9]+)?\b/,
33
- boolean_literals: /\b(?:true|false|null)\b/i,
34
- hexadecimal_literals: /0x[0-9a-fA-F]+/,
35
- comments: /(?:#|--).*?(?=\r|\n|$)/i,
36
- multi_line_comments: %r{\/\*(?:[^\/]|\/[^*])*?(?:\*\/|\/\*.*)}
37
- }.freeze
38
-
39
- MYSQL_COMPONENTS = %i[
40
- single_quotes
41
- double_quotes
42
- numeric_literals
43
- boolean_literals
44
- hexadecimal_literals
45
- comments
46
- multi_line_comments
47
- ].freeze
48
-
49
- FULL_SQL_REGEXP = Regexp.union(MYSQL_COMPONENTS.map { |component| COMPONENTS_REGEX_MAP[component] })
50
-
12
+ module Client
51
13
  def initialize(options = {})
52
14
  @connection_options = options # This is normally done by Trilogy#initialize
53
15
 
@@ -72,10 +34,20 @@ module OpenTelemetry
72
34
 
73
35
  def query(sql)
74
36
  tracer.in_span(
75
- database_span_name(sql),
76
- attributes: client_attributes(sql).merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
37
+ OpenTelemetry::Helpers::MySQL.database_span_name(
38
+ sql,
39
+ OpenTelemetry::Instrumentation::Trilogy.attributes[
40
+ OpenTelemetry::SemanticConventions::Trace::DB_OPERATION
41
+ ],
42
+ database_name,
43
+ config
44
+ ),
45
+ attributes: client_attributes(sql).merge!(
46
+ OpenTelemetry::Instrumentation::Trilogy.attributes
47
+ ),
77
48
  kind: :client
78
- ) do
49
+ ) do |_span, context|
50
+ propagator.inject(sql, context: context)
79
51
  super(sql)
80
52
  end
81
53
  end
@@ -91,12 +63,13 @@ module OpenTelemetry
91
63
  attributes[::OpenTelemetry::SemanticConventions::Trace::DB_NAME] = database_name if database_name
92
64
  attributes[::OpenTelemetry::SemanticConventions::Trace::DB_USER] = database_user if database_user
93
65
  attributes[::OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] unless config[:peer_service].nil?
94
- attributes['db.mysql.instance.address'] = @connected_host if defined?(@connected_host)
66
+ attributes['db.instance.id'] = @connected_host unless @connected_host.nil?
95
67
 
96
68
  if sql
97
69
  case config[:db_statement]
98
70
  when :obfuscate
99
- attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] = obfuscate_sql(sql)
71
+ attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] =
72
+ OpenTelemetry::Helpers::SqlObfuscation.obfuscate_sql(sql, obfuscation_limit: config[:obfuscation_limit], adapter: :mysql)
100
73
  when :include
101
74
  attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] = sql
102
75
  end
@@ -105,53 +78,6 @@ module OpenTelemetry
105
78
  attributes
106
79
  end
107
80
 
108
- def obfuscate_sql(sql)
109
- if sql.size > config[:obfuscation_limit]
110
- first_match_index = sql.index(FULL_SQL_REGEXP)
111
- truncation_message = "SQL truncated (> #{config[:obfuscation_limit]} characters)"
112
- return truncation_message unless first_match_index
113
-
114
- truncated_sql = sql[..first_match_index - 1]
115
- "#{truncated_sql}...\n#{truncation_message}"
116
- else
117
- obfuscated = OpenTelemetry::Common::Utilities.utf8_encode(sql, binary: true)
118
- obfuscated = obfuscated.gsub(FULL_SQL_REGEXP, '?')
119
- obfuscated = 'Failed to obfuscate SQL query - quote characters remained after obfuscation' if detect_unmatched_pairs(obfuscated)
120
- obfuscated
121
- end
122
- rescue StandardError => e
123
- OpenTelemetry.handle_error(message: 'Failed to obfuscate SQL', exception: e)
124
- 'OpenTelemetry error: failed to obfuscate sql'
125
- end
126
-
127
- def detect_unmatched_pairs(obfuscated)
128
- # We use this to check whether the query contains any quote characters
129
- # after obfuscation. If so, that's a good indication that the original
130
- # query was malformed, and so our obfuscation can't reliably find
131
- # literals. In such a case, we'll replace the entire query with a
132
- # placeholder.
133
- %r{'|"|\/\*|\*\/}.match(obfuscated)
134
- end
135
-
136
- def database_span_name(sql)
137
- case config[:span_name]
138
- when :statement_type
139
- extract_statement_type(sql)
140
- when :db_name
141
- database_name
142
- when :db_operation_and_name
143
- op = OpenTelemetry::Instrumentation::Trilogy.attributes['db.operation']
144
- name = database_name
145
- if op && name
146
- "#{op} #{name}"
147
- elsif op
148
- op
149
- elsif name
150
- name
151
- end
152
- end || 'mysql'
153
- end
154
-
155
81
  def database_name
156
82
  connection_options[:database]
157
83
  end
@@ -168,11 +94,8 @@ module OpenTelemetry
168
94
  Trilogy::Instrumentation.instance.config
169
95
  end
170
96
 
171
- def extract_statement_type(sql)
172
- QUERY_NAME_RE.match(sql) { |match| match[1].downcase } unless sql.nil?
173
- rescue StandardError => e
174
- OpenTelemetry.logger.error("Error extracting sql statement type: #{e.message}")
175
- nil
97
+ def propagator
98
+ Trilogy::Instrumentation.instance.propagator
176
99
  end
177
100
  end
178
101
  end
@@ -7,7 +7,7 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module Trilogy
10
- VERSION = '0.57.0'
10
+ VERSION = '0.59.0'
11
11
  end
12
12
  end
13
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-instrumentation-trilogy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.57.0
4
+ version: 0.59.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-27 00:00:00.000000000 Z
11
+ date: 2024-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: opentelemetry-helpers-mysql
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: opentelemetry-helpers-sql-obfuscation
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: opentelemetry-instrumentation-base
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +122,20 @@ dependencies:
94
122
  - - "~>"
95
123
  - !ruby/object:Gem::Version
96
124
  version: '5.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: opentelemetry-propagator-vitess
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.1'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.1'
97
139
  - !ruby/object:Gem::Dependency
98
140
  name: opentelemetry-sdk
99
141
  requirement: !ruby/object:Gem::Requirement
@@ -184,14 +226,28 @@ dependencies:
184
226
  requirements:
185
227
  - - "~>"
186
228
  - !ruby/object:Gem::Version
187
- version: 1.56.1
229
+ version: 1.60.1
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: 1.60.1
237
+ - !ruby/object:Gem::Dependency
238
+ name: rubocop-performance
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: '1.20'
188
244
  type: :development
189
245
  prerelease: false
190
246
  version_requirements: !ruby/object:Gem::Requirement
191
247
  requirements:
192
248
  - - "~>"
193
249
  - !ruby/object:Gem::Version
194
- version: 1.56.1
250
+ version: '1.20'
195
251
  - !ruby/object:Gem::Dependency
196
252
  name: simplecov
197
253
  requirement: !ruby/object:Gem::Requirement
@@ -261,10 +317,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby-contrib
261
317
  licenses:
262
318
  - Apache-2.0
263
319
  metadata:
264
- changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.57.0/file/CHANGELOG.md
320
+ changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.59.0/file/CHANGELOG.md
265
321
  source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/trilogy
266
322
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues
267
- documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.57.0
323
+ documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.59.0
268
324
  post_install_message:
269
325
  rdoc_options: []
270
326
  require_paths: