mongo 2.22.0 → 2.23.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mongo/client.rb +40 -4
  3. data/lib/mongo/cluster.rb +4 -1
  4. data/lib/mongo/collection/view/aggregation/behavior.rb +1 -1
  5. data/lib/mongo/collection/view/aggregation.rb +5 -2
  6. data/lib/mongo/collection/view/iterable.rb +16 -14
  7. data/lib/mongo/collection/view/readable.rb +64 -55
  8. data/lib/mongo/collection/view/writable.rb +52 -46
  9. data/lib/mongo/collection/view.rb +2 -0
  10. data/lib/mongo/collection.rb +56 -46
  11. data/lib/mongo/config.rb +4 -0
  12. data/lib/mongo/crypt/auto_decryption_context.rb +9 -0
  13. data/lib/mongo/crypt/binding.rb +1 -1
  14. data/lib/mongo/crypt/context.rb +10 -0
  15. data/lib/mongo/crypt/explicit_decryption_context.rb +9 -0
  16. data/lib/mongo/database/view.rb +25 -20
  17. data/lib/mongo/database.rb +17 -10
  18. data/lib/mongo/deprecations.rb +98 -0
  19. data/lib/mongo/index/view.rb +28 -19
  20. data/lib/mongo/operation/create.rb +4 -0
  21. data/lib/mongo/operation/insert/op_msg.rb +5 -2
  22. data/lib/mongo/operation/shared/executable.rb +11 -4
  23. data/lib/mongo/operation/shared/specifiable.rb +5 -1
  24. data/lib/mongo/search_index/view.rb +29 -9
  25. data/lib/mongo/server/app_metadata/platform.rb +17 -4
  26. data/lib/mongo/server/connection.rb +18 -0
  27. data/lib/mongo/server/description/features.rb +37 -8
  28. data/lib/mongo/server.rb +2 -1
  29. data/lib/mongo/session.rb +55 -19
  30. data/lib/mongo/srv/monitor.rb +5 -1
  31. data/lib/mongo/srv/result.rb +14 -4
  32. data/lib/mongo/tracing/open_telemetry/command_tracer.rb +320 -0
  33. data/lib/mongo/tracing/open_telemetry/operation_tracer.rb +227 -0
  34. data/lib/mongo/tracing/open_telemetry/tracer.rb +236 -0
  35. data/lib/mongo/tracing/open_telemetry.rb +27 -0
  36. data/lib/mongo/tracing.rb +42 -0
  37. data/lib/mongo/uri/srv_protocol.rb +11 -6
  38. data/lib/mongo/version.rb +1 -1
  39. data/lib/mongo.rb +3 -0
  40. metadata +8 -2
@@ -0,0 +1,227 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025-present MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the 'License');
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an 'AS IS' BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Mongo
18
+ module Tracing
19
+ module OpenTelemetry
20
+ # OperationTracer is responsible for tracing MongoDB driver operations using OpenTelemetry.
21
+ #
22
+ # @api private
23
+ class OperationTracer
24
+ extend Forwardable
25
+
26
+ def_delegators :@parent_tracer,
27
+ :cursor_context_map,
28
+ :parent_context_for,
29
+ :transaction_context_map,
30
+ :transaction_map_key
31
+
32
+ # Initializes a new OperationTracer.
33
+ #
34
+ # @param otel_tracer [ OpenTelemetry::Trace::Tracer ] the OpenTelemetry tracer.
35
+ # @param parent_tracer [ Mongo::Tracing::OpenTelemetry::Tracer ] the parent tracer
36
+ # for accessing shared context maps.
37
+ def initialize(otel_tracer, parent_tracer)
38
+ @otel_tracer = otel_tracer
39
+ @parent_tracer = parent_tracer
40
+ end
41
+
42
+ # Trace a MongoDB operation.
43
+ #
44
+ # Creates an OpenTelemetry span for the operation, capturing attributes such as
45
+ # database name, collection name, operation name, and cursor ID. The span is finished
46
+ # automatically when the operation completes or fails.
47
+ #
48
+ # @param operation [ Mongo::Operation ] the MongoDB operation to trace.
49
+ # @param operation_context [ Mongo::Operation::Context ] the context of the operation.
50
+ # @param op_name [ String | nil ] an optional name for the operation. If nil, the
51
+ # operation class name is used.
52
+ #
53
+ # @yield the block representing the operation to be traced.
54
+ #
55
+ # @return [ Object ] the result of the operation.
56
+ #
57
+ # rubocop:disable Lint/RescueException
58
+ def trace_operation(operation, operation_context, op_name: nil, &block)
59
+ span = create_operation_span(operation, operation_context, op_name)
60
+ execute_with_span(span, operation, &block)
61
+ rescue Exception => e
62
+ handle_span_exception(span, e)
63
+ raise e
64
+ ensure
65
+ span&.finish
66
+ end
67
+ # rubocop:enable Lint/RescueException
68
+
69
+ private
70
+
71
+ # Creates an OpenTelemetry span for the operation.
72
+ #
73
+ # @param operation [ Mongo::Operation ] the operation.
74
+ # @param operation_context [ Mongo::Operation::Context ] the operation context.
75
+ # @param op_name [ String | nil ] optional operation name.
76
+ #
77
+ # @return [ OpenTelemetry::Trace::Span ] the created span.
78
+ def create_operation_span(operation, operation_context, op_name)
79
+ parent_context = parent_context_for(operation_context, operation.cursor_id)
80
+ @otel_tracer.start_span(
81
+ operation_span_name(operation, op_name),
82
+ attributes: span_attributes(operation, op_name),
83
+ with_parent: parent_context,
84
+ kind: :client
85
+ )
86
+ end
87
+
88
+ # Executes the operation block within the span context.
89
+ #
90
+ # @param span [ OpenTelemetry::Trace::Span ] the span.
91
+ # @param operation [ Mongo::Operation ] the operation.
92
+ #
93
+ # @yield the block to execute.
94
+ #
95
+ # @return [ Object ] the result of the block.
96
+ def execute_with_span(span, operation)
97
+ ::OpenTelemetry::Trace.with_span(span) do |s, c|
98
+ yield.tap do |result|
99
+ process_cursor_context(result, operation.cursor_id, c, s)
100
+ end
101
+ end
102
+ end
103
+
104
+ # Handles exception for the span.
105
+ #
106
+ # @param span [ OpenTelemetry::Trace::Span ] the span.
107
+ # @param exception [ Exception ] the exception.
108
+ def handle_span_exception(span, exception)
109
+ return unless span
110
+
111
+ span.record_exception(exception)
112
+ span.status = ::OpenTelemetry::Trace::Status.error(
113
+ "Unhandled exception of type: #{exception.class}"
114
+ )
115
+ end
116
+
117
+ # Returns the operation name from the provided name or operation class.
118
+ #
119
+ # @param operation [ Mongo::Operation ] the operation.
120
+ # @param op_name [ String | nil ] optional operation name.
121
+ #
122
+ # @return [ String ] the operation name in lowercase.
123
+ def operation_name(operation, op_name = nil)
124
+ op_name || operation.class.name.split('::').last.downcase
125
+ end
126
+
127
+ # Builds span attributes for the operation.
128
+ #
129
+ # @param operation [ Mongo::Operation ] the operation.
130
+ # @param op_name [ String | nil ] optional operation name.
131
+ #
132
+ # @return [ Hash ] OpenTelemetry span attributes following MongoDB semantic conventions.
133
+ def span_attributes(operation, op_name)
134
+ {
135
+ 'db.system' => 'mongodb',
136
+ 'db.namespace' => operation.db_name.to_s,
137
+ 'db.collection.name' => collection_name(operation),
138
+ 'db.operation.name' => operation_name(operation, op_name),
139
+ 'db.operation.summary' => operation_span_name(operation, op_name),
140
+ 'db.mongodb.cursor_id' => operation.cursor_id,
141
+ }.compact
142
+ end
143
+
144
+ # Processes cursor context after operation execution.
145
+ #
146
+ # Updates the cursor context map based on the result. Removes closed cursors
147
+ # and stores context for newly created cursors.
148
+ #
149
+ # @param result [ Object ] the operation result.
150
+ # @param cursor_id [ Integer | nil ] the cursor ID before the operation.
151
+ # @param context [ OpenTelemetry::Context ] the OpenTelemetry context.
152
+ # @param span [ OpenTelemetry::Trace::Span ] the current span.
153
+ def process_cursor_context(result, cursor_id, context, span)
154
+ return unless result.is_a?(Cursor)
155
+
156
+ if result.id.zero?
157
+ # If the cursor is closed, remove it from the context map.
158
+ cursor_context_map.delete(cursor_id)
159
+ elsif result.id && cursor_id.nil?
160
+ # New cursor created, store its context.
161
+ cursor_context_map[result.id] = context
162
+ span.set_attribute('db.mongodb.cursor_id', result.id)
163
+ end
164
+ end
165
+
166
+ # Extracts the collection name from the operation.
167
+ #
168
+ # @param operation [ Mongo::Operation ] the operation.
169
+ #
170
+ # @return [ String | nil ] the collection name, or nil if not applicable.
171
+ def collection_name(operation)
172
+ return operation.coll_name.to_s if operation.respond_to?(:coll_name) && operation.coll_name
173
+
174
+ extract_collection_from_spec(operation)
175
+ end
176
+
177
+ # Extracts collection name from operation spec based on operation type.
178
+ #
179
+ # @param operation [ Mongo::Operation ] the operation.
180
+ #
181
+ # @return [ String | nil ] the collection name, or nil if not found.
182
+ def extract_collection_from_spec(operation)
183
+ collection_key = collection_key_for_operation(operation)
184
+ return nil unless collection_key
185
+
186
+ value = if collection_key == :first_value
187
+ operation.spec[:selector].values.first
188
+ else
189
+ operation.spec[:selector][collection_key]
190
+ end
191
+ value&.to_s
192
+ end
193
+
194
+ # Returns the collection key for a given operation type.
195
+ #
196
+ # @param operation [ Mongo::Operation ] the operation.
197
+ #
198
+ # @return [ Symbol | nil ] the collection key symbol or nil.
199
+ def collection_key_for_operation(operation)
200
+ case operation
201
+ when Operation::Aggregate then :aggregate
202
+ when Operation::Count then :count
203
+ when Operation::Create then :create
204
+ when Operation::Distinct then :distinct
205
+ when Operation::Drop then :drop
206
+ when Operation::WriteCommand then :first_value
207
+ end
208
+ end
209
+
210
+ # Generates the span name for the operation.
211
+ #
212
+ # @param operation [ Mongo::Operation ] the operation.
213
+ # @param op_name [ String | nil ] optional operation name.
214
+ #
215
+ # @return [ String ] span name in format "operation_name db.collection" or "operation_name db".
216
+ def operation_span_name(operation, op_name = nil)
217
+ coll_name = collection_name(operation)
218
+ if coll_name && !coll_name.empty?
219
+ "#{operation_name(operation, op_name)} #{operation.db_name}.#{coll_name}"
220
+ else
221
+ "#{operation_name(operation, op_name)} #{operation.db_name}"
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,236 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025-present MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the 'License');
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an 'AS IS' BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Mongo
18
+ module Tracing
19
+ module OpenTelemetry
20
+ # OpenTelemetry tracer for MongoDB operations and commands.
21
+ # @api private
22
+ class Tracer
23
+ # @return [ OpenTelemetry::Trace::Tracer ] the OpenTelemetry tracer implementation
24
+ # used to create spans for MongoDB operations and commands.
25
+ #
26
+ # @api private
27
+ attr_reader :otel_tracer
28
+
29
+ # Initializes a new OpenTelemetry tracer.
30
+ #
31
+ # @param enabled [ Boolean | nil ] whether OpenTelemetry is enabled or not.
32
+ # Defaults to nil, which means it will check the environment variable
33
+ # OTEL_RUBY_INSTRUMENTATION_MONGODB_ENABLED (values: true/1/yes). If the
34
+ # environment variable is not set, OpenTelemetry will be disabled by default.
35
+ # @param query_text_max_length [ Integer | nil ] maximum length for captured query text.
36
+ # Defaults to nil, which means it will check the environment variable
37
+ # OTEL_RUBY_INSTRUMENTATION_MONGODB_QUERY_TEXT_MAX_LENGTH. If the environment variable is not set,
38
+ # the query text will not be captured.
39
+ # @param otel_tracer [ OpenTelemetry::Trace::Tracer | nil ] the OpenTelemetry tracer
40
+ # implementation to use. Defaults to nil, which means it will use the default tracer
41
+ # from OpenTelemetry's tracer provider.
42
+ def initialize(enabled: nil, query_text_max_length: nil, otel_tracer: nil)
43
+ @enabled = if enabled.nil?
44
+ %w[true 1 yes].include?(ENV['OTEL_RUBY_INSTRUMENTATION_MONGODB_ENABLED']&.downcase)
45
+ else
46
+ enabled
47
+ end
48
+ check_opentelemetry_loaded
49
+ @query_text_max_length = if query_text_max_length.nil?
50
+ ENV['OTEL_RUBY_INSTRUMENTATION_MONGODB_QUERY_TEXT_MAX_LENGTH'].to_i
51
+ else
52
+ query_text_max_length
53
+ end
54
+ @otel_tracer = otel_tracer || initialize_tracer
55
+ @operation_tracer = OperationTracer.new(@otel_tracer, self)
56
+ @command_tracer = CommandTracer.new(@otel_tracer, self, query_text_max_length: @query_text_max_length)
57
+ end
58
+
59
+ # Whether OpenTelemetry is enabled or not.
60
+ #
61
+ # @return [Boolean] true if OpenTelemetry is enabled, false otherwise.
62
+ def enabled?
63
+ @enabled
64
+ end
65
+
66
+ # Trace a MongoDB operation.
67
+ #
68
+ # @param operation [Mongo::Operation] The MongoDB operation to trace.
69
+ # @param operation_context [Mongo::Operation::Context] The context of the operation.
70
+ # @param op_name [String, nil] An optional name for the operation.
71
+ # @yield The block representing the operation to be traced.
72
+ # @return [Object] The result of the operation.
73
+ def trace_operation(operation, operation_context, op_name: nil, &block)
74
+ return yield unless enabled?
75
+
76
+ @operation_tracer.trace_operation(operation, operation_context, op_name: op_name, &block)
77
+ end
78
+
79
+ # Trace a MongoDB command.
80
+ #
81
+ # @param message [Mongo::Protocol::Message] The MongoDB command message to trace.
82
+ # @param operation_context [Mongo::Operation::Context] The context of the operation.
83
+ # @param connection [Mongo::Server::Connection] The connection used to send the command
84
+ # @yield The block representing the command to be traced.
85
+ # @return [Object] The result of the command.
86
+ def trace_command(message, operation_context, connection, &block)
87
+ return yield unless enabled?
88
+
89
+ @command_tracer.trace_command(message, operation_context, connection, &block)
90
+ end
91
+
92
+ # Start a transaction span and activate its context.
93
+ #
94
+ # @param session [Mongo::Session] The session starting the transaction.
95
+ def start_transaction_span(session)
96
+ return unless enabled?
97
+
98
+ key = transaction_map_key(session)
99
+ return unless key
100
+
101
+ # Create the transaction span with minimal attributes
102
+ span = @otel_tracer.start_span(
103
+ 'transaction',
104
+ attributes: { 'db.system' => 'mongodb' },
105
+ kind: :client
106
+ )
107
+
108
+ # Create a context containing this span
109
+ context = ::OpenTelemetry::Trace.context_with_span(span)
110
+
111
+ # Activate the context and store the token for later detachment
112
+ token = ::OpenTelemetry::Context.attach(context)
113
+
114
+ # Store span, token, and context for later retrieval
115
+ transaction_span_map[key] = span
116
+ transaction_token_map[key] = token
117
+ transaction_context_map[key] = context
118
+ end
119
+
120
+ # Finish a transaction span and deactivate its context.
121
+ #
122
+ # @param session [Mongo::Session] The session finishing the transaction.
123
+ def finish_transaction_span(session)
124
+ return unless enabled?
125
+
126
+ key = transaction_map_key(session)
127
+ return unless key
128
+
129
+ span = transaction_span_map.delete(key)
130
+ token = transaction_token_map.delete(key)
131
+ transaction_context_map.delete(key)
132
+
133
+ return unless span && token
134
+
135
+ begin
136
+ span.finish
137
+ ensure
138
+ ::OpenTelemetry::Context.detach(token)
139
+ end
140
+ end
141
+
142
+ # Returns the cursor context map for tracking cursor-related OpenTelemetry contexts.
143
+ #
144
+ # @return [ Hash ] map of cursor IDs to OpenTelemetry contexts.
145
+ def cursor_context_map
146
+ @cursor_context_map ||= {}
147
+ end
148
+
149
+ # Generates a unique key for cursor tracking in the context map.
150
+ #
151
+ # @param session [ Mongo::Session ] the session associated with the cursor.
152
+ # @param cursor_id [ Integer ] the cursor ID.
153
+ #
154
+ # @return [ String | nil ] unique key combining session ID and cursor ID, or nil if either is nil.
155
+ def cursor_map_key(session, cursor_id)
156
+ return if cursor_id.nil? || session.nil?
157
+
158
+ "#{session.session_id['id'].to_uuid}-#{cursor_id}"
159
+ end
160
+
161
+ # Determines the parent OpenTelemetry context for an operation.
162
+ #
163
+ # Returns the transaction context if the operation is part of a transaction,
164
+ # otherwise returns nil. Cursor-based context nesting is not currently implemented.
165
+ #
166
+ # @param operation_context [ Mongo::Operation::Context ] the operation context.
167
+ # @param cursor_id [ Integer ] the cursor ID, if applicable.
168
+ #
169
+ # @return [ OpenTelemetry::Context | nil ] parent context or nil.
170
+ def parent_context_for(operation_context, cursor_id)
171
+ if (key = transaction_map_key(operation_context.session))
172
+ transaction_context_map[key]
173
+ elsif (_key = cursor_map_key(operation_context.session, cursor_id))
174
+ # We return nil here unless we decide how to nest cursor operations.
175
+ nil
176
+ end
177
+ end
178
+
179
+ # Returns the transaction context map for tracking active transaction contexts.
180
+ #
181
+ # @return [ Hash ] map of transaction keys to OpenTelemetry contexts.
182
+ def transaction_context_map
183
+ @transaction_context_map ||= {}
184
+ end
185
+
186
+ # Returns the transaction span map for tracking active transaction spans.
187
+ #
188
+ # @return [ Hash ] map of transaction keys to OpenTelemetry spans.
189
+ def transaction_span_map
190
+ @transaction_span_map ||= {}
191
+ end
192
+
193
+ # Returns the transaction token map for tracking context attachment tokens.
194
+ #
195
+ # @return [ Hash ] map of transaction keys to OpenTelemetry context tokens.
196
+ def transaction_token_map
197
+ @transaction_token_map ||= {}
198
+ end
199
+
200
+ # Generates a unique key for transaction tracking.
201
+ #
202
+ # Returns nil for implicit sessions or sessions not in a transaction.
203
+ #
204
+ # @param session [ Mongo::Session ] the session.
205
+ #
206
+ # @return [ String | nil ] unique key combining session ID and transaction number, or nil.
207
+ def transaction_map_key(session)
208
+ return if session.nil? || session.implicit? || !session.in_transaction?
209
+
210
+ "#{session.session_id['id'].to_uuid}-#{session.txn_num}"
211
+ end
212
+
213
+ private
214
+
215
+ def check_opentelemetry_loaded
216
+ return unless @enabled
217
+ return if defined?(::OpenTelemetry)
218
+
219
+ Logger.logger.warn('OpenTelemetry tracing for MongoDB is enabled, ' \
220
+ 'but the OpenTelemetry library is not loaded. ' \
221
+ 'Disabling tracing.')
222
+ @enabled = false
223
+ end
224
+
225
+ def initialize_tracer
226
+ return unless enabled?
227
+
228
+ ::OpenTelemetry.tracer_provider.tracer(
229
+ 'mongo-ruby-driver',
230
+ Mongo::VERSION
231
+ )
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025-present MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the 'License');
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an 'AS IS' BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Mongo
18
+ module Tracing
19
+ # This module contains OpenTelemetry tracing functionality for MongoDB operations.
20
+ module OpenTelemetry
21
+ end
22
+ end
23
+ end
24
+
25
+ require 'mongo/tracing/open_telemetry/command_tracer'
26
+ require 'mongo/tracing/open_telemetry/operation_tracer'
27
+ require 'mongo/tracing/open_telemetry/tracer'
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025-present MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the 'License');
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an 'AS IS' BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Mongo
18
+ # Provides OpenTelemetry tracing capabilities for MongoDB operations.
19
+ module Tracing
20
+ # Creates a new OpenTelemetry tracer for instrumenting MongoDB operations.
21
+ #
22
+ # @param enabled [Boolean, nil] Whether tracing is enabled. Default to nil, which
23
+ # means it will check the environment variable OTEL_RUBY_INSTRUMENTATION_MONGODB_ENABLED.
24
+ # See +Mongo::Tracing::OpenTelemetry::Tracer+ for details.
25
+ # @param query_text_max_length [Integer, nil] Maximum length for captured query text. Default to nil,
26
+ # which means it will check the environment variable OTEL_RUBY_INSTRUMENTATION_MONGODB_QUERY_TEXT_MAX_LENGTH.
27
+ # See +Mongo::Tracing::OpenTelemetry::Tracer+ for details.
28
+ # @param otel_tracer [OpenTelemetry::Trace::Tracer, nil] Custom OpenTelemetry tracer instance.
29
+ #
30
+ # @return [Mongo::Tracing::OpenTelemetry::Tracer] Configured tracer instance.
31
+ def create_tracer(enabled: nil, query_text_max_length: nil, otel_tracer: nil)
32
+ OpenTelemetry::Tracer.new(
33
+ enabled: enabled,
34
+ query_text_max_length: query_text_max_length,
35
+ otel_tracer: otel_tracer
36
+ )
37
+ end
38
+ module_function :create_tracer
39
+ end
40
+ end
41
+
42
+ require 'mongo/tracing/open_telemetry'
@@ -122,11 +122,13 @@ module Mongo
122
122
  end
