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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 659855aedd21b5e568de5d42caddb847da28ede64dde5ea1c1122d5417b6f7bf
|
4
|
+
data.tar.gz: 4bd835b5ece9052f67c598c5b55ee2290f1e27675c252a1bdaf6e54583f9b961
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 |
|
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
|
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(
|
76
|
-
|
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.
|
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] =
|
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
|
172
|
-
|
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
|
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.
|
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:
|
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.
|
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.
|
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.
|
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.
|
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:
|