diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 27551316f..5357eb690 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 name: Clean up stale issues and PRs with: repo-token: ${{ secrets.GITHUB_TOKEN }} @@ -18,7 +18,7 @@ jobs: stale-issue-label: "stale" exempt-issue-labels: "keep" days-before-issue-stale: 30 - days-before-issue-close: -1 + days-before-issue-close: 30 stale-pr-message: "👋 This pull request has been marked as stale because it has been open with no activity. You can: comment on the issue or remove the stale label to hold stale off for a while, add the `keep` label to hold stale off permanently, or do nothing. If you do nothing this pull request will be closed eventually by the stale bot" stale-pr-label: "stale" exempt-pr-labels: "keep" diff --git a/.instrumentation_generator/templates/gemspec.tt b/.instrumentation_generator/templates/gemspec.tt index 6305d176e..cadf4adc7 100644 --- a/.instrumentation_generator/templates/gemspec.tt +++ b/.instrumentation_generator/templates/gemspec.tt @@ -35,6 +35,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rubocop', '~> 1.48.1' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.7.6' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/.rubocop.yml b/.rubocop.yml index efc914429..028015df7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,5 @@ +require: rubocop-performance + AllCops: TargetRubyVersion: '3.0' NewCops: enable diff --git a/Gemfile b/Gemfile index 79b6ff11e..593f654cd 100644 --- a/Gemfile +++ b/Gemfile @@ -7,4 +7,5 @@ source 'https://rubygems.org' gem 'rake', '~> 13.0' -gem 'rubocop', '~> 1.57.1' +gem 'rubocop', '~> 1.58.0' +gem 'rubocop-performance', '~> 1.19.1' diff --git a/README.md b/README.md index d7de85310..427772900 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,8 @@ The Ruby special interest group (SIG) meets regularly. See the OpenTelemetry Approvers ([@open-telemetry/ruby-contrib-approvers](https://github.com/orgs/open-telemetry/teams/ruby-contrib-approvers)): -- (Could _your_ name appear here?) +- [Josef Šimánek](https://github.com/simi) +- [Kayla Reopelle](https://github.com/kaylareopelle), New Relic *Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver).* diff --git a/instrumentation/action_pack/CHANGELOG.md b/instrumentation/action_pack/CHANGELOG.md index 422b99960..ce51354e5 100644 --- a/instrumentation/action_pack/CHANGELOG.md +++ b/instrumentation/action_pack/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History: opentelemetry-instrumentation-action_pack +### v0.8.0 / 2023-11-22 + +* BREAKING CHANGE: Drop Rails 6.0 EOL + +* ADDED: Drop Rails 6.0 EOL + ### v0.7.1 / 2023-10-16 * FIXED: Add Rails 7.1 compatibility diff --git a/instrumentation/action_pack/README.md b/instrumentation/action_pack/README.md index 877e0ec4b..8bbcd69bf 100644 --- a/instrumentation/action_pack/README.md +++ b/instrumentation/action_pack/README.md @@ -30,6 +30,25 @@ OpenTelemetry::SDK.configure do |c| end ``` +## Active Support Instrumentation + +Earlier versions of this instrumentation relied on patching custom `dispatch` hooks from Rails's [Action Controller](https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/metal.rb#L224) to extract request information. + +This instrumentation now relies on `ActiveSupport::Notifications` and registers a custom Subscriber that listens to relevant events to modify the Rack span. + +See the table below for details of what [Rails Framework Hook Events](https://guides.rubyonrails.org/active_support_instrumentation.html#action-controller) are recorded by this instrumentation: + +| Event Name | Subscribe? | Creates Span? | Notes | +| - | - | - | - | +| `process_action.action_controller` | :white_check_mark: | :x: | It modifies the existing Rack span | + + +### Error Handling for Action Controller + +If an error is triggered by Action Controller (such as a 500 internal server error), Action Pack will typically employ the default `ActionDispatch::PublicExceptions.new(Rails.public_path)` as the `exceptions_app`, as detailed in the [documentation](https://guides.rubyonrails.org/configuring.html#config-exceptions-app). + +The error object will be retained within `payload[:exception_object]`. Additionally, its storage in `request.env['action_dispatch.exception']` is contingent upon the configuration of `action_dispatch.show_exceptions` in Rails. + ## Examples Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/action_pack/example/trace_demonstration.ru) diff --git a/instrumentation/action_pack/example/trace_demonstration.ru b/instrumentation/action_pack/example/trace_demonstration.ru index 6e9f08c94..0a8130efb 100644 --- a/instrumentation/action_pack/example/trace_demonstration.ru +++ b/instrumentation/action_pack/example/trace_demonstration.ru @@ -23,7 +23,7 @@ require 'action_controller/railtie' class TraceRequestApp < Rails::Application config.root = __dir__ config.hosts << 'example.org' - secrets.secret_key_base = 'secret_key_base' + credentials.secret_key_base = 'secret_key_base' config.eager_load = false config.logger = Logger.new($stdout) Rails.logger = config.logger @@ -39,6 +39,6 @@ Rails.application.initialize! run Rails.application # To run this example run the `rackup` command with this file -# Example: rackup trace_request_demonstration.ru +# Example: rackup trace_demonstration.ru # Navigate to http://localhost:9292/ # Spans for the requests will appear in the console diff --git a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/handlers.rb b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/handlers.rb new file mode 100644 index 000000000..1e902d4e3 --- /dev/null +++ b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/handlers.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require_relative 'handlers/action_controller' + +module OpenTelemetry + module Instrumentation + module ActionPack + # Module that contains custom event handlers, which are used to generate spans per event + module Handlers + module_function + + def subscribe + return unless Array(@subscriptions).empty? + + config = ActionPack::Instrumentation.instance.config + handlers_by_pattern = { + 'process_action.action_controller' => Handlers::ActionController.new(config) + } + + @subscriptions = handlers_by_pattern.map do |key, handler| + ::ActiveSupport::Notifications.subscribe(key, handler) + end + end + + # Removes Event Handler Subscriptions for Action Controller notifications + # @note this method is not thread-safe and should not be used in a multi-threaded context + def unsubscribe + @subscriptions&.each { |subscriber| ::ActiveSupport::Notifications.unsubscribe(subscriber) } + @subscriptions = nil + end + end + end + end +end diff --git a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/handlers/action_controller.rb b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/handlers/action_controller.rb new file mode 100644 index 000000000..d7b79b64d --- /dev/null +++ b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/handlers/action_controller.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module ActionPack + module Handlers + # Action Controller handler to handle the notification from Active Support + class ActionController + # @param config [Hash] of instrumentation options + def initialize(config) + @config = config + end + + # Invoked by ActiveSupport::Notifications at the start of the instrumentation block + # + # @param _name [String] of the event (unused) + # @param _id [String] of the event (unused) + # @param payload [Hash] the payload passed as a method argument + # @return [Hash] the payload passed as a method argument + def start(_name, _id, payload) + rack_span = OpenTelemetry::Instrumentation::Rack.current_span + + request = payload[:request] + + rack_span.name = "#{payload[:controller]}##{payload[:action]}" unless request.env['action_dispatch.exception'] + + attributes_to_append = { + OpenTelemetry::SemanticConventions::Trace::CODE_NAMESPACE => String(payload[:controller]), + OpenTelemetry::SemanticConventions::Trace::CODE_FUNCTION => String(payload[:action]) + } + + attributes_to_append[OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET] = request.filtered_path if request.filtered_path != request.fullpath + + rack_span.add_attributes(attributes_to_append) + rescue StandardError => e + OpenTelemetry.handle_error(exception: e) + end + + # Invoked by ActiveSupport::Notifications at the end of the instrumentation block + # + # @param _name [String] of the event (unused) + # @param _id [String] of the event (unused) + # @param payload [Hash] the payload passed as a method argument + # @return [Hash] the payload passed as a method argument + def finish(_name, _id, payload) + rack_span = OpenTelemetry::Instrumentation::Rack.current_span + rack_span.record_exception(payload[:exception_object]) if payload[:exception_object] + rescue StandardError => e + OpenTelemetry.handle_error(exception: e) + end + end + end + end + end +end diff --git a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/instrumentation.rb b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/instrumentation.rb index 4b547a7e9..cad8a14a4 100644 --- a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/instrumentation.rb +++ b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/instrumentation.rb @@ -32,11 +32,11 @@ def gem_version end def patch - ::ActionController::Metal.prepend(Patches::ActionController::Metal) + Handlers.subscribe end def require_dependencies - require_relative 'patches/action_controller/metal' + require_relative 'handlers' end def require_railtie diff --git a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/patches/action_controller/metal.rb b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/patches/action_controller/metal.rb deleted file mode 100644 index 6e3b17c9e..000000000 --- a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/patches/action_controller/metal.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Instrumentation - module ActionPack - module Patches - module ActionController - # Module to prepend to ActionController::Metal for instrumentation - module Metal - def dispatch(name, request, response) - rack_span = OpenTelemetry::Instrumentation::Rack.current_span - if rack_span.recording? - rack_span.name = "#{self.class.name}##{name}" unless request.env['action_dispatch.exception'] - - attributes_to_append = { - OpenTelemetry::SemanticConventions::Trace::CODE_NAMESPACE => self.class.name, - OpenTelemetry::SemanticConventions::Trace::CODE_FUNCTION => String(name) - } - attributes_to_append[OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET] = request.filtered_path if request.filtered_path != request.fullpath - rack_span.add_attributes(attributes_to_append) - end - - super(name, request, response) - end - - private - - def instrumentation_config - ActionPack::Instrumentation.instance.config - end - end - end - end - end - end -end diff --git a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/version.rb b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/version.rb index a33cf47dd..ac520594e 100644 --- a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/version.rb +++ b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module ActionPack - VERSION = '0.7.1' + VERSION = '0.8.0' end end end diff --git a/instrumentation/action_pack/opentelemetry-instrumentation-action_pack.gemspec b/instrumentation/action_pack/opentelemetry-instrumentation-action_pack.gemspec index 2e23f7fef..eccdf81a6 100644 --- a/instrumentation/action_pack/opentelemetry-instrumentation-action_pack.gemspec +++ b/instrumentation/action_pack/opentelemetry-instrumentation-action_pack.gemspec @@ -36,7 +36,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rails', '>= 6.1' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/patches/action_controller/metal_test.rb b/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers/action_controller_test.rb similarity index 53% rename from instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/patches/action_controller/metal_test.rb rename to instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers/action_controller_test.rb index fe488d31c..0da17ab15 100644 --- a/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/patches/action_controller/metal_test.rb +++ b/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers/action_controller_test.rb @@ -6,19 +6,30 @@ require 'test_helper' -require_relative '../../../../../../lib/opentelemetry/instrumentation/action_pack' -require_relative '../../../../../../lib/opentelemetry/instrumentation/action_pack/patches/action_controller/metal' +require_relative '../../../../../lib/opentelemetry/instrumentation/action_pack' +require_relative '../../../../../lib/opentelemetry/instrumentation/action_pack/handlers' -describe OpenTelemetry::Instrumentation::ActionPack::Patches::ActionController::Metal do +describe OpenTelemetry::Instrumentation::ActionPack::Handlers::ActionController do include Rack::Test::Methods + let(:instrumentation) { OpenTelemetry::Instrumentation::ActionPack::Instrumentation.instance } let(:exporter) { EXPORTER } let(:spans) { exporter.finished_spans } let(:span) { exporter.finished_spans.last } let(:rails_app) { DEFAULT_RAILS_APP } + let(:config) { {} } # Clear captured spans - before { exporter.reset } + before do + OpenTelemetry::Instrumentation::ActionPack::Handlers.unsubscribe + + instrumentation.instance_variable_set(:@config, config) + instrumentation.instance_variable_set(:@installed, false) + + instrumentation.install(config) + + exporter.reset + end it 'sets the span name to the format: ControllerName#action' do get '/ok' @@ -75,18 +86,57 @@ get 'internal_server_error' _(span.name).must_equal 'ExampleController#internal_server_error' + _(span.kind).must_equal :server + _(span.status.ok?).must_equal false + + _(span.instrumentation_library.name).must_equal 'OpenTelemetry::Instrumentation::Rack' + _(span.instrumentation_library.version).must_equal OpenTelemetry::Instrumentation::Rack::VERSION + + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.host']).must_equal 'example.org' + _(span.attributes['http.scheme']).must_equal 'http' + _(span.attributes['http.target']).must_equal '/internal_server_error' + _(span.attributes['http.status_code']).must_equal 500 + _(span.attributes['http.user_agent']).must_be_nil + _(span.attributes['code.namespace']).must_equal 'ExampleController' + _(span.attributes['code.function']).must_equal 'internal_server_error' end it 'does not set the span name when an exception is raised in middleware' do get '/ok?raise_in_middleware' _(span.name).must_equal 'HTTP GET' + _(span.kind).must_equal :server + _(span.status.ok?).must_equal false + + _(span.instrumentation_library.name).must_equal 'OpenTelemetry::Instrumentation::Rack' + _(span.instrumentation_library.version).must_equal OpenTelemetry::Instrumentation::Rack::VERSION + + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.host']).must_equal 'example.org' + _(span.attributes['http.scheme']).must_equal 'http' + _(span.attributes['http.target']).must_equal '/ok?raise_in_middleware' + _(span.attributes['http.status_code']).must_equal 500 + _(span.attributes['http.user_agent']).must_be_nil + _(span.attributes['code.namespace']).must_be_nil + _(span.attributes['code.function']).must_be_nil end it 'does not set the span name when the request is redirected in middleware' do get '/ok?redirect_in_middleware' _(span.name).must_equal 'HTTP GET' + _(span.kind).must_equal :server + _(span.status.ok?).must_equal true + + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.host']).must_equal 'example.org' + _(span.attributes['http.scheme']).must_equal 'http' + _(span.attributes['http.target']).must_equal '/ok?redirect_in_middleware' + _(span.attributes['http.status_code']).must_equal 307 + _(span.attributes['http.user_agent']).must_be_nil + _(span.attributes['code.namespace']).must_be_nil + _(span.attributes['code.function']).must_be_nil end describe 'when the application has exceptions_app configured' do @@ -96,6 +146,20 @@ get 'internal_server_error' _(span.name).must_equal 'ExampleController#internal_server_error' + _(span.kind).must_equal :server + _(span.status.ok?).must_equal false + + _(span.instrumentation_library.name).must_equal 'OpenTelemetry::Instrumentation::Rack' + _(span.instrumentation_library.version).must_equal OpenTelemetry::Instrumentation::Rack::VERSION + + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.host']).must_equal 'example.org' + _(span.attributes['http.scheme']).must_equal 'http' + _(span.attributes['http.target']).must_equal '/internal_server_error' + _(span.attributes['http.status_code']).must_equal 500 + _(span.attributes['http.user_agent']).must_be_nil + _(span.attributes['code.namespace']).must_equal 'ExceptionsController' + _(span.attributes['code.function']).must_equal 'show' end end diff --git a/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers_test.rb b/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers_test.rb new file mode 100644 index 000000000..3d2419b03 --- /dev/null +++ b/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers_test.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +require_relative '../../../../lib/opentelemetry/instrumentation/action_pack' + +describe 'OpenTelemetry::Instrumentation::ActionPack::Handlers' do + let(:instrumentation) { OpenTelemetry::Instrumentation::ActionPack::Instrumentation.instance } + let(:config) { {} } + + before do + OpenTelemetry::Instrumentation::ActionPack::Handlers.unsubscribe + instrumentation.instance_variable_set(:@config, config) + instrumentation.instance_variable_set(:@installed, false) + + instrumentation.install(config) + end + + it 'success subscribe the notification' do + subscriptions = OpenTelemetry::Instrumentation::ActionPack::Handlers.instance_variable_get(:@subscriptions) + _(subscriptions.count).must_equal 1 + _(subscriptions[0].pattern).must_equal 'process_action.action_controller' + end + + it 'success unsubscribe the notification' do + OpenTelemetry::Instrumentation::ActionPack::Handlers.unsubscribe + subscriptions = OpenTelemetry::Instrumentation::ActionPack::Handlers.instance_variable_get(:@subscriptions) + _(subscriptions).must_be_nil + end +end diff --git a/instrumentation/action_view/CHANGELOG.md b/instrumentation/action_view/CHANGELOG.md index c6d8759b9..2758fae95 100644 --- a/instrumentation/action_view/CHANGELOG.md +++ b/instrumentation/action_view/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History: opentelemetry-instrumentation-action_view +### v0.7.0 / 2023-11-22 + +* BREAKING CHANGE: Drop Rails 6.0 EOL + +* ADDED: Drop Rails 6.0 EOL + ### v0.6.1 / 2023-10-16 * FIXED: Add Rails 7.1 compatibility diff --git a/instrumentation/action_view/example/trace_request_demonstration.ru b/instrumentation/action_view/example/trace_request_demonstration.ru index 58c04a8db..21177c292 100644 --- a/instrumentation/action_view/example/trace_request_demonstration.ru +++ b/instrumentation/action_view/example/trace_request_demonstration.ru @@ -26,7 +26,7 @@ require 'action_view/railtie' class TraceRequestApp < Rails::Application config.root = __dir__ config.hosts << 'example.org' - secrets.secret_key_base = 'secret_key_base' + credentials.secret_key_base = 'secret_key_base' config.eager_load = false diff --git a/instrumentation/action_view/lib/opentelemetry/instrumentation/action_view/version.rb b/instrumentation/action_view/lib/opentelemetry/instrumentation/action_view/version.rb index 9daf5e233..76b5b4867 100644 --- a/instrumentation/action_view/lib/opentelemetry/instrumentation/action_view/version.rb +++ b/instrumentation/action_view/lib/opentelemetry/instrumentation/action_view/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module ActionView - VERSION = '0.6.1' + VERSION = '0.7.0' end end end diff --git a/instrumentation/action_view/opentelemetry-instrumentation-action_view.gemspec b/instrumentation/action_view/opentelemetry-instrumentation-action_view.gemspec index fe22f24db..ae3b8d209 100644 --- a/instrumentation/action_view/opentelemetry-instrumentation-action_view.gemspec +++ b/instrumentation/action_view/opentelemetry-instrumentation-action_view.gemspec @@ -36,7 +36,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rails', '>= 6.1' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/active_job/CHANGELOG.md b/instrumentation/active_job/CHANGELOG.md index 2bccc6b3a..712d456e8 100644 --- a/instrumentation/active_job/CHANGELOG.md +++ b/instrumentation/active_job/CHANGELOG.md @@ -1,5 +1,19 @@ # Release History: opentelemetry-instrumentation-active_job +### v0.7.1 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + +### v0.7.0 / 2023-11-22 + +* BREAKING CHANGE: Drop Rails 6.0 EOL + +* ADDED: Drop Rails 6.0 EOL + +* BREAKING CHANGE: Use ActiveSupport Instrumentation instead of Monkey Patches + +* CHANGED: Use ActiveSupport Instrumentation instead of Money Patches [#677](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/677) + ### v0.6.1 / 2023-10-16 * FIXED: Add Rails 7.1 compatibility diff --git a/instrumentation/active_job/README.md b/instrumentation/active_job/README.md index 7e0c4ba6d..686247ab9 100644 --- a/instrumentation/active_job/README.md +++ b/instrumentation/active_job/README.md @@ -30,6 +30,64 @@ OpenTelemetry::SDK.configure do |c| end ``` +## Active Support Instrumentation + +Earlier versions of this instrumentation relied on registering custom `around_perform` hooks in order to deal with limitations +in `ActiveSupport::Notifications`, however those patches resulted in error reports and inconsistent behavior when combined with other gems. + +This instrumentation now relies entirely on `ActiveSupport::Notifications` and registers a custom Subscriber that listens to relevant events to report as spans. + +See the table below for details of what [Rails Framework Hook Events](https://guides.rubyonrails.org/active_support_instrumentation.html#active-job) are recorded by this instrumentation: + +| Event Name | Creates Span? | Notes | +| - | - | - | +| `enqueue_at.active_job` | :white_check_mark: | Creates an egress span with kind `producer` | +| `enqueue.active_job` | :white_check_mark: | Creates an egress span with kind `producer` | +| `enqueue_retry.active_job` | :white_check_mark: | Creates an `internal` span | +| `perform_start.active_job` | :x: | This is invoked prior to the appropriate ingress point and is therefore ignored | +| `perform.active_job` | :white_check_mark: | Creates an ingress span with kind `consumer` | +| `retry_stopped.active_job` | :white_check_mark: | Creates and `internal` span with an `exception` event | +| `discard.active_job` | :white_check_mark: | Creates and `internal` span with an `exception` event | + +## Semantic Conventions + +This instrumentation generally uses [Messaging semantic conventions](https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/) by treating job enqueuers as `producers` and workers as `consumers`. + +Internal spans are named using the name of the `ActiveSupport` event that was provided. + +Attributes that are specific to this instrumentation are recorded under `messaging.active_job.*`: + +| Attribute Name | Type | Notes | +| - | - | - | +| `code.namespace` | String | `ActiveJob` class name | +| `messaging.system` | String | Static value set to `active_job` | +| `messaging.destination` | String | Set from `ActiveJob#queue_name` | +| `messaging.message.id` | String | Set from `ActiveJob#job_id` | +| `messaging.active_job.adapter.name` | String | The name of the `ActiveJob` adapter implementation | +| `messaging.active_job.message.priority` | String | Present when set by the client from `ActiveJob#priority` | +| `messaging.active_job.message.provider_job_id` | String | Present if the underlying adapter has backend specific message ids | + +## Differences between ActiveJob versions + +### ActiveJob 6.1 + +`perform.active_job` events do not include timings for `ActiveJob` callbacks therefore time spent in `before` and `after` hooks will be missing + +### ActiveJob 7+ + +`perform.active_job` no longer includes exceptions handled using `rescue_from` in the payload. + +In order to preserve this behavior you will have to update the span yourself, e.g. + +```ruby + rescue_from MyCustomError do |e| + # Custom code to handle the error + span = OpenTelemetry::Instrumentation::ActiveJob.current_span + span.record_exception(e) + span.status = OpenTelemetry::Trace::Status.error('Job failed') + end +``` + ## Examples Example usage can be seen in the `./example/active_job.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/active_job/example/active_job.rb) diff --git a/instrumentation/active_job/example/Gemfile b/instrumentation/active_job/example/Gemfile deleted file mode 100644 index 103826612..000000000 --- a/instrumentation/active_job/example/Gemfile +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -source 'https://rubygems.org' - -gem 'activejob' -gem 'opentelemetry-api' -gem 'opentelemetry-instrumentation-active_job' -gem 'opentelemetry-sdk' diff --git a/instrumentation/active_job/example/active_job.rb b/instrumentation/active_job/example/active_job.rb index 808a17b44..71cd31646 100644 --- a/instrumentation/active_job/example/active_job.rb +++ b/instrumentation/active_job/example/active_job.rb @@ -4,30 +4,115 @@ # # SPDX-License-Identifier: Apache-2.0 +ENV['OTEL_SERVICE_NAME'] ||= 'otel-active-job-demo' require 'rubygems' -require 'bundler/setup' -require 'active_job' +require 'bundler/inline' -Bundler.require +gemfile do + source 'https://rubygems.org' + gem 'activejob', '~> 7.0.0', require: 'active_job' + gem 'opentelemetry-instrumentation-active_job', path: '../' + gem 'opentelemetry-sdk' + gem 'opentelemetry-exporter-otlp' +end +ENV['OTEL_LOG_LEVEL'] ||= 'fatal' ENV['OTEL_TRACES_EXPORTER'] ||= 'console' OpenTelemetry::SDK.configure do |c| c.use 'OpenTelemetry::Instrumentation::ActiveJob' + at_exit { OpenTelemetry.tracer_provider.shutdown } +end + +class FailingJob < ::ActiveJob::Base + queue_as :demo + def perform + raise 'this job failed' + end +end + +class FailingRetryJob < ::ActiveJob::Base + queue_as :demo + + retry_on StandardError, attempts: 2, wait: 0 + def perform + raise 'this job failed' + end end +class RetryJob < ::ActiveJob::Base + queue_as :demo + + retry_on StandardError, attempts: 3, wait: 0 + def perform + if executions < 3 + raise 'this job failed' + else + puts <<~EOS + + -------------------------------------------------- + Done Retrying! + -------------------------------------------------- + + EOS + end + end +end + +class DiscardJob < ::ActiveJob::Base + queue_as :demo + + class DiscardError < StandardError; end + + discard_on DiscardError + + def perform + raise DiscardError, 'this job failed' + end +end + +EXAMPLE_TRACER = OpenTelemetry.tracer_provider.tracer('activejob-example', '1.0') + class TestJob < ::ActiveJob::Base def perform - puts <<~EOS + EXAMPLE_TRACER.in_span("custom span") do + puts <<~EOS + + -------------------------------------------------- + The computer is doing some work, beep beep boop. + -------------------------------------------------- + + EOS + end + end +end + +class DoItNowJob < ::ActiveJob::Base + def perform + $stderr.puts <<~EOS -------------------------------------------------- - The computer is doing some work, beep beep boop. + Called with perform_now! -------------------------------------------------- EOS end end +class BatchJob < ::ActiveJob::Base + def perform + TestJob.perform_later + FailingJob.perform_later + FailingRetryJob.perform_later + RetryJob.perform_later + DiscardJob.perform_later + end +end + ::ActiveJob::Base.queue_adapter = :async -TestJob.perform_later -sleep 0.1 # To ensure we see both spans! +EXAMPLE_TRACER.in_span('run-jobs') do + DoItNowJob.perform_now + BatchJob.perform_later +end + +sleep 5 # allow the job to complete diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job.rb index 259425a9c..b158de4ca 100644 --- a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job.rb +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job.rb @@ -11,6 +11,39 @@ module OpenTelemetry module Instrumentation # Contains the OpenTelemetry instrumentation for the ActiveJob gem module ActiveJob + extend self + + CURRENT_SPAN_KEY = Context.create_key('current-span') + private_constant :CURRENT_SPAN_KEY + + # Returns the current span from the current or provided context + # + # @param [optional Context] context The context to lookup the current + # {Span} from. Defaults to Context.current + def current_span(context = nil) + context ||= Context.current + context.value(CURRENT_SPAN_KEY) || OpenTelemetry::Trace::Span::INVALID + end + + # Returns a context containing the span, derived from the optional parent + # context, or the current context if one was not provided. + # + # @param [optional Context] context The context to use as the parent for + # the returned context + def context_with_span(span, parent_context: Context.current) + parent_context.set_value(CURRENT_SPAN_KEY, span) + end + + # Activates/deactivates the Span within the current Context, which makes the "current span" + # available implicitly. + # + # On exit, the Span that was active before calling this method will be reactivated. + # + # @param [Span] span the span to activate + # @yield [span, context] yields span and a context containing the span to the block. + def with_span(span) + Context.with_value(CURRENT_SPAN_KEY, span) { |c, s| yield s, c } + end end end end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers.rb new file mode 100644 index 000000000..7eafb9425 --- /dev/null +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require_relative 'mappers/attribute' +require_relative 'handlers/default' +require_relative 'handlers/enqueue' +require_relative 'handlers/perform' + +module OpenTelemetry + module Instrumentation + module ActiveJob + # Module that contains custom event handlers, which are used to generate spans per event + module Handlers + module_function + + # Subscribes Event Handlers to relevant ActiveJob notifications + # + # The following events are recorded as spans: + # - enqueue + # - enqueue_at + # - enqueue_retry + # - perform + # - retry_stopped + # - discard + # + # Ingress and Egress spans (perform, enqueue, enqueue_at) use Messaging semantic conventions for naming the span, + # while internal spans keep their ActiveSupport event name. + # + # @note this method is not thread safe and should not be used in a multi-threaded context + # @note Why no perform_start? + # This event causes much heartache as it is the first in a series of events that is triggered. + # It should not be the ingress span because it does not measure anything. + # https://github.com/rails/rails/blob/v6.1.7.6/activejob/lib/active_job/instrumentation.rb#L14 + # https://github.com/rails/rails/blob/v7.0.8/activejob/lib/active_job/instrumentation.rb#L19 + def subscribe + return unless Array(@subscriptions).empty? + + mapper = Mappers::Attribute.new + config = ActiveJob::Instrumentation.instance.config + parent_span_provider = OpenTelemetry::Instrumentation::ActiveJob + + # TODO, use delegation instead of inheritance + default_handler = Handlers::Default.new(parent_span_provider, mapper, config) + enqueue_handler = Handlers::Enqueue.new(parent_span_provider, mapper, config) + perform_handler = Handlers::Perform.new(parent_span_provider, mapper, config) + + handlers_by_pattern = { + 'enqueue' => enqueue_handler, + 'enqueue_at' => enqueue_handler, + 'enqueue_retry' => default_handler, + 'perform' => perform_handler, + 'retry_stopped' => default_handler, + 'discard' => default_handler + } + + @subscriptions = handlers_by_pattern.map do |key, handler| + ::ActiveSupport::Notifications.subscribe("#{key}.active_job", handler) + end + end + + # Removes Event Handler Subscriptions for ActiveJob notifications + # @note this method is not thread-safe and should not be used in a multi-threaded context + def unsubscribe + @subscriptions&.each { |subscriber| ActiveSupport::Notifications.unsubscribe(subscriber) } + @subscriptions = nil + end + end + end + end +end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers/default.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers/default.rb new file mode 100644 index 000000000..3c6b6aa7d --- /dev/null +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers/default.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module ActiveJob + module Handlers + # Default handler to create internal spans for events + # This class provides default template methods that derived classes may override to generate spans and register contexts. + class Default + # @param parent_span_provider [Object] provides access to the top most parent span (usually the ingress span) + # @param mapper [Callable] converts ActiveSupport::Notifications payloads to span attributes + # @param config [Hash] of instrumentation options + def initialize(parent_span_provider, mapper, config) + @mapper = mapper + @config = config + @parent_span_provider = parent_span_provider + end + + # Invoked by ActiveSupport::Notifications at the start of the instrumentation block + # It amends the otel context of a Span and Context tokens to the payload + # + # @param name [String] of the Event + # @param id [String] of the event + # @param payload [Hash] containing job run information + # @return [Hash] the payload passed as a method argument + def start(name, id, payload) + payload.merge!(__otel: start_span(name, id, payload)) + rescue StandardError => e + OpenTelemetry.handle_error(exception: e) + end + + # Creates a span and registers it with the current context + # + # @param name [String] of the Event + # @param id [String] of the event + # @param payload [Hash] containing job run information + # @return [Hash] with the span and generated context tokens + def start_span(name, _id, payload) + span = tracer.start_span(name, attributes: @mapper.call(payload)) + tokens = [OpenTelemetry::Context.attach(OpenTelemetry::Trace.context_with_span(span))] + + { span: span, ctx_tokens: tokens } + end + + # Creates a span and registers it with the current context + # + # @param _name [String] of the Event (unused) + # @param _id [String] of the event (unused) + # @param payload [Hash] containing job run information + # @return [Hash] with the span and generated context tokens + def finish(_name, _id, payload) + otel = payload.delete(:__otel) + span = otel&.fetch(:span) + tokens = otel&.fetch(:ctx_tokens) + + on_exception((payload[:error] || payload[:exception_object]), span) + rescue StandardError => e + OpenTelemetry.handle_error(exception: e) + ensure + finish_span(span, tokens) + end + + # Finishes the provided spans and also detaches the associated contexts + # + # @param span [OpenTelemetry::Trace::Span] + # @param tokens [Array] to unregister + def finish_span(span, tokens) + # closes the span after all attributes have been finalized + begin + if span&.recording? + span.status = OpenTelemetry::Trace::Status.ok if span.status.code == OpenTelemetry::Trace::Status::UNSET + span.finish + end + rescue StandardError => e + OpenTelemetry.handle_error(exception: e) + end + + # pops the context stack + tokens&.reverse&.each do |token| + OpenTelemetry::Context.detach(token) + rescue StandardError => e + OpenTelemetry.handle_error(exception: e) + end + end + + # Records exceptions on spans and sets Span statuses to `Error` + # + # Handled exceptions are recorded on internal spans related to the event. E.g. `discard` events are recorded on the `discard.active_job` span + # Handled exceptions _are not_ copied to the ingress span, but it does set the status to `Error` making it easier to know that a job has failed + # Unhandled exceptions bubble up to the ingress span and are recorded there. + # + # @param [Exception] exception to report as a Span Event + # @param [OpenTelemetry::Trace::Span] the currently active span used to record the exception and set the status + def on_exception(exception, span) + return unless exception && span + + span.record_exception(exception) + span.status = + @parent_span_provider.current_span.status = + OpenTelemetry::Trace::Status.error("Unexpected ActiveJob Error #{exception.class.name}") + end + + def tracer + OpenTelemetry::Instrumentation::ActiveJob::Instrumentation.instance.tracer + end + end + end + end + end +end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers/enqueue.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers/enqueue.rb new file mode 100644 index 000000000..7dace8a95 --- /dev/null +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers/enqueue.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module ActiveJob + module Handlers + # Handles `enqueue.active_job` and `enqueue_at.active_job` to generate egress spans + class Enqueue < Default + def initialize(...) + super + @span_name_formatter = if @config[:span_naming] == :job_class + ->(job) { "#{job.class.name} publish" } + else + ->(job) { "#{job.queue_name} publish" } + end + end + + # Overrides the `Default#start_span` method to create an egress span + # and registers it with the current context + # + # @param name [String] of the Event + # @param id [String] of the event + # @param payload [Hash] containing job run information + # @return [Hash] with the span and generated context tokens + def start_span(name, _id, payload) + job = payload.fetch(:job) + span = tracer.start_span(@span_name_formatter.call(job), kind: :producer, attributes: @mapper.call(payload)) + tokens = [OpenTelemetry::Context.attach(OpenTelemetry::Trace.context_with_span(span))] + OpenTelemetry.propagation.inject(job.__otel_headers) # This must be transmitted over the wire + { span: span, ctx_tokens: tokens } + end + end + end + end + end +end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers/perform.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers/perform.rb new file mode 100644 index 000000000..6dd7e2e28 --- /dev/null +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/handlers/perform.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module ActiveJob + module Handlers + # Handles perform.active_job to generate ingress spans + class Perform < Default + def initialize(...) + super + @span_name_formatter = if @config[:span_naming] == :job_class + ->(job) { "#{job.class.name} process" } + else + ->(job) { "#{job.queue_name} process" } + end + end + + # Overrides the `Default#start_span` method to create an ingress span + # and registers it with the current context + # + # @param name [String] of the Event + # @param id [String] of the event + # @param payload [Hash] containing job run information + # @return [Hash] with the span and generated context tokens + def start_span(name, _id, payload) + tokens = [] + job = payload.fetch(:job) + parent_context = OpenTelemetry.propagation.extract(job.__otel_headers) + + span_name = @span_name_formatter.call(job) + + # TODO: Refactor into a propagation strategy + propagation_style = @config[:propagation_style] + if propagation_style == :child + tokens << OpenTelemetry::Context.attach(parent_context) + span = tracer.start_span(span_name, kind: :consumer, attributes: @mapper.call(payload)) + else + span_context = OpenTelemetry::Trace.current_span(parent_context).context + links = [OpenTelemetry::Trace::Link.new(span_context)] if span_context.valid? && propagation_style == :link + span = tracer.start_root_span(span_name, kind: :consumer, attributes: @mapper.call(payload), links: links) + end + + tokens.concat(attach_consumer_context(span)) + + { span: span, ctx_tokens: tokens } + end + + # This method attaches a span to multiple contexts: + # 1. Registers the ingress span as the top level ActiveJob span. + # This is used later to enrich the ingress span in children, e.g. setting span status to error when a child event like `discard` terminates due to an error + # 2. Registers the ingress span as the "active" span, which is the default behavior of the SDK. + # @param span [OpenTelemetry::Trace::Span] the currently active span used to record the exception and set the status + # @return [Array] Context tokens that must be detached when finished + def attach_consumer_context(span) + consumer_context = OpenTelemetry::Trace.context_with_span(span) + internal_context = OpenTelemetry::Instrumentation::ActiveJob.context_with_span(span, parent_context: consumer_context) + + [consumer_context, internal_context].map { |context| OpenTelemetry::Context.attach(context) } + end + end + end + end + end +end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/instrumentation.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/instrumentation.rb index 20f3cac57..d9c6063c5 100644 --- a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/instrumentation.rb +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/instrumentation.rb @@ -17,7 +17,7 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base end present do - defined?(::ActiveJob) + defined?(::ActiveJob) && defined?(::ActiveSupport) end compatible do @@ -64,12 +64,13 @@ def gem_version def require_dependencies require_relative 'patches/base' - require_relative 'patches/active_job_callbacks' + require_relative 'handlers' end def patch_activejob - ::ActiveJob::Base.prepend(Patches::Base) - ::ActiveJob::Base.prepend(Patches::ActiveJobCallbacks) + ::ActiveJob::Base.prepend(Patches::Base) unless ::ActiveJob::Base <= Patches::Base + + Handlers.subscribe end end end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/mappers/attribute.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/mappers/attribute.rb new file mode 100644 index 000000000..d62405b46 --- /dev/null +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/mappers/attribute.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module ActiveJob + module Mappers + # Maps ActiveJob Attributes to Semantic Conventions + class Attribute + # Generates a set of attributes to add to a span using + # general and messaging semantic conventions as well as + # using `rails.active_job.*` namespace for custom attributes + # + # @param payload [Hash] of an ActiveSupport::Notifications payload + # @return [Hash] of semantic attributes + def call(payload) + job = payload.fetch(:job) + + otel_attributes = { + 'code.namespace' => job.class.name, + 'messaging.system' => 'active_job', + 'messaging.destination' => job.queue_name, + 'messaging.message.id' => job.job_id, + 'messaging.active_job.adapter.name' => job.class.queue_adapter_name + } + + # Not all adapters generate or provide back end specific ids for messages + otel_attributes['messaging.active_job.message.provider_job_id'] = job.provider_job_id.to_s if job.provider_job_id + # This can be problematic if programs use invalid attribute types like Symbols for priority instead of using Integers. + otel_attributes['messaging.active_job.message.priority'] = job.priority.to_s if job.priority + + otel_attributes.compact! + + otel_attributes + end + end + end + end + end +end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/patches/active_job_callbacks.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/patches/active_job_callbacks.rb deleted file mode 100644 index 973025352..000000000 --- a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/patches/active_job_callbacks.rb +++ /dev/null @@ -1,96 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Instrumentation - module ActiveJob - module Patches - # Module to prepend to ActiveJob::Base for instrumentation. - module ActiveJobCallbacks - def self.prepended(base) - base.class_eval do - around_enqueue do |job, block| - span_kind = job.class.queue_adapter_name == 'inline' ? :client : :producer - span_name = "#{otel_config[:span_naming] == :job_class ? job.class : job.queue_name} publish" - span_attributes = job_attributes(job) - otel_tracer.in_span(span_name, attributes: span_attributes, kind: span_kind) do - OpenTelemetry.propagation.inject(job.metadata) - block.call - end - end - end - end - - def perform_now - span_kind = self.class.queue_adapter_name == 'inline' ? :server : :consumer - span_name = "#{otel_config[:span_naming] == :job_class ? self.class : queue_name} process" - span_attributes = job_attributes(self).merge('messaging.operation' => 'process', 'code.function' => 'perform_now') - executions_count = (executions || 0) + 1 # because we run before the count is incremented in ActiveJob::Execution - - extracted_context = OpenTelemetry.propagation.extract(metadata) - OpenTelemetry::Context.with_current(extracted_context) do - if otel_config[:propagation_style] == :child - otel_tracer.in_span(span_name, attributes: span_attributes, kind: span_kind) do |span| - span.set_attribute('messaging.active_job.executions', executions_count) - super - end - else - span_links = [] - if otel_config[:propagation_style] == :link - span_context = OpenTelemetry::Trace.current_span(extracted_context).context - span_links << OpenTelemetry::Trace::Link.new(span_context) if span_context.valid? - end - - root_span = otel_tracer.start_root_span(span_name, attributes: span_attributes, links: span_links, kind: span_kind) - OpenTelemetry::Trace.with_span(root_span) do |span| - span.set_attribute('messaging.active_job.executions', executions_count) - super - rescue Exception => e # rubocop:disable Lint/RescueException - span.record_exception(e) - span.status = OpenTelemetry::Trace::Status.error("Unhandled exception of type: #{e.class}") - raise e - ensure - root_span.finish - end - end - end - ensure - # We may be in a job system (eg: resque) that forks and kills worker processes often. - # We don't want to lose spans by not flushing any span processors, so we optionally force it here. - OpenTelemetry.tracer_provider.force_flush if otel_config[:force_flush] - end - - private - - def job_attributes(job) - otel_attributes = { - 'code.namespace' => job.class.name, - 'messaging.destination_kind' => 'queue', - 'messaging.system' => job.class.queue_adapter_name, - 'messaging.destination' => job.queue_name, - 'messaging.message_id' => job.job_id, - 'messaging.active_job.provider_job_id' => job.provider_job_id, - 'messaging.active_job.scheduled_at' => job.scheduled_at&.to_f, - 'messaging.active_job.priority' => job.priority - } - - otel_attributes['net.transport'] = 'inproc' if %w[async inline].include?(job.class.queue_adapter_name) - - otel_attributes.compact - end - - def otel_tracer - ActiveJob::Instrumentation.instance.tracer - end - - def otel_config - ActiveJob::Instrumentation.instance.config - end - end - end - end - end -end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/patches/base.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/patches/base.rb index 42a3626d6..fc61f34aa 100644 --- a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/patches/base.rb +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/patches/base.rb @@ -12,22 +12,33 @@ module Patches module Base def self.prepended(base) base.class_eval do - attr_accessor :metadata + attr_accessor :__otel_headers end end - def initialize(*args) - @metadata = {} + def initialize(...) + @__otel_headers = {} super end - ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true) def serialize - super.merge('metadata' => serialize_arguments(metadata)) + message = super + + begin + message.merge!('__otel_headers' => serialize_arguments(@__otel_headers)) + rescue StandardError => e + OpenTelemetry.handle_error(exception: e) + end + + message end def deserialize(job_data) - self.metadata = deserialize_arguments(job_data['metadata'] || []).to_h + begin + @__otel_headers = deserialize_arguments(job_data.delete('__otel_headers') || []).to_h + rescue StandardError => e + OpenTelemetry.handle_error(exception: e) + end super end end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/version.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/version.rb index 2a4dc878d..2b7b6effe 100644 --- a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/version.rb +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module ActiveJob - VERSION = '0.6.1' + VERSION = '0.7.1' end end end diff --git a/instrumentation/active_job/opentelemetry-instrumentation-active_job.gemspec b/instrumentation/active_job/opentelemetry-instrumentation-active_job.gemspec index 0699b8621..2039a1576 100644 --- a/instrumentation/active_job/opentelemetry-instrumentation-active_job.gemspec +++ b/instrumentation/active_job/opentelemetry-instrumentation-active_job.gemspec @@ -34,9 +34,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'pry' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/active_job/test/instrumentation/active_job/patches/active_job_callbacks_test.rb b/instrumentation/active_job/test/instrumentation/active_job/patches/active_job_callbacks_test.rb deleted file mode 100644 index c5c59d95e..000000000 --- a/instrumentation/active_job/test/instrumentation/active_job/patches/active_job_callbacks_test.rb +++ /dev/null @@ -1,421 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'test_helper' - -require_relative '../../../../lib/opentelemetry/instrumentation/active_job' - -describe OpenTelemetry::Instrumentation::ActiveJob::Patches::ActiveJobCallbacks do - let(:instrumentation) { OpenTelemetry::Instrumentation::ActiveJob::Instrumentation.instance } - # Technically these are the defaults. But ActiveJob seems to act oddly if you re-install - # the instrumentation over and over again - so we manipulate instance variables to - # reset between tests, and that means we should set the defaults here. - let(:config) { { propagation_style: :link, force_flush: false, span_naming: :queue } } - let(:exporter) { EXPORTER } - let(:spans) { exporter.finished_spans } - let(:publish_span) { spans.find { |s| s.name == 'default publish' } } - let(:process_span) { spans.find { |s| s.name == 'default process' } } - - before do - instrumentation.instance_variable_set(:@config, config) - exporter.reset - - ActiveJob::Base.queue_adapter = :async - ActiveJob::Base.queue_adapter.immediate = true - end - - after do - begin - ActiveJob::Base.queue_adapter.shutdown - rescue StandardError - nil - end - ActiveJob::Base.queue_adapter = :inline - instrumentation.instance_variable_set(:@config, config) - end - - describe 'perform_later' do - it 'traces enqueuing and processing the job' do - TestJob.perform_later - - _(publish_span).wont_be_nil - _(process_span).wont_be_nil - end - end - - describe 'perform_now' do - it 'only traces processing the job' do - TestJob.perform_now - - _(publish_span).must_be_nil - _(process_span).wont_be_nil - _(process_span.attributes['code.namespace']).must_equal('TestJob') - _(process_span.attributes['code.function']).must_equal('perform_now') - end - end - - describe 'compatibility' do - it 'works with positional args' do - _(PositionalOnlyArgsJob.perform_now('arg1')).must_be_nil # Make sure this runs without raising an error - end - - it 'works with keyword args' do - _(KeywordOnlyArgsJob.perform_now(keyword2: :keyword2)).must_be_nil # Make sure this runs without raising an error - end - - it 'works with mixed args' do - _(MixedArgsJob.perform_now('arg1', 'arg2', keyword2: :keyword2)).must_be_nil # Make sure this runs without raising an error - end - end - - describe 'exception handling' do - it 'sets span status to error' do - _ { ExceptionJob.perform_now }.must_raise StandardError, 'This job raises an exception' - _(process_span.status.code).must_equal OpenTelemetry::Trace::Status::ERROR - _(process_span.status.description).must_equal 'Unhandled exception of type: StandardError' - end - - it 'records the exception' do - _ { ExceptionJob.perform_now }.must_raise StandardError, 'This job raises an exception' - _(process_span.events.first.name).must_equal 'exception' - _(process_span.events.first.attributes['exception.type']).must_equal 'StandardError' - _(process_span.events.first.attributes['exception.message']).must_equal 'This job raises an exception' - end - end - - describe 'span kind' do - it 'sets correct span kinds for inline jobs' do - begin - ActiveJob::Base.queue_adapter.shutdown - rescue StandardError - nil - end - ActiveJob::Base.queue_adapter = :inline - - TestJob.perform_later - - _(publish_span.kind).must_equal(:client) - _(process_span.kind).must_equal(:server) - end - - it 'sets correct span kinds for all other jobs' do - TestJob.perform_later - - _(publish_span.kind).must_equal(:producer) - _(process_span.kind).must_equal(:consumer) - end - end - - describe 'attributes' do - it 'sets the messaging.operation attribute only when processing the job' do - TestJob.perform_later - - _(publish_span.attributes['messaging.operation']).must_be_nil - _(process_span.attributes['messaging.operation']).must_equal('process') - end - - describe 'net.transport' do - it 'is sets correctly for inline jobs' do - TestJob.perform_later - - [publish_span, process_span].each do |span| - _(span.attributes['net.transport']).must_equal('inproc') - end - end - - it 'is set correctly for async jobs' do - TestJob.perform_later - - [publish_span, process_span].each do |span| - _(span.attributes['net.transport']).must_equal('inproc') - end - end - end - - describe 'messaging.active_job.priority' do - it 'is unset for unprioritized jobs' do - TestJob.perform_later - - [publish_span, process_span].each do |span| - _(span.attributes['messaging.active_job.priority']).must_be_nil - end - end - - it 'is set for jobs with a priority' do - TestJob.set(priority: 1).perform_later - - [publish_span, process_span].each do |span| - _(span.attributes['messaging.active_job.priority']).must_equal(1) - end - end - end - - describe 'messaging.active_job.scheduled_at' do - it 'is unset for jobs that do not specify a wait time' do - TestJob.perform_later - - [publish_span, process_span].each do |span| - _(span.attributes['messaging.active_job.scheduled_at']).must_be_nil - end - end - - it 'records the scheduled at time for apps running Rails 7.1 and newer' do - skip 'scheduled jobs behave differently in Rails 7.1+' if ActiveJob.version < Gem::Version.new('7.1') - - job = TestJob.set(wait: 0.second).perform_later - - _(publish_span.attributes['messaging.active_job.scheduled_at']).must_equal(job.scheduled_at.to_f) - _(process_span.attributes['messaging.active_job.scheduled_at']).must_equal(job.scheduled_at.to_f) - end - - it 'records the scheduled at time for apps running Rails 7.0 or older' do - skip 'scheduled jobs behave differently in Rails 7.1+' if ActiveJob.version >= Gem::Version.new('7.1') - - job = TestJob.set(wait: 0.second).perform_later - - _(publish_span.attributes['messaging.active_job.scheduled_at']).must_equal(job.scheduled_at.to_f) - _(process_span.attributes['messaging.active_job.scheduled_at']).must_be_nil - end - end - - describe 'messaging.system' do - it 'is set correctly for the inline adapter' do - begin - ActiveJob::Base.queue_adapter.shutdown - rescue StandardError - nil - end - - ActiveJob::Base.queue_adapter = :inline - TestJob.perform_later - - [publish_span, process_span].each do |span| - _(span.attributes['messaging.system']).must_equal('inline') - end - end - - it 'is set correctly for the async adapter' do - TestJob.perform_later - - [publish_span, process_span].each do |span| - _(span.attributes['messaging.system']).must_equal('async') - end - end - end - - describe 'messaging.active_job.executions' do - it 'is 1 for a normal job that does not retry' do - TestJob.perform_now - _(process_span.attributes['messaging.active_job.executions']).must_equal(1) - end - - it 'tracks correctly for jobs that do retry' do - begin - RetryJob.perform_later - rescue StandardError - nil - end - - executions = spans.filter { |s| s.kind == :consumer }.sum { |s| s.attributes['messaging.active_job.executions'] } - _(executions).must_equal(3) # total of 3 runs. The initial and 2 retries. - end - end - - describe 'messaging.active_job.provider_job_id' do - it 'is empty for a job that do not sets provider_job_id' do - TestJob.perform_now - _(process_span.attributes['messaging.active_job.provider_job_id']).must_be_nil - end - - it 'sets the correct value if provider_job_id is provided' do - job = TestJob.perform_later - _(process_span.attributes['messaging.active_job.provider_job_id']).must_equal(job.provider_job_id) - end - end - - it 'generally sets other attributes as expected' do - job = TestJob.perform_later - - [publish_span, process_span].each do |span| - _(span.attributes['code.namespace']).must_equal('TestJob') - _(span.attributes['messaging.destination_kind']).must_equal('queue') - _(span.attributes['messaging.system']).must_equal('async') - _(span.attributes['messaging.message_id']).must_equal(job.job_id) - end - end - end - - describe 'span_naming option' do - describe 'when queue - default' do - it 'names spans according to the job queue' do - TestJob.set(queue: :foo).perform_later - publish_span = exporter.finished_spans.find { |s| s.name == 'foo publish' } - _(publish_span).wont_be_nil - - process_span = exporter.finished_spans.find { |s| s.name == 'foo process' } - _(process_span).wont_be_nil - end - end - - describe 'when job_class' do - let(:config) { { propagation_style: :link, span_naming: :job_class } } - - it 'names span according to the job class' do - TestJob.set(queue: :foo).perform_later - publish_span = exporter.finished_spans.find { |s| s.name == 'TestJob publish' } - _(publish_span).wont_be_nil - - process_span = exporter.finished_spans.find { |s| s.name == 'TestJob process' } - _(process_span).wont_be_nil - end - end - end - - describe 'force_flush option' do - let(:mock_tracer_provider) do - mock_tracer_provider = Minitest::Mock.new - mock_tracer_provider.expect(:force_flush, true) - - mock_tracer_provider - end - - describe 'false - default' do - it 'does not forcibly flush the tracer' do - OpenTelemetry.stub(:tracer_provider, mock_tracer_provider) do - TestJob.perform_later - end - - # We *do not* actually force flush in this case, so we expect the mock - # to fail validation - we will not actually call the mocked force_flush method. - expect { mock_tracer_provider.verify }.must_raise MockExpectationError - end - end - - describe 'true' do - let(:config) { { propagation_style: :link, force_flush: true, span_naming: :job_class } } - it 'does forcibly flush the tracer' do - OpenTelemetry.stub(:tracer_provider, mock_tracer_provider) do - TestJob.perform_later - end - - # Nothing should raise, the mock should be successful, we should have flushed. - mock_tracer_provider.verify - end - end - end - - describe 'propagation_style option' do - describe 'link - default' do - # The inline job adapter executes the job immediately upon enqueuing it - # so we can't actually use that in these tests - the actual Context.current at time - # of execution *will* be the context where the job was enqueued, because rails - # ends up doing job.around_enqueue { job.around_perform { block } } inline. - it 'creates span links in separate traces' do - TestJob.perform_later - - _(publish_span.trace_id).wont_equal(process_span.trace_id) - - _(process_span.total_recorded_links).must_equal(1) - _(process_span.links[0].span_context.trace_id).must_equal(publish_span.trace_id) - _(process_span.links[0].span_context.span_id).must_equal(publish_span.span_id) - end - - it 'propagates baggage' do - ctx = OpenTelemetry::Baggage.set_value('testing_baggage', 'it_worked') - OpenTelemetry::Context.with_current(ctx) do - BaggageJob.perform_later - end - - _(publish_span.trace_id).wont_equal(process_span.trace_id) - - _(process_span.total_recorded_links).must_equal(1) - _(process_span.links[0].span_context.trace_id).must_equal(publish_span.trace_id) - _(process_span.links[0].span_context.span_id).must_equal(publish_span.span_id) - _(process_span.attributes['success']).must_equal(true) - end - end - - describe 'when configured to do parent/child spans' do - let(:config) { { propagation_style: :child, span_naming: :queue } } - - it 'creates a parent/child relationship' do - TestJob.perform_later - - _(process_span.total_recorded_links).must_equal(0) - - _(publish_span.trace_id).must_equal(process_span.trace_id) - _(process_span.parent_span_id).must_equal(publish_span.span_id) - end - - it 'propagates baggage' do - ctx = OpenTelemetry::Baggage.set_value('testing_baggage', 'it_worked') - OpenTelemetry::Context.with_current(ctx) do - BaggageJob.perform_later - end - _(process_span.total_recorded_links).must_equal(0) - - _(publish_span.trace_id).must_equal(process_span.trace_id) - _(process_span.parent_span_id).must_equal(publish_span.span_id) - _(process_span.attributes['success']).must_equal(true) - end - end - - describe 'when explicitly configure for no propagation' do - let(:config) { { propagation_style: :none, span_naming: :queue } } - - it 'skips link creation and does not create parent/child relationship' do - TestJob.perform_later - - _(process_span.total_recorded_links).must_equal(0) - - _(publish_span.trace_id).wont_equal(process_span.trace_id) - _(process_span.parent_span_id).wont_equal(publish_span.span_id) - end - - it 'still propagates baggage' do - ctx = OpenTelemetry::Baggage.set_value('testing_baggage', 'it_worked') - OpenTelemetry::Context.with_current(ctx) do - BaggageJob.perform_later - end - - _(process_span.total_recorded_links).must_equal(0) - - _(publish_span.trace_id).wont_equal(process_span.trace_id) - _(process_span.parent_span_id).wont_equal(publish_span.span_id) - _(process_span.attributes['success']).must_equal(true) - end - end - end - - describe 'active_job callbacks' do - it 'makes the tracing context available in before_perform callbacks' do - CallbacksJob.perform_now - - _(CallbacksJob.context_before).wont_be_nil - _(CallbacksJob.context_before).must_be :valid? - end - - it 'makes the tracing context available in after_perform callbacks' do - CallbacksJob.perform_now - - _(CallbacksJob.context_after).wont_be_nil - _(CallbacksJob.context_after).must_be :valid? - end - end - - describe 'perform.active_job notifications' do - it 'makes the tracing context available in notifications' do - context = nil - callback = proc { context = OpenTelemetry::Trace.current_span.context } - ActiveSupport::Notifications.subscribed(callback, 'perform.active_job') do - TestJob.perform_now - end - - _(context).wont_be_nil - _(context).must_be :valid? - end - end -end diff --git a/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers/discard_test.rb b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers/discard_test.rb new file mode 100644 index 000000000..89a32b6c6 --- /dev/null +++ b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers/discard_test.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +require_relative '../../../../../lib/opentelemetry/instrumentation/active_job' + +describe 'OpenTelemetry::Instrumentation::ActiveJob::Handlers::Discard' do + let(:instrumentation) { OpenTelemetry::Instrumentation::ActiveJob::Instrumentation.instance } + let(:config) { { propagation_style: :link, span_naming: :queue } } + let(:exporter) { EXPORTER } + let(:spans) { exporter.finished_spans } + let(:publish_span) { spans.find { |s| s.name == 'default publish' } } + let(:process_span) { spans.find { |s| s.name == 'default process' } } + let(:discard_span) { spans.find { |s| s.name == 'discard.active_job' } } + + before do + OpenTelemetry::Instrumentation::ActiveJob::Handlers.unsubscribe + instrumentation.instance_variable_set(:@config, config) + instrumentation.instance_variable_set(:@installed, false) + + instrumentation.install(config) + ActiveJob::Base.queue_adapter = :async + ActiveJob::Base.queue_adapter.immediate = true + + exporter.reset + end + + after do + begin + ActiveJob::Base.queue_adapter.shutdown + rescue StandardError + nil + end + ActiveJob::Base.queue_adapter = :inline + end + + describe 'exception handling' do + it 'sets discard span status to error' do + DiscardJob.perform_later + + _(process_span.status.code).must_equal OpenTelemetry::Trace::Status::ERROR + _(process_span.status.description).must_equal 'Unexpected ActiveJob Error DiscardJob::DiscardError' + + _(discard_span.status.code).must_equal OpenTelemetry::Trace::Status::ERROR + _(discard_span.status.description).must_equal 'Unexpected ActiveJob Error DiscardJob::DiscardError' + _(discard_span.events.first.name).must_equal 'exception' + _(discard_span.events.first.attributes['exception.type']).must_equal 'DiscardJob::DiscardError' + _(discard_span.events.first.attributes['exception.message']).must_equal 'discard me' + end + end +end diff --git a/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers/perform_test.rb b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers/perform_test.rb new file mode 100644 index 000000000..cf4c9b976 --- /dev/null +++ b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers/perform_test.rb @@ -0,0 +1,264 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +require_relative '../../../../../lib/opentelemetry/instrumentation/active_job' + +describe OpenTelemetry::Instrumentation::ActiveJob::Handlers::Perform do + let(:instrumentation) { OpenTelemetry::Instrumentation::ActiveJob::Instrumentation.instance } + let(:config) { { propagation_style: :link, span_naming: :queue } } + let(:exporter) { EXPORTER } + let(:spans) { exporter.finished_spans } + let(:publish_span) { spans.find { |s| s.name == 'default publish' } } + let(:process_span) { spans.find { |s| s.name == 'default process' } } + + before do + OpenTelemetry::Instrumentation::ActiveJob::Handlers.unsubscribe + instrumentation.instance_variable_set(:@config, config) + instrumentation.instance_variable_set(:@installed, false) + + instrumentation.install(config) + ActiveJob::Base.queue_adapter = :async + ActiveJob::Base.queue_adapter.immediate = true + + exporter.reset + end + + after do + begin + ActiveJob::Base.queue_adapter.shutdown + rescue StandardError + nil + end + ActiveJob::Base.queue_adapter = :inline + end + + describe 'perform_later' do + it 'traces enqueuing and processing the job' do + TestJob.perform_later + + _(publish_span).wont_be_nil + _(process_span).wont_be_nil + end + end + + describe 'perform_now' do + it 'only traces processing the job' do + TestJob.perform_now + + _(publish_span).must_be_nil + _(process_span).wont_be_nil + _(process_span.attributes['code.namespace']).must_equal('TestJob') + end + end + + describe 'exception handling' do + it 'sets span status to error' do + _ { ExceptionJob.perform_later }.must_raise StandardError, 'This job raises an exception' + + _(process_span.status.code).must_equal OpenTelemetry::Trace::Status::ERROR + _(process_span.status.description).must_equal 'Unexpected ActiveJob Error StandardError' + + _(process_span.events.first.name).must_equal 'exception' + _(process_span.events.first.attributes['exception.type']).must_equal 'StandardError' + _(process_span.events.first.attributes['exception.message']).must_equal 'This job raises an exception' + end + + it 'captures errors that were handled by rescue_from in versions earlier than Rails 7' do + skip 'rescue_from jobs behave differently in Rails 7 and newer' if ActiveJob.version >= Gem::Version.new('7') + RescueFromJob.perform_later + + _(process_span.status.code).must_equal OpenTelemetry::Trace::Status::ERROR + _(process_span.status.description).must_equal 'Unexpected ActiveJob Error RescueFromJob::RescueFromError' + + _(process_span.events.first.name).must_equal 'exception' + _(process_span.events.first.attributes['exception.type']).must_equal 'RescueFromJob::RescueFromError' + _(process_span.events.first.attributes['exception.message']).must_equal 'I was handled by rescue_from' + end + + it 'ignores errors that were handled by rescue_from in versions of Rails 7 or newer' do + skip 'rescue_from jobs behave differently in Rails 7 and newer' if ActiveJob.version < Gem::Version.new('7') + RescueFromJob.perform_later + + _(process_span.status.code).must_equal OpenTelemetry::Trace::Status::OK + + _(process_span.events).must_be_nil + end + end + + describe 'span kind' do + it 'sets correct span kinds for inline jobs' do + begin + ActiveJob::Base.queue_adapter.shutdown + rescue StandardError + nil + end + ActiveJob::Base.queue_adapter = :inline + + TestJob.perform_later + + _(publish_span.kind).must_equal(:producer) + _(process_span.kind).must_equal(:consumer) + end + + it 'sets correct span kinds for all other jobs' do + TestJob.perform_later + + _(publish_span.kind).must_equal(:producer) + _(process_span.kind).must_equal(:consumer) + end + end + + describe 'attributes' do + describe 'active_job.priority' do + it 'is unset for unprioritized jobs' do + TestJob.perform_later + + [publish_span, process_span].each do |span| + _(span.attributes['messaging.active_job.message.priority']).must_be_nil + end + end + + it 'is set for jobs with a priority' do + TestJob.set(priority: 1).perform_later + + [publish_span, process_span].each do |span| + _(span.attributes['messaging.active_job.message.priority']).must_equal('1') + end + end + end + end + + describe 'span_naming option' do + describe 'when queue - default' do + it 'names spans according to the job queue' do + TestJob.set(queue: :foo).perform_later + publish_span = exporter.finished_spans.find { |s| s.name == 'foo publish' } + _(publish_span).wont_be_nil + + process_span = exporter.finished_spans.find { |s| s.name == 'foo process' } + _(process_span).wont_be_nil + end + end + + describe 'when job_class' do + let(:config) { { propagation_style: :link, span_naming: :job_class } } + + it 'names span according to the job class' do + TestJob.set(queue: :foo).perform_later + + publish_span = exporter.finished_spans.find { |s| s.name == 'TestJob publish' } + _(publish_span).wont_be_nil + + process_span = exporter.finished_spans.find { |s| s.name == 'TestJob process' } + _(process_span).wont_be_nil + end + end + end + + describe 'propagation_style option' do + describe 'link - default' do + # The inline job adapter executes the job immediately upon enqueuing it + # so we can't actually use that in these tests - the actual Context.current at time + # of execution *will* be the context where the job was enqueued, because rails + # ends up doing job.around_enqueue { job.around_perform { block } } inline. + it 'creates span links in separate traces' do + TestJob.perform_later + + _(publish_span.trace_id).wont_equal(process_span.trace_id) + + _(process_span.total_recorded_links).must_equal(1) + _(process_span.links[0].span_context.trace_id).must_equal(publish_span.trace_id) + _(process_span.links[0].span_context.span_id).must_equal(publish_span.span_id) + end + + it 'propagates baggage' do + ctx = OpenTelemetry::Baggage.set_value('testing_baggage', 'it_worked') + OpenTelemetry::Context.with_current(ctx) do + BaggageJob.perform_later + end + + _(publish_span.trace_id).wont_equal(process_span.trace_id) + + _(process_span.total_recorded_links).must_equal(1) + _(process_span.links[0].span_context.trace_id).must_equal(publish_span.trace_id) + _(process_span.links[0].span_context.span_id).must_equal(publish_span.span_id) + + _(process_span.attributes['success']).must_equal(true) + end + end + + describe 'when configured to do parent/child spans' do + let(:config) { { propagation_style: :child, span_naming: :queue } } + + it 'creates a parent/child relationship' do + TestJob.perform_later + + _(process_span.total_recorded_links).must_equal(0) + + _(publish_span.trace_id).must_equal(process_span.trace_id) + _(process_span.parent_span_id).must_equal(publish_span.span_id) + end + + it 'propagates baggage' do + ctx = OpenTelemetry::Baggage.set_value('testing_baggage', 'it_worked') + OpenTelemetry::Context.with_current(ctx) do + BaggageJob.perform_later + end + _(process_span.total_recorded_links).must_equal(0) + + _(publish_span.trace_id).must_equal(process_span.trace_id) + _(process_span.parent_span_id).must_equal(publish_span.span_id) + _(process_span.attributes['success']).must_equal(true) + end + end + + describe 'when explicitly configure for no propagation' do + let(:config) { { propagation_style: :none, span_naming: :queue } } + + it 'skips link creation and does not create parent/child relationship' do + TestJob.perform_later + + _(process_span.total_recorded_links).must_equal(0) + + _(publish_span.trace_id).wont_equal(process_span.trace_id) + _(process_span.parent_span_id).wont_equal(publish_span.span_id) + end + + it 'still propagates baggage' do + ctx = OpenTelemetry::Baggage.set_value('testing_baggage', 'it_worked') + OpenTelemetry::Context.with_current(ctx) do + BaggageJob.perform_later + end + + _(process_span.total_recorded_links).must_equal(0) + + _(publish_span.trace_id).wont_equal(process_span.trace_id) + _(process_span.parent_span_id).wont_equal(publish_span.span_id) + _(process_span.attributes['success']).must_equal(true) + end + end + end + + describe 'active_job callbacks' do + it 'makes the tracing context available in before_perform callbacks' do + skip "ActiveJob #{ActiveJob.version} subscribers do not include timing information for callbacks" if ActiveJob.version < Gem::Version.new('7') + CallbacksJob.perform_now + + _(CallbacksJob.context_before).wont_be_nil + _(CallbacksJob.context_before).must_be :valid? + end + + it 'makes the tracing context available in after_perform callbacks' do + skip "ActiveJob #{ActiveJob.version} subscribers do not include timing information for callbacks" if ActiveJob.version < Gem::Version.new('7') + CallbacksJob.perform_now + + _(CallbacksJob.context_after).wont_be_nil + _(CallbacksJob.context_after).must_be :valid? + end + end +end diff --git a/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers/retry_stopped_test.rb b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers/retry_stopped_test.rb new file mode 100644 index 000000000..5b4eb774c --- /dev/null +++ b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers/retry_stopped_test.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +require_relative '../../../../../lib/opentelemetry/instrumentation/active_job' + +describe 'OpenTelemetry::Instrumentation::ActiveJob::Handlers::RetryStopped' do + let(:instrumentation) { OpenTelemetry::Instrumentation::ActiveJob::Instrumentation.instance } + let(:config) { { propagation_style: :link, span_naming: :queue } } + let(:exporter) { EXPORTER } + let(:spans) { exporter.finished_spans } + let(:publish_span) { spans.find { |s| s.name == 'default publish' } } + let(:process_span) { spans.find { |s| s.name == 'default process' } } + let(:retry_span) { spans.find { |s| s.name == 'retry_stopped.active_job' } } + + before do + OpenTelemetry::Instrumentation::ActiveJob::Handlers.unsubscribe + instrumentation.instance_variable_set(:@config, config) + instrumentation.instance_variable_set(:@installed, false) + + instrumentation.install(config) + ActiveJob::Base.queue_adapter = :async + ActiveJob::Base.queue_adapter.immediate = true + + exporter.reset + end + + after do + begin + ActiveJob::Base.queue_adapter.shutdown + rescue StandardError + nil + end + ActiveJob::Base.queue_adapter = :inline + end + + describe 'attributes' do + describe 'active_job.executions' do + it 'records retry errors' do + _ { RetryJob.perform_later }.must_raise StandardError + + _(process_span.status.code).must_equal OpenTelemetry::Trace::Status::ERROR + _(process_span.status.description).must_equal 'Unexpected ActiveJob Error StandardError' + + _(retry_span.status.code).must_equal OpenTelemetry::Trace::Status::ERROR + _(retry_span.status.description).must_equal 'Unexpected ActiveJob Error StandardError' + _(retry_span.events.first.name).must_equal 'exception' + _(retry_span.events.first.attributes['exception.type']).must_equal 'StandardError' + _(retry_span.events.first.attributes['exception.message']).must_equal 'from retry job' + end + end + end +end diff --git a/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers_test.rb b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers_test.rb new file mode 100644 index 000000000..790ace52c --- /dev/null +++ b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/handlers_test.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +require_relative '../../../../lib/opentelemetry/instrumentation/active_job' + +describe OpenTelemetry::Instrumentation::ActiveJob::Handlers do + let(:instrumentation) { OpenTelemetry::Instrumentation::ActiveJob::Instrumentation.instance } + let(:config) { { propagation_style: :link, span_naming: :queue } } + let(:exporter) { EXPORTER } + let(:spans) { exporter.finished_spans } + let(:publish_span) { spans.find { |s| s.name == 'default publish' } } + let(:process_span) { spans.find { |s| s.name == 'default process' } } + + before do + OpenTelemetry::Instrumentation::ActiveJob::Handlers.unsubscribe + instrumentation.instance_variable_set(:@config, config) + instrumentation.instance_variable_set(:@installed, false) + + instrumentation.install(config) + ActiveJob::Base.queue_adapter = :async + ActiveJob::Base.queue_adapter.immediate = true + + exporter.reset + end + + after do + begin + ActiveJob::Base.queue_adapter.shutdown + rescue StandardError + nil + end + ActiveJob::Base.queue_adapter = :inline + end + + describe 'compatibility' do + it 'works with positional args' do + _(PositionalOnlyArgsJob.perform_now('arg1')).must_be_nil # Make sure this runs without raising an error + end + + it 'works with keyword args' do + _(KeywordOnlyArgsJob.perform_now(keyword2: :keyword2)).must_be_nil # Make sure this runs without raising an error + end + + it 'works with mixed args' do + _(MixedArgsJob.perform_now('arg1', 'arg2', keyword2: :keyword2)).must_be_nil # Make sure this runs without raising an error + end + end +end diff --git a/instrumentation/active_job/test/instrumentation/active_job/instrumentation_test.rb b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/instrumentation_test.rb similarity index 93% rename from instrumentation/active_job/test/instrumentation/active_job/instrumentation_test.rb rename to instrumentation/active_job/test/opentelemetry/instrumentation/active_job/instrumentation_test.rb index c1c2381ea..e41b7eb5c 100644 --- a/instrumentation/active_job/test/instrumentation/active_job/instrumentation_test.rb +++ b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/instrumentation_test.rb @@ -6,7 +6,7 @@ require 'test_helper' -require_relative '../../../lib/opentelemetry/instrumentation/active_job' +require_relative '../../../../lib/opentelemetry/instrumentation/active_job' describe OpenTelemetry::Instrumentation::ActiveJob do let(:instrumentation) { OpenTelemetry::Instrumentation::ActiveJob::Instrumentation.instance } diff --git a/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/mappers/attribute_test.rb b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/mappers/attribute_test.rb new file mode 100644 index 000000000..060e93f67 --- /dev/null +++ b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/mappers/attribute_test.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +require_relative '../../../../../lib/opentelemetry/instrumentation/active_job' + +describe OpenTelemetry::Instrumentation::ActiveJob::Mappers::Attribute do + let(:instrumentation) { OpenTelemetry::Instrumentation::ActiveJob::Instrumentation.instance } + let(:config) { { propagation_style: :link, span_naming: :queue } } + let(:exporter) { EXPORTER } + let(:spans) { exporter.finished_spans } + let(:publish_span) { spans.find { |s| s.name == 'default publish' } } + let(:process_span) { spans.find { |s| s.name == 'default process' } } + + before do + OpenTelemetry::Instrumentation::ActiveJob::Handlers.unsubscribe + instrumentation.instance_variable_set(:@config, config) + instrumentation.instance_variable_set(:@installed, false) + + instrumentation.install(config) + ActiveJob::Base.queue_adapter = :async + ActiveJob::Base.queue_adapter.immediate = true + + exporter.reset + end + + after do + begin + ActiveJob::Base.queue_adapter.shutdown + rescue StandardError + nil + end + ActiveJob::Base.queue_adapter = :inline + end + + it 'uses trace semantic conventions and Rails specific attributes' do + job = TestJob.perform_later + + [publish_span, process_span].each do |span| + _(span.attributes['code.namespace']).must_equal('TestJob') + _(span.attributes['messaging.system']).must_equal('active_job') + _(span.attributes['messaging.active_job.adapter.name']).must_equal('async') + _(span.attributes['messaging.destination']).must_equal('default') + _(span.attributes['messaging.message.id']).must_equal(job.job_id) + _(span.attributes['messaging.active_job.message.priority']).must_be_nil + end + + _(process_span.attributes['messaging.active_job.message.provider_job_id']).must_equal(job.provider_job_id) + end + + it 'tracks the job priority' do + TestJob.set(priority: 5).perform_later + + [publish_span, process_span].each do |span| + _(span.attributes['messaging.active_job.message.priority']).must_equal('5') + end + end + + it 'is set correctly for the inline adapter' do + begin + ActiveJob::Base.queue_adapter.shutdown + rescue StandardError + nil + end + + ActiveJob::Base.queue_adapter = :inline + TestJob.perform_later + + [publish_span, process_span].each do |span| + _(span.attributes['messaging.active_job.adapter.name']).must_equal('inline') + end + end +end diff --git a/instrumentation/active_job/test/instrumentation/active_job/patches/base_test.rb b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/patches/base_test.rb similarity index 63% rename from instrumentation/active_job/test/instrumentation/active_job/patches/base_test.rb rename to instrumentation/active_job/test/opentelemetry/instrumentation/active_job/patches/base_test.rb index c22dc0b8a..d8c5cc22e 100644 --- a/instrumentation/active_job/test/instrumentation/active_job/patches/base_test.rb +++ b/instrumentation/active_job/test/opentelemetry/instrumentation/active_job/patches/base_test.rb @@ -6,29 +6,20 @@ require 'test_helper' -require_relative '../../../../lib/opentelemetry/instrumentation/active_job' +require_relative '../../../../../lib/opentelemetry/instrumentation/active_job' describe OpenTelemetry::Instrumentation::ActiveJob::Patches::Base do - describe 'attr_accessor' do - it 'adds a "metadata" accessor' do - job = TestJob.new - - _(job).must_respond_to :metadata - _(job).must_respond_to :metadata= - end - end - describe 'serialization / deserialization' do it 'must handle metadata' do job = TestJob.new - job.metadata = { 'foo' => 'bar' } + job.__otel_headers = { 'foo' => 'bar' } serialized_job = job.serialize - _(serialized_job.keys).must_include 'metadata' + _(serialized_job.keys).must_include '__otel_headers' job = TestJob.new job.deserialize(serialized_job) - _(job.metadata).must_equal('foo' => 'bar') + _(job.__otel_headers).must_equal('foo' => 'bar') end it 'handles jobs queued without instrumentation' do # e.g. during a rolling deployment diff --git a/instrumentation/active_job/test/test_helper.rb b/instrumentation/active_job/test/test_helper.rb index 1af04821d..dd134b0ff 100644 --- a/instrumentation/active_job/test/test_helper.rb +++ b/instrumentation/active_job/test/test_helper.rb @@ -11,7 +11,6 @@ require 'active_job' require 'opentelemetry-instrumentation-active_job' require 'minitest/autorun' -require 'webmock/minitest' class TestJob < ActiveJob::Base def perform; end @@ -21,7 +20,16 @@ class RetryJob < ActiveJob::Base retry_on StandardError, wait: 0, attempts: 2 def perform - raise StandardError + raise StandardError, 'from retry job' + end +end + +class DiscardJob < ActiveJob::Base + class DiscardError < StandardError; end + discard_on DiscardError + + def perform + raise DiscardError, 'discard me' end end @@ -33,7 +41,7 @@ def perform class BaggageJob < ActiveJob::Base def perform - OpenTelemetry::Trace.current_span['success'] = true if OpenTelemetry::Baggage.value('testing_baggage') == 'it_worked' + OpenTelemetry::Trace.current_span['success'] = OpenTelemetry::Baggage.value('testing_baggage') == 'it_worked' end end @@ -68,6 +76,18 @@ def initialize(*) end end +class RescueFromJob < ActiveJob::Base + class RescueFromError < StandardError; end + + rescue_from RescueFromError do + # do nothing + end + + def perform + raise RescueFromError, 'I was handled by rescue_from' + end +end + ActiveJob::Base.queue_adapter = :inline ActiveJob::Base.logger = Logger.new($stderr, level: ENV.fetch('OTEL_LOG_LEVEL', 'fatal').to_sym) diff --git a/instrumentation/active_model_serializers/opentelemetry-instrumentation-active_model_serializers.gemspec b/instrumentation/active_model_serializers/opentelemetry-instrumentation-active_model_serializers.gemspec index fa465c7ac..f27de220c 100644 --- a/instrumentation/active_model_serializers/opentelemetry-instrumentation-active_model_serializers.gemspec +++ b/instrumentation/active_model_serializers/opentelemetry-instrumentation-active_model_serializers.gemspec @@ -35,7 +35,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/active_record/CHANGELOG.md b/instrumentation/active_record/CHANGELOG.md index 4896addb4..0da241da2 100644 --- a/instrumentation/active_record/CHANGELOG.md +++ b/instrumentation/active_record/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History: opentelemetry-instrumentation-active_record +### v0.7.0 / 2023-11-22 + +* BREAKING CHANGE: Drop Rails 6.0 EOL + +* ADDED: Drop Rails 6.0 EOL + ### v0.6.3 / 2023-10-16 * FIXED: Add Rails 7.1 compatibility diff --git a/instrumentation/active_record/lib/opentelemetry/instrumentation/active_record/version.rb b/instrumentation/active_record/lib/opentelemetry/instrumentation/active_record/version.rb index bdd1f1083..4d95d58c4 100644 --- a/instrumentation/active_record/lib/opentelemetry/instrumentation/active_record/version.rb +++ b/instrumentation/active_record/lib/opentelemetry/instrumentation/active_record/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module ActiveRecord - VERSION = '0.6.3' + VERSION = '0.7.0' end end end diff --git a/instrumentation/active_record/opentelemetry-instrumentation-active_record.gemspec b/instrumentation/active_record/opentelemetry-instrumentation-active_record.gemspec index dcfa69779..001334973 100644 --- a/instrumentation/active_record/opentelemetry-instrumentation-active_record.gemspec +++ b/instrumentation/active_record/opentelemetry-instrumentation-active_record.gemspec @@ -36,7 +36,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/active_support/CHANGELOG.md b/instrumentation/active_support/CHANGELOG.md index 6254326a6..47f8a176c 100644 --- a/instrumentation/active_support/CHANGELOG.md +++ b/instrumentation/active_support/CHANGELOG.md @@ -1,5 +1,15 @@ # Release History: opentelemetry-instrumentation-active_support +### v0.5.1 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + +### v0.5.0 / 2023-11-22 + +* BREAKING CHANGE: Drop Rails 6.0 EOL + +* ADDED: Drop Rails 6.0 EOL + ### v0.4.4 / 2023-10-31 * FIXED: Remove call to ActiveSupport::Notifications.notifier#synchronize deprecated in Rails 7.2 diff --git a/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/span_subscriber.rb b/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/span_subscriber.rb index e2ab1d700..71692168a 100644 --- a/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/span_subscriber.rb +++ b/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/span_subscriber.rb @@ -67,10 +67,8 @@ def start(name, id, payload) token = OpenTelemetry::Context.attach( OpenTelemetry::Trace.context_with_span(span) ) - payload.merge!( - __opentelemetry_span: span, - __opentelemetry_ctx_token: token - ) + payload[:__opentelemetry_span] = span + payload[:__opentelemetry_ctx_token] = token [span, token] end diff --git a/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/version.rb b/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/version.rb index 96965c3e7..60c531ca6 100644 --- a/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/version.rb +++ b/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module ActiveSupport - VERSION = '0.4.4' + VERSION = '0.5.1' end end end diff --git a/instrumentation/active_support/opentelemetry-instrumentation-active_support.gemspec b/instrumentation/active_support/opentelemetry-instrumentation-active_support.gemspec index f9fdb4027..0725d2221 100644 --- a/instrumentation/active_support/opentelemetry-instrumentation-active_support.gemspec +++ b/instrumentation/active_support/opentelemetry-instrumentation-active_support.gemspec @@ -38,7 +38,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'pry-byebug' spec.add_development_dependency 'rails', '>= 6.1' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/all/CHANGELOG.md b/instrumentation/all/CHANGELOG.md index 33399ca51..887e71912 100644 --- a/instrumentation/all/CHANGELOG.md +++ b/instrumentation/all/CHANGELOG.md @@ -1,5 +1,21 @@ # Release History: opentelemetry-instrumentation-all +### v0.54.0 / 2023-11-28 + +* ADDED: Updated excon to include connect spans + +### v0.53.0 / 2023-11-28 + +* CHANGED: Performance optimization cache attribute hashes [#723](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/723) + +### v0.52.0 / 2023-11-21 + +* BREAKING CHANGE: Drop Support for EoL Rails 6.0 [#680](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/680) +* BREAKING CHANGE: Use ActiveSupport Instrumentation instead of Money Patches [#677](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/677) + +* CHANGED: Drop Support for EoL Rails 6.0 [#680](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/680) +* CHANGED: Use ActiveSupport Instrumentation instead of Money Patches [#677](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/677) + ### v0.51.1 / 2023-10-27 * ADDED: Instrument connect and ping (Trilogy) diff --git a/instrumentation/all/Gemfile b/instrumentation/all/Gemfile index 4ef786f4f..5cfaa5c0b 100644 --- a/instrumentation/all/Gemfile +++ b/instrumentation/all/Gemfile @@ -11,7 +11,7 @@ gemspec group :test do Dir.entries('../') .select { |entry| File.directory?(File.join('../', entry)) } - .reject { |entry| %w[. .. all].include?(entry) } + .reject { |entry| %w[. .. all].include?(entry) } # rubocop:disable Performance/CollectionLiteralInLoop .sort .each { |dir| gem "opentelemetry-instrumentation-#{dir}", path: "../#{dir}" } end diff --git a/instrumentation/all/lib/opentelemetry/instrumentation/all/version.rb b/instrumentation/all/lib/opentelemetry/instrumentation/all/version.rb index 0b3de5313..00e9084e3 100644 --- a/instrumentation/all/lib/opentelemetry/instrumentation/all/version.rb +++ b/instrumentation/all/lib/opentelemetry/instrumentation/all/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module All - VERSION = '0.51.1' + VERSION = '0.54.0' end end end diff --git a/instrumentation/all/opentelemetry-instrumentation-all.gemspec b/instrumentation/all/opentelemetry-instrumentation-all.gemspec index fabc00315..e544a750b 100644 --- a/instrumentation/all/opentelemetry-instrumentation-all.gemspec +++ b/instrumentation/all/opentelemetry-instrumentation-all.gemspec @@ -33,10 +33,10 @@ Gem::Specification.new do |spec| spec.add_dependency 'opentelemetry-instrumentation-dalli', '~> 0.25.0' spec.add_dependency 'opentelemetry-instrumentation-delayed_job', '~> 0.22.0' spec.add_dependency 'opentelemetry-instrumentation-ethon', '~> 0.21.1' - spec.add_dependency 'opentelemetry-instrumentation-excon', '~> 0.21.1' + spec.add_dependency 'opentelemetry-instrumentation-excon', '~> 0.22.0' spec.add_dependency 'opentelemetry-instrumentation-faraday', '~> 0.23.1' spec.add_dependency 'opentelemetry-instrumentation-grape', '~> 0.1.3' - spec.add_dependency 'opentelemetry-instrumentation-graphql', '~> 0.26.2' + spec.add_dependency 'opentelemetry-instrumentation-graphql', '~> 0.27.0' spec.add_dependency 'opentelemetry-instrumentation-gruf', '~> 0.1.0' spec.add_dependency 'opentelemetry-instrumentation-http', '~> 0.23.1' spec.add_dependency 'opentelemetry-instrumentation-http_client', '~> 0.22.1' @@ -49,7 +49,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'opentelemetry-instrumentation-que', '~> 0.7.0' spec.add_dependency 'opentelemetry-instrumentation-racecar', '~> 0.3.0' spec.add_dependency 'opentelemetry-instrumentation-rack', '~> 0.23.1' - spec.add_dependency 'opentelemetry-instrumentation-rails', '~> 0.28.0' + spec.add_dependency 'opentelemetry-instrumentation-rails', '~> 0.29.0' spec.add_dependency 'opentelemetry-instrumentation-rake', '~> 0.2.1' spec.add_dependency 'opentelemetry-instrumentation-rdkafka', '~> 0.4.0' spec.add_dependency 'opentelemetry-instrumentation-redis', '~> 0.25.1' @@ -65,7 +65,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/aws_sdk/opentelemetry-instrumentation-aws_sdk.gemspec b/instrumentation/aws_sdk/opentelemetry-instrumentation-aws_sdk.gemspec index 1c91da124..bd1ce75a1 100644 --- a/instrumentation/aws_sdk/opentelemetry-instrumentation-aws_sdk.gemspec +++ b/instrumentation/aws_sdk/opentelemetry-instrumentation-aws_sdk.gemspec @@ -37,7 +37,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'pry' spec.add_development_dependency 'pry-byebug' unless RUBY_ENGINE == 'jruby' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/base/CHANGELOG.md b/instrumentation/base/CHANGELOG.md index a5f77d31f..575d63cd8 100644 --- a/instrumentation/base/CHANGELOG.md +++ b/instrumentation/base/CHANGELOG.md @@ -1,8 +1,12 @@ # Release History: opentelemetry-instrumentation-base -### v0.22.2 / 2023-08-03 +### v0.22.3 / 2023-11-23 -* FIXED: Remove inline linter rules +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + +### v0.22.2 / 2023-08-03 + +* FIXED: Remove inline linter rules ### v0.22.1 / 2023-06-02 diff --git a/instrumentation/base/lib/opentelemetry/instrumentation/base.rb b/instrumentation/base/lib/opentelemetry/instrumentation/base.rb index d944d1a6c..4e08be3ea 100644 --- a/instrumentation/base/lib/opentelemetry/instrumentation/base.rb +++ b/instrumentation/base/lib/opentelemetry/instrumentation/base.rb @@ -353,7 +353,7 @@ def coerce_env_var(env_var, validation_type) when :array env_var.split(',').map(&:strip) when :boolean - env_var.to_s.strip.downcase == 'true' + env_var.to_s.strip.casecmp('true').zero? when :integer env_var.to_i when :string diff --git a/instrumentation/base/lib/opentelemetry/instrumentation/version.rb b/instrumentation/base/lib/opentelemetry/instrumentation/version.rb index 58c9df556..0f05e445e 100644 --- a/instrumentation/base/lib/opentelemetry/instrumentation/version.rb +++ b/instrumentation/base/lib/opentelemetry/instrumentation/version.rb @@ -6,6 +6,6 @@ module OpenTelemetry module Instrumentation - VERSION = '0.22.2' + VERSION = '0.22.3' end end diff --git a/instrumentation/base/opentelemetry-instrumentation-base.gemspec b/instrumentation/base/opentelemetry-instrumentation-base.gemspec index 98ab793c7..ba6ff4563 100644 --- a/instrumentation/base/opentelemetry-instrumentation-base.gemspec +++ b/instrumentation/base/opentelemetry-instrumentation-base.gemspec @@ -32,7 +32,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.57.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.22.0' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/bunny/opentelemetry-instrumentation-bunny.gemspec b/instrumentation/bunny/opentelemetry-instrumentation-bunny.gemspec index 40aa3a9f5..c502ce30b 100644 --- a/instrumentation/bunny/opentelemetry-instrumentation-bunny.gemspec +++ b/instrumentation/bunny/opentelemetry-instrumentation-bunny.gemspec @@ -34,7 +34,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/concurrent_ruby/CHANGELOG.md b/instrumentation/concurrent_ruby/CHANGELOG.md index 43f2d4254..bbb0b992b 100644 --- a/instrumentation/concurrent_ruby/CHANGELOG.md +++ b/instrumentation/concurrent_ruby/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-concurrent_ruby +### v0.21.2 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.21.1 / 2023-06-05 * FIXED: Base config options diff --git a/instrumentation/concurrent_ruby/lib/opentelemetry/instrumentation/concurrent_ruby/patches/thread_pool_executor.rb b/instrumentation/concurrent_ruby/lib/opentelemetry/instrumentation/concurrent_ruby/patches/thread_pool_executor.rb index 5b7f1e5e7..db8873ea2 100644 --- a/instrumentation/concurrent_ruby/lib/opentelemetry/instrumentation/concurrent_ruby/patches/thread_pool_executor.rb +++ b/instrumentation/concurrent_ruby/lib/opentelemetry/instrumentation/concurrent_ruby/patches/thread_pool_executor.rb @@ -17,7 +17,7 @@ def post(*args, **kwargs, &task) super(*args, **kwargs) do OpenTelemetry::Context.with_current(context) do - task.call(*args, **kwargs) + yield(*args, **kwargs) end end end diff --git a/instrumentation/concurrent_ruby/lib/opentelemetry/instrumentation/concurrent_ruby/version.rb b/instrumentation/concurrent_ruby/lib/opentelemetry/instrumentation/concurrent_ruby/version.rb index 3ce95b41b..027e6d324 100644 --- a/instrumentation/concurrent_ruby/lib/opentelemetry/instrumentation/concurrent_ruby/version.rb +++ b/instrumentation/concurrent_ruby/lib/opentelemetry/instrumentation/concurrent_ruby/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module ConcurrentRuby - VERSION = '0.21.1' + VERSION = '0.21.2' end end end diff --git a/instrumentation/concurrent_ruby/opentelemetry-instrumentation-concurrent_ruby.gemspec b/instrumentation/concurrent_ruby/opentelemetry-instrumentation-concurrent_ruby.gemspec index d2cfb4b33..c5831665d 100644 --- a/instrumentation/concurrent_ruby/opentelemetry-instrumentation-concurrent_ruby.gemspec +++ b/instrumentation/concurrent_ruby/opentelemetry-instrumentation-concurrent_ruby.gemspec @@ -30,11 +30,12 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'appraisal', '~> 2.5' spec.add_development_dependency 'bundler', '~> 2.4' - spec.add_development_dependency 'concurrent-ruby', '~> 1.1.6' + spec.add_development_dependency 'concurrent-ruby', '~> 1.0' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/concurrent_ruby/test/opentelemetry/instrumentation/concurrent-ruby/instrumentation_test.rb b/instrumentation/concurrent_ruby/test/opentelemetry/instrumentation/concurrent-ruby/instrumentation_test.rb index c3f538443..2aa4e5ceb 100644 --- a/instrumentation/concurrent_ruby/test/opentelemetry/instrumentation/concurrent-ruby/instrumentation_test.rb +++ b/instrumentation/concurrent_ruby/test/opentelemetry/instrumentation/concurrent-ruby/instrumentation_test.rb @@ -23,7 +23,7 @@ after do # Force re-install of instrumentation Concurrent.send(:remove_const, :ThreadPoolExecutor) - Concurrent.const_set('ThreadPoolExecutor', unmodified_future) + Concurrent.const_set(:ThreadPoolExecutor, unmodified_future) instrumentation.instance_variable_set(:@installed, false) end diff --git a/instrumentation/dalli/opentelemetry-instrumentation-dalli.gemspec b/instrumentation/dalli/opentelemetry-instrumentation-dalli.gemspec index 8a12e2360..1ee0aeec8 100644 --- a/instrumentation/dalli/opentelemetry-instrumentation-dalli.gemspec +++ b/instrumentation/dalli/opentelemetry-instrumentation-dalli.gemspec @@ -35,7 +35,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/delayed_job/CHANGELOG.md b/instrumentation/delayed_job/CHANGELOG.md index be2e302cb..ac8bd79d9 100644 --- a/instrumentation/delayed_job/CHANGELOG.md +++ b/instrumentation/delayed_job/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-delayed_job +### v0.22.1 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.22.0 / 2023-10-16 * BREAKING CHANGE: Drop DelayedJob ActiveRecord in Tests diff --git a/instrumentation/delayed_job/lib/opentelemetry/instrumentation/delayed_job/plugins/tracer_plugin.rb b/instrumentation/delayed_job/lib/opentelemetry/instrumentation/delayed_job/plugins/tracer_plugin.rb index 304868adb..676f720ed 100644 --- a/instrumentation/delayed_job/lib/opentelemetry/instrumentation/delayed_job/plugins/tracer_plugin.rb +++ b/instrumentation/delayed_job/lib/opentelemetry/instrumentation/delayed_job/plugins/tracer_plugin.rb @@ -14,7 +14,7 @@ module Plugins class TracerPlugin < Delayed::Plugin class << self def instrument_enqueue(job, &block) - return block.call(job) unless enabled? + return yield(job) unless enabled? attributes = build_attributes(job) attributes['messaging.operation'] = 'publish' @@ -28,7 +28,7 @@ def instrument_enqueue(job, &block) end def instrument_invoke(job, &block) - return block.call(job) unless enabled? + return yield(job) unless enabled? attributes = build_attributes(job) attributes['messaging.delayed_job.attempts'] = job.attempts if job.attempts @@ -83,8 +83,10 @@ def job_queue(job) end callbacks do |lifecycle| + # rubocop:disable Performance/MethodObjectAsBlock lifecycle.around(:enqueue, &method(:instrument_enqueue)) lifecycle.around(:invoke_job, &method(:instrument_invoke)) + # rubocop:enable Performance/MethodObjectAsBlock end end end diff --git a/instrumentation/delayed_job/lib/opentelemetry/instrumentation/delayed_job/version.rb b/instrumentation/delayed_job/lib/opentelemetry/instrumentation/delayed_job/version.rb index 8f3f46f79..642c8c07e 100644 --- a/instrumentation/delayed_job/lib/opentelemetry/instrumentation/delayed_job/version.rb +++ b/instrumentation/delayed_job/lib/opentelemetry/instrumentation/delayed_job/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module DelayedJob - VERSION = '0.22.0' + VERSION = '0.22.1' end end end diff --git a/instrumentation/delayed_job/opentelemetry-instrumentation-delayed_job.gemspec b/instrumentation/delayed_job/opentelemetry-instrumentation-delayed_job.gemspec index 9978617c2..d92561f64 100644 --- a/instrumentation/delayed_job/opentelemetry-instrumentation-delayed_job.gemspec +++ b/instrumentation/delayed_job/opentelemetry-instrumentation-delayed_job.gemspec @@ -35,7 +35,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'sqlite3' spec.add_development_dependency 'webmock', '~> 3.19' diff --git a/instrumentation/ethon/CHANGELOG.md b/instrumentation/ethon/CHANGELOG.md index d375ab33c..a579ed745 100644 --- a/instrumentation/ethon/CHANGELOG.md +++ b/instrumentation/ethon/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-ethon +### v0.21.3 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.21.2 / 2023-07-21 * ADDED: Update `opentelemetry-common` from [0.19.3 to 0.20.0](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/537) diff --git a/instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/patches/easy.rb b/instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/patches/easy.rb index f8727126d..18b11dc51 100644 --- a/instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/patches/easy.rb +++ b/instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/patches/easy.rb @@ -42,7 +42,7 @@ def complete @otel_span.status = OpenTelemetry::Trace::Status.error("Request has failed: #{message}") else @otel_span.set_attribute('http.status_code', response_code) - @otel_span.status = OpenTelemetry::Trace::Status.error unless (100..399).include?(response_code.to_i) + @otel_span.status = OpenTelemetry::Trace::Status.error unless (100..399).cover?(response_code.to_i) end ensure @otel_span&.finish diff --git a/instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/version.rb b/instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/version.rb index e2d1f063f..ff7e5ce1d 100644 --- a/instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/version.rb +++ b/instrumentation/ethon/lib/opentelemetry/instrumentation/ethon/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Ethon - VERSION = '0.21.2' + VERSION = '0.21.3' end end end diff --git a/instrumentation/ethon/opentelemetry-instrumentation-ethon.gemspec b/instrumentation/ethon/opentelemetry-instrumentation-ethon.gemspec index e24672d52..7feb678d6 100644 --- a/instrumentation/ethon/opentelemetry-instrumentation-ethon.gemspec +++ b/instrumentation/ethon/opentelemetry-instrumentation-ethon.gemspec @@ -31,11 +31,12 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'appraisal', '~> 2.5' spec.add_development_dependency 'bundler', '~> 2.4' - spec.add_development_dependency 'ethon', '~> 0.12.0' + spec.add_development_dependency 'ethon', '~> 0.11' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/excon/CHANGELOG.md b/instrumentation/excon/CHANGELOG.md index 34b6c1b74..b007f45e6 100644 --- a/instrumentation/excon/CHANGELOG.md +++ b/instrumentation/excon/CHANGELOG.md @@ -1,5 +1,15 @@ # Release History: opentelemetry-instrumentation-excon +### v0.22.0 / 2023-11-28 + +* BREAKING CHANGE: Add a connect span to excon + +* ADDED: Add a connect span to excon + +### v0.21.3 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.21.2 / 2023-07-21 * ADDED: Update `opentelemetry-common` from [0.19.3 to 0.20.0](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/537) diff --git a/instrumentation/excon/lib/opentelemetry/instrumentation/concerns/untraced_hosts.rb b/instrumentation/excon/lib/opentelemetry/instrumentation/concerns/untraced_hosts.rb new file mode 100644 index 000000000..81acdd6a3 --- /dev/null +++ b/instrumentation/excon/lib/opentelemetry/instrumentation/concerns/untraced_hosts.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module Concerns + # The untraced hosts concerns allows instrumentation to skip traces on hostnames in an exclusion list. + # If the current OpenTelemetry context is untraced, all hosts will be treated as untraced. + # When included in a class that extends OpenTelemetry::Instrumentation::Base, this module defines an option named :untraced_hosts. + module UntracedHosts + def self.included(klass) + klass.instance_eval do + # untraced_hosts: if a request's address matches any of the `String` + # or `Regexp` in this array, the instrumentation will not record a + # `kind = :client` representing the request and will not propagate + # context in the request. + option :untraced_hosts, default: [], validate: :array + end + end + + # Checks whether the given host should be treated as untraced. + # If the current OpenTelemetry context is untraced, all hosts will be treated as untraced. + # The given host must be a String. + def untraced?(host) + OpenTelemetry::Common::Utilities.untraced? || untraced_host?(host) + end + + private + + def untraced_host?(host) + config[:untraced_hosts].any? do |rule| + rule.is_a?(Regexp) ? rule.match?(host) : rule == host + end + end + end + end + end +end diff --git a/instrumentation/excon/lib/opentelemetry/instrumentation/excon/instrumentation.rb b/instrumentation/excon/lib/opentelemetry/instrumentation/excon/instrumentation.rb index 1a8a4d334..e20ca9b2d 100644 --- a/instrumentation/excon/lib/opentelemetry/instrumentation/excon/instrumentation.rb +++ b/instrumentation/excon/lib/opentelemetry/instrumentation/excon/instrumentation.rb @@ -4,15 +4,20 @@ # # SPDX-License-Identifier: Apache-2.0 +require_relative '../concerns/untraced_hosts' + module OpenTelemetry module Instrumentation module Excon # The Instrumentation class contains logic to detect and install the Excon # instrumentation class Instrumentation < OpenTelemetry::Instrumentation::Base + include OpenTelemetry::Instrumentation::Concerns::UntracedHosts + install do |_config| require_dependencies add_middleware + patch end present do @@ -25,11 +30,15 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base def require_dependencies require_relative 'middlewares/tracer_middleware' + require_relative 'patches/socket' end def add_middleware - ::Excon.defaults[:middlewares] = - Middlewares::TracerMiddleware.around_default_stack + ::Excon.defaults[:middlewares] = Middlewares::TracerMiddleware.around_default_stack + end + + def patch + ::Excon::Socket.prepend(Patches::Socket) end end end diff --git a/instrumentation/excon/lib/opentelemetry/instrumentation/excon/middlewares/tracer_middleware.rb b/instrumentation/excon/lib/opentelemetry/instrumentation/excon/middlewares/tracer_middleware.rb index 264bf5067..ca0b50d7f 100644 --- a/instrumentation/excon/lib/opentelemetry/instrumentation/excon/middlewares/tracer_middleware.rb +++ b/instrumentation/excon/lib/opentelemetry/instrumentation/excon/middlewares/tracer_middleware.rb @@ -22,24 +22,30 @@ class TracerMiddleware < ::Excon::Middleware::Base end.freeze def request_call(datum) - begin - unless datum.key?(:otel_span) - http_method = HTTP_METHODS_TO_UPPERCASE[datum[:method]] - attributes = span_creation_attributes(datum, http_method) - tracer.start_span( - HTTP_METHODS_TO_SPAN_NAMES[http_method], - attributes: attributes, - kind: :client - ).tap do |span| - datum[:otel_span] = span - OpenTelemetry::Trace.with_span(span) do - OpenTelemetry.propagation.inject(datum[:headers]) - end - end - end - rescue StandardError => e - OpenTelemetry.logger.debug(e.message) - end + return @stack.request_call(datum) if untraced?(datum) + + http_method = HTTP_METHODS_TO_UPPERCASE[datum[:method]] + + attributes = { + OpenTelemetry::SemanticConventions::Trace::HTTP_METHOD => http_method, + OpenTelemetry::SemanticConventions::Trace::HTTP_SCHEME => datum[:scheme], + OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET => datum[:path], + OpenTelemetry::SemanticConventions::Trace::HTTP_HOST => datum[:host], + OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => datum[:hostname], + OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => datum[:port] + } + + peer_service = Excon::Instrumentation.instance.config[:peer_service] + attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = peer_service if peer_service + attributes.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) + + span = tracer.start_span(HTTP_METHODS_TO_SPAN_NAMES[http_method], attributes: attributes, kind: :client) + ctx = OpenTelemetry::Trace.context_with_span(span) + + datum[:otel_span] = span + datum[:otel_token] = OpenTelemetry::Context.attach(ctx) + + OpenTelemetry.propagation.inject(datum[:headers]) @stack.request_call(datum) end @@ -71,43 +77,35 @@ def self.around_default_stack private def handle_response(datum) - if datum.key?(:otel_span) - datum[:otel_span].tap do |span| - return span if span.end_timestamp + datum.delete(:otel_span)&.tap do |span| + return unless span.recording? - if datum.key?(:response) - response = datum[:response] - span.set_attribute('http.status_code', response[:status]) - span.status = OpenTelemetry::Trace::Status.error unless (100..399).include?(response[:status].to_i) - end - - span.status = OpenTelemetry::Trace::Status.error("Request has failed: #{datum[:error]}") if datum.key?(:error) + if datum.key?(:response) + response = datum[:response] + span.set_attribute(OpenTelemetry::SemanticConventions::Trace::HTTP_STATUS_CODE, response[:status]) + span.status = OpenTelemetry::Trace::Status.error unless (100..399).cover?(response[:status].to_i) + end - span.finish - datum.delete(:otel_span) + if datum.key?(:error) + span.status = OpenTelemetry::Trace::Status.error('Request has failed') + span.record_exception(datum[:error]) end + + span.finish + + OpenTelemetry::Context.detach(datum.delete(:otel_token)) if datum.include?(:otel_token) end rescue StandardError => e - OpenTelemetry.logger.debug(e.message) - end - - def span_creation_attributes(datum, http_method) - instrumentation_attrs = { - 'http.host' => datum[:host], - 'http.method' => http_method, - 'http.scheme' => datum[:scheme], - 'http.target' => datum[:path] - } - config = Excon::Instrumentation.instance.config - instrumentation_attrs['peer.service'] = config[:peer_service] if config[:peer_service] - instrumentation_attrs.merge!( - OpenTelemetry::Common::HTTP::ClientContext.attributes - ) + OpenTelemetry.handle_error(e) end def tracer Excon::Instrumentation.instance.tracer end + + def untraced?(datum) + datum.key?(:otel_span) || Excon::Instrumentation.instance.untraced?(datum[:host]) + end end end end diff --git a/instrumentation/excon/lib/opentelemetry/instrumentation/excon/patches/socket.rb b/instrumentation/excon/lib/opentelemetry/instrumentation/excon/patches/socket.rb new file mode 100644 index 000000000..b96ed8833 --- /dev/null +++ b/instrumentation/excon/lib/opentelemetry/instrumentation/excon/patches/socket.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module Excon + module Patches + # Module to prepend to an Excon Socket for instrumentation + module Socket + private + + def connect + return super if untraced? + + if @data[:proxy] + conn_address = @data.dig(:proxy, :hostname) + conn_port = @data.dig(:proxy, :port) + else + conn_address = @data[:hostname] + conn_port = @port + end + + attributes = { OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => conn_address, OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => conn_port }.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) + + if is_a?(::Excon::SSLSocket) && @data[:proxy] + span_name = 'HTTP CONNECT' + span_kind = :client + else + span_name = 'connect' + span_kind = :internal + end + + tracer.in_span(span_name, attributes: attributes, kind: span_kind) do + super + end + end + + def tracer + Excon::Instrumentation.instance.tracer + end + + def untraced? + address = if @data[:proxy] + @data.dig(:proxy, :hostname) + else + @data[:hostname] + end + + Excon::Instrumentation.instance.untraced?(address) + end + end + end + end + end +end diff --git a/instrumentation/excon/lib/opentelemetry/instrumentation/excon/version.rb b/instrumentation/excon/lib/opentelemetry/instrumentation/excon/version.rb index eb739fe32..45107d5c0 100644 --- a/instrumentation/excon/lib/opentelemetry/instrumentation/excon/version.rb +++ b/instrumentation/excon/lib/opentelemetry/instrumentation/excon/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Excon - VERSION = '0.21.2' + VERSION = '0.22.0' end end end diff --git a/instrumentation/excon/opentelemetry-instrumentation-excon.gemspec b/instrumentation/excon/opentelemetry-instrumentation-excon.gemspec index 117c4e6f1..79534f7d4 100644 --- a/instrumentation/excon/opentelemetry-instrumentation-excon.gemspec +++ b/instrumentation/excon/opentelemetry-instrumentation-excon.gemspec @@ -35,7 +35,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/excon/test/opentelemetry/instrumentation/excon/instrumentation_test.rb b/instrumentation/excon/test/opentelemetry/instrumentation/excon/instrumentation_test.rb index 2e1ba7bea..fa166e1e6 100644 --- a/instrumentation/excon/test/opentelemetry/instrumentation/excon/instrumentation_test.rb +++ b/instrumentation/excon/test/opentelemetry/instrumentation/excon/instrumentation_test.rb @@ -8,6 +8,7 @@ require_relative '../../../../lib/opentelemetry/instrumentation/excon' require_relative '../../../../lib/opentelemetry/instrumentation/excon/middlewares/tracer_middleware' +require_relative '../../../../lib/opentelemetry/instrumentation/excon/patches/socket' describe OpenTelemetry::Instrumentation::Excon::Instrumentation do let(:instrumentation) { OpenTelemetry::Instrumentation::Excon::Instrumentation.instance } @@ -39,7 +40,7 @@ end it 'before request' do - _(exporter.finished_spans.size).must_equal 0 + _(exporter.finished_spans).must_be_empty end it 'after request with success code' do @@ -96,14 +97,16 @@ _(span.status.code).must_equal( OpenTelemetry::Trace::Status::ERROR ) - _(span.status.description).must_equal( - 'Request has failed: Excon::Error::Timeout' - ) + _(span.status.description).must_equal('Request has failed') assert_requested( :get, 'http://example.com/timeout', headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } ) + + exception_event = span.events.first + _(exception_event.attributes['exception.type']).must_equal('Excon::Error::Timeout') + _(exception_event.attributes['exception.message']).must_equal('Excon::Error::Timeout') end it 'merges HTTP client context' do @@ -150,4 +153,164 @@ _(span.attributes['peer.service']).must_equal 'example:custom' end end + + describe 'untraced?' do + before do + instrumentation.install(untraced_hosts: ['foobar.com', /bazqux\.com/]) + + stub_request(:get, 'http://example.com/body').to_return(status: 200) + stub_request(:get, 'http://foobar.com/body').to_return(status: 200) + stub_request(:get, 'http://bazqux.com/body').to_return(status: 200) + end + + it 'does not create a span when request ignored using a string' do + Excon.get('http://foobar.com/body') + _(exporter.finished_spans).must_be_empty + end + + it 'does not create a span when request ignored using a regexp' do + Excon.get('http://bazqux.com/body') + _(exporter.finished_spans).must_be_empty + end + + it 'does not create a span on connect when request ignored using a regexp' do + uri = URI.parse('http://bazqux.com') + + Excon::Socket.new(hostname: uri.host, port: uri.port) + + _(exporter.finished_spans).must_be_empty + end + + it 'creates a span for a non-ignored request' do + Excon.get('http://example.com/body') + + _(exporter.finished_spans.size).must_equal 1 + _(span.name).must_equal 'HTTP GET' + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.host']).must_equal 'example.com' + end + + it 'creates a span on connect for a non-ignored request' do + uri = URI.parse('http://example.com') + + Excon::Socket.new(hostname: uri.host, port: uri.port) + + _(exporter.finished_spans.size).must_equal 1 + _(span.name).must_equal('connect') + _(span.kind).must_equal(:internal) + _(span.attributes['net.peer.name']).must_equal('example.com') + _(span.attributes['net.peer.port']).must_equal(80) + end + end + + # NOTE: WebMock introduces an extra HTTP request span due to the way the mocking is implemented. + describe '#connect' do + before do + instrumentation.install + WebMock.allow_net_connect! + end + + after do + WebMock.disable_net_connect! + end + + it 'emits span on connect' do + TCPServer.open('localhost', 0) do |server| + Thread.start do + server.accept + rescue IOError + nil + end + + port = server.addr[1] + + _(-> { Excon.get("http://localhost:#{port}/example", read_timeout: 0) }).must_raise(Excon::Error::Timeout) + end + + _(exporter.finished_spans.size).must_equal(3) + _(span.name).must_equal 'connect' + _(span.attributes['net.peer.name']).must_equal('localhost') + _(span.attributes['net.peer.port']).wont_be_nil + + assert_http_spans(target: '/example', exception: 'Excon::Error::Timeout') + end + + it 'captures errors' do + _(-> { Excon.get('http://invalid.com:99999/example') }).must_raise + + _(exporter.finished_spans.size).must_equal(3) + _(span.name).must_equal 'connect' + _(span.attributes['net.peer.name']).must_equal('invalid.com') + _(span.attributes['net.peer.port']).must_equal(99_999) + + span_event = span.events.first + + _(span_event.name).must_equal 'exception' + _(span_event.attributes['exception.type']).must_equal(SocketError.name) + + assert_http_spans(host: 'invalid.com', target: '/example') + end + + it '[BUG] fails to emit an HTTP CONNECT span when connecting through an SSL proxy for an HTTP service' do + _(-> { Excon.get('http://localhost/', proxy: 'https://proxy_user:proxy_pass@localhost') }).must_raise(Excon::Error::Socket) + + _(exporter.finished_spans.size).must_equal(3) + _(span.name).must_equal 'connect' + _(span.kind).must_equal(:internal) + _(span.attributes['net.peer.name']).must_equal('localhost') + _(span.attributes['net.peer.port']).must_equal(443) + + assert_http_spans + end + + it 'emits an HTTP CONNECT span when connecting through an SSL proxy' do + _(-> { Excon.get('https://localhost/', proxy: 'https://proxy_user:proxy_pass@localhost') }).must_raise(Excon::Error::Socket) + + _(exporter.finished_spans.size).must_equal(3) + _(span.name).must_equal 'HTTP CONNECT' + _(span.kind).must_equal(:client) + _(span.attributes['net.peer.name']).must_equal('localhost') + _(span.attributes['net.peer.port']).must_equal(443) + + assert_http_spans(scheme: 'https') + end + + it 'emits a "connect" span when connecting through an non-ssl proxy' do + _(-> { Excon.get('http://localhost', proxy: 'https://proxy_user:proxy_pass@localhost') }).must_raise(Excon::Error::Socket) + + _(exporter.finished_spans.size).must_equal(3) + _(span.name).must_equal 'connect' + _(span.kind).must_equal(:internal) + _(span.attributes['net.peer.name']).must_equal('localhost') + _(span.attributes['net.peer.port']).must_equal(443) + + assert_http_spans(exception: 'Excon::Error::Socket') + end + + it 'emits no spans when untraced' do + OpenTelemetry::Common::Utilities.untraced do + _(-> { Excon.get('http://localhost', proxy: 'https://proxy_user:proxy_pass@localhost') }).must_raise(Excon::Error::Socket) + + _(exporter.finished_spans.size).must_equal(0) + end + end + end + + def assert_http_spans(scheme: 'http', host: 'localhost', target: '/', exception: nil) + exporter.finished_spans[1..].each do |http_span| + _(http_span.name).must_equal 'HTTP GET' + _(http_span.attributes['http.method']).must_equal 'GET' + _(http_span.attributes['http.scheme']).must_equal scheme + _(http_span.attributes['http.host']).must_equal host + _(http_span.attributes['http.target']).must_equal target + _(http_span.status.code).must_equal( + OpenTelemetry::Trace::Status::ERROR + ) + + if exception + exception_event = http_span.events.first + _(exception_event.attributes['exception.type']).must_equal(exception) + end + end + end end diff --git a/instrumentation/faraday/CHANGELOG.md b/instrumentation/faraday/CHANGELOG.md index fa06abffe..538cb4f69 100644 --- a/instrumentation/faraday/CHANGELOG.md +++ b/instrumentation/faraday/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-faraday +### v0.23.4 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.23.3 / 2023-10-16 * FIXED: Omit `nil` `net.peer.name` attributes diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware.rb index c6b73c3c9..01c6da394 100644 --- a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware.rb +++ b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware.rb @@ -60,7 +60,7 @@ def tracer def trace_response(span, response) span.set_attribute('http.status_code', response.status) - span.status = OpenTelemetry::Trace::Status.error unless (100..399).include?(response.status.to_i) + span.status = OpenTelemetry::Trace::Status.error unless (100..399).cover?(response.status.to_i) end end end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/version.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/version.rb index f4cb955f3..7eb5e99b1 100644 --- a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/version.rb +++ b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Faraday - VERSION = '0.23.3' + VERSION = '0.23.4' end end end diff --git a/instrumentation/faraday/opentelemetry-instrumentation-faraday.gemspec b/instrumentation/faraday/opentelemetry-instrumentation-faraday.gemspec index d89bcaf74..9744b9676 100644 --- a/instrumentation/faraday/opentelemetry-instrumentation-faraday.gemspec +++ b/instrumentation/faraday/opentelemetry-instrumentation-faraday.gemspec @@ -31,11 +31,12 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'appraisal', '~> 2.5' spec.add_development_dependency 'bundler', '~> 2.4' - spec.add_development_dependency 'faraday', '~> 0.17.0' + spec.add_development_dependency 'faraday' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/grape/CHANGELOG.md b/instrumentation/grape/CHANGELOG.md index a6a55b96e..640a501fe 100644 --- a/instrumentation/grape/CHANGELOG.md +++ b/instrumentation/grape/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-grape +### v0.1.6 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.1.5 / 2023-10-31 * FIXED: Remove dependency on ActiveSupport core extensions from Grape instrumentation diff --git a/instrumentation/grape/lib/opentelemetry/instrumentation/grape/event_handler.rb b/instrumentation/grape/lib/opentelemetry/instrumentation/grape/event_handler.rb index 7228247fc..1e5d2b9e2 100644 --- a/instrumentation/grape/lib/opentelemetry/instrumentation/grape/event_handler.rb +++ b/instrumentation/grape/lib/opentelemetry/instrumentation/grape/event_handler.rb @@ -79,7 +79,7 @@ def handle_payload_exception(span, exception) # Only record exceptions if they were not raised (i.e. do not have a status code in Grape) # or do not have a 5xx status code. These exceptions are recorded by Rack. # See instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/tracer_middleware.rb#L155 - return unless exception.respond_to?('status') && ::Rack::Utils.status_code(exception.status) < 500 + return unless exception.respond_to?(:status) && ::Rack::Utils.status_code(exception.status) < 500 span.record_exception(exception) span.status = OpenTelemetry::Trace::Status.error("Unhandled exception of type: #{exception.class}") @@ -93,8 +93,8 @@ def path(endpoint) return '' unless endpoint.routes namespace = endpoint.routes.first.namespace - version = endpoint.routes.first.options[:version] || '' - prefix = endpoint.routes.first.options[:prefix]&.to_s || '' + version = endpoint.routes.first.options[:version]&.to_s + prefix = endpoint.routes.first.options[:prefix]&.to_s parts = [prefix, version] + namespace.split('/') + endpoint.options[:path] parts.reject { |p| p.nil? || p.empty? || p.eql?('/') }.join('/').prepend('/') end @@ -108,7 +108,7 @@ def formatter_type(formatter) end def built_in_grape_formatter?(formatter) - formatter.respond_to?('name') && formatter.name.include?('Grape::Formatter') + formatter.respond_to?(:name) && formatter.name.include?('Grape::Formatter') end end end diff --git a/instrumentation/grape/lib/opentelemetry/instrumentation/grape/version.rb b/instrumentation/grape/lib/opentelemetry/instrumentation/grape/version.rb index 4bf132dcd..4e913a982 100644 --- a/instrumentation/grape/lib/opentelemetry/instrumentation/grape/version.rb +++ b/instrumentation/grape/lib/opentelemetry/instrumentation/grape/version.rb @@ -8,7 +8,7 @@ module OpenTelemetry module Instrumentation module Grape # Current gem version - VERSION = '0.1.5' + VERSION = '0.1.6' end end end diff --git a/instrumentation/grape/opentelemetry-instrumentation-grape.gemspec b/instrumentation/grape/opentelemetry-instrumentation-grape.gemspec index 1d59fb9a6..08162fda1 100644 --- a/instrumentation/grape/opentelemetry-instrumentation-grape.gemspec +++ b/instrumentation/grape/opentelemetry-instrumentation-grape.gemspec @@ -39,7 +39,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'rack-test' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/grape/test/test_helper.rb b/instrumentation/grape/test/test_helper.rb index b079d1571..7b12c181c 100644 --- a/instrumentation/grape/test/test_helper.rb +++ b/instrumentation/grape/test/test_helper.rb @@ -23,7 +23,7 @@ # Helper functions def uninstall_and_cleanup - instrumentation.instance_variable_set('@installed', false) + instrumentation.instance_variable_set(:@installed, false) unsubscribe EXPORTER.reset end diff --git a/instrumentation/graphql/CHANGELOG.md b/instrumentation/graphql/CHANGELOG.md index 1fb6b31a0..c75886695 100644 --- a/instrumentation/graphql/CHANGELOG.md +++ b/instrumentation/graphql/CHANGELOG.md @@ -1,5 +1,13 @@ # Release History: opentelemetry-instrumentation-graphql +### v0.27.0 / 2023-11-28 + +* CHANGED: Performance optimization cache attribute hashes [#723](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/723) + +### v0.26.8 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.26.7 / 2023-09-27 * FIXED: Micro optimization: build Hash w/ {} (https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/665) diff --git a/instrumentation/graphql/lib/opentelemetry/instrumentation/graphql/tracers/graphql_trace.rb b/instrumentation/graphql/lib/opentelemetry/instrumentation/graphql/tracers/graphql_trace.rb index 881aa10ec..84ebae562 100644 --- a/instrumentation/graphql/lib/opentelemetry/instrumentation/graphql/tracers/graphql_trace.rb +++ b/instrumentation/graphql/lib/opentelemetry/instrumentation/graphql/tracers/graphql_trace.rb @@ -16,8 +16,46 @@ module GraphQLTrace # rubocop:disable Metrics/ModuleLength def initialize(trace_scalars: false, **_options) @trace_scalars = trace_scalars @_otel_field_key_cache = Hash.new { |h, k| h[k] = _otel_field_key(k) } + @_otel_field_key_cache.compare_by_identity @_otel_authorized_key_cache = Hash.new { |h, k| h[k] = _otel_authorized_key(k) } + @_otel_authorized_key_cache.compare_by_identity @_otel_resolve_type_key_cache = Hash.new { |h, k| h[k] = _otel_resolve_type_key(k) } + @_otel_resolve_type_key_cache.compare_by_identity + + @_otel_type_attrs_cache = Hash.new do |h, type| + h[type] = { + 'graphql.type.name' => type.graphql_name, + 'graphql.lazy' => false + }.freeze + end + @_otel_type_attrs_cache.compare_by_identity + + @_otel_lazy_type_attrs_cache = Hash.new do |h, type| + h[type] = { + 'graphql.type.name' => type.graphql_name, + 'graphql.lazy' => true + }.freeze + end + @_otel_lazy_type_attrs_cache.compare_by_identity + + @_otel_field_attrs_cache = Hash.new do |h, field| + h[field] = { + 'graphql.field.parent' => field.owner&.graphql_name, + 'graphql.field.name' => field.graphql_name, + 'graphql.lazy' => false + }.freeze + end + @_otel_field_attrs_cache.compare_by_identity + + @_otel_lazy_field_attrs_cache = Hash.new do |h, field| + h[field] = { + 'graphql.field.parent' => field.owner&.graphql_name, + 'graphql.field.name' => field.graphql_name, + 'graphql.lazy' => true + }.freeze + end + @_otel_lazy_field_attrs_cache.compare_by_identity + super end @@ -73,26 +111,18 @@ def execute_query_lazy(query:, multiplex:, &block) def execute_field(field:, query:, ast_node:, arguments:, object:, &block) platform_key = _otel_execute_field_key(field: field) - return super unless platform_key + return super(field: field, query: query, ast_node: ast_node, object: object, arguments: arguments, &block) unless platform_key - attributes = { - 'graphql.field.parent' => field.owner&.graphql_name, - 'graphql.field.name' => field.graphql_name, - 'graphql.lazy' => false - } + attributes = @_otel_field_attrs_cache[field] tracer.in_span(platform_key, attributes: attributes, &block) end def execute_field_lazy(field:, query:, ast_node:, arguments:, object:, &block) platform_key = _otel_execute_field_key(field: field) - return super unless platform_key + return super(field: field, query: query, ast_node: ast_node, object: object, arguments: arguments, &block) unless platform_key - attributes = { - 'graphql.field.parent' => field.owner&.graphql_name, - 'graphql.field.name' => field.graphql_name, - 'graphql.lazy' => true - } + attributes = @_otel_lazy_field_attrs_cache[field] tracer.in_span(platform_key, attributes: attributes, &block) end @@ -101,10 +131,7 @@ def authorized(query:, type:, object:, &block) platform_key = @_otel_authorized_key_cache[type] return super unless platform_key - attributes = { - 'graphql.type.name' => type.graphql_name, - 'graphql.lazy' => false - } + attributes = @_otel_type_attrs_cache[type] tracer.in_span(platform_key, attributes: attributes, &block) end @@ -113,33 +140,19 @@ def authorized_lazy(query:, type:, object:, &block) platform_key = @_otel_authorized_key_cache[type] return super unless platform_key - attributes = { - 'graphql.type.name' => type.graphql_name, - 'graphql.lazy' => true - } - + attributes = @_otel_lazy_type_attrs_cache[type] tracer.in_span(platform_key, attributes: attributes, &block) end def resolve_type(query:, type:, object:, &block) platform_key = @_otel_resolve_type_key_cache[type] - - attributes = { - 'graphql.type.name' => type.graphql_name, - 'graphql.lazy' => false - } - + attributes = @_otel_type_attrs_cache[type] tracer.in_span(platform_key, attributes: attributes, &block) end def resolve_type_lazy(query:, type:, object:, &block) platform_key = @_otel_resolve_type_key_cache[type] - - attributes = { - 'graphql.type.name' => type.graphql_name, - 'graphql.lazy' => true - } - + attributes = @_otel_lazy_type_attrs_cache[type] tracer.in_span(platform_key, attributes: attributes, &block) end diff --git a/instrumentation/graphql/lib/opentelemetry/instrumentation/graphql/version.rb b/instrumentation/graphql/lib/opentelemetry/instrumentation/graphql/version.rb index aca6963d2..db8496fff 100644 --- a/instrumentation/graphql/lib/opentelemetry/instrumentation/graphql/version.rb +++ b/instrumentation/graphql/lib/opentelemetry/instrumentation/graphql/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module GraphQL - VERSION = '0.26.7' + VERSION = '0.27.0' end end end diff --git a/instrumentation/graphql/opentelemetry-instrumentation-graphql.gemspec b/instrumentation/graphql/opentelemetry-instrumentation-graphql.gemspec index c5a8678c3..b3f06ed7b 100644 --- a/instrumentation/graphql/opentelemetry-instrumentation-graphql.gemspec +++ b/instrumentation/graphql/opentelemetry-instrumentation-graphql.gemspec @@ -35,7 +35,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/graphql/test/instrumentation/graphql/tracers/graphql_trace_test.rb b/instrumentation/graphql/test/instrumentation/graphql/tracers/graphql_trace_test.rb index 5d4111b74..59de00473 100644 --- a/instrumentation/graphql/test/instrumentation/graphql/tracers/graphql_trace_test.rb +++ b/instrumentation/graphql/test/instrumentation/graphql/tracers/graphql_trace_test.rb @@ -291,7 +291,7 @@ describe 'compatibility with other tracers' do let(:config) { { enable_platform_field: true } } - if GraphQL::Tracing.const_defined?('PlatformTrace') + if GraphQL::Tracing.const_defined?(:PlatformTrace) module CustomPlatformTracer include ::GraphQL::Tracing::PlatformTrace diff --git a/instrumentation/gruf/opentelemetry-instrumentation-gruf.gemspec b/instrumentation/gruf/opentelemetry-instrumentation-gruf.gemspec index 4a7a0b550..70b299c9f 100644 --- a/instrumentation/gruf/opentelemetry-instrumentation-gruf.gemspec +++ b/instrumentation/gruf/opentelemetry-instrumentation-gruf.gemspec @@ -36,7 +36,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.0' spec.add_development_dependency 'opentelemetry-test-helpers' spec.add_development_dependency 'rake', '~> 12.3.3' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/http/CHANGELOG.md b/instrumentation/http/CHANGELOG.md index e27725612..4063891f7 100644 --- a/instrumentation/http/CHANGELOG.md +++ b/instrumentation/http/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-http +### v0.23.2 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.23.1 / 2023-06-05 * FIXED: Base config options diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/client.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/client.rb index 21153a926..f814e1a65 100644 --- a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/client.rb +++ b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/client.rb @@ -43,7 +43,7 @@ def annotate_span_with_response!(span, response) status_code = response.status.to_i span.set_attribute('http.status_code', status_code) - span.status = OpenTelemetry::Trace::Status.error unless (100..399).include?(status_code.to_i) + span.status = OpenTelemetry::Trace::Status.error unless (100..399).cover?(status_code.to_i) end def create_request_span_name(request_method, request_path) diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/version.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/version.rb index 482b29b2f..03c0bd0ab 100644 --- a/instrumentation/http/lib/opentelemetry/instrumentation/http/version.rb +++ b/instrumentation/http/lib/opentelemetry/instrumentation/http/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module HTTP - VERSION = '0.23.1' + VERSION = '0.23.2' end end end diff --git a/instrumentation/http/opentelemetry-instrumentation-http.gemspec b/instrumentation/http/opentelemetry-instrumentation-http.gemspec index c8cd137b4..68442db16 100644 --- a/instrumentation/http/opentelemetry-instrumentation-http.gemspec +++ b/instrumentation/http/opentelemetry-instrumentation-http.gemspec @@ -36,7 +36,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/http/test/instrumentation/http/patches/client_test.rb b/instrumentation/http/test/instrumentation/http/patches/client_test.rb index 65ba6569c..8d62a5b07 100644 --- a/instrumentation/http/test/instrumentation/http/patches/client_test.rb +++ b/instrumentation/http/test/instrumentation/http/patches/client_test.rb @@ -26,7 +26,7 @@ propagator = OpenTelemetry::Trace::Propagation::TraceContext.text_map_propagator OpenTelemetry.propagation = propagator # simulate a fresh install: - instrumentation.instance_variable_set('@installed', false) + instrumentation.instance_variable_set(:@installed, false) instrumentation.install(config) stub_request(:get, 'http://example.com/success').to_return(status: 200) stub_request(:post, 'http://example.com/failure').to_return(status: 500) @@ -128,7 +128,7 @@ let(:span_name_formatter) do # demonstrate simple addition of path and string to span name: lambda { |request_method, request_path| - return "HTTP #{request_method} #{request_path} miniswan" + "HTTP #{request_method} #{request_path} miniswan" } end diff --git a/instrumentation/http_client/CHANGELOG.md b/instrumentation/http_client/CHANGELOG.md index cd3058832..45889acfb 100644 --- a/instrumentation/http_client/CHANGELOG.md +++ b/instrumentation/http_client/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-http_client +### v0.22.3 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.22.2 / 2023-07-21 * ADDED: Update `opentelemetry-common` from [0.19.3 to 0.20.0](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/537) diff --git a/instrumentation/http_client/lib/opentelemetry/instrumentation/http_client/patches/client.rb b/instrumentation/http_client/lib/opentelemetry/instrumentation/http_client/patches/client.rb index fcdae5e70..a71c8ad7b 100644 --- a/instrumentation/http_client/lib/opentelemetry/instrumentation/http_client/patches/client.rb +++ b/instrumentation/http_client/lib/opentelemetry/instrumentation/http_client/patches/client.rb @@ -42,7 +42,7 @@ def annotate_span_with_response!(span, response) status_code = response.status_code.to_i span.set_attribute('http.status_code', status_code) - span.status = OpenTelemetry::Trace::Status.error unless (100..399).include?(status_code.to_i) + span.status = OpenTelemetry::Trace::Status.error unless (100..399).cover?(status_code.to_i) end def tracer diff --git a/instrumentation/http_client/lib/opentelemetry/instrumentation/http_client/version.rb b/instrumentation/http_client/lib/opentelemetry/instrumentation/http_client/version.rb index b5c7bdd29..df4af6cac 100644 --- a/instrumentation/http_client/lib/opentelemetry/instrumentation/http_client/version.rb +++ b/instrumentation/http_client/lib/opentelemetry/instrumentation/http_client/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module HttpClient - VERSION = '0.22.2' + VERSION = '0.22.3' end end end diff --git a/instrumentation/http_client/opentelemetry-instrumentation-http_client.gemspec b/instrumentation/http_client/opentelemetry-instrumentation-http_client.gemspec index 6bd4328fe..9beb7fbb9 100644 --- a/instrumentation/http_client/opentelemetry-instrumentation-http_client.gemspec +++ b/instrumentation/http_client/opentelemetry-instrumentation-http_client.gemspec @@ -36,7 +36,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/httpx/CHANGELOG.md b/instrumentation/httpx/CHANGELOG.md index 8f13d82f7..d77ecae3c 100644 --- a/instrumentation/httpx/CHANGELOG.md +++ b/instrumentation/httpx/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-httpx +### v0.1.1 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.1.0 / 2023-11-06 * Initial Release. diff --git a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/plugin.rb b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/plugin.rb index 10738e1ed..137fca976 100644 --- a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/plugin.rb +++ b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/plugin.rb @@ -16,7 +16,7 @@ def initialize(request) end def call - @request.on(:response, &method(:finish)) + @request.on(:response, &method(:finish)) # rubocop:disable Performance/MethodObjectAsBlock uri = @request.uri request_method = @request.verb @@ -54,7 +54,7 @@ def finish(response) @span.status = Trace::Status.error("Unhandled exception of type: #{response.error.class}") else @span.set_attribute(OpenTelemetry::SemanticConventions::Trace::HTTP_STATUS_CODE, response.status) - @span.status = Trace::Status.error unless (100..399).include?(response.status) + @span.status = Trace::Status.error unless (100..399).cover?(response.status) end OpenTelemetry::Context.detach(@trace_token) if @trace_token diff --git a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb index b05472d1e..da576ff94 100644 --- a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb +++ b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module HTTPX - VERSION = '0.1.0' + VERSION = '0.1.1' end end end diff --git a/instrumentation/httpx/opentelemetry-instrumentation-httpx.gemspec b/instrumentation/httpx/opentelemetry-instrumentation-httpx.gemspec index 6531619a7..296177a31 100644 --- a/instrumentation/httpx/opentelemetry-instrumentation-httpx.gemspec +++ b/instrumentation/httpx/opentelemetry-instrumentation-httpx.gemspec @@ -36,7 +36,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/koala/opentelemetry-instrumentation-koala.gemspec b/instrumentation/koala/opentelemetry-instrumentation-koala.gemspec index 578fd1e1c..a3b5ae261 100644 --- a/instrumentation/koala/opentelemetry-instrumentation-koala.gemspec +++ b/instrumentation/koala/opentelemetry-instrumentation-koala.gemspec @@ -37,7 +37,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/lmdb/opentelemetry-instrumentation-lmdb.gemspec b/instrumentation/lmdb/opentelemetry-instrumentation-lmdb.gemspec index f5c24419d..fbc70cbbe 100644 --- a/instrumentation/lmdb/opentelemetry-instrumentation-lmdb.gemspec +++ b/instrumentation/lmdb/opentelemetry-instrumentation-lmdb.gemspec @@ -35,7 +35,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/mongo/CHANGELOG.md b/instrumentation/mongo/CHANGELOG.md index ec1ebe964..671a8b733 100644 --- a/instrumentation/mongo/CHANGELOG.md +++ b/instrumentation/mongo/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-mongo +### v0.22.2 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.22.1 / 2023-06-05 * FIXED: Base config options diff --git a/instrumentation/mongo/lib/opentelemetry/instrumentation/mongo/command_serializer.rb b/instrumentation/mongo/lib/opentelemetry/instrumentation/mongo/command_serializer.rb index 3d3c217e6..3696c102f 100644 --- a/instrumentation/mongo/lib/opentelemetry/instrumentation/mongo/command_serializer.rb +++ b/instrumentation/mongo/lib/opentelemetry/instrumentation/mongo/command_serializer.rb @@ -75,7 +75,7 @@ def build_pipeline pipeline = command['pipeline'] return unless pipeline - payload['pipeline'] = pipeline.map(&method(:mask)) + payload['pipeline'] = pipeline.map { |x| mask(x) } end def add_val(payload, command, key) diff --git a/instrumentation/mongo/lib/opentelemetry/instrumentation/mongo/version.rb b/instrumentation/mongo/lib/opentelemetry/instrumentation/mongo/version.rb index 97c32b4e8..db4bb7e65 100644 --- a/instrumentation/mongo/lib/opentelemetry/instrumentation/mongo/version.rb +++ b/instrumentation/mongo/lib/opentelemetry/instrumentation/mongo/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Mongo - VERSION = '0.22.1' + VERSION = '0.22.2' end end end diff --git a/instrumentation/mongo/opentelemetry-instrumentation-mongo.gemspec b/instrumentation/mongo/opentelemetry-instrumentation-mongo.gemspec index 38fa563e1..60ebed8cb 100644 --- a/instrumentation/mongo/opentelemetry-instrumentation-mongo.gemspec +++ b/instrumentation/mongo/opentelemetry-instrumentation-mongo.gemspec @@ -37,7 +37,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'pry' spec.add_development_dependency 'pry-byebug' unless RUBY_ENGINE == 'jruby' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/mysql2/opentelemetry-instrumentation-mysql2.gemspec b/instrumentation/mysql2/opentelemetry-instrumentation-mysql2.gemspec index e4cdc1c55..710cb3a72 100644 --- a/instrumentation/mysql2/opentelemetry-instrumentation-mysql2.gemspec +++ b/instrumentation/mysql2/opentelemetry-instrumentation-mysql2.gemspec @@ -36,7 +36,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'pry' spec.add_development_dependency 'pry-byebug' unless RUBY_ENGINE == 'jruby' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/net_http/CHANGELOG.md b/instrumentation/net_http/CHANGELOG.md index 8347cb2e1..1e4c9deca 100644 --- a/instrumentation/net_http/CHANGELOG.md +++ b/instrumentation/net_http/CHANGELOG.md @@ -1,5 +1,13 @@ # Release History: opentelemetry-instrumentation-net_http +### v0.22.4 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + +### v0.22.3 / 2023-11-22 + +* FIXED: Update `Net::HTTP` instrumentation to no-op on untraced contexts + ### v0.22.2 / 2023-07-21 * ADDED: Update `opentelemetry-common` from [0.19.3 to 0.20.0](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/537) diff --git a/instrumentation/net_http/lib/opentelemetry/instrumentation/net/http/patches/instrumentation.rb b/instrumentation/net_http/lib/opentelemetry/instrumentation/net/http/patches/instrumentation.rb index 32a67122c..2edcc2274 100644 --- a/instrumentation/net_http/lib/opentelemetry/instrumentation/net/http/patches/instrumentation.rb +++ b/instrumentation/net_http/lib/opentelemetry/instrumentation/net/http/patches/instrumentation.rb @@ -78,7 +78,7 @@ def annotate_span_with_response!(span, response) status_code = response.code.to_i span.set_attribute(OpenTelemetry::SemanticConventions::Trace::HTTP_STATUS_CODE, status_code) - span.status = OpenTelemetry::Trace::Status.error unless (100..399).include?(status_code.to_i) + span.status = OpenTelemetry::Trace::Status.error unless (100..399).cover?(status_code.to_i) end def tracer @@ -86,12 +86,20 @@ def tracer end def untraced? + untraced_context? || untraced_host? + end + + def untraced_host? return true if Net::HTTP::Instrumentation.instance.config[:untraced_hosts]&.any? do |host| host.is_a?(Regexp) ? host.match?(@address) : host == @address end false end + + def untraced_context? + OpenTelemetry::Common::Utilities.untraced? + end end end end diff --git a/instrumentation/net_http/lib/opentelemetry/instrumentation/net/http/version.rb b/instrumentation/net_http/lib/opentelemetry/instrumentation/net/http/version.rb index 567ff1aa0..b61097b9c 100644 --- a/instrumentation/net_http/lib/opentelemetry/instrumentation/net/http/version.rb +++ b/instrumentation/net_http/lib/opentelemetry/instrumentation/net/http/version.rb @@ -8,7 +8,7 @@ module OpenTelemetry module Instrumentation module Net module HTTP - VERSION = '0.22.2' + VERSION = '0.22.4' end end end diff --git a/instrumentation/net_http/opentelemetry-instrumentation-net_http.gemspec b/instrumentation/net_http/opentelemetry-instrumentation-net_http.gemspec index d61af1b88..3f8c366e2 100644 --- a/instrumentation/net_http/opentelemetry-instrumentation-net_http.gemspec +++ b/instrumentation/net_http/opentelemetry-instrumentation-net_http.gemspec @@ -34,7 +34,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0.1' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rspec-mocks' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/net_http/test/opentelemetry/instrumentation/net/http/instrumentation_test.rb b/instrumentation/net_http/test/opentelemetry/instrumentation/net/http/instrumentation_test.rb index 2ab764299..fb4d61a92 100644 --- a/instrumentation/net_http/test/opentelemetry/instrumentation/net/http/instrumentation_test.rb +++ b/instrumentation/net_http/test/opentelemetry/instrumentation/net/http/instrumentation_test.rb @@ -178,6 +178,34 @@ _(span.attributes['net.peer.port']).must_equal(80) end end + + describe 'untraced context' do + it 'no-ops on #request' do + # Calling `tracer.in_span` within an untraced context causes the logging of "called + # finish on an ended Span" messages. To avoid log noise, the instrumentation must + # no-op (i.e., not call `tracer.in_span`) when the context is untraced. + expect(instrumentation.tracer).not_to receive(:in_span) + + OpenTelemetry::Common::Utilities.untraced do + Net::HTTP.get('example.com', '/body') + end + + _(exporter.finished_spans.size).must_equal 0 + end + + it 'no-ops on #connect' do + expect(instrumentation.tracer).not_to receive(:in_span) + + OpenTelemetry::Common::Utilities.untraced do + uri = URI.parse('http://example.com/body') + http = Net::HTTP.new(uri.host, uri.port) + http.send(:connect) + http.send(:do_finish) + end + + _(exporter.finished_spans.size).must_equal 0 + end + end end describe '#connect' do diff --git a/instrumentation/net_http/test/test_helper.rb b/instrumentation/net_http/test/test_helper.rb index d617b91c2..921a7e11c 100644 --- a/instrumentation/net_http/test/test_helper.rb +++ b/instrumentation/net_http/test/test_helper.rb @@ -9,6 +9,7 @@ Bundler.require(:default, :development, :test) require 'minitest/autorun' +require 'rspec/mocks/minitest_integration' require 'webmock/minitest' # global opentelemetry-sdk setup: diff --git a/instrumentation/pg/CHANGELOG.md b/instrumentation/pg/CHANGELOG.md index f5d811f66..a980aa738 100644 --- a/instrumentation/pg/CHANGELOG.md +++ b/instrumentation/pg/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-pg +### v0.26.1 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.26.0 / 2023-10-16 * BREAKING CHANGE: Obfuscation for mysql2, dalli and postgresql as default option for db_statement diff --git a/instrumentation/pg/lib/opentelemetry/instrumentation/pg/version.rb b/instrumentation/pg/lib/opentelemetry/instrumentation/pg/version.rb index 35f70e60f..15ed8f008 100644 --- a/instrumentation/pg/lib/opentelemetry/instrumentation/pg/version.rb +++ b/instrumentation/pg/lib/opentelemetry/instrumentation/pg/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module PG - VERSION = '0.26.0' + VERSION = '0.26.1' end end end diff --git a/instrumentation/pg/opentelemetry-instrumentation-pg.gemspec b/instrumentation/pg/opentelemetry-instrumentation-pg.gemspec index 2c77b6629..d77bedd76 100644 --- a/instrumentation/pg/opentelemetry-instrumentation-pg.gemspec +++ b/instrumentation/pg/opentelemetry-instrumentation-pg.gemspec @@ -37,7 +37,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'pg', '>= 1.1.0' spec.add_development_dependency 'pry' spec.add_development_dependency 'pry-byebug' unless RUBY_ENGINE == 'jruby' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/pg/test/opentelemetry/instrumentation/pg/instrumentation_test.rb b/instrumentation/pg/test/opentelemetry/instrumentation/pg/instrumentation_test.rb index 32dedf646..332e90720 100644 --- a/instrumentation/pg/test/opentelemetry/instrumentation/pg/instrumentation_test.rb +++ b/instrumentation/pg/test/opentelemetry/instrumentation/pg/instrumentation_test.rb @@ -346,7 +346,7 @@ client.query('SELECT 1') _(span.attributes['net.peer.name']).must_equal host - _(span.attributes['net.peer.port']).must_equal port.to_i if PG.const_defined?('DEF_PORT') + _(span.attributes['net.peer.port']).must_equal port.to_i if PG.const_defined?(:DEF_PORT) end end end unless ENV['OMIT_SERVICES'] diff --git a/instrumentation/que/CHANGELOG.md b/instrumentation/que/CHANGELOG.md index 91c8a240c..3769ba41e 100644 --- a/instrumentation/que/CHANGELOG.md +++ b/instrumentation/que/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-que +### v0.7.1 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.7.0 / 2023-09-07 * FIXED: Align messaging instrumentation operation names diff --git a/instrumentation/que/lib/opentelemetry/instrumentation/que/middlewares/server_middleware.rb b/instrumentation/que/lib/opentelemetry/instrumentation/que/middlewares/server_middleware.rb index 1e5c0c15d..386a6d5cd 100644 --- a/instrumentation/que/lib/opentelemetry/instrumentation/que/middlewares/server_middleware.rb +++ b/instrumentation/que/lib/opentelemetry/instrumentation/que/middlewares/server_middleware.rb @@ -20,7 +20,7 @@ def self.call(job, &block) OpenTelemetry::Context.with_current(extracted_context) do if otel_config[:propagation_style] == :child tracer.in_span(span_name, attributes: attributes, kind: :consumer) do |span| - block.call + yield enhance_span_after_job_completion(span, job) end else @@ -28,7 +28,7 @@ def self.call(job, &block) root_span = tracer.start_root_span(span_name, attributes: attributes, links: span_links, kind: :consumer) OpenTelemetry::Trace.with_span(root_span) do |span| - block.call + yield enhance_span_after_job_completion(span, job) ensure root_span.finish diff --git a/instrumentation/que/lib/opentelemetry/instrumentation/que/version.rb b/instrumentation/que/lib/opentelemetry/instrumentation/que/version.rb index b49a45f06..873b81bed 100644 --- a/instrumentation/que/lib/opentelemetry/instrumentation/que/version.rb +++ b/instrumentation/que/lib/opentelemetry/instrumentation/que/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Que - VERSION = '0.7.0' + VERSION = '0.7.1' end end end diff --git a/instrumentation/que/opentelemetry-instrumentation-que.gemspec b/instrumentation/que/opentelemetry-instrumentation-que.gemspec index af9982566..1ce51a70a 100644 --- a/instrumentation/que/opentelemetry-instrumentation-que.gemspec +++ b/instrumentation/que/opentelemetry-instrumentation-que.gemspec @@ -36,9 +36,10 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'pg', '~> 1.1' - spec.add_development_dependency 'que', '~> 1.2.0' + spec.add_development_dependency 'que' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/racecar/opentelemetry-instrumentation-racecar.gemspec b/instrumentation/racecar/opentelemetry-instrumentation-racecar.gemspec index cb52a1d09..142715ecd 100644 --- a/instrumentation/racecar/opentelemetry-instrumentation-racecar.gemspec +++ b/instrumentation/racecar/opentelemetry-instrumentation-racecar.gemspec @@ -37,7 +37,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'racecar', '~> 2.7' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/rack/CHANGELOG.md b/instrumentation/rack/CHANGELOG.md index bc40bd3bb..3df214395 100644 --- a/instrumentation/rack/CHANGELOG.md +++ b/instrumentation/rack/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-rack +### v0.23.5 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.23.4 / 2023-08-03 * FIXED: Remove inline linter rules diff --git a/instrumentation/rack/README.md b/instrumentation/rack/README.md index e63fc02bc..f154e504f 100644 --- a/instrumentation/rack/README.md +++ b/instrumentation/rack/README.md @@ -12,6 +12,19 @@ gem install opentelemetry-instrumentation-rack Or, if you use [bundler][bundler-home], include `opentelemetry-instrumentation-rack` in your `Gemfile`. +### Version Compatibility + +Older versions of Rack are not supported by the latest version of this instrumentation. If you are using an older version of Rack and need an earlier version of this instrumentation, then consider installing and pinning the compatible gem version, e.g.: + +```console +gem opentelemetry-instrumentation-rack, "" +``` + +| Rack Version | Instrumentation Version | +| ------------ | ----------------------- | +| `< 2.0` | `= 0.22.1` | +| `>= 2.0` | `~> 0.23` | + ## Usage To use the instrumentation, call `use` with the name of the instrumentation: diff --git a/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/tracer_middleware.rb b/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/tracer_middleware.rb index d68c7400a..353d5192f 100644 --- a/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/tracer_middleware.rb +++ b/instrumentation/rack/lib/opentelemetry/instrumentation/rack/middlewares/tracer_middleware.rb @@ -150,7 +150,7 @@ def create_request_span_name(request_uri_or_path_info, env) end def set_attributes_after_request(span, status, headers, _response) - span.status = OpenTelemetry::Trace::Status.error unless (100..499).include?(status.to_i) + span.status = OpenTelemetry::Trace::Status.error unless (100..499).cover?(status.to_i) span.set_attribute('http.status_code', status) # NOTE: if data is available, it would be good to do this: diff --git a/instrumentation/rack/lib/opentelemetry/instrumentation/rack/version.rb b/instrumentation/rack/lib/opentelemetry/instrumentation/rack/version.rb index ae0a2aa0f..07c864bd7 100644 --- a/instrumentation/rack/lib/opentelemetry/instrumentation/rack/version.rb +++ b/instrumentation/rack/lib/opentelemetry/instrumentation/rack/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Rack - VERSION = '0.23.4' + VERSION = '0.23.5' end end end diff --git a/instrumentation/rack/opentelemetry-instrumentation-rack.gemspec b/instrumentation/rack/opentelemetry-instrumentation-rack.gemspec index 35d20b559..36fca16bb 100644 --- a/instrumentation/rack/opentelemetry-instrumentation-rack.gemspec +++ b/instrumentation/rack/opentelemetry-instrumentation-rack.gemspec @@ -39,7 +39,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'rack-test' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/rack/test/opentelemetry/instrumentation/rack/instrumentation_test.rb b/instrumentation/rack/test/opentelemetry/instrumentation/rack/instrumentation_test.rb index 2814bde0d..3e9529245 100644 --- a/instrumentation/rack/test/opentelemetry/instrumentation/rack/instrumentation_test.rb +++ b/instrumentation/rack/test/opentelemetry/instrumentation/rack/instrumentation_test.rb @@ -13,7 +13,7 @@ before do # simulate a fresh install: - instrumentation.instance_variable_set('@installed', false) + instrumentation.instance_variable_set(:@installed, false) instrumentation.config.clear end diff --git a/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/event_handler_test.rb b/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/event_handler_test.rb index ff43da7d1..d08857637 100644 --- a/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/event_handler_test.rb +++ b/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/event_handler_test.rb @@ -63,7 +63,7 @@ exporter.reset # simulate a fresh install: - instrumentation.instance_variable_set('@installed', false) + instrumentation.instance_variable_set(:@installed, false) instrumentation.install(config) end diff --git a/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/tracer_middleware_test.rb b/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/tracer_middleware_test.rb index 5e9df36e8..9deb47183 100644 --- a/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/tracer_middleware_test.rb +++ b/instrumentation/rack/test/opentelemetry/instrumentation/rack/middlewares/tracer_middleware_test.rb @@ -36,7 +36,7 @@ exporter.reset # simulate a fresh install: - instrumentation.instance_variable_set('@installed', false) + instrumentation.instance_variable_set(:@installed, false) instrumentation.install(config) # clear out cached config: @@ -49,7 +49,7 @@ after do # installation is 'global', so it should be reset: - instrumentation.instance_variable_set('@installed', false) + instrumentation.instance_variable_set(:@installed, false) instrumentation.install(default_config) end diff --git a/instrumentation/rails/CHANGELOG.md b/instrumentation/rails/CHANGELOG.md index 09c338f0f..e727af268 100644 --- a/instrumentation/rails/CHANGELOG.md +++ b/instrumentation/rails/CHANGELOG.md @@ -1,5 +1,15 @@ # Release History: opentelemetry-instrumentation-rails +### v0.29.1 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + +### v0.29.0 / 2023-11-22 + +* BREAKING CHANGE: Drop Rails 6.0 EOL + +* ADDED: Drop Rails 6.0 EOL + ### v0.28.1 / 2023-10-16 * FIXED: Add Rails 7.1 compatibility diff --git a/instrumentation/rails/example/trace_request_demonstration.ru b/instrumentation/rails/example/trace_request_demonstration.ru index 1a6f2b16d..1c74c0f39 100644 --- a/instrumentation/rails/example/trace_request_demonstration.ru +++ b/instrumentation/rails/example/trace_request_demonstration.ru @@ -23,7 +23,7 @@ require 'action_controller/railtie' class TraceRequestApp < Rails::Application config.root = __dir__ config.hosts << 'example.org' - secrets.secret_key_base = 'secret_key_base' + credentials.secret_key_base = 'secret_key_base' config.eager_load = false config.logger = Logger.new($stdout) Rails.logger = config.logger diff --git a/instrumentation/rails/lib/opentelemetry/instrumentation/rails/version.rb b/instrumentation/rails/lib/opentelemetry/instrumentation/rails/version.rb index a53ef0c6c..77fad1459 100644 --- a/instrumentation/rails/lib/opentelemetry/instrumentation/rails/version.rb +++ b/instrumentation/rails/lib/opentelemetry/instrumentation/rails/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Rails - VERSION = '0.28.1' + VERSION = '0.29.1' end end end diff --git a/instrumentation/rails/opentelemetry-instrumentation-rails.gemspec b/instrumentation/rails/opentelemetry-instrumentation-rails.gemspec index af60bd48f..4ceaf44cd 100644 --- a/instrumentation/rails/opentelemetry-instrumentation-rails.gemspec +++ b/instrumentation/rails/opentelemetry-instrumentation-rails.gemspec @@ -26,11 +26,11 @@ Gem::Specification.new do |spec| spec.required_ruby_version = '>= 3.0' spec.add_dependency 'opentelemetry-api', '~> 1.0' - spec.add_dependency 'opentelemetry-instrumentation-action_pack', '~> 0.7.0' - spec.add_dependency 'opentelemetry-instrumentation-action_view', '~> 0.6.0' - spec.add_dependency 'opentelemetry-instrumentation-active_job', '~> 0.6.0' - spec.add_dependency 'opentelemetry-instrumentation-active_record', '~> 0.6.1' - spec.add_dependency 'opentelemetry-instrumentation-active_support', '~> 0.4.1' + spec.add_dependency 'opentelemetry-instrumentation-action_pack', '~> 0.8.0' + spec.add_dependency 'opentelemetry-instrumentation-action_view', '~> 0.7.0' + spec.add_dependency 'opentelemetry-instrumentation-active_job', '~> 0.7.0' + spec.add_dependency 'opentelemetry-instrumentation-active_record', '~> 0.7.0' + spec.add_dependency 'opentelemetry-instrumentation-active_support', '~> 0.5.0' spec.add_dependency 'opentelemetry-instrumentation-base', '~> 0.22.1' spec.add_development_dependency 'appraisal', '~> 2.5' @@ -41,7 +41,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'rack-test', '~> 2.1.0' spec.add_development_dependency 'rails', '>= 6.1' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.22.0' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/rails/test/railtie/opentelemetry/instrumentation/rails/railtie_test.rb b/instrumentation/rails/test/railtie/opentelemetry/instrumentation/rails/railtie_test.rb index b3465aaf8..53911790d 100644 --- a/instrumentation/rails/test/railtie/opentelemetry/instrumentation/rails/railtie_test.rb +++ b/instrumentation/rails/test/railtie/opentelemetry/instrumentation/rails/railtie_test.rb @@ -9,10 +9,10 @@ class OpenTelemetry::Instrumentation::Rails::RailtieTest < ActiveSupport::TestCa include OpenTelemetry::SemanticConventions setup do - OpenTelemetry::Instrumentation.registry.instance_variable_get('@instrumentation').each do |i| - i.instance_variable_set('@instance', nil) + OpenTelemetry::Instrumentation.registry.instance_variable_get(:@instrumentation).each do |i| + i.instance_variable_set(:@instance, nil) end - OpenTelemetry::SDK::Resources::Resource.instance_variable_set('@default', nil) + OpenTelemetry::SDK::Resources::Resource.instance_variable_set(:@default, nil) OpenTelemetry.tracer_provider = OpenTelemetry::Internal::ProxyTracerProvider.new end @@ -20,7 +20,7 @@ class OpenTelemetry::Instrumentation::Rails::RailtieTest < ActiveSupport::TestCa OpenTelemetry::TestHelpers.with_env('OTEL_SERVICE_NAME' => nil) do run_initializer assert_instance_of(OpenTelemetry::SDK::Trace::TracerProvider, OpenTelemetry.tracer_provider) - assert_same(Rails.logger, OpenTelemetry.logger.instance_variable_get('@logger')) + assert_same(Rails.logger, OpenTelemetry.logger.instance_variable_get(:@logger)) end end diff --git a/instrumentation/rake/opentelemetry-instrumentation-rake.gemspec b/instrumentation/rake/opentelemetry-instrumentation-rake.gemspec index 086244590..3cf76962e 100644 --- a/instrumentation/rake/opentelemetry-instrumentation-rake.gemspec +++ b/instrumentation/rake/opentelemetry-instrumentation-rake.gemspec @@ -34,7 +34,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.0' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '>= 0.9.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/rdkafka/CHANGELOG.md b/instrumentation/rdkafka/CHANGELOG.md index 4b66d4fd6..9cdc2fbbb 100644 --- a/instrumentation/rdkafka/CHANGELOG.md +++ b/instrumentation/rdkafka/CHANGELOG.md @@ -1,5 +1,13 @@ # Release History: opentelemetry-instrumentation-rdkafka +### v0.4.2 / 2023-11-23 + +* FIXED: Retry Release of 0.4.1 [#730](https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues/730) + +### v0.4.1 / 2023-11-22 + +* FIXED: Get Rdkafka version from VERSION contant + ### v0.4.0 / 2023-09-07 * FIXED: Align messaging instrumentation operation names diff --git a/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/instrumentation.rb b/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/instrumentation.rb index 34c0ac27c..4d9919145 100644 --- a/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/instrumentation.rb +++ b/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/instrumentation.rb @@ -12,7 +12,7 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base MINIMUM_VERSION = Gem::Version.new('0.10.0') compatible do - Gem.loaded_specs['rdkafka'].version >= MINIMUM_VERSION + Gem::Version.new(::Rdkafka::VERSION) >= MINIMUM_VERSION end install do |_config| diff --git a/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/version.rb b/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/version.rb index 150141cec..747ab970e 100644 --- a/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/version.rb +++ b/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Rdkafka - VERSION = '0.4.0' + VERSION = '0.4.2' end end end diff --git a/instrumentation/rdkafka/opentelemetry-instrumentation-rdkafka.gemspec b/instrumentation/rdkafka/opentelemetry-instrumentation-rdkafka.gemspec index 9dbd122db..fbafb7a96 100644 --- a/instrumentation/rdkafka/opentelemetry-instrumentation-rdkafka.gemspec +++ b/instrumentation/rdkafka/opentelemetry-instrumentation-rdkafka.gemspec @@ -37,7 +37,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'pry-byebug' unless RUBY_ENGINE == 'jruby' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rdkafka', '>= 0.12' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/redis/opentelemetry-instrumentation-redis.gemspec b/instrumentation/redis/opentelemetry-instrumentation-redis.gemspec index 3b8b39298..491456f17 100644 --- a/instrumentation/redis/opentelemetry-instrumentation-redis.gemspec +++ b/instrumentation/redis/opentelemetry-instrumentation-redis.gemspec @@ -34,9 +34,10 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'redis', '~> 4.1.0' + spec.add_development_dependency 'redis', '~> 4.1' spec.add_development_dependency 'redis-client', '~> 0.7' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/resque/opentelemetry-instrumentation-resque.gemspec b/instrumentation/resque/opentelemetry-instrumentation-resque.gemspec index 6294c5453..61172db99 100644 --- a/instrumentation/resque/opentelemetry-instrumentation-resque.gemspec +++ b/instrumentation/resque/opentelemetry-instrumentation-resque.gemspec @@ -35,7 +35,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'resque' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/restclient/CHANGELOG.md b/instrumentation/restclient/CHANGELOG.md index 3575888c7..93f93e602 100644 --- a/instrumentation/restclient/CHANGELOG.md +++ b/instrumentation/restclient/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-restclient +### v0.22.3 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.22.2 / 2023-07-21 * ADDED: Update `opentelemetry-common` from [0.19.3 to 0.20.0](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/537) diff --git a/instrumentation/restclient/lib/opentelemetry/instrumentation/restclient/patches/request.rb b/instrumentation/restclient/lib/opentelemetry/instrumentation/restclient/patches/request.rb index dd98bf912..7ba48061b 100644 --- a/instrumentation/restclient/lib/opentelemetry/instrumentation/restclient/patches/request.rb +++ b/instrumentation/restclient/lib/opentelemetry/instrumentation/restclient/patches/request.rb @@ -49,12 +49,12 @@ def trace_request # If so, add additional attributes. if response.is_a?(::RestClient::Response) span.set_attribute('http.status_code', response.code) - span.status = OpenTelemetry::Trace::Status.error unless (100..399).include?(response.code.to_i) + span.status = OpenTelemetry::Trace::Status.error unless (100..399).cover?(response.code.to_i) end end rescue ::RestClient::ExceptionWithResponse => e span.set_attribute('http.status_code', e.http_code) - span.status = OpenTelemetry::Trace::Status.error unless (100..399).include?(e.http_code.to_i) + span.status = OpenTelemetry::Trace::Status.error unless (100..399).cover?(e.http_code.to_i) raise e ensure diff --git a/instrumentation/restclient/lib/opentelemetry/instrumentation/restclient/version.rb b/instrumentation/restclient/lib/opentelemetry/instrumentation/restclient/version.rb index a9d94fbfc..47e4b1e0b 100644 --- a/instrumentation/restclient/lib/opentelemetry/instrumentation/restclient/version.rb +++ b/instrumentation/restclient/lib/opentelemetry/instrumentation/restclient/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module RestClient - VERSION = '0.22.2' + VERSION = '0.22.3' end end end diff --git a/instrumentation/restclient/opentelemetry-instrumentation-restclient.gemspec b/instrumentation/restclient/opentelemetry-instrumentation-restclient.gemspec index 42aaaa0fe..7d392fadf 100644 --- a/instrumentation/restclient/opentelemetry-instrumentation-restclient.gemspec +++ b/instrumentation/restclient/opentelemetry-instrumentation-restclient.gemspec @@ -34,8 +34,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'rest-client', '~> 2.1.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rest-client', '~> 2.0' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/rspec/CHANGELOG.md b/instrumentation/rspec/CHANGELOG.md index f246adfa2..3d8448414 100644 --- a/instrumentation/rspec/CHANGELOG.md +++ b/instrumentation/rspec/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-instrumentation-rspec +### v0.3.2 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.3.1 / 2023-06-05 * FIXED: Base config options diff --git a/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/formatter.rb b/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/formatter.rb index 538625c23..11a37b8f8 100644 --- a/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/formatter.rb +++ b/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/formatter.rb @@ -121,7 +121,7 @@ def strip_console_codes(string) end def multiple_failure_message(exception) - exception.failures.map(&:message).map(&method(:strip_console_codes)).join("\n\n") + exception.failures.map(&:message).map { |x| strip_console_codes(x) }.join("\n\n") end end end diff --git a/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/version.rb b/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/version.rb index dc6826d98..b27e31705 100644 --- a/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/version.rb +++ b/instrumentation/rspec/lib/opentelemetry/instrumentation/rspec/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module RSpec - VERSION = '0.3.1' + VERSION = '0.3.2' end end end diff --git a/instrumentation/rspec/opentelemetry-instrumentation-rspec.gemspec b/instrumentation/rspec/opentelemetry-instrumentation-rspec.gemspec index 976bd7c10..4e3089ec9 100644 --- a/instrumentation/rspec/opentelemetry-instrumentation-rspec.gemspec +++ b/instrumentation/rspec/opentelemetry-instrumentation-rspec.gemspec @@ -35,7 +35,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec', '~> 3.10.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/ruby_kafka/lib/opentelemetry/instrumentation/ruby_kafka/instrumentation.rb b/instrumentation/ruby_kafka/lib/opentelemetry/instrumentation/ruby_kafka/instrumentation.rb index 2fd61a413..c2c045e3e 100644 --- a/instrumentation/ruby_kafka/lib/opentelemetry/instrumentation/ruby_kafka/instrumentation.rb +++ b/instrumentation/ruby_kafka/lib/opentelemetry/instrumentation/ruby_kafka/instrumentation.rb @@ -22,7 +22,7 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base end compatible do - (!gem_version.nil? && gem_version >= MINIMUM_VERSION) + !gem_version.nil? && gem_version >= MINIMUM_VERSION end private diff --git a/instrumentation/ruby_kafka/opentelemetry-instrumentation-ruby_kafka.gemspec b/instrumentation/ruby_kafka/opentelemetry-instrumentation-ruby_kafka.gemspec index 740399830..884799779 100644 --- a/instrumentation/ruby_kafka/opentelemetry-instrumentation-ruby_kafka.gemspec +++ b/instrumentation/ruby_kafka/opentelemetry-instrumentation-ruby_kafka.gemspec @@ -34,7 +34,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'ruby-kafka' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/sidekiq/opentelemetry-instrumentation-sidekiq.gemspec b/instrumentation/sidekiq/opentelemetry-instrumentation-sidekiq.gemspec index 009da600c..0aabd6b60 100644 --- a/instrumentation/sidekiq/opentelemetry-instrumentation-sidekiq.gemspec +++ b/instrumentation/sidekiq/opentelemetry-instrumentation-sidekiq.gemspec @@ -36,8 +36,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' - spec.add_development_dependency 'sidekiq', '~> 5.2.0' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' + spec.add_development_dependency 'sidekiq' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/sinatra/Appraisals b/instrumentation/sinatra/Appraisals index 77bc21d6f..f4ebf5e8a 100644 --- a/instrumentation/sinatra/Appraisals +++ b/instrumentation/sinatra/Appraisals @@ -11,7 +11,3 @@ end appraise 'sinatra-2.x' do gem 'sinatra', '~> 2.1' end - -appraise 'sinatra-1.x' do - gem 'sinatra', '~> 1.4' -end diff --git a/instrumentation/sinatra/README.md b/instrumentation/sinatra/README.md index 69a77984a..ddbad1f95 100644 --- a/instrumentation/sinatra/README.md +++ b/instrumentation/sinatra/README.md @@ -10,8 +10,22 @@ Install the gem using: gem install opentelemetry-instrumentation-sinatra ``` + Or, if you use [bundler][bundler-home], include `opentelemetry-instrumentation-sinatra` to your `Gemfile`. +### Version Compatibility + +Older versions of Sinatra depend on older version of Rack, which are not supported by the latest version of Rack instrumentation. If you are using an older version of Sinatra and need an earlier version of Rack instrumentation, then consider installing and pinning the compatible gem version, e.g.: + +```console +gem opentelemetry-instrumentation-rack, "" +``` + +| Sinatra Version | Rack Instrumentation Version | +| --------------- | ---------------------------- | +| `< 2.0` | `= 0.22.1` | +| `>= 2.0` | `~> 0.22` | + ## Usage To install the instrumentation, add the gem to your Gemfile: diff --git a/instrumentation/sinatra/opentelemetry-instrumentation-sinatra.gemspec b/instrumentation/sinatra/opentelemetry-instrumentation-sinatra.gemspec index 3bc862704..e5f71d8d5 100644 --- a/instrumentation/sinatra/opentelemetry-instrumentation-sinatra.gemspec +++ b/instrumentation/sinatra/opentelemetry-instrumentation-sinatra.gemspec @@ -36,9 +36,10 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rack-test', '~> 1.1.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' - spec.add_development_dependency 'sinatra', '~> 2.0.7' + spec.add_development_dependency 'sinatra' spec.add_development_dependency 'webmock', '~> 3.19' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/trilogy/lib/opentelemetry/instrumentation/trilogy/patches/client.rb b/instrumentation/trilogy/lib/opentelemetry/instrumentation/trilogy/patches/client.rb index 9858d5981..c155a7a40 100644 --- a/instrumentation/trilogy/lib/opentelemetry/instrumentation/trilogy/patches/client.rb +++ b/instrumentation/trilogy/lib/opentelemetry/instrumentation/trilogy/patches/client.rb @@ -91,7 +91,7 @@ def client_attributes(sql = nil) attributes[::OpenTelemetry::SemanticConventions::Trace::DB_NAME] = database_name if database_name attributes[::OpenTelemetry::SemanticConventions::Trace::DB_USER] = database_user if database_user attributes[::OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] unless config[:peer_service].nil? - attributes['db.mysql.instance.address'] = @connected_host if defined?(@connected_host) + attributes['db.instance.id'] = @connected_host if defined?(@connected_host) if sql case config[:db_statement] diff --git a/instrumentation/trilogy/opentelemetry-instrumentation-trilogy.gemspec b/instrumentation/trilogy/opentelemetry-instrumentation-trilogy.gemspec index d3cad653a..600c96598 100644 --- a/instrumentation/trilogy/opentelemetry-instrumentation-trilogy.gemspec +++ b/instrumentation/trilogy/opentelemetry-instrumentation-trilogy.gemspec @@ -38,7 +38,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'pry-byebug' unless RUBY_ENGINE == 'jruby' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec-mocks' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' spec.add_development_dependency 'trilogy', '>= 2.0', '< 3.0' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb b/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb index b4cf1e6d7..ffc1a58ec 100644 --- a/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb +++ b/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb @@ -139,7 +139,7 @@ _(span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_SYSTEM]).must_equal 'mysql' _(span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT]).must_equal 'SELECT ?' _(span.attributes[OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME]).must_equal(host) - _(span.attributes['db.mysql.instance.address']).must_be_nil + _(span.attributes['db.instance.id']).must_be_nil end it 'extracts statement type' do @@ -177,7 +177,7 @@ _(span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_USER]).must_equal(username) _(span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_SYSTEM]).must_equal 'mysql' _(span.attributes[OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME]).must_equal(host) - _(span.attributes['db.mysql.instance.address']).must_be_nil + _(span.attributes['db.instance.id']).must_be_nil end end @@ -207,7 +207,7 @@ _(span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_SYSTEM]).must_equal 'mysql' _(span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT]).must_equal 'select @@hostname' _(span.attributes[OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME]).must_equal(host) - _(span.attributes['db.mysql.instance.address']).must_be_nil + _(span.attributes['db.instance.id']).must_be_nil client.query('SELECT 1') @@ -219,7 +219,7 @@ _(last_span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_SYSTEM]).must_equal 'mysql' _(last_span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT]).must_equal 'SELECT ?' _(last_span.attributes[OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME]).must_equal(host) - _(last_span.attributes['db.mysql.instance.address']).must_equal client.connected_host + _(last_span.attributes['db.instance.id']).must_equal client.connected_host end end diff --git a/propagator/ottrace/CHANGELOG.md b/propagator/ottrace/CHANGELOG.md index 874a340f3..0b8547296 100644 --- a/propagator/ottrace/CHANGELOG.md +++ b/propagator/ottrace/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-propagator-ottrace +### v0.21.2 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.21.1 / 2023-07-19 * DOCS: Add some clarity to ottrace docs [#522](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/522) diff --git a/propagator/ottrace/lib/opentelemetry/propagator/ottrace/text_map_propagator.rb b/propagator/ottrace/lib/opentelemetry/propagator/ottrace/text_map_propagator.rb index bbbfd19e0..40604fba0 100644 --- a/propagator/ottrace/lib/opentelemetry/propagator/ottrace/text_map_propagator.rb +++ b/propagator/ottrace/lib/opentelemetry/propagator/ottrace/text_map_propagator.rb @@ -116,10 +116,10 @@ def set_baggage(carrier:, context:, getter:) getter.keys(carrier).each do |carrier_key| baggage_key = carrier_key.start_with?(prefix) && carrier_key[prefix.length..-1] next unless baggage_key - next unless VALID_BAGGAGE_HEADER_NAME_CHARS =~ baggage_key + next unless VALID_BAGGAGE_HEADER_NAME_CHARS.match?(baggage_key) value = getter.get(carrier, carrier_key) - next unless INVALID_BAGGAGE_HEADER_VALUE_CHARS !~ value + next if INVALID_BAGGAGE_HEADER_VALUE_CHARS.match?(value) builder.set_value(baggage_key, value) end diff --git a/propagator/ottrace/lib/opentelemetry/propagator/ottrace/version.rb b/propagator/ottrace/lib/opentelemetry/propagator/ottrace/version.rb index fe289a7ac..83215e678 100644 --- a/propagator/ottrace/lib/opentelemetry/propagator/ottrace/version.rb +++ b/propagator/ottrace/lib/opentelemetry/propagator/ottrace/version.rb @@ -15,7 +15,7 @@ module OpenTelemetry module Propagator # Namespace for OpenTelemetry OTTrace propagation module OTTrace - VERSION = '0.21.1' + VERSION = '0.21.2' end end end diff --git a/propagator/ottrace/opentelemetry-propagator-ottrace.gemspec b/propagator/ottrace/opentelemetry-propagator-ottrace.gemspec index cacacdd6c..14cdee898 100644 --- a/propagator/ottrace/opentelemetry-propagator-ottrace.gemspec +++ b/propagator/ottrace/opentelemetry-propagator-ottrace.gemspec @@ -28,7 +28,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.57.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.22.0' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/propagator/xray/CHANGELOG.md b/propagator/xray/CHANGELOG.md index fda517ff3..5448ad7b9 100644 --- a/propagator/xray/CHANGELOG.md +++ b/propagator/xray/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History: opentelemetry-propagator-xray +### v0.22.1 / 2023-11-23 + +* CHANGED: Applied Rubocop Performance Recommendations [#727](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/727) + ### v0.22.0 / 2023-04-17 * BREAKING CHANGE: Drop support for EoL Ruby 2.7 diff --git a/propagator/xray/lib/opentelemetry/propagator/xray/text_map_propagator.rb b/propagator/xray/lib/opentelemetry/propagator/xray/text_map_propagator.rb index ee1f8ce05..1041643ac 100644 --- a/propagator/xray/lib/opentelemetry/propagator/xray/text_map_propagator.rb +++ b/propagator/xray/lib/opentelemetry/propagator/xray/text_map_propagator.rb @@ -119,7 +119,7 @@ def to_trace_flags(sampling_state) def to_trace_state(trace_state) return nil unless trace_state - Trace::Tracestate.from_string(trace_state.gsub(';', ',')) + Trace::Tracestate.from_string(trace_state.tr(';', ',')) end end end diff --git a/propagator/xray/lib/opentelemetry/propagator/xray/version.rb b/propagator/xray/lib/opentelemetry/propagator/xray/version.rb index d0d932009..0984efef4 100644 --- a/propagator/xray/lib/opentelemetry/propagator/xray/version.rb +++ b/propagator/xray/lib/opentelemetry/propagator/xray/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Propagator module XRay - VERSION = '0.22.0' + VERSION = '0.22.1' end end end diff --git a/propagator/xray/opentelemetry-propagator-xray.gemspec b/propagator/xray/opentelemetry-propagator-xray.gemspec index 66da780a5..daddd3e79 100644 --- a/propagator/xray/opentelemetry-propagator-xray.gemspec +++ b/propagator/xray/opentelemetry-propagator-xray.gemspec @@ -31,7 +31,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.57.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.22.0' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/resources/azure/opentelemetry-resource-detector-azure.gemspec b/resources/azure/opentelemetry-resource-detector-azure.gemspec index 0c3d09755..002cdfde1 100644 --- a/resources/azure/opentelemetry-resource-detector-azure.gemspec +++ b/resources/azure/opentelemetry-resource-detector-azure.gemspec @@ -30,7 +30,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.55.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17' spec.add_development_dependency 'webmock', '~> 3.19.1' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/resources/container/opentelemetry-resource-detector-container.gemspec b/resources/container/opentelemetry-resource-detector-container.gemspec index baf1db746..5137d2600 100644 --- a/resources/container/opentelemetry-resource-detector-container.gemspec +++ b/resources/container/opentelemetry-resource-detector-container.gemspec @@ -30,7 +30,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17' spec.add_development_dependency 'yard', '~> 0.9' diff --git a/resources/google_cloud_platform/opentelemetry-resource-detector-google_cloud_platform.gemspec b/resources/google_cloud_platform/opentelemetry-resource-detector-google_cloud_platform.gemspec index 931751f63..0fa9f9dd0 100644 --- a/resources/google_cloud_platform/opentelemetry-resource-detector-google_cloud_platform.gemspec +++ b/resources/google_cloud_platform/opentelemetry-resource-detector-google_cloud_platform.gemspec @@ -31,7 +31,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'rake', '~> 13.0' - spec.add_development_dependency 'rubocop', '~> 1.55.1' + spec.add_development_dependency 'rubocop', '~> 1.58.0' + spec.add_development_dependency 'rubocop-performance', '~> 1.19.1' spec.add_development_dependency 'simplecov', '~> 0.17' spec.add_development_dependency 'webmock', '~> 3.19.1' spec.add_development_dependency 'yard', '~> 0.9'