123
123
 
124
124
  # Gets the SRV resolver.
125
+ # If domain verification fails or no SRV records are found,
126
+ # an error must not be raised per the spec; instead, a warning is logged.
125
127
  #
126
128
  # @return [ Mongo::Srv::Resolver ]
127
129
  def resolver
128
130
  @resolver ||= Srv::Resolver.new(
129
- raise_on_invalid: true,
131
+ raise_on_invalid: false,
130
132
  resolv_options: options[:resolv_options],
131
133
  timeout: options[:connect_timeout],
132
134
  )
@@ -149,7 +151,11 @@ module Mongo
149
151
 
150
152
  log_debug "attempting to resolve #{hostname}"
151
153
 
152
- @srv_result = resolver.get_records(hostname, uri_options[:srv_service_name], uri_options[:srv_max_hosts])
154
+ @srv_result = resolver.get_records(
155
+ hostname,
156
+ uri_options[:srv_service_name] || options[:srv_service_name],
157
+ uri_options[:srv_max_hosts] || options[:srv_max_hosts]
158
+ )
153
159
  if srv_result.empty?
154
160
  raise Error::NoSRVRecords.new(NO_SRV_RECORDS % hostname)
155
161
  end
@@ -168,8 +174,7 @@ module Mongo
168
174
  # The hostname cannot include a port.
