opentelemetry-instrumentation-trilogy 0.57.0 → 0.59.0

Sign up to get free protection for your applications and to get access to all the features.
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: