opentelemetry-instrumentation-trilogy 0.68.0 → 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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +44 -9
- data/lib/opentelemetry/instrumentation/trilogy/instrumentation.rb +99 -5
- data/lib/opentelemetry/instrumentation/trilogy/patches/dup/client.rb +157 -0
- data/lib/opentelemetry/instrumentation/trilogy/patches/old/client.rb +119 -0
- data/lib/opentelemetry/instrumentation/trilogy/patches/stable/client.rb +132 -0
- data/lib/opentelemetry/instrumentation/trilogy/version.rb +1 -1
- metadata +7 -5
- data/lib/opentelemetry/instrumentation/trilogy/patches/client.rb +0 -117
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 61673a70660a205354946b86bedb7ee5a3aa2cfd7af0aebab52b3c10e80b8c63
|
|
4
|
+
data.tar.gz: 6db4aa4e8c9cf0b62093d39b8e71a27f66735702271ac33426a755fce2240bd9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 216d40455f51acf894bb5aecf79abc6050d972598509b19e0356ce1c01bef1c57da6f12045d2be745ffc9411ef449817a594bd312aa01ee357b35f0836c7a84e
|
|
7
|
+
data.tar.gz: d5b67b6383b4a21e9932ef6123d617a92d8f13763c6df1163ae749106503e4667a17329ff7213e8baa7eee3909e7bb5679392045a407978fdc3472376e0463cd
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Release History: opentelemetry-instrumentation-trilogy
|
|
2
2
|
|
|
3
|
+
## v0.69.0 / 2026-05-21
|
|
4
|
+
|
|
5
|
+
- ADDED: Add `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable support for span attributes (#2095)
|
|
6
|
+
|
|
3
7
|
## v0.68.0 / 2026-04-14
|
|
4
8
|
|
|
5
9
|
- BREAKING CHANGE: Min Ruby Version 3.3 (#2125)
|
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
|
-
|
|
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,7 +83,7 @@ module OpenTelemetry
|
|
|
20
83
|
end
|
|
21
84
|
|
|
22
85
|
compatible do
|
|
23
|
-
Gem::Requirement.create('>= 2.
|
|
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
|
|
@@ -30,16 +93,47 @@ module OpenTelemetry
|
|
|
30
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
|
-
|
|
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
|
-
|
|
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)
|
|
@@ -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
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.69.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OpenTelemetry Authors
|
|
@@ -94,16 +94,18 @@ files:
|
|
|
94
94
|
- lib/opentelemetry/instrumentation.rb
|
|
95
95
|
- lib/opentelemetry/instrumentation/trilogy.rb
|
|
96
96
|
- lib/opentelemetry/instrumentation/trilogy/instrumentation.rb
|
|
97
|
-
- 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
|
|
98
100
|
- lib/opentelemetry/instrumentation/trilogy/version.rb
|
|
99
101
|
homepage: https://github.com/open-telemetry/opentelemetry-ruby-contrib
|
|
100
102
|
licenses:
|
|
101
103
|
- Apache-2.0
|
|
102
104
|
metadata:
|
|
103
|
-
changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.
|
|
104
|
-
source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/opentelemetry-instrumentation-trilogy/v0.
|
|
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
|
|
105
107
|
bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues
|
|
106
|
-
documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.
|
|
108
|
+
documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-trilogy/0.69.0
|
|
107
109
|
rdoc_options: []
|
|
108
110
|
require_paths:
|
|
109
111
|
- lib
|
|
@@ -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
|
-
@_otel_database_name = connection_options&.dig(:database)
|
|
19
|
-
@_otel_base_attributes = _build_otel_base_attributes.freeze
|
|
20
|
-
|
|
21
|
-
tracer.in_span(
|
|
22
|
-
'connect',
|
|
23
|
-
attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
|
|
24
|
-
kind: :client,
|
|
25
|
-
record_exception: config[:record_exception]
|
|
26
|
-
) do
|
|
27
|
-
super
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def ping(...)
|
|
32
|
-
tracer.in_span(
|
|
33
|
-
'ping',
|
|
34
|
-
attributes: client_attributes.merge!(OpenTelemetry::Instrumentation::Trilogy.attributes),
|
|
35
|
-
kind: :client,
|
|
36
|
-
record_exception: config[:record_exception]
|
|
37
|
-
) do
|
|
38
|
-
super
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def query(sql)
|
|
43
|
-
context_attributes = OpenTelemetry::Instrumentation::Trilogy.attributes
|
|
44
|
-
|
|
45
|
-
tracer.in_span(
|
|
46
|
-
OpenTelemetry::Helpers::MySQL.database_span_name(
|
|
47
|
-
sql,
|
|
48
|
-
context_attributes[OpenTelemetry::SemanticConventions::Trace::DB_OPERATION],
|
|
49
|
-
@_otel_database_name,
|
|
50
|
-
config
|
|
51
|
-
),
|
|
52
|
-
attributes: client_attributes(sql).merge!(context_attributes),
|
|
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 _build_otel_base_attributes
|
|
71
|
-
database_user = connection_options&.dig(:username)
|
|
72
|
-
|
|
73
|
-
attributes = {
|
|
74
|
-
::OpenTelemetry::SemanticConventions::Trace::DB_SYSTEM => 'mysql',
|
|
75
|
-
::OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => connection_options&.fetch(:host, 'unknown sock') || 'unknown sock'
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
attributes[::OpenTelemetry::SemanticConventions::Trace::DB_NAME] = @_otel_database_name if @_otel_database_name
|
|
79
|
-
attributes[::OpenTelemetry::SemanticConventions::Trace::DB_USER] = database_user if database_user
|
|
80
|
-
attributes[::OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] unless config[:peer_service].nil?
|
|
81
|
-
attributes
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def client_attributes(sql = nil)
|
|
85
|
-
attributes = @_otel_base_attributes.dup
|
|
86
|
-
|
|
87
|
-
attributes['db.instance.id'] = @connected_host unless @connected_host.nil?
|
|
88
|
-
|
|
89
|
-
if sql
|
|
90
|
-
case config[:db_statement]
|
|
91
|
-
when :obfuscate
|
|
92
|
-
attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] =
|
|
93
|
-
OpenTelemetry::Helpers::SqlProcessor.obfuscate_sql(sql, obfuscation_limit: config[:obfuscation_limit], adapter: :mysql)
|
|
94
|
-
when :include
|
|
95
|
-
attributes[::OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT] = sql
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
attributes
|
|
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
|