169
175
  #
170
176
  # The hostname must not begin with a dot, end with a dot, or have
171
- # consecutive dots. The hostname must have a minimum of 3 total
172
- # components (foo.bar.tld).
177
+ # consecutive dots. The hostname must have a minimum of 1 component
173
178
  #
174
179
  # Raises Error::InvalidURI if validation fails.
175
180
  def validate_srv_hostname(hostname)
@@ -185,8 +190,8 @@ module Mongo
185
190
  if parts.any?(&:empty?)
186
191
  raise_invalid_error!("Hostname cannot have consecutive dots: #{hostname}")
187
192
  end
188
- if parts.length < 3
189
- raise_invalid_error!("Hostname must have a minimum of 3 components (foo.bar.tld): #{hostname}")
193
+ if parts.length < 1
194
+ raise_invalid_error!("Hostname cannot be empty: #{hostname}")
190
195
  end
191
196
  end
192
197
 
data/lib/mongo/version.rb CHANGED
@@ -5,5 +5,5 @@ module Mongo
5
5
  #
6
6
  # Note that this file is automatically updated via `rake candidate:create`.
7
7
  # Manual changes to this file will be overwritten by that rake task.
8
- VERSION = '2.22.0'
8
+ VERSION = '2.23.0'
9
9
  end
data/lib/mongo.rb CHANGED
@@ -42,6 +42,7 @@ require 'mongo/condition_variable'
42
42
  require 'mongo/csot_timeout_holder'
43
43
  require 'mongo/options'
44
44
  require 'mongo/loggable'
45
+ require 'mongo/deprecations'
45
46
  require 'mongo/cluster_time'
46
47
  require 'mongo/topology_version'
47
48
  require 'mongo/monitoring'
@@ -74,6 +75,7 @@ require 'mongo/session'
74
75
  require 'mongo/socket'
75
76
  require 'mongo/srv'
76
77
  require 'mongo/timeout'
78
+ require 'mongo/tracing'
77
79
  require 'mongo/uri'
78
80
  require 'mongo/version'
79
81
  require 'mongo/write_concern'
@@ -100,6 +102,7 @@ module Mongo
100
102
  delegate_option Config, :broken_view_aggregate
101
103
  delegate_option Config, :broken_view_options
102
104
  delegate_option Config, :validate_update_replace
105
+ delegate_option Config, :csfle_convert_to_ruby_types
103
106
  end
104
107
 
105
108
  # Clears the driver's OCSP response cache.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.22.0
4
+ version: 2.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - The MongoDB Ruby Team
@@ -193,6 +193,7 @@ files:
193
193
  - lib/mongo/database.rb
194
194
  - lib/mongo/database/view.rb
195
195
  - lib/mongo/dbref.rb
196
+ - lib/mongo/deprecations.rb
196
197
  - lib/mongo/distinguishing_semaphore.rb
197
198
  - lib/mongo/error.rb
198
199
  - lib/mongo/error/auth_error.rb
@@ -520,6 +521,11 @@ files:
520
521
  - lib/mongo/srv/result.rb
521
522
  - lib/mongo/timeout.rb
522
523
  - lib/mongo/topology_version.rb
524
+ - lib/mongo/tracing.rb
525
+ - lib/mongo/tracing/open_telemetry.rb
526
+ - lib/mongo/tracing/open_telemetry/command_tracer.rb
527
+ - lib/mongo/tracing/open_telemetry/operation_tracer.rb
528
+ - lib/mongo/tracing/open_telemetry/tracer.rb
523
529
  - lib/mongo/uri.rb
524
530
  - lib/mongo/uri/options_mapper.rb
525
531
  - lib/mongo/uri/srv_protocol.rb
@@ -553,7 +559,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
553
559
  - !ruby/object:Gem::Version
554
560
  version: '0'
555
561
  requirements: []
556
- rubygems_version: 3.7.2
562
+ rubygems_version: 4.0.5
557
563
  specification_version: 4
558
564
  summary: Ruby driver for MongoDB
559
565
  test_files: []