diff --git a/.github/actions/test_gem/action.yml b/.github/actions/test_gem/action.yml index 1d0cb24ef0..1b807d8a1d 100644 --- a/.github/actions/test_gem/action.yml +++ b/.github/actions/test_gem/action.yml @@ -84,7 +84,7 @@ runs: # ...but not for appraisals, sadly. - name: Install Ruby ${{ inputs.ruby }} with dependencies if: "${{ steps.setup.outputs.appraisals == 'false' }}" - uses: ruby/setup-ruby@v1.245.0 + uses: ruby/setup-ruby@v1.237.0 with: ruby-version: "${{ inputs.ruby }}" working-directory: "${{ steps.setup.outputs.gem_dir }}" @@ -95,7 +95,7 @@ runs: # If we're using appraisals, do it all manually. - name: Install Ruby ${{ inputs.ruby }} without dependencies if: "${{ steps.setup.outputs.appraisals == 'true' }}" - uses: ruby/setup-ruby@v1.245.0 + uses: ruby/setup-ruby@v1.237.0 with: ruby-version: "${{ inputs.ruby }}" bundler: "latest" diff --git a/.github/workflows/check-spelling.yml b/.github/workflows/check-spelling.yml index fc99b4de8b..4d699bea9d 100644 --- a/.github/workflows/check-spelling.yml +++ b/.github/workflows/check-spelling.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: streetsidesoftware/cspell-action@v7 + - uses: streetsidesoftware/cspell-action@v6 with: # Files should be consistent with check:spelling files files: | diff --git a/.github/workflows/ci-instrumentation-with-services.yml b/.github/workflows/ci-instrumentation-with-services.yml index 848d1c1c96..55eabc04d1 100644 --- a/.github/workflows/ci-instrumentation-with-services.yml +++ b/.github/workflows/ci-instrumentation-with-services.yml @@ -157,7 +157,7 @@ jobs: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 kafka: - image: confluentinc/cp-kafka:7.9.1 + image: confluentinc/cp-kafka:latest ports: - 9092:9092 - 29092:29092 diff --git a/.github/workflows/ci-markdownlint.yml b/.github/workflows/ci-markdownlint.yml index ada59ffc7a..93350d7c44 100644 --- a/.github/workflows/ci-markdownlint.yml +++ b/.github/workflows/ci-markdownlint.yml @@ -11,10 +11,10 @@ jobs: # equivalent cli: markdownlint-cli2 "**/*.md" "#**/CHANGELOG.md" --config .markdownlint.json - name: "Markdown Lint Check" - uses: DavidAnson/markdownlint-cli2-action@v20 - continue-on-error: true + uses: DavidAnson/markdownlint-cli2-action@v19 with: fix: false globs: | **/*.md !**/CHANGELOG.md + continue-on-error: true diff --git a/.github/workflows/fossa.yml b/.github/workflows/fossa.yml index 34bf6ad7c7..b1d2947d5b 100644 --- a/.github/workflows/fossa.yml +++ b/.github/workflows/fossa.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # v1.7.0 + - uses: fossas/fossa-action@c0a7d013f84c8ee5e910593186598625513cc1e4 # v1.6.0 with: api-key: ${{secrets.FOSSA_API_KEY}} team: OpenTelemetry diff --git a/.github/workflows/installation-tests.yml b/.github/workflows/installation-tests.yml index c623841059..f99675b71e 100644 --- a/.github/workflows/installation-tests.yml +++ b/.github/workflows/installation-tests.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 # ATTENTION: Dependabot does not know how to update shared actions file. # If you see it update setup-ruby here also update it as part of actions/test_gem/action.yml - - uses: ruby/setup-ruby@v1.245.0 + - uses: ruby/setup-ruby@v1.237.0 with: ruby-version: ${{ matrix.ruby-version }} - name: "Install Latest Gem Versions on ${{ matrix.ruby-version }}" diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index 02aef01470..176e1d5110 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - - uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 + - uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 with: results_file: results.sarif results_format: sarif @@ -43,6 +43,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 + uses: github/codeql-action/upload-sarif@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16 with: sarif_file: results.sarif diff --git a/.github/workflows/release-hook-on-closed.yml b/.github/workflows/release-hook-on-closed.yml index 8d117dfa0c..68ea9ff95f 100644 --- a/.github/workflows/release-hook-on-closed.yml +++ b/.github/workflows/release-hook-on-closed.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Ruby ${{ env.ruby_version }} - uses: ruby/setup-ruby@v1.245.0 + uses: ruby/setup-ruby@v1.237.0 with: ruby-version: ${{ env.ruby_version }} - name: Checkout repo diff --git a/.github/workflows/release-hook-on-push.yml b/.github/workflows/release-hook-on-push.yml index 007ecd9da4..e4ea7f8587 100644 --- a/.github/workflows/release-hook-on-push.yml +++ b/.github/workflows/release-hook-on-push.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Ruby ${{ env.ruby_version }} - uses: ruby/setup-ruby@v1.245.0 + uses: ruby/setup-ruby@v1.237.0 with: ruby-version: ${{ env.ruby_version }} - name: Checkout repo diff --git a/.github/workflows/release-perform.yml b/.github/workflows/release-perform.yml index adc5428c53..c8d7622184 100644 --- a/.github/workflows/release-perform.yml +++ b/.github/workflows/release-perform.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Ruby ${{ env.ruby_version }} - uses: ruby/setup-ruby@v1.245.0 + uses: ruby/setup-ruby@v1.237.0 with: ruby-version: ${{ env.ruby_version }} - name: Checkout repo diff --git a/.github/workflows/release-please.yaml b/.github/workflows/release-please.yaml index 41dd9b9111..8b26a37001 100644 --- a/.github/workflows/release-please.yaml +++ b/.github/workflows/release-please.yaml @@ -50,7 +50,7 @@ jobs: chmod 0600 $HOME/.gem/credentials printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials - - uses: ruby/setup-ruby@v1.245.0 + - uses: ruby/setup-ruby@v1.237.0 with: ruby-version: "3.1" bundler: latest diff --git a/.github/workflows/release-request-weekly.yml b/.github/workflows/release-request-weekly.yml index 0b7dd20dfe..43eb2f9f02 100644 --- a/.github/workflows/release-request-weekly.yml +++ b/.github/workflows/release-request-weekly.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Ruby ${{ env.ruby_version }} - uses: ruby/setup-ruby@v1.245.0 + uses: ruby/setup-ruby@v1.237.0 with: ruby-version: ${{ env.ruby_version }} - name: Checkout repo diff --git a/.github/workflows/release-request.yml b/.github/workflows/release-request.yml index 3bc5d96aa9..f2356dbca5 100644 --- a/.github/workflows/release-request.yml +++ b/.github/workflows/release-request.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Ruby ${{ env.ruby_version }} - uses: ruby/setup-ruby@v1.245.0 + uses: ruby/setup-ruby@v1.237.0 with: ruby-version: ${{ env.ruby_version }} - name: Checkout repo diff --git a/.github/workflows/release-retry.yml b/.github/workflows/release-retry.yml index bfc2e91724..da36cf6919 100644 --- a/.github/workflows/release-retry.yml +++ b/.github/workflows/release-retry.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Ruby ${{ env.ruby_version }} - uses: ruby/setup-ruby@v1.245.0 + uses: ruby/setup-ruby@v1.237.0 with: ruby-version: ${{ env.ruby_version }} - name: Checkout repo diff --git a/.instrumentation_generator/templates/Gemfile b/.instrumentation_generator/templates/Gemfile index 579438213d..3723fca98e 100644 --- a/.instrumentation_generator/templates/Gemfile +++ b/.instrumentation_generator/templates/Gemfile @@ -20,7 +20,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.0' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.17.1' gem 'webmock', '~> 3.24' diff --git a/.instrumentation_generator/templates/Readme.md.tt b/.instrumentation_generator/templates/Readme.md.tt index 5b3e33e61d..68b6399770 100644 --- a/.instrumentation_generator/templates/Readme.md.tt +++ b/.instrumentation_generator/templates/Readme.md.tt @@ -32,7 +32,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/<%= instrumentation_name %>/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/<%= instrumentation_name %>/example/trace_demonstration.rb) ## How can I get involved? diff --git a/Gemfile b/Gemfile index 0c317a23b9..18df87d61b 100644 --- a/Gemfile +++ b/Gemfile @@ -7,5 +7,5 @@ source 'https://rubygems.org' gem 'rake', '~> 13.0' -gem 'rubocop', '~> 1.76.2' +gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' diff --git a/README.md b/README.md index b4465433b7..65d33dfd0c 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,15 @@ requests. The Ruby special interest group (SIG) meets regularly. See the OpenTelemetry [community page][ruby-sig] repo for information on this and other language SIGs. -### Maintainers +Approvers ([@open-telemetry/ruby-contrib-approvers](https://github.com/orgs/open-telemetry/teams/ruby-contrib-approvers)): + +- [Josef Šimánek](https://github.com/simi) +- [Xuan Cao](https://github.com/xuan-cao-swi), Solarwinds + +*Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver).* + +Maintainers ([@open-telemetry/ruby-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/ruby-contrib-maintainers)): -- [Andrew Hayworth](https://github.com/ahayworth) - [Ariel Valentin](https://github.com/arielvalentin), GitHub - [Daniel Azuma](https://github.com/dazuma), Google - [Eric Mustin](https://github.com/ericmustin) @@ -38,14 +44,7 @@ The Ruby special interest group (SIG) meets regularly. See the OpenTelemetry - [Robert Laurin](https://github.com/robertlaurin), Shopify - [Sam Handler](https://github.com/plantfansam), Shopify -For more information about the maintainer role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer). - -### Approvers - -- [Josef Šimánek](https://github.com/simi) -- [Xuan Cao](https://github.com/xuan-cao-swi), Solarwinds - -For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver). +*Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).* ## Instrumentation Libraries @@ -93,7 +92,7 @@ Consult instrumentation gem's README file and gemspec for details about library ### Releases -This repository was extracted from the [OpenTelemetry Ruby repository][otel-ruby]. Versions of libraries contained in this repo released prior to 2022-06-13 are available on the [OpenTelemetry Ruby Releases][otel-ruby-releases] page. Newer versions are available [on the opentelemetry-ruby-contrib Releases page][otel-ruby-contrib-releases]. +This repository was extracted from the [OpenTelemetry Ruby repository][otel-ruby]. Versions of libraries contained in this repo released prior to 2022-06-13 are available on the [OpenTelemetry Ruby Releases][otel-ruby-releases] page. Newer versions are available [here][otel-ruby-contrib-releases] ## Useful links diff --git a/docker-compose.yml b/docker-compose.yml index 5b3a01ee7f..a2fb5633fa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -226,7 +226,7 @@ services: ZOOKEEPER_TICK_TIME: 2000 kafka: - image: confluentinc/cp-kafka:7.9.1 + image: confluentinc/cp-kafka:latest ports: - "9092:9092" - "29092:29092" diff --git a/helpers/mysql/Gemfile b/helpers/mysql/Gemfile index 7cb7b668fa..3d1086e0fb 100644 --- a/helpers/mysql/Gemfile +++ b/helpers/mysql/Gemfile @@ -13,7 +13,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/helpers/sql-obfuscation/Gemfile b/helpers/sql-obfuscation/Gemfile index 7cb7b668fa..3d1086e0fb 100644 --- a/helpers/sql-obfuscation/Gemfile +++ b/helpers/sql-obfuscation/Gemfile @@ -13,7 +13,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/helpers/sql/Gemfile b/helpers/sql/Gemfile index d14143591b..d9711191f1 100644 --- a/helpers/sql/Gemfile +++ b/helpers/sql/Gemfile @@ -18,7 +18,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/README.md b/instrumentation/README.md index 614c832717..dec813917c 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -8,7 +8,7 @@ Instrumentation libraries provide pre-built OpenTelemetry instrumentation for po Released instrumentations can be found at the [OpenTelemetry registry](https://opentelemetry.io/registry/?language=ruby&component=instrumentation#). You can also look in this project's Github repository: Individual instrumentation libraries can be found in subdirectories under `/instrumentation`. -[In-progress instrumentations can be found here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues?q=is%3Aopen+label%3Ainstrumentation+-label%3A%22help+wanted%22+). +In-progress instrumentations can be found [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues?q=is%3Aopen+label%3Ainstrumentation+-label%3A%22help+wanted%22+). ## How do I get started? @@ -49,7 +49,7 @@ Please review the individual instrumentation READMEs for more information about The source for all OpenTelemetry Ruby instrumentation gems is [on github](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation). -If you are interested in helping out with an instrumentation, check out [instrumentations that have been requested but are not currently in-progress](https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues?q=is%3Aopen+label%3Ainstrumentation+label%3A%22help+wanted%22). +If you are interested in helping out with an instrumentation, you can see instrumentations that have been requested but are not currently in-progress [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues?q=is%3Aopen+label%3Ainstrumentation+label%3A%22help+wanted%22). The OpenTelemetry Ruby gems are maintained by the OpenTelemetry Ruby special interest group (SIG). You can get involved by joining us on our [GitHub Discussions][discussions-url], [Slack Channel][slack-channel] or attending our weekly meeting. See the [meeting calendar][community-meetings] for dates and times. For more information on this and other language SIGs, see the OpenTelemetry [community page][ruby-sig]. diff --git a/instrumentation/action_mailer/Gemfile b/instrumentation/action_mailer/Gemfile index 9737b82a6c..1433110629 100644 --- a/instrumentation/action_mailer/Gemfile +++ b/instrumentation/action_mailer/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/action_mailer/README.md b/instrumentation/action_mailer/README.md index edb5590eaa..3d429e7d2c 100644 --- a/instrumentation/action_mailer/README.md +++ b/instrumentation/action_mailer/README.md @@ -91,7 +91,7 @@ Internal spans are named using the name of the `ActiveSupport` event that was pr ## Examples -Example usage can be seen in the [`./example/trace_request_demonstration.ru` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/action_mailer/example/trace_request_demonstration.ru) +Example usage can be seen in the `./example/trace_request_demonstration.ru` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/action_mailer/example/trace_request_demonstration.ru) ## How can I get involved? diff --git a/instrumentation/action_pack/CHANGELOG.md b/instrumentation/action_pack/CHANGELOG.md index ba9d821f86..3eff08eb9b 100644 --- a/instrumentation/action_pack/CHANGELOG.md +++ b/instrumentation/action_pack/CHANGELOG.md @@ -1,17 +1,5 @@ # Release History: opentelemetry-instrumentation-action_pack -### v0.12.3 / 2025-06-16 - -* FIXED: Action_pack always assuming sdk spans - -### v0.12.2 / 2025-06-04 - -* FIXED: Rack span class naming - -### v0.12.1 / 2025-05-07 - -* FIXED: Account for `nil` routes - ### v0.12.0 / 2025-02-04 * ADDED: Strip Rails `(.:format)` suffix from `http.route` diff --git a/instrumentation/action_pack/Gemfile b/instrumentation/action_pack/Gemfile index 61c7975c49..cc0e435d99 100644 --- a/instrumentation/action_pack/Gemfile +++ b/instrumentation/action_pack/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/action_pack/README.md b/instrumentation/action_pack/README.md index 8eb0fd76eb..c8b84f5ef8 100644 --- a/instrumentation/action_pack/README.md +++ b/instrumentation/action_pack/README.md @@ -69,7 +69,7 @@ The error object will be retained within `payload[:exception_object]`. Additiona ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/action_pack/example/trace_demonstration.ru) +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) ## How can I get involved? 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 index 6999068815..133afb0037 100644 --- 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 @@ -23,34 +23,10 @@ def initialize(config) # @param payload [Hash] the payload passed as a method argument # @return [Hash] the payload passed as a method argument def start(_name, _id, payload) - span = OpenTelemetry::Instrumentation::Rack.current_span - return unless span.recording? - - request = payload[:request] - # It seems that there are cases in Rails functional tests where it bypasses the routing system and the `action_dispatch.route_uri_pattern` header not being set. - # Our Test suite executes the routing system so we are unable to recreate this error case. - # https://github.com/rails/rails/blob/747f85f200e7bb2c1a31b4e26e5a5655e2dc0cdc/actionpack/lib/action_dispatch/http/request.rb#L160 - http_route = request.route_uri_pattern&.chomp('(.:format)') if request.respond_to?(:route_uri_pattern) - - attributes = { - OpenTelemetry::SemanticConventions::Trace::CODE_NAMESPACE => String(payload[:controller]), - OpenTelemetry::SemanticConventions::Trace::CODE_FUNCTION => String(payload[:action]) - } - attributes[OpenTelemetry::SemanticConventions::Trace::HTTP_ROUTE] = http_route if http_route - attributes[OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET] = request.filtered_path if request.filtered_path != request.fullpath - - if @span_naming == :semconv - span.name = if http_route - "#{request.method} #{http_route}" - else - "#{request.method} /#{payload.dig(:params, :controller)}/#{payload.dig(:params, :action)}" - end - # If there is an exception we want to keep the original span name - # so it is easier to see where the request was routed to. - elsif !request.env['action_dispatch.exception'] - span.name = "#{payload[:controller]}##{payload[:action]}" - end + span_name, attributes = to_span_name_and_attributes(payload) + span = OpenTelemetry::Instrumentation::Rack.current_span + span.name = span_name span.add_attributes(attributes) rescue StandardError => e OpenTelemetry.handle_error(exception: e) @@ -68,6 +44,32 @@ def finish(_name, _id, payload) rescue StandardError => e OpenTelemetry.handle_error(exception: e) end + + private + + # Extracts the span name and attributes from the payload + # + # @param payload [Hash] the payload passed from ActiveSupport::Notifications + # @return [Array] the span name and attributes + def to_span_name_and_attributes(payload) + request = payload[:request] + http_route = request.route_uri_pattern.chomp('(.:format)') if request.respond_to?(:route_uri_pattern) + + attributes = { + OpenTelemetry::SemanticConventions::Trace::CODE_NAMESPACE => String(payload[:controller]), + OpenTelemetry::SemanticConventions::Trace::CODE_FUNCTION => String(payload[:action]) + } + attributes[OpenTelemetry::SemanticConventions::Trace::HTTP_ROUTE] = http_route if http_route + attributes[OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET] = request.filtered_path if request.filtered_path != request.fullpath + + if @span_naming == :semconv + return ["#{request.method} #{http_route}", attributes] if http_route + + return ["#{request.method} /#{payload.dig(:params, :controller)}/#{payload.dig(:params, :action)}", attributes] + end + + ["#{payload[:controller]}##{payload[:action]}", attributes] + 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 8865f42404..57cb47a9aa 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.12.3' + VERSION = '0.12.0' end end end diff --git a/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers/action_controller_test.rb b/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers/action_controller_test.rb index 47cfe648a3..8ce8924430 100644 --- a/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers/action_controller_test.rb +++ b/instrumentation/action_pack/test/opentelemetry/instrumentation/action_pack/handlers/action_controller_test.rb @@ -215,12 +215,11 @@ describe 'when the application has exceptions_app configured' do let(:rails_app) { AppConfig.initialize_app(use_exceptions_app: true) } - let(:config) { { span_naming: :class } } it 'does not overwrite the span name from the controller that raised' do get 'internal_server_error' - _(span.name).must_equal 'ExampleController#internal_server_error' + _(span.name).must_match(/^GET/) _(span.kind).must_equal :server _(span.status.ok?).must_equal false @@ -236,12 +235,6 @@ _(span.attributes['code.namespace']).must_equal 'ExceptionsController' _(span.attributes['code.function']).must_equal 'show' end - - it 'does not raise with api/non recording spans' do - with_sampler(OpenTelemetry::SDK::Trace::Samplers::ALWAYS_OFF) do - get 'internal_server_error' - end - end end it 'sets filters `http.target`' do diff --git a/instrumentation/action_pack/test/test_helper.rb b/instrumentation/action_pack/test/test_helper.rb index 8ea8f9ec92..992871d77d 100644 --- a/instrumentation/action_pack/test/test_helper.rb +++ b/instrumentation/action_pack/test/test_helper.rb @@ -24,11 +24,3 @@ c.use 'OpenTelemetry::Instrumentation::ActionPack' c.add_span_processor span_processor end - -def with_sampler(sampler) - previous_sampler = OpenTelemetry.tracer_provider.sampler - OpenTelemetry.tracer_provider.sampler = sampler - yield -ensure - OpenTelemetry.tracer_provider.sampler = previous_sampler -end diff --git a/instrumentation/action_view/Gemfile b/instrumentation/action_view/Gemfile index 911fcfc676..afbb2d8e11 100644 --- a/instrumentation/action_view/Gemfile +++ b/instrumentation/action_view/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/action_view/README.md b/instrumentation/action_view/README.md index 208f5877d3..340a285c9e 100644 --- a/instrumentation/action_view/README.md +++ b/instrumentation/action_view/README.md @@ -34,7 +34,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_request_demonstration.ru` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/action_view/example/trace_request_demonstration.ru) +Example usage can be seen in the `./example/trace_request_demonstration.ru` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/action_view/example/trace_request_demonstration.ru) ## Known issues diff --git a/instrumentation/active_job/Gemfile b/instrumentation/active_job/Gemfile index 35abd9d688..a2eceb969b 100644 --- a/instrumentation/active_job/Gemfile +++ b/instrumentation/active_job/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/active_job/README.md b/instrumentation/active_job/README.md index 52ad445101..ee8a01432f 100644 --- a/instrumentation/active_job/README.md +++ b/instrumentation/active_job/README.md @@ -90,7 +90,7 @@ In order to preserve this behavior you will have to update the span yourself, e. ## Examples -Example usage can be seen in the [`./example/active_job.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/active_job/example/active_job.rb) +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) ## How can I get involved? diff --git a/instrumentation/active_model_serializers/Gemfile b/instrumentation/active_model_serializers/Gemfile index 174682f81f..eaa2d79162 100644 --- a/instrumentation/active_model_serializers/Gemfile +++ b/instrumentation/active_model_serializers/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/active_model_serializers/README.md b/instrumentation/active_model_serializers/README.md index f095dcdbde..7e8fe0bd5c 100644 --- a/instrumentation/active_model_serializers/README.md +++ b/instrumentation/active_model_serializers/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage of active_model_serializers can be seen [in the `./example/` folder](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/active_model_serializers/example) +Example usage of active_model_serializers can be seen in the `./example/` folder [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/active_model_serializers/example) ## How can I get involved? diff --git a/instrumentation/active_record/Gemfile b/instrumentation/active_record/Gemfile index 35abd9d688..a2eceb969b 100644 --- a/instrumentation/active_record/Gemfile +++ b/instrumentation/active_record/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/active_record/README.md b/instrumentation/active_record/README.md index 6eba159909..c64e2da1fc 100644 --- a/instrumentation/active_record/README.md +++ b/instrumentation/active_record/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/active_record/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/active_record/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/active_storage/Gemfile b/instrumentation/active_storage/Gemfile index 911fcfc676..afbb2d8e11 100644 --- a/instrumentation/active_storage/Gemfile +++ b/instrumentation/active_storage/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/active_storage/README.md b/instrumentation/active_storage/README.md index 17abb1dc2f..3ee418aafb 100644 --- a/instrumentation/active_storage/README.md +++ b/instrumentation/active_storage/README.md @@ -75,7 +75,7 @@ Attributes attached to each event payload are prefixed with `active_storage.` (e ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/active_storage/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/active_storage/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/active_support/Gemfile b/instrumentation/active_support/Gemfile index eac033c5e2..21723b363c 100644 --- a/instrumentation/active_support/Gemfile +++ b/instrumentation/active_support/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/active_support/README.md b/instrumentation/active_support/README.md index 519b20323a..2a305e163e 100644 --- a/instrumentation/active_support/README.md +++ b/instrumentation/active_support/README.md @@ -42,7 +42,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/active_support/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/active_support/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/all/CHANGELOG.md b/instrumentation/all/CHANGELOG.md index 11ea92b7e5..9bd6685281 100644 --- a/instrumentation/all/CHANGELOG.md +++ b/instrumentation/all/CHANGELOG.md @@ -1,18 +1,5 @@ # Release History: opentelemetry-instrumentation-all -### v0.78.0 / 2025-06-17 - -* ADDED: Add `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable to HTTP.rb instrumentation [#1547](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/1547) - -### v0.77.0 / 2025-06-03 - -* ADDED: Suppress internal spans with Faraday instrumentation -* FIXED: Handle force_flush for rake task with arguments - -### v0.76.0 / 2025-05-06 - -* ADDED: Update minimum required version of rdkafka to 0.18.0 - ### v0.75.1 / 2025-04-16 * (No significant changes) diff --git a/instrumentation/all/Gemfile b/instrumentation/all/Gemfile index 1e9fb077cc..4e664ef1c5 100644 --- a/instrumentation/all/Gemfile +++ b/instrumentation/all/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/all/lib/opentelemetry/instrumentation/all/version.rb b/instrumentation/all/lib/opentelemetry/instrumentation/all/version.rb index ba0904497f..9e0ab652ec 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.78.0' + VERSION = '0.75.1' end end end diff --git a/instrumentation/all/opentelemetry-instrumentation-all.gemspec b/instrumentation/all/opentelemetry-instrumentation-all.gemspec index d82679955c..2012d18e10 100644 --- a/instrumentation/all/opentelemetry-instrumentation-all.gemspec +++ b/instrumentation/all/opentelemetry-instrumentation-all.gemspec @@ -35,12 +35,12 @@ Gem::Specification.new do |spec| spec.add_dependency 'opentelemetry-instrumentation-delayed_job', '~> 0.23.0' spec.add_dependency 'opentelemetry-instrumentation-ethon', '~> 0.22.0' spec.add_dependency 'opentelemetry-instrumentation-excon', '~> 0.23.0' - spec.add_dependency 'opentelemetry-instrumentation-faraday', '~> 0.27.0' + spec.add_dependency 'opentelemetry-instrumentation-faraday', '~> 0.26.0' spec.add_dependency 'opentelemetry-instrumentation-grape', '~> 0.3.0' spec.add_dependency 'opentelemetry-instrumentation-graphql', '~> 0.29.0' spec.add_dependency 'opentelemetry-instrumentation-grpc', '~> 0.2.0' spec.add_dependency 'opentelemetry-instrumentation-gruf', '~> 0.3.0' - spec.add_dependency 'opentelemetry-instrumentation-http', '~> 0.25.0' + spec.add_dependency 'opentelemetry-instrumentation-http', '~> 0.24.0' spec.add_dependency 'opentelemetry-instrumentation-http_client', '~> 0.23.0' spec.add_dependency 'opentelemetry-instrumentation-koala', '~> 0.21.0' spec.add_dependency 'opentelemetry-instrumentation-lmdb', '~> 0.23.0' @@ -52,8 +52,8 @@ Gem::Specification.new do |spec| spec.add_dependency 'opentelemetry-instrumentation-racecar', '~> 0.4.0' spec.add_dependency 'opentelemetry-instrumentation-rack', '~> 0.26.0' spec.add_dependency 'opentelemetry-instrumentation-rails', '~> 0.36.0' - spec.add_dependency 'opentelemetry-instrumentation-rake', '~> 0.3.1' - spec.add_dependency 'opentelemetry-instrumentation-rdkafka', '~> 0.7.0' + spec.add_dependency 'opentelemetry-instrumentation-rake', '~> 0.3.0' + spec.add_dependency 'opentelemetry-instrumentation-rdkafka', '~> 0.6.0' spec.add_dependency 'opentelemetry-instrumentation-redis', '~> 0.26.1' spec.add_dependency 'opentelemetry-instrumentation-resque', '~> 0.6.0' spec.add_dependency 'opentelemetry-instrumentation-restclient', '~> 0.23.0' diff --git a/instrumentation/aws_lambda/Gemfile b/instrumentation/aws_lambda/Gemfile index 204d0e0b36..a30cb0e121 100644 --- a/instrumentation/aws_lambda/Gemfile +++ b/instrumentation/aws_lambda/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/aws_sdk/CHANGELOG.md b/instrumentation/aws_sdk/CHANGELOG.md index d8552e5eab..32c00db85f 100644 --- a/instrumentation/aws_sdk/CHANGELOG.md +++ b/instrumentation/aws_sdk/CHANGELOG.md @@ -1,9 +1,5 @@ # Release History: opentelemetry-instrumentation-aws_sdk -### v0.8.1 / 2025-05-13 - -* DOCS: Use AWS SDK v3 in example - ### v0.8.0 / 2025-01-16 * BREAKING CHANGE: Set minimum supported version to Ruby 3.1 diff --git a/instrumentation/aws_sdk/Gemfile b/instrumentation/aws_sdk/Gemfile index 204d0e0b36..a30cb0e121 100644 --- a/instrumentation/aws_sdk/Gemfile +++ b/instrumentation/aws_sdk/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/aws_sdk/example/Gemfile b/instrumentation/aws_sdk/example/Gemfile index 03d50ddc9c..eec14bbdb3 100644 --- a/instrumentation/aws_sdk/example/Gemfile +++ b/instrumentation/aws_sdk/example/Gemfile @@ -2,10 +2,7 @@ source 'https://rubygems.org' -gem 'aws-sdk-core', '~> 3.203.0' -gem 'aws-sdk-sns', '~> 1.83.0' +gem 'aws-sdk' gem 'opentelemetry-api' -gem 'opentelemetry-instrumentation-aws_sdk', '~> 0.7.0' +gem 'opentelemetry-instrumentation-aws_sdk' gem 'opentelemetry-sdk' -# AWS SDK core needs an XML library -gem 'rexml' diff --git a/instrumentation/aws_sdk/example/trace_demonstration.rb b/instrumentation/aws_sdk/example/trace_demonstration.rb index 605d49cfd1..4d4eb22b2d 100755 --- a/instrumentation/aws_sdk/example/trace_demonstration.rb +++ b/instrumentation/aws_sdk/example/trace_demonstration.rb @@ -13,10 +13,8 @@ ENV['OTEL_TRACES_EXPORTER'] ||= 'console' OpenTelemetry::SDK.configure do |c| - c.use 'OpenTelemetry::Instrumentation::AwsSdk' + c.use 'OpenTelemetry::Instrumentation::AwsSdk', suppress_internal_instrumentation: false end -# For more examples and options, see also https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/observability.html -otel_provider = Aws::Telemetry::OTelProvider.new -sns = Aws::SNS::Client.new(telemetry_provider: otel_provider) +sns = Aws::SNS::Client.new sns.publish message: 'ruby sending message to sns' diff --git a/instrumentation/aws_sdk/lib/opentelemetry/instrumentation/aws_sdk/version.rb b/instrumentation/aws_sdk/lib/opentelemetry/instrumentation/aws_sdk/version.rb index e24539f649..ea7561258d 100644 --- a/instrumentation/aws_sdk/lib/opentelemetry/instrumentation/aws_sdk/version.rb +++ b/instrumentation/aws_sdk/lib/opentelemetry/instrumentation/aws_sdk/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module AwsSdk - VERSION = '0.8.1' + VERSION = '0.8.0' end end end diff --git a/instrumentation/base/Gemfile b/instrumentation/base/Gemfile index ba339ca68d..7974f37165 100644 --- a/instrumentation/base/Gemfile +++ b/instrumentation/base/Gemfile @@ -13,7 +13,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/bunny/Gemfile b/instrumentation/bunny/Gemfile index 8933592e8d..8f27a80732 100644 --- a/instrumentation/bunny/Gemfile +++ b/instrumentation/bunny/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/bunny/README.md b/instrumentation/bunny/README.md index a0de6d56f5..d3c0d936a1 100644 --- a/instrumentation/bunny/README.md +++ b/instrumentation/bunny/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage can be seen in the [`./example/bunny.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/bunny/example/bunny.rb) +Example usage can be seen in the `./example/bunny.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/bunny/example/bunny.rb) ## How can I get involved? diff --git a/instrumentation/concurrent_ruby/Gemfile b/instrumentation/concurrent_ruby/Gemfile index 8933592e8d..8f27a80732 100644 --- a/instrumentation/concurrent_ruby/Gemfile +++ b/instrumentation/concurrent_ruby/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/dalli/CHANGELOG.md b/instrumentation/dalli/CHANGELOG.md index 1c98e548a9..02d2d843cb 100644 --- a/instrumentation/dalli/CHANGELOG.md +++ b/instrumentation/dalli/CHANGELOG.md @@ -1,9 +1,5 @@ # Release History: opentelemetry-instrumentation-dalli -### v0.27.3 / 2025-05-27 - -* FIXED: Compact Dalli attributes - ### v0.27.2 / 2025-04-30 * FIXED: Do not pollute the `OpenTelemetry::Instrumentation` namespace diff --git a/instrumentation/dalli/Gemfile b/instrumentation/dalli/Gemfile index 8933592e8d..8f27a80732 100644 --- a/instrumentation/dalli/Gemfile +++ b/instrumentation/dalli/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/dalli/lib/opentelemetry/instrumentation/dalli/patches/server.rb b/instrumentation/dalli/lib/opentelemetry/instrumentation/dalli/patches/server.rb index efe599baac..3d1c102740 100644 --- a/instrumentation/dalli/lib/opentelemetry/instrumentation/dalli/patches/server.rb +++ b/instrumentation/dalli/lib/opentelemetry/instrumentation/dalli/patches/server.rb @@ -15,10 +15,9 @@ def request(op, *args) # rubocop:disable Naming/MethodParameterName attributes = { 'db.system' => 'memcached', 'db.operation' => operation, - 'net.peer.name' => hostname + 'net.peer.name' => hostname, + 'net.peer.port' => port } - attributes['net.peer.port'] = port if port - if config[:db_statement] == :include attributes['db.statement'] = Utils.format_command(operation, args) elsif config[:db_statement] == :obfuscate diff --git a/instrumentation/dalli/lib/opentelemetry/instrumentation/dalli/version.rb b/instrumentation/dalli/lib/opentelemetry/instrumentation/dalli/version.rb index 5c1240ac2e..891f0ecced 100644 --- a/instrumentation/dalli/lib/opentelemetry/instrumentation/dalli/version.rb +++ b/instrumentation/dalli/lib/opentelemetry/instrumentation/dalli/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Dalli - VERSION = '0.27.3' + VERSION = '0.27.2' end end end diff --git a/instrumentation/dalli/test/opentelemetry/instrumentation/dalli/instrumentation_test.rb b/instrumentation/dalli/test/opentelemetry/instrumentation/dalli/instrumentation_test.rb index 4770c9ff07..434c185397 100644 --- a/instrumentation/dalli/test/opentelemetry/instrumentation/dalli/instrumentation_test.rb +++ b/instrumentation/dalli/test/opentelemetry/instrumentation/dalli/instrumentation_test.rb @@ -142,24 +142,6 @@ _(span.name).must_equal 'gat' _(span.attributes['db.statement']).must_equal 'gat foo 0' end - - it 'supports unix domain socket' do - dalli.version - exporter.reset - - server = dalli.instance_variable_get(:@ring).servers.first - server.stub(:hostname, '/tmp/memcached.sock') do - server.stub(:port, nil) do - dalli.set('foo', 'bar') - - puts exporter.finished_spans - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'set' - _(span.attributes).wont_include 'net.peer.port' - _(span.attributes['net.peer.name']).must_equal '/tmp/memcached.sock' - end - end - end end end diff --git a/instrumentation/delayed_job/Gemfile b/instrumentation/delayed_job/Gemfile index 67252ecfd3..648e7a08f1 100644 --- a/instrumentation/delayed_job/Gemfile +++ b/instrumentation/delayed_job/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/delayed_job/README.md b/instrumentation/delayed_job/README.md index c5994c5798..0a72d2cb07 100644 --- a/instrumentation/delayed_job/README.md +++ b/instrumentation/delayed_job/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage of delayed_job can be seen in the [`./example/delayed_job.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/delayed_job/example/delayed_job.rb) +Example usage of delayed_job can be seen in the `./example/delayed_job.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/delayed_job/example/delayed_job.rb) ## How can I get involved? diff --git a/instrumentation/delayed_job/test/opentelemetry/instrumentation/delayed_job_test.rb b/instrumentation/delayed_job/test/opentelemetry/instrumentation/delayed_job_test.rb index 561cc67164..907122b347 100644 --- a/instrumentation/delayed_job/test/opentelemetry/instrumentation/delayed_job_test.rb +++ b/instrumentation/delayed_job/test/opentelemetry/instrumentation/delayed_job_test.rb @@ -55,11 +55,9 @@ it 'after job' do payload = Class.new do - # rubocop:disable Naming/PredicateMethod def perform true end - # rubocop:enable Naming/PredicateMethod end job = Delayed::Job.enqueue(payload.new) diff --git a/instrumentation/ethon/Gemfile b/instrumentation/ethon/Gemfile index 8933592e8d..8f27a80732 100644 --- a/instrumentation/ethon/Gemfile +++ b/instrumentation/ethon/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/ethon/README.md b/instrumentation/ethon/README.md index bb686b09e0..fcf92dca7c 100644 --- a/instrumentation/ethon/README.md +++ b/instrumentation/ethon/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage of faraday can be seen in the [`./example/ethon.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/ethon/example/ethon.rb) +Example usage of faraday can be seen in the `./example/ethon.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/ethon/example/ethon.rb) ## How can I get involved? diff --git a/instrumentation/excon/Gemfile b/instrumentation/excon/Gemfile index 9484691699..33388452b1 100644 --- a/instrumentation/excon/Gemfile +++ b/instrumentation/excon/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/faraday/Appraisals b/instrumentation/faraday/Appraisals index 4ed32e3428..594dee720b 100644 --- a/instrumentation/faraday/Appraisals +++ b/instrumentation/faraday/Appraisals @@ -4,12 +4,22 @@ # # SPDX-License-Identifier: Apache-2.0 -%w[1.0 2.0].each do |version| - appraise "faraday-#{version}" do - gem 'faraday', "~> #{version}" +# To faclitate HTTP semantic convention stability migration, we are using +# appraisal to test the different semantic convention modes along with different +# gem versions. For more information on the semantic convention modes, see: +# https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/ + +versions = %w[1.0 2.0] +semconv_stability = %w[old stable dup] + +semconv_stability.each do |mode| + versions.each do |version| + appraise "faraday-#{version}-#{mode}" do + gem 'faraday', "~> #{version}" + end end -end -appraise 'faraday-latest' do - gem 'faraday' + appraise "faraday-latest-#{mode}" do + gem 'faraday' + end end diff --git a/instrumentation/faraday/CHANGELOG.md b/instrumentation/faraday/CHANGELOG.md index 342a08975f..dec9956876 100644 --- a/instrumentation/faraday/CHANGELOG.md +++ b/instrumentation/faraday/CHANGELOG.md @@ -1,9 +1,5 @@ # Release History: opentelemetry-instrumentation-faraday -### v0.27.0 / 2025-06-03 - -* ADDED: Suppress internal spans with Faraday instrumentation - ### v0.26.0 / 2025-01-16 * BREAKING CHANGE: Set minimum supported version to Ruby 3.1 diff --git a/instrumentation/faraday/Gemfile b/instrumentation/faraday/Gemfile index 9484691699..33388452b1 100644 --- a/instrumentation/faraday/Gemfile +++ b/instrumentation/faraday/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/faraday/README.md b/instrumentation/faraday/README.md index 88b77cad23..6178db4e6b 100644 --- a/instrumentation/faraday/README.md +++ b/instrumentation/faraday/README.md @@ -18,9 +18,7 @@ To install the instrumentation, call `use` with the name of the instrumentation. ```ruby OpenTelemetry::SDK.configure do |c| - c.use 'OpenTelemetry::Instrumentation::Faraday', { - enable_internal_instrumentation: false - } + c.use 'OpenTelemetry::Instrumentation::Faraday' end ``` @@ -32,14 +30,9 @@ OpenTelemetry::SDK.configure do |c| end ``` -### Configuration options -This instrumentation offers the following configuration options: -* `enable_internal_instrumentation` (default: `false`): When set to `true`, any spans with - span kind of `internal` are included in traces. - ## Examples -Example usage of faraday can be seen in the [`./example/faraday.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/faraday/example/faraday.rb) +Example usage of faraday can be seen in the `./example/faraday.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/faraday/example/faraday.rb) ## How can I get involved? @@ -59,3 +52,19 @@ Apache 2.0 license. See [LICENSE][license-github] for more information. [community-meetings]: https://github.com/open-telemetry/community#community-meetings [slack-channel]: https://cloud-native.slack.com/archives/C01NWKKMKMY [discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions + +## HTTP semantic convention stability + +In the OpenTelemetry ecosystem, HTTP semantic conventions have now reached a stable state. However, the initial Faraday instrumentation was introduced before this stability was achieved, which resulted in HTTP attributes being based on an older version of the semantic conventions. + +To facilitate the migration to stable semantic conventions, you can use the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This variable allows you to opt-in to the new stable conventions, ensuring compatibility and future-proofing your instrumentation. + +When setting the value for `OTEL_SEMCONV_STABILITY_OPT_IN`, you can specify which conventions you wish to adopt: + +- `http` - Emits the stable HTTP and networking conventions and ceases emitting the old conventions previously emitted by the instrumentation. +- `http/dup` - Emits both the old and stable HTTP and networking conventions, enabling a phased rollout of the stable semantic conventions. +- Default behavior (in the absence of either value) is to continue emitting the old HTTP and networking conventions the instrumentation previously emitted. + +During the transition from old to stable conventions, Faraday instrumentation code comes in three patch versions: `dup`, `old`, and `stable`. These versions are identical except for the attributes they send. Any changes to Faraday instrumentation should consider all three patches. + +For additional information on migration, please refer to our [documentation](https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/). \ No newline at end of file diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/instrumentation.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/instrumentation.rb index 6aa08328ad..79be614688 100644 --- a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/instrumentation.rb +++ b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/instrumentation.rb @@ -13,9 +13,10 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base MINIMUM_VERSION = Gem::Version.new('1.0') install do |_config| - require_dependencies - register_tracer_middleware - use_middleware_by_default + patch_type = determine_semconv + send(:"require_dependencies_#{patch_type}") + send(:"register_tracer_middleware_#{patch_type}") + send(:"use_middleware_by_default_#{patch_type}") end compatible do @@ -28,7 +29,6 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base option :span_kind, default: :client, validate: %i[client internal] option :peer_service, default: nil, validate: :string - option :enable_internal_instrumentation, default: false, validate: :boolean private @@ -36,19 +36,62 @@ def gem_version Gem::Version.new(::Faraday::VERSION) end - def require_dependencies - require_relative 'middlewares/tracer_middleware' - require_relative 'patches/connection' + def determine_semconv + stability_opt_in = ENV.fetch('OTEL_SEMCONV_STABILITY_OPT_IN', '') + values = stability_opt_in.split(',').map(&:strip) + + if values.include?('http/dup') + 'dup' + elsif values.include?('http') + 'stable' + else + 'old' + end + end + + def require_dependencies_dup + require_relative 'middlewares/dup/tracer_middleware' + require_relative 'patches/dup/connection' + end + + def require_dependencies_old + require_relative 'middlewares/old/tracer_middleware' + require_relative 'patches/old/connection' end - def register_tracer_middleware + def require_dependencies_stable + require_relative 'middlewares/stable/tracer_middleware' + require_relative 'patches/stable/connection' + end + + def register_tracer_middleware_dup ::Faraday::Middleware.register_middleware( - open_telemetry: Middlewares::TracerMiddleware + open_telemetry: Middlewares::Dup::TracerMiddleware ) end - def use_middleware_by_default - ::Faraday::Connection.prepend(Patches::Connection) + def register_tracer_middleware_old + ::Faraday::Middleware.register_middleware( + open_telemetry: Middlewares::Old::TracerMiddleware + ) + end + + def register_tracer_middleware_stable + ::Faraday::Middleware.register_middleware( + open_telemetry: Middlewares::Stable::TracerMiddleware + ) + end + + def use_middleware_by_default_dup + ::Faraday::Connection.prepend(Patches::Dup::Connection) + end + + def use_middleware_by_default_old + ::Faraday::Connection.prepend(Patches::Old::Connection) + end + + def use_middleware_by_default_stable + ::Faraday::Connection.prepend(Patches::Stable::Connection) end end end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/dup/tracer_middleware.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/dup/tracer_middleware.rb new file mode 100644 index 0000000000..78565ab827 --- /dev/null +++ b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/dup/tracer_middleware.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module Faraday + module Middlewares + module Dup + # TracerMiddleware propagates context and instruments Faraday requests + # by way of its middleware system + class TracerMiddleware < ::Faraday::Middleware + HTTP_METHODS_SYMBOL_TO_STRING = { + connect: 'CONNECT', + delete: 'DELETE', + get: 'GET', + head: 'HEAD', + options: 'OPTIONS', + patch: 'PATCH', + post: 'POST', + put: 'PUT', + trace: 'TRACE' + }.freeze + + # Constant for the HTTP status range + HTTP_STATUS_SUCCESS_RANGE = (100..399) + + def call(env) + http_method = HTTP_METHODS_SYMBOL_TO_STRING[env.method] + config = Faraday::Instrumentation.instance.config + + attributes = span_creation_attributes( + http_method: http_method, url: env.url, config: config + ) + + OpenTelemetry::Common::HTTP::ClientContext.with_attributes(attributes) do |attrs, _| + tracer.in_span( + http_method.to_s, attributes: attrs, kind: config.fetch(:span_kind) + ) do |span| + OpenTelemetry.propagation.inject(env.request_headers) + + if config[:enable_internal_instrumentation] == false + OpenTelemetry::Common::Utilities.untraced do + app.call(env).on_complete { |resp| trace_response(span, resp.status) } + end + else + app.call(env).on_complete { |resp| trace_response(span, resp.status) } + end + rescue ::Faraday::Error => e + trace_response(span, e.response[:status]) if e.response + + raise + end + end + end + + private + + def span_creation_attributes(http_method:, url:, config:) + attrs = { + 'http.method' => http_method, + 'http.request.method' => http_method, + 'http.url' => OpenTelemetry::Common::Utilities.cleanse_url(url.to_s), + 'url.full' => OpenTelemetry::Common::Utilities.cleanse_url(url.to_s), + 'faraday.adapter.name' => app.class.name + } + attrs['net.peer.name'] = url.host if url.host + attrs['server.address'] = url.host if url.host + attrs['peer.service'] = config[:peer_service] if config[:peer_service] + + attrs.merge!( + OpenTelemetry::Common::HTTP::ClientContext.attributes + ) + end + + # Versions prior to 1.0 do not define an accessor for app + attr_reader :app if Gem::Version.new(Faraday::VERSION) < Gem::Version.new('1.0.0') + + def tracer + Faraday::Instrumentation.instance.tracer + end + + def trace_response(span, status) + span.set_attribute('http.status_code', status) + span.set_attribute('http.response.status_code', status) + span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status.to_i) + end + end + end + end + end + end +end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/old/tracer_middleware.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/old/tracer_middleware.rb new file mode 100644 index 0000000000..7b263a2f9e --- /dev/null +++ b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/old/tracer_middleware.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module Faraday + module Middlewares + module Old + # TracerMiddleware propagates context and instruments Faraday requests + # by way of its middleware system + class TracerMiddleware < ::Faraday::Middleware + HTTP_METHODS_SYMBOL_TO_STRING = { + connect: 'CONNECT', + delete: 'DELETE', + get: 'GET', + head: 'HEAD', + options: 'OPTIONS', + patch: 'PATCH', + post: 'POST', + put: 'PUT', + trace: 'TRACE' + }.freeze + + # Constant for the HTTP status range + HTTP_STATUS_SUCCESS_RANGE = (100..399) + + def call(env) + http_method = HTTP_METHODS_SYMBOL_TO_STRING[env.method] + config = Faraday::Instrumentation.instance.config + + attributes = span_creation_attributes( + http_method: http_method, url: env.url, config: config + ) + + OpenTelemetry::Common::HTTP::ClientContext.with_attributes(attributes) do |attrs, _| + tracer.in_span( + "HTTP #{http_method}", attributes: attrs, kind: config.fetch(:span_kind) + ) do |span| + OpenTelemetry.propagation.inject(env.request_headers) + + if config[:enable_internal_instrumentation] == false + OpenTelemetry::Common::Utilities.untraced do + app.call(env).on_complete { |resp| trace_response(span, resp.status) } + end + else + app.call(env).on_complete { |resp| trace_response(span, resp.status) } + end + rescue ::Faraday::Error => e + trace_response(span, e.response[:status]) if e.response + + raise + end + end + end + + private + + def span_creation_attributes(http_method:, url:, config:) + attrs = { + 'http.method' => http_method, + 'http.url' => OpenTelemetry::Common::Utilities.cleanse_url(url.to_s), + 'faraday.adapter.name' => app.class.name + } + attrs['net.peer.name'] = url.host if url.host + attrs['peer.service'] = config[:peer_service] if config[:peer_service] + + attrs.merge!( + OpenTelemetry::Common::HTTP::ClientContext.attributes + ) + end + + # Versions prior to 1.0 do not define an accessor for app + attr_reader :app if Gem::Version.new(Faraday::VERSION) < Gem::Version.new('1.0.0') + + def tracer + Faraday::Instrumentation.instance.tracer + end + + def trace_response(span, status) + span.set_attribute('http.status_code', status) + span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status.to_i) + end + end + end + end + end + end +end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/stable/tracer_middleware.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/stable/tracer_middleware.rb new file mode 100644 index 0000000000..587fecc204 --- /dev/null +++ b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/stable/tracer_middleware.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module Faraday + module Middlewares + module Stable + # TracerMiddleware propagates context and instruments Faraday requests + # by way of its middleware system + class TracerMiddleware < ::Faraday::Middleware + HTTP_METHODS_SYMBOL_TO_STRING = { + connect: 'CONNECT', + delete: 'DELETE', + get: 'GET', + head: 'HEAD', + options: 'OPTIONS', + patch: 'PATCH', + post: 'POST', + put: 'PUT', + trace: 'TRACE' + }.freeze + + # Constant for the HTTP status range + HTTP_STATUS_SUCCESS_RANGE = (100..399) + + def call(env) + http_method = HTTP_METHODS_SYMBOL_TO_STRING[env.method] + config = Faraday::Instrumentation.instance.config + + attributes = span_creation_attributes( + http_method: http_method, url: env.url, config: config + ) + + OpenTelemetry::Common::HTTP::ClientContext.with_attributes(attributes) do |attrs, _| + tracer.in_span( + http_method.to_s, attributes: attrs, kind: config.fetch(:span_kind) + ) do |span| + OpenTelemetry.propagation.inject(env.request_headers) + + if config[:enable_internal_instrumentation] == false + OpenTelemetry::Common::Utilities.untraced do + app.call(env).on_complete { |resp| trace_response(span, resp.status) } + end + else + app.call(env).on_complete { |resp| trace_response(span, resp.status) } + end + rescue ::Faraday::Error => e + trace_response(span, e.response[:status]) if e.response + + raise + end + end + end + + private + + def span_creation_attributes(http_method:, url:, config:) + attrs = { + 'http.request.method' => http_method, + 'url.full' => OpenTelemetry::Common::Utilities.cleanse_url(url.to_s), + 'faraday.adapter.name' => app.class.name + } + attrs['server.address'] = url.host if url.host + attrs['peer.service'] = config[:peer_service] if config[:peer_service] + + attrs.merge!( + OpenTelemetry::Common::HTTP::ClientContext.attributes + ) + end + + # Versions prior to 1.0 do not define an accessor for app + attr_reader :app if Gem::Version.new(Faraday::VERSION) < Gem::Version.new('1.0.0') + + def tracer + Faraday::Instrumentation.instance.tracer + end + + def trace_response(span, status) + span.set_attribute('http.response.status_code', status) + span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status.to_i) + end + end + end + end + end + end +end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware.rb deleted file mode 100644 index ac4b298431..0000000000 --- a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Instrumentation - module Faraday - module Middlewares - # TracerMiddleware propagates context and instruments Faraday requests - # by way of its middleware system - class TracerMiddleware < ::Faraday::Middleware - HTTP_METHODS_SYMBOL_TO_STRING = { - connect: 'CONNECT', - delete: 'DELETE', - get: 'GET', - head: 'HEAD', - options: 'OPTIONS', - patch: 'PATCH', - post: 'POST', - put: 'PUT', - trace: 'TRACE' - }.freeze - - # Constant for the HTTP status range - HTTP_STATUS_SUCCESS_RANGE = (100..399) - - def call(env) - http_method = HTTP_METHODS_SYMBOL_TO_STRING[env.method] - config = Faraday::Instrumentation.instance.config - - attributes = span_creation_attributes( - http_method: http_method, url: env.url, config: config - ) - - OpenTelemetry::Common::HTTP::ClientContext.with_attributes(attributes) do |attrs, _| - tracer.in_span( - "HTTP #{http_method}", attributes: attrs, kind: config.fetch(:span_kind) - ) do |span| - OpenTelemetry.propagation.inject(env.request_headers) - - if config[:enable_internal_instrumentation] == false - OpenTelemetry::Common::Utilities.untraced do - app.call(env).on_complete { |resp| trace_response(span, resp.status) } - end - else - app.call(env).on_complete { |resp| trace_response(span, resp.status) } - end - rescue ::Faraday::Error => e - trace_response(span, e.response[:status]) if e.response - - raise - end - end - end - - private - - def span_creation_attributes(http_method:, url:, config:) - attrs = { - 'http.method' => http_method, - 'http.url' => OpenTelemetry::Common::Utilities.cleanse_url(url.to_s), - 'faraday.adapter.name' => app.class.name - } - attrs['net.peer.name'] = url.host if url.host - attrs['peer.service'] = config[:peer_service] if config[:peer_service] - - attrs.merge!( - OpenTelemetry::Common::HTTP::ClientContext.attributes - ) - end - - # Versions prior to 1.0 do not define an accessor for app - attr_reader :app if Gem::Version.new(Faraday::VERSION) < Gem::Version.new('1.0.0') - - def tracer - Faraday::Instrumentation.instance.tracer - end - - def trace_response(span, status) - span.set_attribute('http.status_code', status) - span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status.to_i) - end - end - end - end - end -end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/connection.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/connection.rb deleted file mode 100644 index 1819488ad0..0000000000 --- a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/connection.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Instrumentation - module Faraday - module Patches - # Module to be prepended to force Faraday to use the middleware by - # default so the user doesn't have to call `use` for every connection. - module Connection - # Wraps Faraday::Connection#initialize: - # https://github.com/lostisland/faraday/blob/ff9dc1d1219a1bbdba95a9a4cf5d135b97247ee2/lib/faraday/connection.rb#L62-L92 - def initialize(...) - super.tap do - use(:open_telemetry) unless builder.handlers.any? do |handler| - handler.klass == Middlewares::TracerMiddleware - end - end - end - end - end - end - end -end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/dup/connection.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/dup/connection.rb new file mode 100644 index 0000000000..621ca05962 --- /dev/null +++ b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/dup/connection.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module Faraday + module Patches + module Dup + # Module to be prepended to force Faraday to use the middleware by + # default so the user doesn't have to call `use` for every connection. + module Connection + # Wraps Faraday::Connection#initialize: + # https://github.com/lostisland/faraday/blob/ff9dc1d1219a1bbdba95a9a4cf5d135b97247ee2/lib/faraday/connection.rb#L62-L92 + def initialize(...) + super.tap do + use(:open_telemetry) unless builder.handlers.any? do |handler| + handler.klass == Middlewares::Dup::TracerMiddleware + end + end + end + end + end + end + end + end +end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/old/connection.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/old/connection.rb new file mode 100644 index 0000000000..dbe067900a --- /dev/null +++ b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/old/connection.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module Faraday + module Patches + module Old + # Module to be prepended to force Faraday to use the middleware by + # default so the user doesn't have to call `use` for every connection. + module Connection + # Wraps Faraday::Connection#initialize: + # https://github.com/lostisland/faraday/blob/ff9dc1d1219a1bbdba95a9a4cf5d135b97247ee2/lib/faraday/connection.rb#L62-L92 + def initialize(...) + super.tap do + use(:open_telemetry) unless builder.handlers.any? do |handler| + handler.klass == Middlewares::Old::TracerMiddleware + end + end + end + end + end + end + end + end +end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/stable/connection.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/stable/connection.rb new file mode 100644 index 0000000000..8cb5a880bc --- /dev/null +++ b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/patches/stable/connection.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module Faraday + module Patches + module Stable + # Module to be prepended to force Faraday to use the middleware by + # default so the user doesn't have to call `use` for every connection. + module Connection + # Wraps Faraday::Connection#initialize: + # https://github.com/lostisland/faraday/blob/ff9dc1d1219a1bbdba95a9a4cf5d135b97247ee2/lib/faraday/connection.rb#L62-L92 + def initialize(...) + super.tap do + use(:open_telemetry) unless builder.handlers.any? do |handler| + handler.klass == Middlewares::Stable::TracerMiddleware + end + end + end + end + end + end + end + end +end diff --git a/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/version.rb b/instrumentation/faraday/lib/opentelemetry/instrumentation/faraday/version.rb index 44b14fa388..92ffabb8a0 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.27.0' + VERSION = '0.26.0' end end end diff --git a/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/dup/tracer_middleware_test.rb b/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/dup/tracer_middleware_test.rb new file mode 100644 index 0000000000..15b6badb0e --- /dev/null +++ b/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/dup/tracer_middleware_test.rb @@ -0,0 +1,264 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +# require Instrumentation so .install method is found: +require_relative '../../../../../../lib/opentelemetry/instrumentation/faraday/middlewares/dup/tracer_middleware' + +describe OpenTelemetry::Instrumentation::Faraday::Middlewares::Dup::TracerMiddleware do + let(:instrumentation) { OpenTelemetry::Instrumentation::Faraday::Instrumentation.instance } + let(:exporter) { EXPORTER } + let(:span) { exporter.finished_spans.first } + + let(:client) do + Faraday.new('http://username:password@example.com') do |builder| + builder.adapter(:test) do |stub| + stub.get('/success') { |_| [200, {}, 'OK'] } + stub.get('/failure') { |_| [500, {}, 'OK'] } + stub.get('/not_found') { |_| [404, {}, 'OK'] } + stub.get('/show-shared-attributes') { |_| [200, {}, OpenTelemetry::Common::HTTP::ClientContext.attributes.to_json] } + end + end + end + + before do + skip unless ENV['BUNDLE_GEMFILE'].include?('dup') + + ENV['OTEL_SEMCONV_STABILITY_OPT_IN'] = 'http/dup' + exporter.reset + + # this is currently a noop but this will future proof the test + @orig_propagation = OpenTelemetry.propagation + propagator = OpenTelemetry::Trace::Propagation::TraceContext.text_map_propagator + OpenTelemetry.propagation = propagator + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install + end + + after do + OpenTelemetry.propagation = @orig_propagation + end + + describe 'first span' do + describe 'given a client with a base url' do + it 'has http 200 attributes' do + response = client.get('/success') + + _(span.name).must_equal 'GET' + # old attributes + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.status_code']).must_equal 200 + _(span.attributes['http.url']).must_equal 'http://example.com/success' + _(span.attributes['net.peer.name']).must_equal 'example.com' + # stable attributes + _(span.attributes['http.request.method']).must_equal 'GET' + _(span.attributes['http.response.status_code']).must_equal 200 + _(span.attributes['url.full']).must_equal 'http://example.com/success' + _(span.attributes['server.address']).must_equal 'example.com' + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + + it 'has http.status_code 404' do + response = client.get('/not_found') + + _(span.name).must_equal 'GET' + # old attributes + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.status_code']).must_equal 404 + _(span.attributes['http.url']).must_equal 'http://example.com/not_found' + _(span.attributes['net.peer.name']).must_equal 'example.com' + # stable attributes + _(span.attributes['http.request.method']).must_equal 'GET' + _(span.attributes['http.response.status_code']).must_equal 404 + _(span.attributes['url.full']).must_equal 'http://example.com/not_found' + _(span.attributes['server.address']).must_equal 'example.com' + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + + it 'has http.status_code 500' do + response = client.get('/failure') + + _(span.name).must_equal 'GET' + # old attributes + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.status_code']).must_equal 500 + _(span.attributes['http.url']).must_equal 'http://example.com/failure' + _(span.attributes['net.peer.name']).must_equal 'example.com' + # stable attributes + _(span.attributes['http.request.method']).must_equal 'GET' + _(span.attributes['http.response.status_code']).must_equal 500 + _(span.attributes['url.full']).must_equal 'http://example.com/failure' + _(span.attributes['server.address']).must_equal 'example.com' + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + + it 'merges http client attributes' do + client_context_attrs = { + 'test.attribute' => 'test.value', 'http.method' => 'OVERRIDE', 'http.request.method' => 'OVERRIDE' + } + response = OpenTelemetry::Common::HTTP::ClientContext.with_attributes(client_context_attrs) do + client.get('/success') + end + + _(span.name).must_equal 'GET' + # old attributes + _(span.attributes['http.method']).must_equal 'OVERRIDE' + _(span.attributes['http.status_code']).must_equal 200 + _(span.attributes['http.url']).must_equal 'http://example.com/success' + _(span.attributes['net.peer.name']).must_equal 'example.com' + # stable attributes + _(span.attributes['http.request.method']).must_equal 'OVERRIDE' + _(span.attributes['http.response.status_code']).must_equal 200 + _(span.attributes['url.full']).must_equal 'http://example.com/success' + _(span.attributes['server.address']).must_equal 'example.com' + _(span.attributes['test.attribute']).must_equal 'test.value' + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + + it 'ammends attributes to client context' do + response = client.get('/show-shared-attributes') + shared_attributes = JSON.parse(response.body) + expected_attributes = { + 'http.method' => 'GET', + 'http.url' => 'http://example.com/show-shared-attributes', + 'faraday.adapter.name' => 'Faraday::Adapter::Test', + 'net.peer.name' => 'example.com', + 'http.request.method' => 'GET', + 'url.full' => 'http://example.com/show-shared-attributes', + 'server.address' => 'example.com' + } + + _(shared_attributes).must_equal expected_attributes + end + + it 'accepts peer service name from config' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install(peer_service: 'example:faraday') + + client.get('/success') + + _(span.attributes['peer.service']).must_equal 'example:faraday' + end + + it 'defaults to span kind client' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install + + client.get('/success') + + _(span.kind).must_equal :client + end + + it 'allows overriding the span kind to internal' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install(span_kind: :internal) + + client.get('/success') + + _(span.kind).must_equal :internal + end + + it 'reports the name of the configured adapter' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install + + client.get('/success') + + _(span.attributes.fetch('faraday.adapter.name')).must_equal Faraday::Adapter::Test.name + end + + it 'prioritizes context attributes over config for peer service name' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install(peer_service: 'example:faraday') + + client_context_attrs = { 'peer.service' => 'example:custom' } + OpenTelemetry::Common::HTTP::ClientContext.with_attributes(client_context_attrs) do + client.get('/success') + end + + _(span.attributes['peer.service']).must_equal 'example:custom' + end + + it 'does not leak authentication credentials' do + client.run_request(:get, 'http://username:password@example.com/success', nil, {}) + + _(span.attributes['http.url']).must_equal 'http://example.com/success' + end + end + + describe 'given a client without a base url' do + let(:client) do + Faraday.new do |builder| + builder.adapter(:test) do |stub| + stub.get('/success') { |_| [200, {}, 'OK'] } + end + end + end + + it 'omits missing attributes' do + response = client.get('/success') + + _(span.name).must_equal 'GET' + # old attributes + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.status_code']).must_equal 200 + _(span.attributes['http.url']).must_equal 'http:/success' + _(span.attributes).wont_include('net.peer.name') + # stable attributes + _(span.attributes['http.request.method']).must_equal 'GET' + _(span.attributes['http.response.status_code']).must_equal 200 + _(span.attributes['url.full']).must_equal 'http:/success' + _(span.attributes).wont_include('server.address') + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + end + + describe 'when faraday raises an error' do + let(:client) do + Faraday.new do |builder| + builder.response :raise_error + builder.adapter(:test) do |stub| + stub.get('/not_found') { |_| [404, {}, 'NOT FOUND'] } + end + end + end + + it 'adds response attributes' do + assert_raises Faraday::Error do + client.get('/not_found') + end + + _(span.attributes['http.status_code']).must_equal 404 + _(span.attributes['http.response.status_code']).must_equal 404 + _(span.status.code).must_equal OpenTelemetry::Trace::Status::ERROR + end + end + + describe 'when explicitly adding the tracer middleware' do + let(:client) do + Faraday.new do |builder| + builder.use :open_telemetry + end + end + + it 'only adds the middleware once' do + tracers = client.builder.handlers.count(OpenTelemetry::Instrumentation::Faraday::Middlewares::Dup::TracerMiddleware) + _(tracers).must_equal 1 + end + end + end +end diff --git a/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware_test.rb b/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/old/tracer_middleware_test.rb similarity index 96% rename from instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware_test.rb rename to instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/old/tracer_middleware_test.rb index 67aab661f9..4f88b61b0c 100644 --- a/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware_test.rb +++ b/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/old/tracer_middleware_test.rb @@ -7,9 +7,9 @@ require 'test_helper' # require Instrumentation so .install method is found: -require_relative '../../../../../lib/opentelemetry/instrumentation/faraday/middlewares/tracer_middleware' +require_relative '../../../../../../lib/opentelemetry/instrumentation/faraday/middlewares/old/tracer_middleware' -describe OpenTelemetry::Instrumentation::Faraday::Middlewares::TracerMiddleware do +describe OpenTelemetry::Instrumentation::Faraday::Middlewares::Old::TracerMiddleware do let(:instrumentation) { OpenTelemetry::Instrumentation::Faraday::Instrumentation.instance } let(:exporter) { EXPORTER } let(:span) { exporter.finished_spans.first } @@ -26,6 +26,8 @@ end before do + skip unless ENV['BUNDLE_GEMFILE'].include?('old') + exporter.reset # this is currently a noop but this will future proof the test @@ -218,7 +220,7 @@ end it 'only adds the middleware once' do - tracers = client.builder.handlers.count(OpenTelemetry::Instrumentation::Faraday::Middlewares::TracerMiddleware) + tracers = client.builder.handlers.count(OpenTelemetry::Instrumentation::Faraday::Middlewares::Old::TracerMiddleware) _(tracers).must_equal 1 end end diff --git a/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/stable/tracer_middleware_test.rb b/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/stable/tracer_middleware_test.rb new file mode 100644 index 0000000000..7cfaf8142b --- /dev/null +++ b/instrumentation/faraday/test/opentelemetry/instrumentation/faraday/middlewares/stable/tracer_middleware_test.rb @@ -0,0 +1,230 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +# require Instrumentation so .install method is found: +require_relative '../../../../../../lib/opentelemetry/instrumentation/faraday/middlewares/stable/tracer_middleware' + +describe OpenTelemetry::Instrumentation::Faraday::Middlewares::Stable::TracerMiddleware do + let(:instrumentation) { OpenTelemetry::Instrumentation::Faraday::Instrumentation.instance } + let(:exporter) { EXPORTER } + let(:span) { exporter.finished_spans.first } + + let(:client) do + Faraday.new('http://username:password@example.com') do |builder| + builder.adapter(:test) do |stub| + stub.get('/success') { |_| [200, {}, 'OK'] } + stub.get('/failure') { |_| [500, {}, 'OK'] } + stub.get('/not_found') { |_| [404, {}, 'OK'] } + stub.get('/show-shared-attributes') { |_| [200, {}, OpenTelemetry::Common::HTTP::ClientContext.attributes.to_json] } + end + end + end + + before do + skip unless ENV['BUNDLE_GEMFILE'].include?('stable') + + ENV['OTEL_SEMCONV_STABILITY_OPT_IN'] = 'http' + exporter.reset + + # this is currently a noop but this will future proof the test + @orig_propagation = OpenTelemetry.propagation + propagator = OpenTelemetry::Trace::Propagation::TraceContext.text_map_propagator + OpenTelemetry.propagation = propagator + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install + end + + after do + OpenTelemetry.propagation = @orig_propagation + end + + describe 'first span' do + describe 'given a client with a base url' do + it 'has http 200 attributes' do + response = client.get('/success') + + _(span.name).must_equal 'GET' + _(span.attributes['http.request.method']).must_equal 'GET' + _(span.attributes['http.response.status_code']).must_equal 200 + _(span.attributes['url.full']).must_equal 'http://example.com/success' + _(span.attributes['server.address']).must_equal 'example.com' + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + + it 'has http.response.status_code 404' do + response = client.get('/not_found') + + _(span.name).must_equal 'GET' + _(span.attributes['http.request.method']).must_equal 'GET' + _(span.attributes['http.response.status_code']).must_equal 404 + _(span.attributes['url.full']).must_equal 'http://example.com/not_found' + _(span.attributes['server.address']).must_equal 'example.com' + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + + it 'has http.response.status_code 500' do + response = client.get('/failure') + + _(span.name).must_equal 'GET' + _(span.attributes['http.request.method']).must_equal 'GET' + _(span.attributes['http.response.status_code']).must_equal 500 + _(span.attributes['url.full']).must_equal 'http://example.com/failure' + _(span.attributes['server.address']).must_equal 'example.com' + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + + it 'merges http client attributes' do + client_context_attrs = { + 'test.attribute' => 'test.value', 'http.request.method' => 'OVERRIDE' + } + response = OpenTelemetry::Common::HTTP::ClientContext.with_attributes(client_context_attrs) do + client.get('/success') + end + + _(span.name).must_equal 'GET' + _(span.attributes['http.request.method']).must_equal 'OVERRIDE' + _(span.attributes['http.response.status_code']).must_equal 200 + _(span.attributes['url.full']).must_equal 'http://example.com/success' + _(span.attributes['server.address']).must_equal 'example.com' + _(span.attributes['test.attribute']).must_equal 'test.value' + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + + it 'ammends attributes to client context' do + response = client.get('/show-shared-attributes') + shared_attributes = JSON.parse(response.body) + expected_attributes = { + 'http.request.method' => 'GET', + 'url.full' => 'http://example.com/show-shared-attributes', + 'faraday.adapter.name' => 'Faraday::Adapter::Test', + 'server.address' => 'example.com' + } + + _(shared_attributes).must_equal expected_attributes + end + + it 'accepts peer service name from config' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install(peer_service: 'example:faraday') + + client.get('/success') + + _(span.attributes['peer.service']).must_equal 'example:faraday' + end + + it 'defaults to span kind client' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install + + client.get('/success') + + _(span.kind).must_equal :client + end + + it 'allows overriding the span kind to internal' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install(span_kind: :internal) + + client.get('/success') + + _(span.kind).must_equal :internal + end + + it 'reports the name of the configured adapter' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install + + client.get('/success') + + _(span.attributes.fetch('faraday.adapter.name')).must_equal Faraday::Adapter::Test.name + end + + it 'prioritizes context attributes over config for peer service name' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install(peer_service: 'example:faraday') + + client_context_attrs = { 'peer.service' => 'example:custom' } + OpenTelemetry::Common::HTTP::ClientContext.with_attributes(client_context_attrs) do + client.get('/success') + end + + _(span.attributes['peer.service']).must_equal 'example:custom' + end + + it 'does not leak authentication credentials' do + client.run_request(:get, 'http://username:password@example.com/success', nil, {}) + + _(span.attributes['url.full']).must_equal 'http://example.com/success' + end + end + + describe 'given a client without a base url' do + let(:client) do + Faraday.new do |builder| + builder.adapter(:test) do |stub| + stub.get('/success') { |_| [200, {}, 'OK'] } + end + end + end + + it 'omits missing attributes' do + response = client.get('/success') + + _(span.name).must_equal 'GET' + _(span.attributes['http.request.method']).must_equal 'GET' + _(span.attributes['http.response.status_code']).must_equal 200 + _(span.attributes['url.full']).must_equal 'http:/success' + _(span.attributes).wont_include('server.address') + _(response.env.request_headers['Traceparent']).must_equal( + "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" + ) + end + end + + describe 'when faraday raises an error' do + let(:client) do + Faraday.new do |builder| + builder.response :raise_error + builder.adapter(:test) do |stub| + stub.get('/not_found') { |_| [404, {}, 'NOT FOUND'] } + end + end + end + + it 'adds response attributes' do + assert_raises Faraday::Error do + client.get('/not_found') + end + + _(span.attributes['http.response.status_code']).must_equal 404 + _(span.status.code).must_equal OpenTelemetry::Trace::Status::ERROR + end + end + + describe 'when explicitly adding the tracer middleware' do + let(:client) do + Faraday.new do |builder| + builder.use :open_telemetry + end + end + + it 'only adds the middleware once' do + tracers = client.builder.handlers.count(OpenTelemetry::Instrumentation::Faraday::Middlewares::Stable::TracerMiddleware) + _(tracers).must_equal 1 + end + end + end +end diff --git a/instrumentation/faraday/test/opentelemetry/instrumentation/faraday_test.rb b/instrumentation/faraday/test/opentelemetry/instrumentation/faraday_test.rb index eabf86e05f..d4cace38f6 100644 --- a/instrumentation/faraday/test/opentelemetry/instrumentation/faraday_test.rb +++ b/instrumentation/faraday/test/opentelemetry/instrumentation/faraday_test.rb @@ -11,6 +11,8 @@ let(:exporter) { EXPORTER } before do + skip unless ENV['BUNDLE_GEMFILE'].include?('old') + instrumentation.install exporter.reset end diff --git a/instrumentation/grape/Gemfile b/instrumentation/grape/Gemfile index 33a221f896..95a1c92820 100644 --- a/instrumentation/grape/Gemfile +++ b/instrumentation/grape/Gemfile @@ -18,7 +18,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/grape/README.md b/instrumentation/grape/README.md index be1fd5708c..ca046a2350 100644 --- a/instrumentation/grape/README.md +++ b/instrumentation/grape/README.md @@ -2,7 +2,7 @@ The Grape instrumentation is a community-maintained instrumentation for [Grape][grape], a REST-like API framework for Ruby. -It relies on the [Grape built-in support for `ActiveSupport::Notifications`](https://github.com/ruby-grape/grape#active-support-instrumentation) and the [OpenTelemetry Rack instrumentation](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/opentelemetry-instrumentation-rack/v0.24.6/instrumentation/rack). +It relies on the Grape built-in support for `ActiveSupport::Notifications` (more info [here](https://github.com/ruby-grape/grape#active-support-instrumentation)) and the [OpenTelemetry Rack instrumentation](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/opentelemetry-instrumentation-rack/v0.24.6/instrumentation/rack). It currently supports the following events: @@ -69,7 +69,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/grape/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/grape/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/graphql/Gemfile b/instrumentation/graphql/Gemfile index 35abd9d688..a2eceb969b 100644 --- a/instrumentation/graphql/Gemfile +++ b/instrumentation/graphql/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/grpc/Gemfile b/instrumentation/grpc/Gemfile index e6a605279b..529d14941a 100644 --- a/instrumentation/grpc/Gemfile +++ b/instrumentation/grpc/Gemfile @@ -18,7 +18,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.4' gem 'rake', '~> 13.2' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/grpc/README.md b/instrumentation/grpc/README.md index 822133fc64..b7cf4839e6 100644 --- a/instrumentation/grpc/README.md +++ b/instrumentation/grpc/README.md @@ -43,7 +43,7 @@ instrumentation. ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/grpc/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/grpc/example/trace_demonstration.rb) ## Development diff --git a/instrumentation/gruf/Gemfile b/instrumentation/gruf/Gemfile index 6113ae0fa6..82410bca6d 100644 --- a/instrumentation/gruf/Gemfile +++ b/instrumentation/gruf/Gemfile @@ -18,7 +18,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.0' gem 'rake', '~> 12.3.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/gruf/README.md b/instrumentation/gruf/README.md index 4edc9838e6..fae675ebc6 100644 --- a/instrumentation/gruf/README.md +++ b/instrumentation/gruf/README.md @@ -37,7 +37,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/gruf/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/gruf/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/http/Appraisals b/instrumentation/http/Appraisals index 3e908a481d..5a6c74f7a4 100644 --- a/instrumentation/http/Appraisals +++ b/instrumentation/http/Appraisals @@ -4,19 +4,10 @@ # # SPDX-License-Identifier: Apache-2.0 -# To faclitate HTTP semantic convention stability migration, we are using -# appraisal to test the different semantic convention modes along with different -# HTTP gem versions. For more information on the semantic convention modes, see: -# https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/ - -semconv_stability = %w[dup stable old] - -semconv_stability.each do |mode| - appraise "http-4.4.0-#{mode}" do - gem 'http', '~> 4.4.0' - end +appraise 'http-4.4' do + gem 'http', '~> 4.4.0' +end - appraise "http-3.3.0-#{mode}" do - gem 'http', '~> 3.3.0' - end +appraise 'http-3.3.0' do + gem 'http', '~> 3.3.0' end diff --git a/instrumentation/http/CHANGELOG.md b/instrumentation/http/CHANGELOG.md index d3645f588f..3cb0602ae4 100644 --- a/instrumentation/http/CHANGELOG.md +++ b/instrumentation/http/CHANGELOG.md @@ -1,13 +1,5 @@ # Release History: opentelemetry-instrumentation-http -### v0.25.1 / 2025-07-01 - -* FIXED: Update span name when semconv stability is enabled - -### v0.25.0 / 2025-06-17 - -* ADDED: Add `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable [#1547](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/1547) - ### v0.24.0 / 2025-01-16 * BREAKING CHANGE: Set minimum supported version to Ruby 3.1 @@ -32,28 +24,28 @@ ### v0.23.1 / 2023-06-05 -* FIXED: Base config options +* FIXED: Base config options ### v0.23.0 / 2023-05-15 -* ADDED: Add span_preprocessor hook +* ADDED: Add span_preprocessor hook ### v0.22.0 / 2023-04-17 -* BREAKING CHANGE: Drop support for EoL Ruby 2.7 +* BREAKING CHANGE: Drop support for EoL Ruby 2.7 -* ADDED: Drop support for EoL Ruby 2.7 +* ADDED: Drop support for EoL Ruby 2.7 ### v0.21.0 / 2023-01-14 -* ADDED: Add request/response hooks to more http clients -* DOCS: Fix gem homepage -* DOCS: More gem documentation fixes +* ADDED: Add request/response hooks to more http clients +* DOCS: Fix gem homepage +* DOCS: More gem documentation fixes ### v0.20.0 / 2022-06-09 * Upgrading Base dependency version -* FIXED: Broken test file requirements +* FIXED: Broken test file requirements ### v0.19.6 / 2022-05-05 @@ -61,15 +53,15 @@ ### v0.19.5 / 2022-05-02 -* FIXED: RubyGems Fallback +* FIXED: RubyGems Fallback ### v0.19.4 / 2022-02-02 -* FIXED: Excessive hash creation on context attr merging +* FIXED: Excessive hash creation on context attr merging ### v0.19.3 / 2021-12-01 -* FIXED: Change net attribute names to match the semantic conventions spec for http +* FIXED: Change net attribute names to match the semantic conventions spec for http ### v0.19.2 / 2021-09-29 @@ -81,9 +73,9 @@ ### v0.19.0 / 2021-06-23 -* BREAKING CHANGE: Total order constraint on span.status= +* BREAKING CHANGE: Total order constraint on span.status= -* FIXED: Total order constraint on span.status= +* FIXED: Total order constraint on span.status= ### v0.18.0 / 2021-05-21 diff --git a/instrumentation/http/Gemfile b/instrumentation/http/Gemfile index 60447ac0ab..a07a1265b1 100644 --- a/instrumentation/http/Gemfile +++ b/instrumentation/http/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/http/README.md b/instrumentation/http/README.md index 9ae2296a1d..91d7fe8d99 100644 --- a/instrumentation/http/README.md +++ b/instrumentation/http/README.md @@ -44,7 +44,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/http/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/http/example/trace_demonstration.rb) ## How can I get involved? @@ -64,19 +64,3 @@ The `opentelemetry-instrumentation-http` gem is distributed under the Apache 2.0 [community-meetings]: https://github.com/open-telemetry/community#community-meetings [slack-channel]: https://cloud-native.slack.com/archives/C01NWKKMKMY [discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions - -## HTTP semantic convention stability - -In the OpenTelemetry ecosystem, HTTP semantic conventions have now reached a stable state. However, the initial HTTP instrumentation was introduced before this stability was achieved, which resulted in HTTP attributes being based on an older version of the semantic conventions. - -To facilitate the migration to stable semantic conventions, you can use the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This variable allows you to opt-in to the new stable conventions, ensuring compatibility and future-proofing your instrumentation. - -When setting the value for `OTEL_SEMCONV_STABILITY_OPT_IN`, you can specify which conventions you wish to adopt: - -- `http` - Emits the stable HTTP and networking conventions and ceases emitting the old conventions previously emitted by the instrumentation. -- `http/dup` - Emits both the old and stable HTTP and networking conventions, enabling a phased rollout of the stable semantic conventions. -- Default behavior (in the absence of either value) is to continue emitting the old HTTP and networking conventions the instrumentation previously emitted. - -During the transition from old to stable conventions, HTTP instrumentation code comes in three patch versions: `dup`, `old`, and `stable`. These versions are identical except for the attributes they send. Any changes to HTTP instrumentation should consider all three patches. - -For additional information on migration, please refer to our [documentation](https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/). diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/instrumentation.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/instrumentation.rb index a7d228cfd3..dfe3951bfc 100644 --- a/instrumentation/http/lib/opentelemetry/instrumentation/http/instrumentation.rb +++ b/instrumentation/http/lib/opentelemetry/instrumentation/http/instrumentation.rb @@ -10,9 +10,8 @@ module HTTP # The Instrumentation class contains logic to detect and install the Http instrumentation class Instrumentation < OpenTelemetry::Instrumentation::Base install do |_config| - patch_type = determine_semconv - send(:"require_dependencies_#{patch_type}") - send(:"patch_#{patch_type}") + require_dependencies + patch end present do @@ -21,47 +20,14 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base option :span_name_formatter, default: nil, validate: :callable - def determine_semconv - stability_opt_in = ENV.fetch('OTEL_SEMCONV_STABILITY_OPT_IN', '') - values = stability_opt_in.split(',').map(&:strip) - - if values.include?('http/dup') - 'dup' - elsif values.include?('http') - 'stable' - else - 'old' - end - end - - def patch_old - ::HTTP::Client.prepend(Patches::Old::Client) - ::HTTP::Connection.prepend(Patches::Old::Connection) - end - - def patch_dup - ::HTTP::Client.prepend(Patches::Dup::Client) - ::HTTP::Connection.prepend(Patches::Dup::Connection) - end - - def patch_stable - ::HTTP::Client.prepend(Patches::Stable::Client) - ::HTTP::Connection.prepend(Patches::Stable::Connection) - end - - def require_dependencies_dup - require_relative 'patches/dup/client' - require_relative 'patches/dup/connection' - end - - def require_dependencies_old - require_relative 'patches/old/client' - require_relative 'patches/old/connection' + def patch + ::HTTP::Client.prepend(Patches::Client) + ::HTTP::Connection.prepend(Patches::Connection) end - def require_dependencies_stable - require_relative 'patches/stable/client' - require_relative 'patches/stable/connection' + def require_dependencies + require_relative 'patches/client' + require_relative 'patches/connection' end end end diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/client.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/client.rb new file mode 100644 index 0000000000..1d98cb5c11 --- /dev/null +++ b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/client.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module HTTP + module Patches + # Module to prepend to HTTP::Client for instrumentation + module Client + # Constant for the HTTP status range + HTTP_STATUS_SUCCESS_RANGE = (100..399) + + def perform(req, options) + uri = req.uri + request_method = req.verb.to_s.upcase + span_name = create_request_span_name(request_method, uri.path) + + attributes = { + 'http.method' => request_method, + 'http.scheme' => uri.scheme, + 'http.target' => uri.path, + 'http.url' => "#{uri.scheme}://#{uri.host}", + 'net.peer.name' => uri.host, + 'net.peer.port' => uri.port + }.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) + + tracer.in_span(span_name, attributes: attributes, kind: :client) do |span| + OpenTelemetry.propagation.inject(req.headers) + super.tap do |response| + annotate_span_with_response!(span, response) + end + end + end + + private + + def config + OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance.config + end + + def annotate_span_with_response!(span, response) + return unless response&.status + + status_code = response.status.to_i + span.set_attribute('http.status_code', status_code) + span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status_code) + end + + def create_request_span_name(request_method, request_path) + if (implementation = config[:span_name_formatter]) + updated_span_name = implementation.call(request_method, request_path) + updated_span_name.is_a?(String) ? updated_span_name : "HTTP #{request_method}" + else + "HTTP #{request_method}" + end + rescue StandardError + "HTTP #{request_method}" + end + + def tracer + HTTP::Instrumentation.instance.tracer + end + end + end + end + end +end diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/connection.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/connection.rb new file mode 100644 index 0000000000..6e162886fa --- /dev/null +++ b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/connection.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module HTTP + module Patches + # Module to prepend to HTTP::Connection for instrumentation + module Connection + def initialize(req, options) + attributes = { + 'net.peer.name' => req.uri.host, + 'net.peer.port' => req.uri.port + }.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) + + tracer.in_span('HTTP CONNECT', attributes: attributes) do + super + end + end + + private + + def tracer + HTTP::Instrumentation.instance.tracer + end + end + end + end + end +end diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/dup/client.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/dup/client.rb deleted file mode 100644 index c32717525f..0000000000 --- a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/dup/client.rb +++ /dev/null @@ -1,84 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Instrumentation - module HTTP - module Patches - # Module using old and stable HTTP semantic conventions - module Dup - # Module to prepend to HTTP::Client for instrumentation - module Client - # Constant for the HTTP status range - HTTP_STATUS_SUCCESS_RANGE = (100..399) - - def perform(req, options) - uri = req.uri - request_method = req.verb.to_s.upcase - span_name = create_request_span_name(request_method, uri.path) - - attributes = { - # old semconv - 'http.method' => request_method, - 'http.scheme' => uri.scheme, - 'http.target' => uri.path, - 'http.url' => "#{uri.scheme}://#{uri.host}", - 'net.peer.name' => uri.host, - 'net.peer.port' => uri.port, - # stable semconv - 'http.request.method' => request_method, - 'url.scheme' => uri.scheme, - 'url.path' => uri.path, - 'url.full' => "#{uri.scheme}://#{uri.host}", - 'server.address' => uri.host, - 'server.port' => uri.port - } - attributes['url.query'] = uri.query unless uri.query.nil? - attributes.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) - - tracer.in_span(span_name, attributes: attributes, kind: :client) do |span| - OpenTelemetry.propagation.inject(req.headers) - super.tap do |response| - annotate_span_with_response!(span, response) - end - end - end - - private - - def config - OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance.config - end - - def annotate_span_with_response!(span, response) - return unless response&.status - - status_code = response.status.to_i - span.set_attribute('http.status_code', status_code) # old semconv - span.set_attribute('http.response.status_code', status_code) # stable semconv - span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status_code) - end - - def create_request_span_name(request_method, request_path) - if (implementation = config[:span_name_formatter]) - updated_span_name = implementation.call(request_method, request_path) - updated_span_name.is_a?(String) ? updated_span_name : request_method.to_s - else - request_method.to_s - end - rescue StandardError - request_method.to_s - end - - def tracer - HTTP::Instrumentation.instance.tracer - end - end - end - end - end - end -end diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/dup/connection.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/dup/connection.rb deleted file mode 100644 index 9a7c3f76fe..0000000000 --- a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/dup/connection.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 HTTP - module Patches - # Module using old and stable HTTP semantic conventions - module Dup - # Module to prepend to HTTP::Connection for instrumentation - module Connection - def initialize(req, options) - attributes = { - # old semconv - 'net.peer.name' => req.uri.host, - 'net.peer.port' => req.uri.port, - # stable semconv - 'server.address' => req.uri.host, - 'server.port' => req.uri.port - }.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) - - tracer.in_span('CONNECT', attributes: attributes) do - super - end - end - - private - - def tracer - HTTP::Instrumentation.instance.tracer - end - end - end - end - end - end -end diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/old/client.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/old/client.rb deleted file mode 100644 index 356a7caee9..0000000000 --- a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/old/client.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Instrumentation - module HTTP - module Patches - # Module using old HTTP semantic conventions - module Old - # Module to prepend to HTTP::Client for instrumentation - module Client - # Constant for the HTTP status range - HTTP_STATUS_SUCCESS_RANGE = (100..399) - - def perform(req, options) - uri = req.uri - request_method = req.verb.to_s.upcase - span_name = create_request_span_name(request_method, uri.path) - - attributes = { - 'http.method' => request_method, - 'http.scheme' => uri.scheme, - 'http.target' => uri.path, - 'http.url' => "#{uri.scheme}://#{uri.host}", - 'net.peer.name' => uri.host, - 'net.peer.port' => uri.port - }.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) - - tracer.in_span(span_name, attributes: attributes, kind: :client) do |span| - OpenTelemetry.propagation.inject(req.headers) - super.tap do |response| - annotate_span_with_response!(span, response) - end - end - end - - private - - def config - OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance.config - end - - def annotate_span_with_response!(span, response) - return unless response&.status - - status_code = response.status.to_i - span.set_attribute('http.status_code', status_code) - span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status_code) - end - - def create_request_span_name(request_method, request_path) - if (implementation = config[:span_name_formatter]) - updated_span_name = implementation.call(request_method, request_path) - updated_span_name.is_a?(String) ? updated_span_name : "HTTP #{request_method}" - else - "HTTP #{request_method}" - end - rescue StandardError - "HTTP #{request_method}" - end - - def tracer - HTTP::Instrumentation.instance.tracer - end - end - end - end - end - end -end diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/old/connection.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/old/connection.rb deleted file mode 100644 index b4f3b09bff..0000000000 --- a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/old/connection.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Instrumentation - module HTTP - module Patches - # Module using old HTTP semantic conventions - module Old - # Module to prepend to HTTP::Connection for instrumentation - module Connection - def initialize(req, options) - attributes = { - 'net.peer.name' => req.uri.host, - 'net.peer.port' => req.uri.port - }.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) - - tracer.in_span('HTTP CONNECT', attributes: attributes) do - super - end - end - - private - - def tracer - HTTP::Instrumentation.instance.tracer - end - end - end - end - end - end -end diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/stable/client.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/stable/client.rb deleted file mode 100644 index 51706faa2d..0000000000 --- a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/stable/client.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Instrumentation - module HTTP - module Patches - # Module using stable HTTP semantic conventions - module Stable - # Module to prepend to HTTP::Client for instrumentation - module Client - # Constant for the HTTP status range - HTTP_STATUS_SUCCESS_RANGE = (100..399) - - def perform(req, options) - uri = req.uri - request_method = req.verb.to_s.upcase - span_name = create_request_span_name(request_method, uri.path) - - attributes = { - 'http.request.method' => request_method, - 'url.scheme' => uri.scheme, - 'url.path' => uri.path, - 'url.full' => "#{uri.scheme}://#{uri.host}", - 'server.address' => uri.host, - 'server.port' => uri.port - } - attributes['url.query'] = uri.query unless uri.query.nil? - attributes.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) - - tracer.in_span(span_name, attributes: attributes, kind: :client) do |span| - OpenTelemetry.propagation.inject(req.headers) - super.tap do |response| - annotate_span_with_response!(span, response) - end - end - end - - private - - def config - OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance.config - end - - def annotate_span_with_response!(span, response) - return unless response&.status - - status_code = response.status.to_i - span.set_attribute('http.response.status_code', status_code) - span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status_code) - end - - def create_request_span_name(request_method, request_path) - if (implementation = config[:span_name_formatter]) - updated_span_name = implementation.call(request_method, request_path) - updated_span_name.is_a?(String) ? updated_span_name : request_method.to_s - else - request_method.to_s - end - rescue StandardError - request_method.to_s - end - - def tracer - HTTP::Instrumentation.instance.tracer - end - end - end - end - end - end -end diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/stable/connection.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/stable/connection.rb deleted file mode 100644 index 25bc0a8e36..0000000000 --- a/instrumentation/http/lib/opentelemetry/instrumentation/http/patches/stable/connection.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Instrumentation - module HTTP - module Patches - # Module using stable HTTP semantic conventions - module Stable - # Module to prepend to HTTP::Connection for instrumentation - module Connection - def initialize(req, options) - attributes = { - 'server.address' => req.uri.host, - 'server.port' => req.uri.port - }.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) - - tracer.in_span('CONNECT', attributes: attributes) do - super - end - end - - private - - def tracer - HTTP::Instrumentation.instance.tracer - end - end - end - end - end - end -end diff --git a/instrumentation/http/lib/opentelemetry/instrumentation/http/version.rb b/instrumentation/http/lib/opentelemetry/instrumentation/http/version.rb index 3d42bcb27e..7fb6283f32 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.25.1' + VERSION = '0.24.0' end end end diff --git a/instrumentation/http/test/instrumentation/http/instrumentation_test.rb b/instrumentation/http/test/instrumentation/http/instrumentation_test.rb index 3bc4ca26cc..302ac483d4 100644 --- a/instrumentation/http/test/instrumentation/http/instrumentation_test.rb +++ b/instrumentation/http/test/instrumentation/http/instrumentation_test.rb @@ -9,8 +9,6 @@ require_relative '../../../lib/opentelemetry/instrumentation/http' describe OpenTelemetry::Instrumentation::HTTP do - before { skip unless ENV['BUNDLE_GEMFILE'].include?('old') } - let(:instrumentation) { OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance } it 'has #name' do @@ -38,30 +36,4 @@ _(instrumentation.install({})).must_equal(true) end end - - describe 'determine_semconv' do - it 'returns "dup" when OTEL_SEMCONV_STABILITY_OPT_IN includes other configs' do - OpenTelemetry::TestHelpers.with_env('OTEL_SEMCONV_STABILITY_OPT_IN' => 'http/dup, database') do - _(instrumentation.determine_semconv).must_equal('dup') - end - end - - it 'returns "dup" when OTEL_SEMCONV_STABILITY_OPT_IN includes both http/dup and http' do - OpenTelemetry::TestHelpers.with_env('OTEL_SEMCONV_STABILITY_OPT_IN' => 'http/dup, http') do - _(instrumentation.determine_semconv).must_equal('dup') - end - end - - it 'returns "stable" when OTEL_SEMCONV_STABILITY_OPT_IN is http' do - OpenTelemetry::TestHelpers.with_env('OTEL_SEMCONV_STABILITY_OPT_IN' => 'http') do - _(instrumentation.determine_semconv).must_equal('stable') - end - end - - it 'returns "old" when OTEL_SEMCONV_STABILITY_OPT_IN is empty' do - OpenTelemetry::TestHelpers.with_env('OTEL_SEMCONV_STABILITY_OPT_IN' => '') do - _(instrumentation.determine_semconv).must_equal('old') - end - end - end end diff --git a/instrumentation/http/test/instrumentation/http/patches/old/client_test.rb b/instrumentation/http/test/instrumentation/http/patches/client_test.rb similarity index 95% rename from instrumentation/http/test/instrumentation/http/patches/old/client_test.rb rename to instrumentation/http/test/instrumentation/http/patches/client_test.rb index 6579dc8b5d..8d62a5b07c 100644 --- a/instrumentation/http/test/instrumentation/http/patches/old/client_test.rb +++ b/instrumentation/http/test/instrumentation/http/patches/client_test.rb @@ -6,10 +6,10 @@ require 'test_helper' -require_relative '../../../../../lib/opentelemetry/instrumentation/http' -require_relative '../../../../../lib/opentelemetry/instrumentation/http/patches/old/client' +require_relative '../../../../lib/opentelemetry/instrumentation/http' +require_relative '../../../../lib/opentelemetry/instrumentation/http/patches/client' -describe OpenTelemetry::Instrumentation::HTTP::Patches::Old::Client do +describe OpenTelemetry::Instrumentation::HTTP::Patches::Client do let(:instrumentation) { OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance } let(:exporter) { EXPORTER } let(:span) { exporter.finished_spans.first } @@ -21,8 +21,6 @@ let(:span_name_formatter) { nil } before do - skip unless ENV['BUNDLE_GEMFILE'].include?('old') - exporter.reset @orig_propagation = OpenTelemetry.propagation propagator = OpenTelemetry::Trace::Propagation::TraceContext.text_map_propagator diff --git a/instrumentation/http/test/instrumentation/http/patches/old/connection.rb b/instrumentation/http/test/instrumentation/http/patches/connection_test.rb similarity index 79% rename from instrumentation/http/test/instrumentation/http/patches/old/connection.rb rename to instrumentation/http/test/instrumentation/http/patches/connection_test.rb index 89ed18b02f..fc0b2b2a49 100644 --- a/instrumentation/http/test/instrumentation/http/patches/old/connection.rb +++ b/instrumentation/http/test/instrumentation/http/patches/connection_test.rb @@ -6,17 +6,15 @@ require 'test_helper' -require_relative '../../../../../lib/opentelemetry/instrumentation/http' -require_relative '../../../../../lib/opentelemetry/instrumentation/http/patches/old/connection' +require_relative '../../../../lib/opentelemetry/instrumentation/http' +require_relative '../../../../lib/opentelemetry/instrumentation/http/patches/connection' -describe OpenTelemetry::Instrumentation::HTTP::Patches::Old::Connection do +describe OpenTelemetry::Instrumentation::HTTP::Patches::Connection do let(:instrumentation) { OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance } let(:exporter) { EXPORTER } let(:span) { exporter.finished_spans.first } before do - skip unless ENV['BUNDLE_GEMFILE'].include?('old') - exporter.reset instrumentation.install({}) end diff --git a/instrumentation/http/test/instrumentation/http/patches/dup/client_test.rb b/instrumentation/http/test/instrumentation/http/patches/dup/client_test.rb deleted file mode 100644 index be0adb3a3a..0000000000 --- a/instrumentation/http/test/instrumentation/http/patches/dup/client_test.rb +++ /dev/null @@ -1,250 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'test_helper' - -require_relative '../../../../../lib/opentelemetry/instrumentation/http' -require_relative '../../../../../lib/opentelemetry/instrumentation/http/patches/dup/client' - -describe OpenTelemetry::Instrumentation::HTTP::Patches::Dup::Client do - let(:instrumentation) { OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance } - let(:exporter) { EXPORTER } - let(:span) { exporter.finished_spans.first } - let(:config) do - { - span_name_formatter: span_name_formatter - } - end - let(:span_name_formatter) { nil } - - before do - skip unless ENV['BUNDLE_GEMFILE'].include?('dup') - - ENV['OTEL_SEMCONV_STABILITY_OPT_IN'] = 'http/dup' - exporter.reset - @orig_propagation = OpenTelemetry.propagation - propagator = OpenTelemetry::Trace::Propagation::TraceContext.text_map_propagator - OpenTelemetry.propagation = propagator - # simulate a fresh install: - instrumentation.instance_variable_set(:@installed, false) - instrumentation.install(config) - stub_request(:get, 'http://example.com/success').to_return(status: 200) - stub_request(:get, 'http://example.com/success?hello=there').to_return(status: 200) - stub_request(:post, 'http://example.com/failure').to_return(status: 500) - stub_request(:get, 'https://example.com/timeout').to_timeout - end - - after do - ENV.delete('OTEL_SEMCONV_STABILITY_OPT_IN') - # Force re-install of instrumentation - instrumentation.instance_variable_set(:@installed, false) - OpenTelemetry.propagation = @orig_propagation - end - - describe '#perform' do - it 'traces a simple request' do - HTTP.get('http://example.com/success') - _(exporter.finished_spans.size).must_equal(1) - _(span.name).must_equal 'GET' - # Old semantic conventions - _(span.attributes['http.method']).must_equal 'GET' - _(span.attributes['http.scheme']).must_equal 'http' - _(span.attributes['http.status_code']).must_equal 200 - _(span.attributes['http.target']).must_equal '/success' - _(span.attributes['net.peer.name']).must_equal 'example.com' - _(span.attributes['net.peer.port']).must_equal 80 - # Stable semantic conventions - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 200 - _(span.attributes['url.path']).must_equal '/success' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_be_nil - - assert_requested( - :get, - 'http://example.com/success', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - - it 'after request with failure code' do - HTTP.post('http://example.com/failure') - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'POST' - # Old semantic conventions - _(span.attributes['http.method']).must_equal 'POST' - _(span.attributes['http.scheme']).must_equal 'http' - _(span.attributes['http.status_code']).must_equal 500 - _(span.attributes['http.target']).must_equal '/failure' - _(span.attributes['net.peer.name']).must_equal 'example.com' - _(span.attributes['net.peer.port']).must_equal 80 - # Stable semantic conventions - _(span.attributes['http.request.method']).must_equal 'POST' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 500 - _(span.attributes['url.path']).must_equal '/failure' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_be_nil - assert_requested( - :post, - 'http://example.com/failure', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - - it 'after request timeout' do - expect do - HTTP.get('https://example.com/timeout') - end.must_raise HTTP::TimeoutError - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'GET' - # Old semantic conventions - _(span.attributes['http.method']).must_equal 'GET' - _(span.attributes['http.scheme']).must_equal 'https' - _(span.attributes['http.status_code']).must_be_nil - _(span.attributes['http.target']).must_equal '/timeout' - _(span.attributes['net.peer.name']).must_equal 'example.com' - _(span.attributes['net.peer.port']).must_equal 443 - # Stable semantic conventions - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'https' - _(span.attributes['http.response.status_code']).must_be_nil - _(span.attributes['url.path']).must_equal '/timeout' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'https://example.com' - _(span.attributes['server.port']).must_equal 443 - _(span.attributes['url.query']).must_be_nil - _(span.status.code).must_equal( - OpenTelemetry::Trace::Status::ERROR - ) - _(span.status.description).must_equal( - 'Unhandled exception of type: HTTP::TimeoutError' - ) - assert_requested( - :get, - 'https://example.com/timeout', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - - it 'merges http client attributes' do - OpenTelemetry::Common::HTTP::ClientContext.with_attributes('peer.service' => 'foo') do - HTTP.get('http://example.com/success?hello=there') - end - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'GET' - # Old semantic conventions - _(span.attributes['http.method']).must_equal 'GET' - _(span.attributes['http.scheme']).must_equal 'http' - _(span.attributes['http.status_code']).must_equal 200 - _(span.attributes['http.target']).must_equal '/success' - _(span.attributes['net.peer.name']).must_equal 'example.com' - _(span.attributes['net.peer.port']).must_equal 80 - _(span.attributes['peer.service']).must_equal 'foo' - # Stable semantic conventions - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 200 - _(span.attributes['url.path']).must_equal '/success' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_equal 'hello=there' - assert_requested( - :get, - 'http://example.com/success?hello=there', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - - describe 'when span_name_formatter specified' do - let(:span_name_formatter) do - # demonstrate simple addition of path and string to span name: - lambda { |request_method, request_path| - "#{request_method} #{request_path} miniswan" - } - end - - it 'enriches the span' do - OpenTelemetry::Common::HTTP::ClientContext.with_attributes('peer.service' => 'foo') do - HTTP.get('http://example.com/success') - end - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'GET /success miniswan' - # Old semantic conventions - _(span.attributes['http.method']).must_equal 'GET' - _(span.attributes['http.scheme']).must_equal 'http' - _(span.attributes['http.status_code']).must_equal 200 - _(span.attributes['http.target']).must_equal '/success' - _(span.attributes['net.peer.name']).must_equal 'example.com' - _(span.attributes['net.peer.port']).must_equal 80 - _(span.attributes['peer.service']).must_equal 'foo' - # Stable semantic conventions - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 200 - _(span.attributes['url.path']).must_equal '/success' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_be_nil - assert_requested( - :get, - 'http://example.com/success', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - end - describe 'when span_formatter specified and it errors' do - let(:span_name_formatter) do - # demonstrate simple addition of path and string to span name: - lambda { |_request_method, _request_path| - raise 'Something Bad' - } - end - - it 'provides a sane default' do - OpenTelemetry::Common::HTTP::ClientContext.with_attributes('peer.service' => 'foo') do - HTTP.get('http://example.com/success') - end - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'GET' - # Old semantic conventions - _(span.attributes['http.method']).must_equal 'GET' - _(span.attributes['http.scheme']).must_equal 'http' - _(span.attributes['http.status_code']).must_equal 200 - _(span.attributes['http.target']).must_equal '/success' - _(span.attributes['net.peer.name']).must_equal 'example.com' - _(span.attributes['net.peer.port']).must_equal 80 - _(span.attributes['peer.service']).must_equal 'foo' - # Stable semantic conventions - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 200 - _(span.attributes['url.path']).must_equal '/success' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_be_nil - assert_requested( - :get, - 'http://example.com/success', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - end - end -end diff --git a/instrumentation/http/test/instrumentation/http/patches/dup/connection_test.rb b/instrumentation/http/test/instrumentation/http/patches/dup/connection_test.rb deleted file mode 100644 index 1fa1907a4d..0000000000 --- a/instrumentation/http/test/instrumentation/http/patches/dup/connection_test.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'test_helper' - -require_relative '../../../../../lib/opentelemetry/instrumentation/http' -require_relative '../../../../../lib/opentelemetry/instrumentation/http/patches/dup/connection' - -describe OpenTelemetry::Instrumentation::HTTP::Patches::Dup::Connection do - let(:instrumentation) { OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance } - let(:exporter) { EXPORTER } - let(:span) { exporter.finished_spans.first } - - before do - skip unless ENV['BUNDLE_GEMFILE'].include?('dup') - - ENV['OTEL_SEMCONV_STABILITY_OPT_IN'] = 'http/dup' - exporter.reset - instrumentation.install({}) - end - - # Force re-install of instrumentation - after do - ENV.delete('OTEL_SEMCONV_STABILITY_OPT_IN') - instrumentation.instance_variable_set(:@installed, false) - end - - describe '#connect' do - it 'emits span on connect' do - WebMock.allow_net_connect! - TCPServer.open('localhost', 0) do |server| - Thread.start { server.accept } - port = server.addr[1] - - assert_raises(HTTP::TimeoutError) do - HTTP.timeout(connect: 0.1, write: 0.1, read: 0.1).get("http://localhost:#{port}/example") - end - end - - _(exporter.finished_spans.size).must_equal(2) - _(span.name).must_equal 'CONNECT' - # Old semantic conventions - _(span.attributes['net.peer.name']).must_equal('localhost') - _(span.attributes['net.peer.port']).wont_be_nil - # Stable semantic conventions - _(span.attributes['server.address']).must_equal('localhost') - _(span.attributes['server.port']).wont_be_nil - ensure - WebMock.disable_net_connect! - end - end -end diff --git a/instrumentation/http/test/instrumentation/http/patches/stable/client_test.rb b/instrumentation/http/test/instrumentation/http/patches/stable/client_test.rb deleted file mode 100644 index ef0fad1211..0000000000 --- a/instrumentation/http/test/instrumentation/http/patches/stable/client_test.rb +++ /dev/null @@ -1,199 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'test_helper' - -require_relative '../../../../../lib/opentelemetry/instrumentation/http' -require_relative '../../../../../lib/opentelemetry/instrumentation/http/patches/stable/client' - -describe OpenTelemetry::Instrumentation::HTTP::Patches::Stable::Client do - let(:instrumentation) { OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance } - let(:exporter) { EXPORTER } - let(:span) { exporter.finished_spans.first } - let(:config) do - { - span_name_formatter: span_name_formatter - } - end - let(:span_name_formatter) { nil } - - before do - skip unless ENV['BUNDLE_GEMFILE'].include?('stable') - - ENV['OTEL_SEMCONV_STABILITY_OPT_IN'] = 'http' - exporter.reset - @orig_propagation = OpenTelemetry.propagation - propagator = OpenTelemetry::Trace::Propagation::TraceContext.text_map_propagator - OpenTelemetry.propagation = propagator - # simulate a fresh install: - instrumentation.instance_variable_set(:@installed, false) - instrumentation.install(config) - stub_request(:get, 'http://example.com/success').to_return(status: 200) - stub_request(:get, 'http://example.com/success?hello=there').to_return(status: 200) - stub_request(:post, 'http://example.com/failure').to_return(status: 500) - stub_request(:get, 'https://example.com/timeout').to_timeout - end - - after do - ENV.delete('OTEL_SEMCONV_STABILITY_OPT_IN') - # Force re-install of instrumentation - instrumentation.instance_variable_set(:@installed, false) - - OpenTelemetry.propagation = @orig_propagation - end - - describe '#perform' do - it 'traces a simple request' do - HTTP.get('http://example.com/success') - _(exporter.finished_spans.size).must_equal(1) - _(span.name).must_equal 'GET' - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 200 - _(span.attributes['url.path']).must_equal '/success' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_be_nil - assert_requested( - :get, - 'http://example.com/success', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - - it 'after request with failure code' do - HTTP.post('http://example.com/failure') - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'POST' - _(span.attributes['http.request.method']).must_equal 'POST' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 500 - _(span.attributes['url.path']).must_equal '/failure' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_be_nil - assert_requested( - :post, - 'http://example.com/failure', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - - it 'after request timeout' do - expect do - HTTP.get('https://example.com/timeout') - end.must_raise HTTP::TimeoutError - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'GET' - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'https' - _(span.attributes['http.response.status_code']).must_be_nil - _(span.attributes['url.path']).must_equal '/timeout' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'https://example.com' - _(span.attributes['server.port']).must_equal 443 - _(span.attributes['url.query']).must_be_nil - _(span.status.code).must_equal( - OpenTelemetry::Trace::Status::ERROR - ) - _(span.status.description).must_equal( - 'Unhandled exception of type: HTTP::TimeoutError' - ) - assert_requested( - :get, - 'https://example.com/timeout', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - - it 'merges http client attributes' do - OpenTelemetry::Common::HTTP::ClientContext.with_attributes('peer.service' => 'foo') do - HTTP.get('http://example.com/success?hello=there') - end - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'GET' - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 200 - _(span.attributes['url.path']).must_equal '/success' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_equal 'hello=there' - assert_requested( - :get, - 'http://example.com/success?hello=there', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - - describe 'when span_name_formatter specified' do - let(:span_name_formatter) do - # demonstrate simple addition of path and string to span name: - lambda { |request_method, request_path| - "#{request_method} #{request_path} miniswan" - } - end - - it 'enriches the span' do - OpenTelemetry::Common::HTTP::ClientContext.with_attributes('peer.service' => 'foo') do - HTTP.get('http://example.com/success') - end - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'GET /success miniswan' - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 200 - _(span.attributes['url.path']).must_equal '/success' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_be_nil - assert_requested( - :get, - 'http://example.com/success', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - end - describe 'when span_formatter specified and it errors' do - let(:span_name_formatter) do - # demonstrate simple addition of path and string to span name: - lambda { |_request_method, _request_path| - raise 'Something Bad' - } - end - - it 'provides a sane default' do - OpenTelemetry::Common::HTTP::ClientContext.with_attributes('peer.service' => 'foo') do - HTTP.get('http://example.com/success') - end - - _(exporter.finished_spans.size).must_equal 1 - _(span.name).must_equal 'GET' - _(span.attributes['http.request.method']).must_equal 'GET' - _(span.attributes['url.scheme']).must_equal 'http' - _(span.attributes['http.response.status_code']).must_equal 200 - _(span.attributes['url.path']).must_equal '/success' - _(span.attributes['server.address']).must_equal 'example.com' - _(span.attributes['url.full']).must_equal 'http://example.com' - _(span.attributes['server.port']).must_equal 80 - _(span.attributes['url.query']).must_be_nil - assert_requested( - :get, - 'http://example.com/success', - headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } - ) - end - end - end -end diff --git a/instrumentation/http/test/instrumentation/http/patches/stable/connection.rb b/instrumentation/http/test/instrumentation/http/patches/stable/connection.rb deleted file mode 100644 index fb69a9c157..0000000000 --- a/instrumentation/http/test/instrumentation/http/patches/stable/connection.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'test_helper' - -require_relative '../../../../../lib/opentelemetry/instrumentation/http' -require_relative '../../../../../lib/opentelemetry/instrumentation/http/patches/stable/connection' - -describe OpenTelemetry::Instrumentation::HTTP::Patches::Stable::Connection do - let(:instrumentation) { OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance } - let(:exporter) { EXPORTER } - let(:span) { exporter.finished_spans.first } - - before do - skip unless ENV['BUNDLE_GEMFILE'].include?('stable') - - ENV['OTEL_SEMCONV_STABILITY_OPT_IN'] = 'http' - exporter.reset - instrumentation.install({}) - end - - # Force re-install of instrumentation - after do - ENV.delete('OTEL_SEMCONV_STABILITY_OPT_IN') - instrumentation.instance_variable_set(:@installed, false) - end - - describe '#connect' do - it 'emits span on connect' do - WebMock.allow_net_connect! - TCPServer.open('localhost', 0) do |server| - Thread.start { server.accept } - port = server.addr[1] - - assert_raises(HTTP::TimeoutError) do - HTTP.timeout(connect: 0.1, write: 0.1, read: 0.1).get("http://localhost:#{port}/example") - end - end - - _(exporter.finished_spans.size).must_equal(2) - _(span.name).must_equal 'CONNECT' - _(span.attributes['server.address']).must_equal('localhost') - _(span.attributes['server.port']).wont_be_nil - ensure - WebMock.disable_net_connect! - end - end -end diff --git a/instrumentation/http_client/Gemfile b/instrumentation/http_client/Gemfile index 35abd9d688..a2eceb969b 100644 --- a/instrumentation/http_client/Gemfile +++ b/instrumentation/http_client/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/http_client/README.md b/instrumentation/http_client/README.md index 126ee790b1..3f5719d971 100644 --- a/instrumentation/http_client/README.md +++ b/instrumentation/http_client/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/http_client/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/http_client/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/httpx/Gemfile b/instrumentation/httpx/Gemfile index 60447ac0ab..a07a1265b1 100644 --- a/instrumentation/httpx/Gemfile +++ b/instrumentation/httpx/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/koala/Gemfile b/instrumentation/koala/Gemfile index 60447ac0ab..a07a1265b1 100644 --- a/instrumentation/koala/Gemfile +++ b/instrumentation/koala/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/koala/README.md b/instrumentation/koala/README.md index ceecc2bee5..b304d01b54 100644 --- a/instrumentation/koala/README.md +++ b/instrumentation/koala/README.md @@ -33,7 +33,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/koala/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/koala/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/lmdb/Gemfile b/instrumentation/lmdb/Gemfile index 35abd9d688..a2eceb969b 100644 --- a/instrumentation/lmdb/Gemfile +++ b/instrumentation/lmdb/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/mongo/Appraisals b/instrumentation/mongo/Appraisals index 1f2b50d354..63b14c31eb 100644 --- a/instrumentation/mongo/Appraisals +++ b/instrumentation/mongo/Appraisals @@ -4,9 +4,6 @@ # # SPDX-License-Identifier: Apache-2.0 -appraise 'mongo-2' do - gem 'mongo', '~> 2.13' - - # TODO: bson 5.1.0 isn't compatible with JRuby as of 2025/06/17 - gem 'bson', '< 5.1.0' if defined?(JRUBY_VERSION) +appraise 'mongo-2.13' do + gem 'mongo', '~> 2.13.0' end diff --git a/instrumentation/mongo/Gemfile b/instrumentation/mongo/Gemfile index 1ed03c3be7..0378df5f77 100644 --- a/instrumentation/mongo/Gemfile +++ b/instrumentation/mongo/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/mongo/test/opentelemetry/instrumentation/mongo/subscriber_test.rb b/instrumentation/mongo/test/opentelemetry/instrumentation/mongo/subscriber_test.rb index fe6ff241db..4a0a7af0e6 100644 --- a/instrumentation/mongo/test/opentelemetry/instrumentation/mongo/subscriber_test.rb +++ b/instrumentation/mongo/test/opentelemetry/instrumentation/mongo/subscriber_test.rb @@ -380,7 +380,7 @@ module MongoTraceTest _(span.events[0].name).must_equal 'exception' _(span.events[0].timestamp).must_be_kind_of Integer _(span.events[0].attributes['exception.type']).must_equal 'CommandFailed' - _(span.events[0].attributes['exception.message']).must_equal '[26:NamespaceNotFound]: ns not found' + _(span.events[0].attributes['exception.message']).must_equal 'ns not found (26)' end describe 'that triggers #failed before #started' do @@ -402,8 +402,7 @@ module MongoTraceTest database: TestHelper.database, auth_mech: :plain, user: 'plain_user', - password: 'plain_pass', - auth_source: '$external' + password: 'plain_pass' } end diff --git a/instrumentation/mysql2/Gemfile b/instrumentation/mysql2/Gemfile index 93fb6fe9d9..c9fadb8134 100644 --- a/instrumentation/mysql2/Gemfile +++ b/instrumentation/mysql2/Gemfile @@ -18,7 +18,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/net_http/Gemfile b/instrumentation/net_http/Gemfile index a2a8674575..31b475bb19 100644 --- a/instrumentation/net_http/Gemfile +++ b/instrumentation/net_http/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0.1' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/pg/Gemfile b/instrumentation/pg/Gemfile index 9cd578b547..912305ffee 100644 --- a/instrumentation/pg/Gemfile +++ b/instrumentation/pg/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/que/Gemfile b/instrumentation/que/Gemfile index faa7562f6c..2c835fa4c6 100644 --- a/instrumentation/que/Gemfile +++ b/instrumentation/que/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/racecar/Gemfile b/instrumentation/racecar/Gemfile index 3e17908bf9..57d90e370f 100644 --- a/instrumentation/racecar/Gemfile +++ b/instrumentation/racecar/Gemfile @@ -23,7 +23,7 @@ group :test do gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' gem 'rspec-mocks' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/racecar/README.md b/instrumentation/racecar/README.md index 6f2b11ef26..a7f93d5f1c 100644 --- a/instrumentation/racecar/README.md +++ b/instrumentation/racecar/README.md @@ -36,7 +36,7 @@ end ## Examples -Example usage can be seen in the [`./example` directory](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/racecar/example). Run `./trace_demonstration.sh` to see its behaviour. +Example usage can be seen in the `./example` directory [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/racecar/example). Run `./trace_demonstration.sh` to see its behaviour. ## How can I get involved? diff --git a/instrumentation/rack/Gemfile b/instrumentation/rack/Gemfile index 2d7875a45f..c6751136e2 100644 --- a/instrumentation/rack/Gemfile +++ b/instrumentation/rack/Gemfile @@ -16,7 +16,7 @@ group :test do gem 'opentelemetry-sdk-experimental', '~> 0.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/rack/README.md b/instrumentation/rack/README.md index 6373900448..79c935c08f 100644 --- a/instrumentation/rack/README.md +++ b/instrumentation/rack/README.md @@ -81,7 +81,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/rack/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/rack/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/rails/Gemfile b/instrumentation/rails/Gemfile index 59101eee6e..ef771300ff 100644 --- a/instrumentation/rails/Gemfile +++ b/instrumentation/rails/Gemfile @@ -16,7 +16,7 @@ group :test do gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rack-test', '~> 2.1.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/rails/README.md b/instrumentation/rails/README.md index 5f51e354c6..efb048ca8b 100644 --- a/instrumentation/rails/README.md +++ b/instrumentation/rails/README.md @@ -64,7 +64,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/rails/example/trace_request_demonstration.ru) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/rails/example/trace_request_demonstration.ru) ## How can I get involved? diff --git a/instrumentation/rake/CHANGELOG.md b/instrumentation/rake/CHANGELOG.md index b2b26f886f..304d8b840a 100644 --- a/instrumentation/rake/CHANGELOG.md +++ b/instrumentation/rake/CHANGELOG.md @@ -1,9 +1,5 @@ # Release History: opentelemetry-instrumentation-rake -### v0.3.1 / 2025-06-03 - -* FIXED: Handle force_flush for rake task with arguments - ### v0.3.0 / 2025-01-16 * BREAKING CHANGE: Set minimum supported version to Ruby 3.1 diff --git a/instrumentation/rake/Gemfile b/instrumentation/rake/Gemfile index 286f809466..b7ae0066e5 100644 --- a/instrumentation/rake/Gemfile +++ b/instrumentation/rake/Gemfile @@ -18,7 +18,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.0' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/rake/README.md b/instrumentation/rake/README.md index b119f2730b..bcdccaa030 100644 --- a/instrumentation/rake/README.md +++ b/instrumentation/rake/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/opentelemetry-instrumentation-rake/v0.2.2/instrumentation/rake/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/opentelemetry-instrumentation-rake/v0.2.2/instrumentation/rake/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/rake/lib/opentelemetry/instrumentation/rake/patches/task.rb b/instrumentation/rake/lib/opentelemetry/instrumentation/rake/patches/task.rb index b012dd4d4f..afddecb0fe 100644 --- a/instrumentation/rake/lib/opentelemetry/instrumentation/rake/patches/task.rb +++ b/instrumentation/rake/lib/opentelemetry/instrumentation/rake/patches/task.rb @@ -29,11 +29,7 @@ def tracer end def force_flush - top_level_task_names = ::Rake.application.top_level_tasks.map { |t| t.split('[').first } - - if top_level_task_names.include?(name) - OpenTelemetry.tracer_provider.force_flush - end + OpenTelemetry.tracer_provider.force_flush if ::Rake.application.top_level_tasks.include?(name) end end end diff --git a/instrumentation/rake/lib/opentelemetry/instrumentation/rake/version.rb b/instrumentation/rake/lib/opentelemetry/instrumentation/rake/version.rb index 756487f005..2db11acc9f 100644 --- a/instrumentation/rake/lib/opentelemetry/instrumentation/rake/version.rb +++ b/instrumentation/rake/lib/opentelemetry/instrumentation/rake/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module Rake - VERSION = '0.3.1' + VERSION = '0.3.0' end end end diff --git a/instrumentation/rake/test/opentelemetry/instrumentation/rake/patches/task_test.rb b/instrumentation/rake/test/opentelemetry/instrumentation/rake/patches/task_test.rb index f067c419af..f40f9d511b 100644 --- a/instrumentation/rake/test/opentelemetry/instrumentation/rake/patches/task_test.rb +++ b/instrumentation/rake/test/opentelemetry/instrumentation/rake/patches/task_test.rb @@ -56,25 +56,6 @@ _(execute_span.parent_span_id).must_equal(invoke_span.span_id) end - describe 'with a task argument' do - it 'should call force_flush on OpenTelemetry.tracer_provider' do - mock = Minitest::Mock.new - mock.expect(:force_flush, nil) - mock.expect(:force_flush, nil) - - Rake::Task.define_task("#{task_name}[:arg]") - task_string = "#{task_name}[test_arg]" - - Rake.application.instance_eval { @top_level_tasks = [task_string] } - - OpenTelemetry.stub(:tracer_provider, mock) do - Rake.application.invoke_task(task_string) - end - - mock.verify - end - end - describe 'with a prerequisite task' do before do Rake::Task.define_task(prerequisite_task_name) diff --git a/instrumentation/rdkafka/CHANGELOG.md b/instrumentation/rdkafka/CHANGELOG.md index 2ff6262887..62e61ad0ab 100644 --- a/instrumentation/rdkafka/CHANGELOG.md +++ b/instrumentation/rdkafka/CHANGELOG.md @@ -1,9 +1,5 @@ # Release History: opentelemetry-instrumentation-rdkafka -### v0.7.0 / 2025-05-06 - -* ADDED: Update minimum gem version requirement for rdkafka to 0.18.0 - ### v0.6.0 / 2025-02-11 * ADDED: Rdkafka support to v0.19 including diff --git a/instrumentation/rdkafka/Gemfile b/instrumentation/rdkafka/Gemfile index 496c887e72..e152bbd50f 100644 --- a/instrumentation/rdkafka/Gemfile +++ b/instrumentation/rdkafka/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/rdkafka/README.md b/instrumentation/rdkafka/README.md index 8cf9e7384e..21c57c3d71 100644 --- a/instrumentation/rdkafka/README.md +++ b/instrumentation/rdkafka/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage can be seen in the [`./example/rdkafka_trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/rdkafka/example/rdkafka_trace_demonstration.rb) +Example usage can be seen in the `./example/rdkafka_trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/rdkafka/example/rdkafka_trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/version.rb b/instrumentation/rdkafka/lib/opentelemetry/instrumentation/rdkafka/version.rb index 59be3b3bd0..27afb41ef4 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.7.0' + VERSION = '0.6.0' end end end diff --git a/instrumentation/redis/Gemfile b/instrumentation/redis/Gemfile index 8933592e8d..8f27a80732 100644 --- a/instrumentation/redis/Gemfile +++ b/instrumentation/redis/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/resque/Gemfile b/instrumentation/resque/Gemfile index d34d609ceb..0a1b56028d 100644 --- a/instrumentation/resque/Gemfile +++ b/instrumentation/resque/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/resque/README.md b/instrumentation/resque/README.md index 7aa498b45c..fc46ca1add 100644 --- a/instrumentation/resque/README.md +++ b/instrumentation/resque/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/resque/example/trace_demonstration.rb) +Example usage can be seen in the `./example/trace_demonstration.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/resque/example/trace_demonstration.rb) ## How can I get involved? diff --git a/instrumentation/restclient/Gemfile b/instrumentation/restclient/Gemfile index 9484691699..33388452b1 100644 --- a/instrumentation/restclient/Gemfile +++ b/instrumentation/restclient/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/rspec/Gemfile b/instrumentation/rspec/Gemfile index 2539442e57..be2d93adde 100644 --- a/instrumentation/rspec/Gemfile +++ b/instrumentation/rspec/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/rspec/README.md b/instrumentation/rspec/README.md index c9814cd8d6..c14f7674fa 100644 --- a/instrumentation/rspec/README.md +++ b/instrumentation/rspec/README.md @@ -55,7 +55,7 @@ To avoid spans from being dropped, which will mean you lose insight into your sp ## Examples -Example usage can be seen in the [`/example` directory](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/rspec/example) +Example usage can be seen in the `/example` directory [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/rspec/example) ## How can I get involved? diff --git a/instrumentation/ruby_kafka/Gemfile b/instrumentation/ruby_kafka/Gemfile index 6dbb02d0c7..07ac19d13b 100644 --- a/instrumentation/ruby_kafka/Gemfile +++ b/instrumentation/ruby_kafka/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/ruby_kafka/README.md b/instrumentation/ruby_kafka/README.md index 4ec4656816..65c38b8ea7 100644 --- a/instrumentation/ruby_kafka/README.md +++ b/instrumentation/ruby_kafka/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage can be seen in the [`./example/ruby_kafka.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/ruby_kafka/example/ruby_kafka.rb) +Example usage can be seen in the `./example/ruby_kafka.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/ruby_kafka/example/ruby_kafka.rb) ## How can I get involved? diff --git a/instrumentation/ruby_kafka/docker-compose.yml b/instrumentation/ruby_kafka/docker-compose.yml index 0c27ebfe54..5be91ad8fd 100644 --- a/instrumentation/ruby_kafka/docker-compose.yml +++ b/instrumentation/ruby_kafka/docker-compose.yml @@ -10,7 +10,7 @@ services: ZOOKEEPER_TICK_TIME: 2000 kafka: - image: confluentinc/cp-kafka:7.9.1 + image: confluentinc/cp-kafka:latest ports: - "9092:9092" - "29092:29092" diff --git a/instrumentation/ruby_kafka/example/docker-compose.yml b/instrumentation/ruby_kafka/example/docker-compose.yml index 1d3e5bd19c..db2397b923 100644 --- a/instrumentation/ruby_kafka/example/docker-compose.yml +++ b/instrumentation/ruby_kafka/example/docker-compose.yml @@ -15,7 +15,7 @@ services: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 kafka: - image: confluentinc/cp-kafka:7.9.1 + image: confluentinc/cp-kafka:latest ports: - "9092:9092" - "29092:29092" diff --git a/instrumentation/sidekiq/Gemfile b/instrumentation/sidekiq/Gemfile index 99f0a8f43e..db0968f4c8 100644 --- a/instrumentation/sidekiq/Gemfile +++ b/instrumentation/sidekiq/Gemfile @@ -14,7 +14,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/instrumentation/sidekiq/README.md b/instrumentation/sidekiq/README.md index 985cd25be5..5e435acfce 100644 --- a/instrumentation/sidekiq/README.md +++ b/instrumentation/sidekiq/README.md @@ -32,7 +32,7 @@ end ## Examples -Example usage can be seen in the [`./example/sidekiq.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/sidekiq/example/sidekiq.rb) +Example usage can be seen in the `./example/sidekiq.rb` file [here](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/sidekiq/example/sidekiq.rb) ## Development diff --git a/instrumentation/sinatra/Gemfile b/instrumentation/sinatra/Gemfile index e34da4052b..5c2bbcf78b 100644 --- a/instrumentation/sinatra/Gemfile +++ b/instrumentation/sinatra/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rack-test', '~> 2.1' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/instrumentation/trilogy/Gemfile b/instrumentation/trilogy/Gemfile index 1b269dddd6..852411dbbb 100644 --- a/instrumentation/trilogy/Gemfile +++ b/instrumentation/trilogy/Gemfile @@ -15,7 +15,7 @@ group :test do gem 'opentelemetry-sdk', '~> 1.1' gem 'opentelemetry-test-helpers', '~> 0.3' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/processor/baggage/Gemfile b/processor/baggage/Gemfile index 62d3167c48..d0f1fbee53 100644 --- a/processor/baggage/Gemfile +++ b/processor/baggage/Gemfile @@ -10,7 +10,7 @@ group :test do gem 'minitest', '~> 5.0' gem 'opentelemetry-sdk', '~> 1.1' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/propagator/google_cloud_trace_context/Gemfile b/propagator/google_cloud_trace_context/Gemfile index dcb12336fd..32cf4f817d 100644 --- a/propagator/google_cloud_trace_context/Gemfile +++ b/propagator/google_cloud_trace_context/Gemfile @@ -8,7 +8,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/propagator/ottrace/Gemfile b/propagator/ottrace/Gemfile index bf02a254dc..9708a23451 100644 --- a/propagator/ottrace/Gemfile +++ b/propagator/ottrace/Gemfile @@ -9,7 +9,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/propagator/vitess/Gemfile b/propagator/vitess/Gemfile index 4dc6e68538..e7c1bde87c 100644 --- a/propagator/vitess/Gemfile +++ b/propagator/vitess/Gemfile @@ -9,7 +9,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/propagator/xray/CHANGELOG.md b/propagator/xray/CHANGELOG.md index 0a2fd9bccd..e95db1ad5f 100644 --- a/propagator/xray/CHANGELOG.md +++ b/propagator/xray/CHANGELOG.md @@ -1,9 +1,5 @@ # Release History: opentelemetry-propagator-xray -### v0.24.0 / 2025-05-06 - -* ADDED: Contribute xray lambda propagator - ### v0.23.0 / 2025-01-16 * BREAKING CHANGE: Set minimum supported version to Ruby 3.1 diff --git a/propagator/xray/Gemfile b/propagator/xray/Gemfile index e111f7525a..5516c83446 100644 --- a/propagator/xray/Gemfile +++ b/propagator/xray/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/propagator/xray/lib/opentelemetry/propagator/xray/version.rb b/propagator/xray/lib/opentelemetry/propagator/xray/version.rb index c5075baa8b..82e809bf11 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.24.0' + VERSION = '0.23.0' end end end diff --git a/resources/aws/CHANGELOG.md b/resources/aws/CHANGELOG.md index 4033d76ffc..bd0ba80519 100644 --- a/resources/aws/CHANGELOG.md +++ b/resources/aws/CHANGELOG.md @@ -1,14 +1,5 @@ # Release History: opentelemetry-resource-detector-aws -### v0.4.0 / 2025-06-03 - -* ADDED: Contribute aws eks resource detector - -### v0.3.0 / 2025-05-07 - -* ADDED: Contribute aws lambda resource detector -* FIXED: Add missing semantic conventions require in AWS resource detectors - ### v0.2.0 / 2025-04-29 * ADDED: Contribute aws ecs resource detector diff --git a/resources/aws/Gemfile b/resources/aws/Gemfile index 351b117b66..b55c4be964 100644 --- a/resources/aws/Gemfile +++ b/resources/aws/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.2' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/resources/aws/README.md b/resources/aws/README.md index b627d422dd..d2c42a92e1 100644 --- a/resources/aws/README.md +++ b/resources/aws/README.md @@ -31,12 +31,11 @@ require 'opentelemetry/resource/detector' OpenTelemetry::SDK.configure do |c| # Specify which AWS resource detectors to use - c.resource = OpenTelemetry::Resource::Detector::AWS.detect([:ec2, :ecs, :eks, :lambda]) + c.resource = OpenTelemetry::Resource::Detector::AWS.detect([:ec2, :ecs, :lambda]) # Or use just one detector c.resource = OpenTelemetry::Resource::Detector::AWS.detect([:ec2]) c.resource = OpenTelemetry::Resource::Detector::AWS.detect([:ecs]) - c.resource = OpenTelemetry::Resource::Detector::AWS.detect([:eks]) c.resource = OpenTelemetry::Resource::Detector::AWS.detect([:lambda]) end ``` @@ -77,21 +76,6 @@ Populates `cloud`, `container`, and AWS ECS-specific attributes for processes ru | `aws.log.stream.names` | The CloudWatch log stream names (if awslogs driver is used) | | `aws.log.stream.arns` | The CloudWatch log stream ARNs (if awslogs driver is used) | -### AWS EKS Detector - -Populates `cloud`, `container`, and Kubernetes (k8s) attributes for processes running on Amazon EKS. -| Resource Attribute | Description | -|--------------------|-------------| -| `cloud.platform` | The cloud platform. In this context, it's always "aws_eks" | -| `cloud.provider` | The cloud provider. In this context, it's always "aws" | -| `container.id` | The container ID from the `/proc/self/cgroup` file | -| `k8s.cluster.name` | The name of the EKS cluster from the `cluster-info` config map in the `amazon-cloudwatch` namespace | - -The EKS detector verifies that the process is running on EKS by checking: -1. Presence of Kubernetes service account token and certificate -2. Ability to access the `aws-auth` config map in the `kube-system` namespace -3. Availability of either cluster name or container ID - ### AWS Lambda Detector Populates `cloud` and `faas` (Function as a Service) attributes for processes running on AWS Lambda. | Resource Attribute | Description | @@ -104,6 +88,8 @@ Populates `cloud` and `faas` (Function as a Service) attributes for processes ru | `faas.instance` | The Lambda function instance ID from the `AWS_LAMBDA_LOG_STREAM_NAME` environment variable | | `faas.max_memory` | The Lambda function memory size in MB from the `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` environment variable | +Additional AWS platforms (EKS) will be supported in future versions. + ## License The `opentelemetry-resource-detector-aws` gem is distributed under the Apache 2.0 license. See LICENSE for more information. diff --git a/resources/aws/lib/opentelemetry-resource-detector-aws.rb b/resources/aws/lib/opentelemetry-resource-detector-aws.rb index 806c814560..a740ef21cc 100644 --- a/resources/aws/lib/opentelemetry-resource-detector-aws.rb +++ b/resources/aws/lib/opentelemetry-resource-detector-aws.rb @@ -4,5 +4,4 @@ # # SPDX-License-Identifier: Apache-2.0 -require 'opentelemetry/semantic_conventions/resource' require_relative 'opentelemetry/resource/detector' diff --git a/resources/aws/lib/opentelemetry/resource/detector/aws.rb b/resources/aws/lib/opentelemetry/resource/detector/aws.rb index c14beeea50..0b06ed7315 100644 --- a/resources/aws/lib/opentelemetry/resource/detector/aws.rb +++ b/resources/aws/lib/opentelemetry/resource/detector/aws.rb @@ -7,7 +7,6 @@ require 'opentelemetry/resource/detector/aws/ec2' require 'opentelemetry/resource/detector/aws/ecs' require 'opentelemetry/resource/detector/aws/lambda' -require 'opentelemetry/resource/detector/aws/eks' module OpenTelemetry module Resource @@ -31,8 +30,6 @@ def detect(detectors = []) EC2.detect when :ecs ECS.detect - when :eks - EKS.detect when :lambda Lambda.detect else diff --git a/resources/aws/lib/opentelemetry/resource/detector/aws/ec2.rb b/resources/aws/lib/opentelemetry/resource/detector/aws/ec2.rb index 581cc18924..0cee4fee51 100644 --- a/resources/aws/lib/opentelemetry/resource/detector/aws/ec2.rb +++ b/resources/aws/lib/opentelemetry/resource/detector/aws/ec2.rb @@ -7,7 +7,6 @@ require 'net/http' require 'json' require 'opentelemetry/common' -require 'opentelemetry/semantic_conventions/resource' module OpenTelemetry module Resource diff --git a/resources/aws/lib/opentelemetry/resource/detector/aws/ecs.rb b/resources/aws/lib/opentelemetry/resource/detector/aws/ecs.rb index 667d07a969..b0386346b7 100644 --- a/resources/aws/lib/opentelemetry/resource/detector/aws/ecs.rb +++ b/resources/aws/lib/opentelemetry/resource/detector/aws/ecs.rb @@ -8,7 +8,6 @@ require 'json' require 'socket' require 'opentelemetry/common' -require 'opentelemetry/semantic_conventions/resource' module OpenTelemetry module Resource @@ -52,7 +51,7 @@ def detect task_metadata = JSON.parse(http_get("#{metadata_uri_v4}/task")) task_arn = task_metadata['TaskARN'] - base_arn = task_arn[0..(task_arn.rindex(':') - 1)] + base_arn = task_arn[0..task_arn.rindex(':') - 1] cluster = task_metadata['Cluster'] cluster_arn = cluster.start_with?('arn:') ? cluster : "#{base_arn}:cluster/#{cluster}" diff --git a/resources/aws/lib/opentelemetry/resource/detector/aws/eks.rb b/resources/aws/lib/opentelemetry/resource/detector/aws/eks.rb deleted file mode 100644 index b66207c259..0000000000 --- a/resources/aws/lib/opentelemetry/resource/detector/aws/eks.rb +++ /dev/null @@ -1,174 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'net/http' -require 'json' -require 'openssl' -require 'uri' -require 'opentelemetry/common' -require 'opentelemetry/semantic_conventions/resource' - -module OpenTelemetry - module Resource - module Detector - module AWS - # EKS contains detect class method for determining EKS resource attributes - module EKS - extend self - - # Container ID length from cgroup file - CONTAINER_ID_LENGTH = 64 - - # HTTP request timeout in seconds - HTTP_TIMEOUT = 5 - - # Kubernetes token and certificate paths - TOKEN_PATH = '/var/run/secrets/kubernetes.io/serviceaccount/token' - CERT_PATH = '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt' - - # Kubernetes API paths - AWS_AUTH_PATH = '/api/v1/namespaces/kube-system/configmaps/aws-auth' - CLUSTER_INFO_PATH = '/api/v1/namespaces/amazon-cloudwatch/configmaps/cluster-info' - - # Create a constant for resource semantic conventions - RESOURCE = OpenTelemetry::SemanticConventions::Resource - - def detect - # Return empty resource if not running on K8s - return OpenTelemetry::SDK::Resources::Resource.create({}) unless k8s? - - resource_attributes = {} - - begin - # Get K8s credentials - cred_value = k8s_cred_value - - # Verify this is an EKS cluster - unless eks?(cred_value) - OpenTelemetry.logger.debug('Could not confirm process is running on EKS') - return OpenTelemetry::SDK::Resources::Resource.create({}) - end - - # Get cluster name and container ID - cluster_name_val = cluster_name(cred_value) - container_id_val = container_id - - if container_id_val.empty? && cluster_name_val.empty? - OpenTelemetry.logger.debug('Neither cluster name nor container ID found on EKS process') - return OpenTelemetry::SDK::Resources::Resource.create({}) - end - - # Set resource attributes - resource_attributes[RESOURCE::CLOUD_PROVIDER] = 'aws' - resource_attributes[RESOURCE::CLOUD_PLATFORM] = 'aws_eks' - resource_attributes[RESOURCE::K8S_CLUSTER_NAME] = cluster_name_val unless cluster_name_val.empty? - resource_attributes[RESOURCE::CONTAINER_ID] = container_id_val unless container_id_val.empty? - rescue StandardError => e - OpenTelemetry.logger.debug("EKS resource detection failed: #{e.message}") - return OpenTelemetry::SDK::Resources::Resource.create({}) - end - - resource_attributes.delete_if { |_key, value| value.nil? || value.empty? } - OpenTelemetry::SDK::Resources::Resource.create(resource_attributes) - end - - private - - # Check if running on K8s - # - # @return [Boolean] true if running on K8s - def k8s? - File.exist?(TOKEN_PATH) && File.exist?(CERT_PATH) - end - - # Get K8s token - # - # @return [String] K8s token - # @raise [StandardError] if token could not be read - def k8s_cred_value - token = File.read(TOKEN_PATH).strip - "Bearer #{token}" - rescue StandardError => e - OpenTelemetry.logger.debug("Failed to get k8s token: #{e.message}") - raise e - end - - # Check if running on EKS - # - # @param cred_value [String] K8s credentials - # @return [Boolean] true if running on EKS - def eks?(cred_value) - # Just try to to access the aws-auth configmap - # If it exists and we can access it, we're on EKS - aws_http_request(AWS_AUTH_PATH, cred_value) - true - rescue StandardError - false - end - - # Get EKS cluster name - # - # @param cred_value [String] K8s credentials - # @return [String] Cluster name or empty string if not found - def cluster_name(cred_value) - begin - response = aws_http_request(CLUSTER_INFO_PATH, cred_value) - cluster_info = JSON.parse(response) - return cluster_info['data']['cluster.name'] if cluster_info['data'] && cluster_info['data']['cluster.name'] - rescue StandardError => e - OpenTelemetry.logger.debug("Cannot get cluster name on EKS: #{e.message}") - end - '' - end - - # Get container ID from cgroup file - # - # @return [String] Container ID or empty string if not found - def container_id - begin - File.open('/proc/self/cgroup', 'r') do |file| - file.each_line do |line| - line = line.strip - # Look for container ID (64 chars) at the end of the line - return line[-CONTAINER_ID_LENGTH..-1] if line.length > CONTAINER_ID_LENGTH - end - end - rescue StandardError => e - OpenTelemetry.logger.debug("Failed to get container ID on EKS: #{e.message}") - end - '' - end - - # Make HTTP GET request to K8s API - # - # @param path [String] API path - # @param cred_value [String] Authorization header value - # @return [String] Response body - # @raise [StandardError] if request fails - def aws_http_request(path, cred_value) - uri = URI.parse("https://kubernetes.default.svc#{path}") - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = true - http.verify_mode = OpenSSL::SSL::VERIFY_PEER - http.ca_file = CERT_PATH - http.open_timeout = HTTP_TIMEOUT - http.read_timeout = HTTP_TIMEOUT - - request = Net::HTTP::Get.new(uri) - request['Authorization'] = cred_value - - OpenTelemetry::Common::Utilities.untraced do - response = http.request(request) - raise "HTTP request failed with status #{response.code}" unless response.is_a?(Net::HTTPSuccess) - - response.body - end - end - end - end - end - end -end diff --git a/resources/aws/lib/opentelemetry/resource/detector/aws/lambda.rb b/resources/aws/lib/opentelemetry/resource/detector/aws/lambda.rb index f8db75bbfd..8f3a83e0ef 100644 --- a/resources/aws/lib/opentelemetry/resource/detector/aws/lambda.rb +++ b/resources/aws/lib/opentelemetry/resource/detector/aws/lambda.rb @@ -4,8 +4,6 @@ # # SPDX-License-Identifier: Apache-2.0 -require 'opentelemetry/semantic_conventions/resource' - module OpenTelemetry module Resource module Detector diff --git a/resources/aws/lib/opentelemetry/resource/detector/aws/version.rb b/resources/aws/lib/opentelemetry/resource/detector/aws/version.rb index a98b557f67..0777ad1f1e 100644 --- a/resources/aws/lib/opentelemetry/resource/detector/aws/version.rb +++ b/resources/aws/lib/opentelemetry/resource/detector/aws/version.rb @@ -8,7 +8,7 @@ module OpenTelemetry module Resource module Detector module AWS - VERSION = '0.4.0' + VERSION = '0.2.0' end end end diff --git a/resources/aws/test/opentelemetry/resource/detector/aws/eks_test.rb b/resources/aws/test/opentelemetry/resource/detector/aws/eks_test.rb deleted file mode 100644 index 83a6047464..0000000000 --- a/resources/aws/test/opentelemetry/resource/detector/aws/eks_test.rb +++ /dev/null @@ -1,244 +0,0 @@ -# frozen_string_literal: true - -# Copyright The OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'test_helper' - -describe OpenTelemetry::Resource::Detector::AWS::EKS do - let(:detector) { OpenTelemetry::Resource::Detector::AWS::EKS } - # Constants for paths used in testing - let(:token_path) { OpenTelemetry::Resource::Detector::AWS::EKS::TOKEN_PATH } - let(:cert_path) { OpenTelemetry::Resource::Detector::AWS::EKS::CERT_PATH } - let(:aws_auth_path) { OpenTelemetry::Resource::Detector::AWS::EKS::AWS_AUTH_PATH } - let(:cluster_info_path) { OpenTelemetry::Resource::Detector::AWS::EKS::CLUSTER_INFO_PATH } - - describe '.detect' do - before do - # Set up file existence checks - @token_path_exists = false - @cert_path_exists = false - - # Store original environment variables - @original_env = ENV.to_hash - ENV.clear - - # Disable external network connections - WebMock.disable_net_connect! - end - - after do - # Restore original environment - ENV.replace(@original_env) - - # Re-enable network connections - WebMock.allow_net_connect! - end - - it 'returns empty resource when not running on K8s' do - @token_path_exists = false - @cert_path_exists = false - - File.stub :exist?, lambda { |path| - if path == token_path - @token_path_exists - elsif path == cert_path - @cert_path_exists - else - false - end - } do - resource = detector.detect - _(resource).must_be_instance_of(OpenTelemetry::SDK::Resources::Resource) - _(resource.attribute_enumerator.to_h).must_equal({}) - end - end - - it 'returns empty resource when only token exists' do - @token_path_exists = true - @cert_path_exists = false - - File.stub :exist?, lambda { |path| - if path == token_path - @token_path_exists - elsif path == cert_path - @cert_path_exists - else - false - end - } do - resource = detector.detect - _(resource).must_be_instance_of(OpenTelemetry::SDK::Resources::Resource) - _(resource.attribute_enumerator.to_h).must_equal({}) - end - end - - it 'returns empty resource when only cert exists' do - @token_path_exists = false - @cert_path_exists = true - - File.stub :exist?, lambda { |path| - if path == token_path - @token_path_exists - elsif path == cert_path - @cert_path_exists - else - false - end - } do - resource = detector.detect - _(resource).must_be_instance_of(OpenTelemetry::SDK::Resources::Resource) - _(resource.attribute_enumerator.to_h).must_equal({}) - end - end - - describe 'when running on K8s' do - # Mock values for EKS tests - let(:mock_token) { 'k8s-token-value' } - let(:mock_cred_value) { "Bearer #{mock_token}" } - let(:mock_aws_auth_response) { '{"kind":"ConfigMap","data":{}}' } - let(:mock_cluster_info_response) { '{"data":{"cluster.name":"my-eks-cluster"}}' } - let(:mock_container_id) { '0123456789abcdef' * 4 } - let(:mock_cluster_name) { 'my-eks-cluster' } - - before do - @token_path_exists = true - @cert_path_exists = true - end - - let(:expected_resource_attributes) do - { - OpenTelemetry::SemanticConventions::Resource::CLOUD_PROVIDER => 'aws', - OpenTelemetry::SemanticConventions::Resource::CLOUD_PLATFORM => 'aws_eks', - OpenTelemetry::SemanticConventions::Resource::K8S_CLUSTER_NAME => mock_cluster_name, - OpenTelemetry::SemanticConventions::Resource::CONTAINER_ID => mock_container_id - } - end - - it 'detects EKS resources' do - # Mock file existence check - File.stub :exist?, lambda { |path| - if path == token_path - @token_path_exists - elsif path == cert_path - @cert_path_exists - else - false - end - } do - # Mock token file read - File.stub :read, lambda { |path| - raise "Unexpected file read: #{path}" unless path == token_path - - mock_token - } do - # Mock container ID retrieval - detector.stub :container_id, mock_container_id do - # Mock cluster name retrieval - detector.stub :cluster_name, ->(_) { mock_cluster_name } do - # Mock HTTP requests - detector.stub :aws_http_request, lambda { |path, _auth| - if path == aws_auth_path - mock_aws_auth_response - elsif path == cluster_info_path - mock_cluster_info_response - else - raise "Unexpected HTTP request to #{path}" - end - } do - resource = detector.detect - attributes = resource.attribute_enumerator.to_h - - # Check attributes - _(resource).must_be_instance_of(OpenTelemetry::SDK::Resources::Resource) - _(attributes).must_equal(expected_resource_attributes) - end - end - end - end - end - end - - it 'handles missing cluster name' do - # Simplified test with direct stubs - expected_attrs = { - OpenTelemetry::SemanticConventions::Resource::CLOUD_PROVIDER => 'aws', - OpenTelemetry::SemanticConventions::Resource::CLOUD_PLATFORM => 'aws_eks', - OpenTelemetry::SemanticConventions::Resource::CONTAINER_ID => mock_container_id - } - - detector.stub :k8s?, true do - detector.stub :k8s_cred_value, mock_cred_value do - detector.stub :eks?, true do - detector.stub :cluster_name, ->(_) { '' } do - detector.stub :container_id, mock_container_id do - resource = detector.detect - attributes = resource.attribute_enumerator.to_h - - # Should still have container ID but no cluster name - _(resource).must_be_instance_of(OpenTelemetry::SDK::Resources::Resource) - _(attributes).must_equal(expected_attrs) - end - end - end - end - end - end - - it 'handles missing container ID' do - # Simplified test with direct stubs - expected_attrs = { - OpenTelemetry::SemanticConventions::Resource::CLOUD_PROVIDER => 'aws', - OpenTelemetry::SemanticConventions::Resource::CLOUD_PLATFORM => 'aws_eks', - OpenTelemetry::SemanticConventions::Resource::K8S_CLUSTER_NAME => mock_cluster_name - } - - detector.stub :k8s?, true do - detector.stub :k8s_cred_value, mock_cred_value do - detector.stub :eks?, true do - detector.stub :cluster_name, ->(_) { mock_cluster_name } do - detector.stub :container_id, '' do - resource = detector.detect - attributes = resource.attribute_enumerator.to_h - - # Should still have cluster name but no container ID - _(resource).must_be_instance_of(OpenTelemetry::SDK::Resources::Resource) - _(attributes).must_equal(expected_attrs) - end - end - end - end - end - end - - it 'returns empty resource when aws-auth check fails' do - # Simplified test with direct stubs - detector.stub :k8s?, true do - detector.stub :k8s_cred_value, mock_cred_value do - detector.stub :eks?, false do - resource = detector.detect - _(resource.attribute_enumerator.to_h).must_equal({}) - end - end - end - end - - it 'returns empty resource when both cluster name and container ID are missing' do - # Simplified test with direct stubs - detector.stub :k8s?, true do - detector.stub :k8s_cred_value, mock_cred_value do - detector.stub :eks?, true do - detector.stub :cluster_name, ->(_) { '' } do - detector.stub :container_id, '' do - resource = detector.detect - _(resource.attribute_enumerator.to_h).must_equal({}) - end - end - end - end - end - end - end - end -end diff --git a/resources/aws/test/opentelemetry/resource/detector/aws_test.rb b/resources/aws/test/opentelemetry/resource/detector/aws_test.rb index a386015016..08703f744b 100644 --- a/resources/aws/test/opentelemetry/resource/detector/aws_test.rb +++ b/resources/aws/test/opentelemetry/resource/detector/aws_test.rb @@ -62,16 +62,12 @@ def assert_detection_result(detectors) assert_detection_result([:lambda]) end - it 'returns an empty resource when EKS detection fails' do - assert_detection_result([:eks]) - end - it 'returns an empty resource with unknown detector' do assert_detection_result([:unknown]) end it 'returns an empty resource with multiple detectors when all fail' do - assert_detection_result(%i[ec2 ecs eks lambda unknown]) + assert_detection_result(%i[ec2 ecs unknown]) end describe 'with successful EC2 detection' do @@ -227,70 +223,6 @@ def assert_detection_result(detectors) end end end - - describe 'with successful EKS detection' do - let(:cluster_name) { 'my-eks-cluster' } - let(:container_id) { '0123456789abcdef' * 4 } - - before do - # No specific environment setup needed for EKS tests - # They rely completely on stubbing - end - - it 'detects EKS resources when specified' do - # Create a mock EKS resource - eks_resource = OpenTelemetry::SDK::Resources::Resource.create({ - RESOURCE::CLOUD_PROVIDER => 'aws', - RESOURCE::CLOUD_PLATFORM => 'aws_eks', - RESOURCE::K8S_CLUSTER_NAME => cluster_name, - RESOURCE::CONTAINER_ID => container_id - }) - - # Stub EKS detection to return the mock resource - OpenTelemetry::Resource::Detector::AWS::EKS.stub :detect, eks_resource do - resource = detector.detect([:eks]) - attributes = resource.attribute_enumerator.to_h - - # Check EKS attributes - _(attributes[RESOURCE::CLOUD_PROVIDER]).must_equal('aws') - _(attributes[RESOURCE::CLOUD_PLATFORM]).must_equal('aws_eks') - _(attributes[RESOURCE::K8S_CLUSTER_NAME]).must_equal(cluster_name) - _(attributes[RESOURCE::CONTAINER_ID]).must_equal(container_id) - end - end - - it 'combines EC2 and EKS resources when both are detected' do - # Create a mock EC2 resource - ec2_resource = OpenTelemetry::SDK::Resources::Resource.create({ - RESOURCE::HOST_ID => 'i-1234567890abcdef0', - RESOURCE::HOST_TYPE => 'm5.xlarge' - }) - - # Create a mock EKS resource - eks_resource = OpenTelemetry::SDK::Resources::Resource.create({ - RESOURCE::CLOUD_PROVIDER => 'aws', - RESOURCE::CLOUD_PLATFORM => 'aws_eks', - RESOURCE::K8S_CLUSTER_NAME => cluster_name, - RESOURCE::CONTAINER_ID => container_id - }) - - # Stub both detectors - OpenTelemetry::Resource::Detector::AWS::EC2.stub :detect, ec2_resource do - OpenTelemetry::Resource::Detector::AWS::EKS.stub :detect, eks_resource do - resource = detector.detect(%i[ec2 eks]) - attributes = resource.attribute_enumerator.to_h - - # Should include attributes from both detectors - _(attributes[RESOURCE::CLOUD_PROVIDER]).must_equal('aws') - _(attributes[RESOURCE::CLOUD_PLATFORM]).must_equal('aws_eks') - _(attributes[RESOURCE::K8S_CLUSTER_NAME]).must_equal(cluster_name) - _(attributes[RESOURCE::CONTAINER_ID]).must_equal(container_id) - _(attributes[RESOURCE::HOST_ID]).must_equal('i-1234567890abcdef0') - _(attributes[RESOURCE::HOST_TYPE]).must_equal('m5.xlarge') - end - end - end - end end end end diff --git a/resources/azure/Gemfile b/resources/azure/Gemfile index 351b117b66..cb9965eb44 100644 --- a/resources/azure/Gemfile +++ b/resources/azure/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/resources/container/Gemfile b/resources/container/Gemfile index a7675baf59..8bf2eb907b 100644 --- a/resources/container/Gemfile +++ b/resources/container/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/resources/google_cloud_platform/Gemfile b/resources/google_cloud_platform/Gemfile index 351b117b66..cb9965eb44 100644 --- a/resources/google_cloud_platform/Gemfile +++ b/resources/google_cloud_platform/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.1' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'webmock', '~> 3.24' diff --git a/sampler/xray/Gemfile b/sampler/xray/Gemfile index 8d900ea2d5..1b6d489203 100644 --- a/sampler/xray/Gemfile +++ b/sampler/xray/Gemfile @@ -12,7 +12,7 @@ group :test do gem 'bundler', '~> 2.4' gem 'minitest', '~> 5.0' gem 'rake', '~> 13.0' - gem 'rubocop', '~> 1.76.2' + gem 'rubocop', '~> 1.75.2' gem 'rubocop-performance', '~> 1.24.0' gem 'simplecov', '~> 0.22.0' gem 'yard', '~> 0.9' diff --git a/sampler/xray/lib/opentelemetry/sampler/xray/aws_xray_remote_sampler.rb b/sampler/xray/lib/opentelemetry/sampler/xray/aws_xray_remote_sampler.rb index 41f051ca2f..13238f9c1a 100644 --- a/sampler/xray/lib/opentelemetry/sampler/xray/aws_xray_remote_sampler.rb +++ b/sampler/xray/lib/opentelemetry/sampler/xray/aws_xray_remote_sampler.rb @@ -8,9 +8,7 @@ require 'json' require 'opentelemetry/sdk' require_relative 'sampling_rule' -require_relative 'fallback_sampler' require_relative 'sampling_rule_applier' -require_relative 'rule_cache' require_relative 'aws_xray_sampling_client' module OpenTelemetry @@ -59,9 +57,7 @@ def initialize(endpoint: '127.0.0.1:2000', polling_interval: DEFAULT_RULES_POLLI @target_polling_jitter_millis = (rand / 10) * 1000 @aws_proxy_endpoint = endpoint || DEFAULT_AWS_PROXY_ENDPOINT - @fallback_sampler = OpenTelemetry::Sampler::XRay::FallbackSampler.new @client_id = self.class.generate_client_id - @rule_cache = OpenTelemetry::Sampler::XRay::RuleCache.new(resource) @sampling_client = OpenTelemetry::Sampler::XRay::AWSXRaySamplingClient.new(@aws_proxy_endpoint) @@ -72,25 +68,10 @@ def initialize(endpoint: '127.0.0.1:2000', polling_interval: DEFAULT_RULES_POLLI end def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:) - if @rule_cache.expired? - OpenTelemetry.logger.debug('Rule cache is expired, so using fallback sampling strategy') - return @fallback_sampler.should_sample?( - trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes - ) - end - - matched_rule = @rule_cache.get_matched_rule(attributes) - if matched_rule - return matched_rule.should_sample?( - trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes - ) - end - - OpenTelemetry.logger.debug( - 'Using fallback sampler as no rule match was found. This is likely due to a bug, since default rule should always match' - ) - @fallback_sampler.should_sample?( - trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes + OpenTelemetry::SDK::Trace::Samplers::Result.new( + decision: OpenTelemetry::SDK::Trace::Samplers::Decision::DROP, + tracestate: tracestate, + attributes: attributes ) end @@ -121,8 +102,6 @@ def retrieve_and_update_sampling_rules else OpenTelemetry.logger.error('GetSamplingRules Response is falsy') end - rescue StandardError => e - OpenTelemetry.handle_error(exception: e, message: 'Error occurred when retrieving or updating Sampling Rules') end def update_sampling_rules(response_object) @@ -134,7 +113,7 @@ def update_sampling_rules(response_object) sampling_rules << SamplingRuleApplier.new(sampling_rule) end end - @rule_cache.update_rules(sampling_rules) + # TODO: Add Sampling Rules to a Rule Cache else OpenTelemetry.logger.error('SamplingRuleRecords from GetSamplingRules request is not defined') end diff --git a/sampler/xray/lib/opentelemetry/sampler/xray/aws_xray_sampling_client.rb b/sampler/xray/lib/opentelemetry/sampler/xray/aws_xray_sampling_client.rb index 3660e1a14a..84b1323b9c 100644 --- a/sampler/xray/lib/opentelemetry/sampler/xray/aws_xray_sampling_client.rb +++ b/sampler/xray/lib/opentelemetry/sampler/xray/aws_xray_sampling_client.rb @@ -51,7 +51,7 @@ def parse_endpoint(endpoint) host, port = endpoint.split(':') [host, port.to_i] rescue StandardError => e - OpenTelemetry.handle_error(exception: e, message: "Invalid endpoint: #{endpoint}") + OpenTelemetry.logger.error("Invalid endpoint: #{endpoint}") raise e end end diff --git a/sampler/xray/lib/opentelemetry/sampler/xray/fallback_sampler.rb b/sampler/xray/lib/opentelemetry/sampler/xray/fallback_sampler.rb deleted file mode 100644 index f25b08052c..0000000000 --- a/sampler/xray/lib/opentelemetry/sampler/xray/fallback_sampler.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -# Copyright OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Sampler - module XRay - # FallbackSampler samples 1 req/sec and additional 5% of requests using TraceIdRatioBasedSampler. - class FallbackSampler - def initialize - @fixed_rate_sampler = OpenTelemetry::SDK::Trace::Samplers::TraceIdRatioBased.new(0.05) - end - - def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:) - # TODO: implement and use Rate Limiting Sampler - - @fixed_rate_sampler.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes) - end - - def description - 'FallbackSampler{fallback sampling with sampling config of 1 req/sec and 5% of additional requests}' - end - end - end - end -end diff --git a/sampler/xray/lib/opentelemetry/sampler/xray/rule_cache.rb b/sampler/xray/lib/opentelemetry/sampler/xray/rule_cache.rb deleted file mode 100644 index 4583fe8397..0000000000 --- a/sampler/xray/lib/opentelemetry/sampler/xray/rule_cache.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true - -# Copyright OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -module OpenTelemetry - module Sampler - module XRay - # RuleCache stores all the Sampling Rule Appliers, each corresponding - # to the user's Sampling Rules that were retrieved from AWS X-Ray - class RuleCache - # The cache expires 1 hour after the last refresh time. - RULE_CACHE_TTL_MILLIS = 60 * 60 * 1000 - - def initialize(sampler_resource) - @rule_appliers = [] - @sampler_resource = sampler_resource - @last_updated_epoch_millis = Time.now.to_i * 1000 - @cache_lock = Mutex.new - end - - def expired? - now_in_millis = Time.now.to_i * 1000 - now_in_millis > @last_updated_epoch_millis + RULE_CACHE_TTL_MILLIS - end - - def get_matched_rule(attributes) - @rule_appliers.find do |rule| - rule.matches?(attributes, @sampler_resource) || rule.sampling_rule.rule_name == 'Default' - end - end - - def update_rules(new_rule_appliers) - old_rule_appliers_map = {} - - @cache_lock.synchronize do - @rule_appliers.each do |rule| - old_rule_appliers_map[rule.sampling_rule.rule_name] = rule - end - - new_rule_appliers.each_with_index do |new_rule, index| - rule_name_to_check = new_rule.sampling_rule.rule_name - next unless old_rule_appliers_map.key?(rule_name_to_check) - - old_rule = old_rule_appliers_map[rule_name_to_check] - new_rule_appliers[index] = old_rule if new_rule.sampling_rule.equals?(old_rule.sampling_rule) - end - - @rule_appliers = new_rule_appliers - sort_rules_by_priority - @last_updated_epoch_millis = Time.now.to_i * 1000 - end - end - - private - - def sort_rules_by_priority - @rule_appliers.sort! do |rule1, rule2| - if rule1.sampling_rule.priority == rule2.sampling_rule.priority - rule1.sampling_rule.rule_name < rule2.sampling_rule.rule_name ? -1 : 1 - else - rule1.sampling_rule.priority - rule2.sampling_rule.priority - end - end - end - end - end - end -end diff --git a/sampler/xray/lib/opentelemetry/sampler/xray/sampling_rule_applier.rb b/sampler/xray/lib/opentelemetry/sampler/xray/sampling_rule_applier.rb index 0863d738c5..d6f0aac971 100644 --- a/sampler/xray/lib/opentelemetry/sampler/xray/sampling_rule_applier.rb +++ b/sampler/xray/lib/opentelemetry/sampler/xray/sampling_rule_applier.rb @@ -7,7 +7,6 @@ require 'opentelemetry/sdk' require 'opentelemetry-semantic_conventions' require 'date' -require_relative 'sampling_rule' require_relative 'statistics' require_relative 'utils' @@ -20,92 +19,16 @@ class SamplingRuleApplier attr_reader :sampling_rule MAX_DATE_TIME_SECONDS = Time.at(8_640_000_000_000) - SEMCONV = OpenTelemetry::SemanticConventions def initialize(sampling_rule, statistics = OpenTelemetry::Sampler::XRay::Statistics.new, target = nil) @sampling_rule = sampling_rule - @fixed_rate_sampler = OpenTelemetry::SDK::Trace::Samplers::TraceIdRatioBased.new(@sampling_rule.fixed_rate) - - # TODO: Add Reservoir Sampler (Rate Limiting Sampler) - - @reservoir_expiry_time = MAX_DATE_TIME_SECONDS - @statistics = statistics - end - - def matches?(attributes, resource) - http_target = nil - http_url = nil - http_method = nil - http_host = nil - - unless attributes.nil? - http_target = attributes[SEMCONV::Trace::HTTP_TARGET] - http_url = attributes[SEMCONV::Trace::HTTP_URL] - http_method = attributes[SEMCONV::Trace::HTTP_METHOD] - http_host = attributes[SEMCONV::Trace::HTTP_HOST] - end - - service_type = nil - resource_arn = nil - - resource_hash = resource.attribute_enumerator.to_h - - if resource - service_name = resource_hash[SEMCONV::Resource::SERVICE_NAME] || '' - cloud_platform = resource_hash[SEMCONV::Resource::CLOUD_PLATFORM] - service_type = OpenTelemetry::Sampler::XRay::Utils::CLOUD_PLATFORM_MAPPING[cloud_platform] if cloud_platform.is_a?(String) - resource_arn = get_arn(resource, attributes) - end - - if http_target.nil? && http_url.is_a?(String) - begin - uri = URI(http_url) - http_target = uri.path.empty? ? '/' : uri.path - rescue URI::InvalidURIError - http_target = '/' - end - elsif http_target.nil? && http_url.nil? - http_target = '/' - end - - OpenTelemetry::Sampler::XRay::Utils.attribute_match?(attributes, @sampling_rule.attributes) && - OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.host, http_host) && - OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.http_method, http_method) && - OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.service_name, service_name) && - OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.url_path, http_target) && - OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.service_type, service_type) && - OpenTelemetry::Sampler::XRay::Utils.wildcard_match(@sampling_rule.resource_arn, resource_arn) end def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:) - # TODO: Record Sampling Statistics - - result = OpenTelemetry::SDK::Trace::Samplers::Result.new( + OpenTelemetry::SDK::Trace::Samplers::Result.new( decision: OpenTelemetry::SDK::Trace::Samplers::Decision::DROP, tracestate: OpenTelemetry::Trace::Tracestate::DEFAULT ) - - # TODO: Apply Reservoir Sampling - - if result.instance_variable_get(:@decision) == OpenTelemetry::SDK::Trace::Samplers::Decision::DROP - result = @fixed_rate_sampler.should_sample?( - trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes - ) - end - - result - end - - private - - def get_arn(resource, attributes) - resource_hash = resource.attribute_enumerator.to_h - arn = resource_hash[SEMCONV::Resource::AWS_ECS_CONTAINER_ARN] || - resource_hash[SEMCONV::Resource::AWS_ECS_CLUSTER_ARN] || - resource_hash[SEMCONV::Resource::AWS_EKS_CLUSTER_ARN] - - arn = attributes[SEMCONV::Trace::AWS_LAMBDA_INVOKED_ARN] || resource_hash[SEMCONV::Resource::FAAS_ID] if arn.nil? - arn end end end diff --git a/sampler/xray/lib/opentelemetry/sampler/xray/utils.rb b/sampler/xray/lib/opentelemetry/sampler/xray/utils.rb index a5913e0163..15698b622e 100644 --- a/sampler/xray/lib/opentelemetry/sampler/xray/utils.rb +++ b/sampler/xray/lib/opentelemetry/sampler/xray/utils.rb @@ -45,7 +45,7 @@ def wildcard_match(pattern = nil, text = nil) match end - def attribute_match?(attributes = nil, rule_attributes = nil) + def attribute_match(attributes = nil, rule_attributes = nil) return true if rule_attributes.nil? || rule_attributes.empty? return false if attributes.nil? || diff --git a/sampler/xray/test/aws_xray_remote_sampler_test.rb b/sampler/xray/test/aws_xray_remote_sampler_test.rb index 3de4299cb5..9dcb5a8c4f 100644 --- a/sampler/xray/test/aws_xray_remote_sampler_test.rb +++ b/sampler/xray/test/aws_xray_remote_sampler_test.rb @@ -9,7 +9,6 @@ DATA_DIR_SAMPLING_RULES = File.join(__dir__, 'data/test-remote-sampler_sampling-rules-response-sample.json') DATA_DIR_SAMPLING_TARGETS = File.join(__dir__, 'data/test-remote-sampler_sampling-targets-response-sample.json') TEST_URL = 'localhost:2000' -SEMCONV = OpenTelemetry::SemanticConventions describe OpenTelemetry::Sampler::XRay::AWSXRayRemoteSampler do it 'creates remote sampler with empty resource' do @@ -23,7 +22,6 @@ assert !sampler.instance_variable_get(:@rule_poller).nil? assert_equal(sampler.instance_variable_get(:@rule_polling_interval_millis), 300 * 1000) assert !sampler.instance_variable_get(:@sampling_client).nil? - assert !sampler.instance_variable_get(:@rule_cache).nil? assert_match(/[a-f0-9]{24}/, sampler.instance_variable_get(:@client_id)) end @@ -34,16 +32,14 @@ .to_return(status: 200, body: File.read(DATA_DIR_SAMPLING_TARGETS)) resource = OpenTelemetry::SDK::Resources::Resource.create( - SEMCONV::Resource::SERVICE_NAME => 'test-service-name', - SEMCONV::Resource::CLOUD_PLATFORM => 'test-cloud-platform' + OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => 'test-service-name', + OpenTelemetry::SemanticConventions::Resource::CLOUD_PLATFORM => 'test-cloud-platform' ) sampler = OpenTelemetry::Sampler::XRay::InternalAWSXRayRemoteSampler.new(resource: resource) assert !sampler.instance_variable_get(:@rule_poller).nil? assert_equal(sampler.instance_variable_get(:@rule_polling_interval_millis), 300 * 1000) assert !sampler.instance_variable_get(:@sampling_client).nil? - assert !sampler.instance_variable_get(:@rule_cache).nil? - assert_equal(sampler.instance_variable_get(:@rule_cache).instance_variable_get(:@sampler_resource), resource) assert_match(/[a-f0-9]{24}/, sampler.instance_variable_get(:@client_id)) end @@ -54,8 +50,8 @@ .to_return(status: 200, body: File.read(DATA_DIR_SAMPLING_TARGETS)) resource = OpenTelemetry::SDK::Resources::Resource.create( - SEMCONV::Resource::SERVICE_NAME => 'test-service-name', - SEMCONV::Resource::CLOUD_PLATFORM => 'test-cloud-platform' + OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME => 'test-service-name', + OpenTelemetry::SemanticConventions::Resource::CLOUD_PLATFORM => 'test-cloud-platform' ) sampler = OpenTelemetry::Sampler::XRay::InternalAWSXRayRemoteSampler.new( resource: resource, @@ -66,34 +62,10 @@ assert !sampler.instance_variable_get(:@rule_poller).nil? assert_equal(sampler.instance_variable_get(:@rule_polling_interval_millis), 120 * 1000) assert !sampler.instance_variable_get(:@sampling_client).nil? - assert !sampler.instance_variable_get(:@rule_cache).nil? - assert_equal(sampler.instance_variable_get(:@rule_cache).instance_variable_get(:@sampler_resource), resource) assert_equal(sampler.instance_variable_get(:@aws_proxy_endpoint), 'abc.com') assert_match(/[a-f0-9]{24}/, sampler.instance_variable_get(:@client_id)) end - it 'updates sampling rules and targets with pollers and should sample' do - stub_request(:post, "#{TEST_URL}/GetSamplingRules") - .to_return(status: 200, body: File.read(DATA_DIR_SAMPLING_RULES)) - stub_request(:post, "#{TEST_URL}/SamplingTargets") - .to_return(status: 200, body: File.read(DATA_DIR_SAMPLING_TARGETS)) - - resource = OpenTelemetry::SDK::Resources::Resource.create( - SEMCONV::Resource::SERVICE_NAME => 'test-service-name', - SEMCONV::Resource::CLOUD_PLATFORM => 'test-cloud-platform' - ) - rs = OpenTelemetry::Sampler::XRay::AWSXRayRemoteSampler.new(resource: resource) - - attributes = { 'abc' => '1234' } - - test_rule_applier = rs.instance_variable_get(:@root).instance_variable_get(:@root).instance_variable_get(:@rule_cache).instance_variable_get(:@rule_appliers)[0] - assert_equal 'test', test_rule_applier.instance_variable_get(:@sampling_rule).instance_variable_get(:@rule_name) - assert_equal OpenTelemetry::SDK::Trace::Samplers::Decision::DROP, - rs.should_sample?(parent_context: nil, trace_id: '3759e988bd862e3fe1be46a994272793', name: 'name', kind: OpenTelemetry::Trace::SpanKind::SERVER, attributes: attributes, links: []).instance_variable_get(:@decision) - - # TODO: Run more tests after updating Sampling Targets - end - it 'generates valid client id' do client_id = OpenTelemetry::Sampler::XRay::InternalAWSXRayRemoteSampler.generate_client_id assert_match(/[0-9a-z]{24}/, client_id) @@ -109,15 +81,4 @@ expected_string = 'InternalAWSXRayRemoteSampler{aws_proxy_endpoint=127.0.0.1:2000, rule_polling_interval_millis=300000}' assert_equal(sampler.description, expected_string) end - - def create_spans(sampled_array, thread_id, span_attributes, remote_sampler, number_of_spans) - sampled = 0 - number_of_spans.times do - sampled += 1 if remote_sampler.should_sample?(parent_context: nil, trace_id: '3759e988bd862e3fe1be46a994272793', name: 'name', kind: OpenTelemetry::Trace::SpanKind::SERVER, attributes: span_attributes, - links: []).instance_variable_get(:@decision) != OpenTelemetry::SDK::Trace::Samplers::Decision::DROP - end - sampled_array[thread_id] = sampled - end - - # TODO: Run tests for Reservoir Sampling end diff --git a/sampler/xray/test/fallback_sampler_test.rb b/sampler/xray/test/fallback_sampler_test.rb deleted file mode 100644 index 01f5224b71..0000000000 --- a/sampler/xray/test/fallback_sampler_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -# Copyright OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'test_helper' - -describe OpenTelemetry::Sampler::XRay::FallbackSampler do - # TODO: Add tests for Fallback sampler when Rate Limiter is implemented - - it 'test_to_string' do - assert_equal( - 'FallbackSampler{fallback sampling with sampling config of 1 req/sec and 5% of additional requests}', - OpenTelemetry::Sampler::XRay::FallbackSampler.new.description - ) - end -end diff --git a/sampler/xray/test/rule_cache_test.rb b/sampler/xray/test/rule_cache_test.rb deleted file mode 100644 index bad80e3fc0..0000000000 --- a/sampler/xray/test/rule_cache_test.rb +++ /dev/null @@ -1,113 +0,0 @@ -# frozen_string_literal: true - -# Copyright OpenTelemetry Authors -# -# SPDX-License-Identifier: Apache-2.0 - -require 'test_helper' - -describe OpenTelemetry::Sampler::XRay::RuleCache do - def create_rule(name, priority, reservoir_size, fixed_rate) - test_sampling_rule = { - 'RuleName' => name, - 'Priority' => priority, - 'ReservoirSize' => reservoir_size, - 'FixedRate' => fixed_rate, - 'ServiceName' => '*', - 'ServiceType' => '*', - 'Host' => '*', - 'HTTPMethod' => '*', - 'URLPath' => '*', - 'ResourceARN' => '*', - 'Version' => 1 - } - OpenTelemetry::Sampler::XRay::SamplingRuleApplier.new(OpenTelemetry::Sampler::XRay::SamplingRule.new(test_sampling_rule)) - end - - it 'test_cache_updates_and_sorts_rules' do - # Set up default rule in rule cache - default_rule = create_rule('Default', 10_000, 1, 0.05) - cache = OpenTelemetry::Sampler::XRay::RuleCache.new(OpenTelemetry::SDK::Resources::Resource.create({})) - cache.update_rules([default_rule]) - - # Expect default rule to exist - assert_equal 1, cache.instance_variable_get(:@rule_appliers).length - - # Set up incoming rules - rule1 = create_rule('low', 200, 0, 0.0) - rule2 = create_rule('abc', 100, 0, 0.0) - rule3 = create_rule('Abc', 100, 0, 0.0) - rule4 = create_rule('ab', 100, 0, 0.0) - rule5 = create_rule('A', 100, 0, 0.0) - rule6 = create_rule('high', 10, 0, 0.0) - rules = [rule1, rule2, rule3, rule4, rule5, rule6] - - cache.update_rules(rules) - - rule_appliers = cache.instance_variable_get(:@rule_appliers) - assert_equal rules.length, rule_appliers.length - assert_equal 'high', rule_appliers[0].sampling_rule.rule_name - assert_equal 'A', rule_appliers[1].sampling_rule.rule_name - assert_equal 'Abc', rule_appliers[2].sampling_rule.rule_name - assert_equal 'ab', rule_appliers[3].sampling_rule.rule_name - assert_equal 'abc', rule_appliers[4].sampling_rule.rule_name - assert_equal 'low', rule_appliers[5].sampling_rule.rule_name - end - - it 'test_rule_cache_expiration_logic' do - Timecop.freeze(Time.now) do - default_rule = create_rule('Default', 10_000, 1, 0.05) - cache = OpenTelemetry::Sampler::XRay::RuleCache.new(OpenTelemetry::SDK::Resources::Resource.create({})) - cache.update_rules([default_rule]) - - Timecop.travel(2 * 60 * 60) # Travel 2 hours into the future - assert cache.expired? - end - end - - it 'test_update_cache_with_only_one_rule_changed' do - cache = OpenTelemetry::Sampler::XRay::RuleCache.new(OpenTelemetry::SDK::Resources::Resource.create({})) - rule1 = create_rule('rule_1', 1, 0, 0.0) - rule2 = create_rule('rule_2', 10, 0, 0.0) - rule3 = create_rule('rule_3', 100, 0, 0.0) - rule_appliers = [rule1, rule2, rule3] - - cache.update_rules(rule_appliers) - rule_appliers_copy = cache.instance_variable_get(:@rule_appliers).dup - - new_rule3 = create_rule('new_rule_3', 5, 0, 0.0) - new_rule_appliers = [rule1, rule2, new_rule3] - cache.update_rules(new_rule_appliers) - - current_appliers = cache.instance_variable_get(:@rule_appliers) - assert_equal 3, current_appliers.length - assert_equal 'rule_1', current_appliers[0].sampling_rule.rule_name - assert_equal 'new_rule_3', current_appliers[1].sampling_rule.rule_name - assert_equal 'rule_2', current_appliers[2].sampling_rule.rule_name - - assert_equal rule_appliers_copy[0], current_appliers[0] - assert_equal rule_appliers_copy[1], current_appliers[2] - refute_equal rule_appliers_copy[2], current_appliers[1] - end - - it 'test_update_rules_removes_older_rule' do - cache = OpenTelemetry::Sampler::XRay::RuleCache.new(OpenTelemetry::SDK::Resources::Resource.create({})) - assert_equal 0, cache.instance_variable_get(:@rule_appliers).length - - rule1 = create_rule('first_rule', 200, 0, 0.0) - cache.update_rules([rule1]) - - rule_appliers = cache.instance_variable_get(:@rule_appliers) - assert_equal 1, rule_appliers.length - assert_equal 'first_rule', rule_appliers[0].sampling_rule.rule_name - - replacement_rule1 = create_rule('second_rule', 200, 0, 0.0) - cache.update_rules([replacement_rule1]) - - rule_appliers = cache.instance_variable_get(:@rule_appliers) - assert_equal 1, rule_appliers.length - assert_equal 'second_rule', rule_appliers[0].sampling_rule.rule_name - end - - # TODO: Add tests for updating Sampling Targets and getting statistics -end diff --git a/sampler/xray/test/sampling_rule_applier_test.rb b/sampler/xray/test/sampling_rule_applier_test.rb index 4fcf49445f..3509bfa9d2 100644 --- a/sampler/xray/test/sampling_rule_applier_test.rb +++ b/sampler/xray/test/sampling_rule_applier_test.rb @@ -8,204 +8,4 @@ require 'json' describe OpenTelemetry::Sampler::XRay::SamplingRuleApplier do - DATA_DIR = File.join(File.dirname(__FILE__), 'data') - - it 'test_applier_attribute_matching_from_xray_response' do - sample_data = JSON.parse(File.read(File.join(DATA_DIR, 'get-sampling-rules-response-sample-2.json'))) - - all_rules = sample_data['SamplingRuleRecords'] - default_rule = OpenTelemetry::Sampler::XRay::SamplingRule.new(all_rules[0]['SamplingRule']) - sampling_rule_applier = OpenTelemetry::Sampler::XRay::SamplingRuleApplier.new(default_rule) - - resource = OpenTelemetry::SDK::Resources::Resource.create({ - 'service.name' => 'test_service_name', - 'cloud.platform' => 'test_cloud_platform' - }) - - attr = { - 'http.target' => '/target', - 'http.method' => 'method', - 'http.url' => 'url', - 'http.host' => 'host', - 'foo' => 'bar', - 'abc' => '1234' - } - - assert sampling_rule_applier.matches?(attr, resource) - end - - it 'test_applier_matches_with_all_attributes' do - rule = OpenTelemetry::Sampler::XRay::SamplingRule.new({ - 'Attributes' => { 'abc' => '123', 'def' => '4?6', 'ghi' => '*89' }, - 'FixedRate' => 0.11, - 'HTTPMethod' => 'GET', - 'Host' => 'localhost', - 'Priority' => 20, - 'ReservoirSize' => 1, - 'ResourceARN' => 'arn:aws:lambda:us-west-2:123456789012:function:my-function', - 'RuleARN' => 'arn:aws:xray:us-east-1:999999999999:sampling-rule/test', - 'RuleName' => 'test', - 'ServiceName' => 'myServiceName', - 'ServiceType' => 'AWS::Lambda::Function', - 'URLPath' => '/helloworld', - 'Version' => 1 - }) - - attributes = { - 'http.host' => 'localhost', - 'http.method' => 'GET', - 'aws.lambda.invoked_arn' => 'arn:aws:lambda:us-west-2:123456789012:function:my-function', - 'http.url' => 'http://127.0.0.1:5000/helloworld', - 'abc' => '123', - 'def' => '456', - 'ghi' => '789' - } - - resource = OpenTelemetry::SDK::Resources::Resource.create({ - 'service.name' => 'myServiceName', - 'cloud.platform' => 'aws_lambda' - }) - - rule_applier = OpenTelemetry::Sampler::XRay::SamplingRuleApplier.new(rule) - - assert rule_applier.matches?(attributes, resource) - - attributes.delete('http.url') - attributes['http.target'] = '/helloworld' - assert rule_applier.matches?(attributes, resource) - end - - it 'test_applier_wild_card_attributes_matches_span_attributes' do - rule = OpenTelemetry::Sampler::XRay::SamplingRule.new({ - 'Attributes' => { - 'attr1' => '*', - 'attr2' => '*', - 'attr3' => 'HelloWorld', - 'attr4' => 'Hello*', - 'attr5' => '*World', - 'attr6' => '?ello*', - 'attr7' => 'Hell?W*d', - 'attr8' => '*.World', - 'attr9' => '*.World' - }, - 'FixedRate' => 0.11, - 'HTTPMethod' => '*', - 'Host' => '*', - 'Priority' => 20, - 'ReservoirSize' => 1, - 'ResourceARN' => '*', - 'RuleARN' => 'arn:aws:xray:us-east-1:999999999999:sampling-rule/test', - 'RuleName' => 'test', - 'ServiceName' => '*', - 'ServiceType' => '*', - 'URLPath' => '*', - 'Version' => 1 - }) - - rule_applier = OpenTelemetry::Sampler::XRay::SamplingRuleApplier.new(rule) - - attributes = { - 'attr1' => '', - 'attr2' => 'HelloWorld', - 'attr3' => 'HelloWorld', - 'attr4' => 'HelloWorld', - 'attr5' => 'HelloWorld', - 'attr6' => 'HelloWorld', - 'attr7' => 'HelloWorld', - 'attr8' => 'Hello.World', - 'attr9' => 'Bye.World' - } - - assert rule_applier.matches?(attributes, OpenTelemetry::SDK::Resources::Resource.create) - end - - it 'test_applier_wild_card_attributes_matches_http_span_attributes' do - rule_applier = OpenTelemetry::Sampler::XRay::SamplingRuleApplier.new( - OpenTelemetry::Sampler::XRay::SamplingRule.new({ - 'Attributes' => {}, - 'FixedRate' => 0.11, - 'HTTPMethod' => '*', - 'Host' => '*', - 'Priority' => 20, - 'ReservoirSize' => 1, - 'ResourceARN' => '*', - 'RuleARN' => 'arn:aws:xray:us-east-1:999999999999:sampling-rule/test', - 'RuleName' => 'test', - 'ServiceName' => '*', - 'ServiceType' => '*', - 'URLPath' => '*', - 'Version' => 1 - }) - ) - - attributes = { - 'http.host' => 'localhost', - 'http.method' => 'GET', - 'http.url' => 'http://127.0.0.1:5000/helloworld' - } - - assert rule_applier.matches?(attributes, OpenTelemetry::SDK::Resources::Resource.create) - end - - it 'test_applier_wild_card_attributes_matches_with_empty_attributes' do - rule_applier = OpenTelemetry::Sampler::XRay::SamplingRuleApplier.new( - OpenTelemetry::Sampler::XRay::SamplingRule.new({ - 'Attributes' => {}, - 'FixedRate' => 0.11, - 'HTTPMethod' => '*', - 'Host' => '*', - 'Priority' => 20, - 'ReservoirSize' => 1, - 'ResourceARN' => '*', - 'RuleARN' => 'arn:aws:xray:us-east-1:999999999999:sampling-rule/test', - 'RuleName' => 'test', - 'ServiceName' => '*', - 'ServiceType' => '*', - 'URLPath' => '*', - 'Version' => 1 - }) - ) - - attributes = {} - resource = OpenTelemetry::SDK::Resources::Resource.create({ - 'service.name' => 'myServiceName', - 'cloud.platform' => 'aws_ec2' - }) - - assert rule_applier.matches?(attributes, resource) - assert rule_applier.matches?({}, resource) - assert rule_applier.matches?(attributes, OpenTelemetry::SDK::Resources::Resource.create) - assert rule_applier.matches?({}, OpenTelemetry::SDK::Resources::Resource.create) - assert rule_applier.matches?(attributes, OpenTelemetry::SDK::Resources::Resource.create({})) - assert rule_applier.matches?({}, OpenTelemetry::SDK::Resources::Resource.create({})) - end - - it 'test_applier_matches_with_http_url_with_http_target_undefined' do - rule_applier = OpenTelemetry::Sampler::XRay::SamplingRuleApplier.new( - OpenTelemetry::Sampler::XRay::SamplingRule.new({ - 'Attributes' => {}, - 'FixedRate' => 0.11, - 'HTTPMethod' => '*', - 'Host' => '*', - 'Priority' => 20, - 'ReservoirSize' => 1, - 'ResourceARN' => '*', - 'RuleARN' => 'arn:aws:xray:us-east-1:999999999999:sampling-rule/test', - 'RuleName' => 'test', - 'ServiceName' => '*', - 'ServiceType' => '*', - 'URLPath' => '/somerandompath', - 'Version' => 1 - }) - ) - - attributes = { - 'http.url' => 'https://somerandomurl.com/somerandompath' - } - resource = OpenTelemetry::SDK::Resources::Resource.create({}) - - assert rule_applier.matches?(attributes, resource) - assert rule_applier.matches?(attributes, OpenTelemetry::SDK::Resources::Resource.create) - assert rule_applier.matches?(attributes, OpenTelemetry::SDK::Resources::Resource.create({})) - end end diff --git a/sampler/xray/test/utils_test.rb b/sampler/xray/test/utils_test.rb index fc95dbe0b1..fdcf29952b 100644 --- a/sampler/xray/test/utils_test.rb +++ b/sampler/xray/test/utils_test.rb @@ -99,9 +99,9 @@ it 'test_attribute_match_with_undefined_attributes' do rule_attributes = { 'string' => 'string', 'string2' => 'string2' } - refute OpenTelemetry::Sampler::XRay::Utils.attribute_match?(nil, rule_attributes) - refute OpenTelemetry::Sampler::XRay::Utils.attribute_match?({}, rule_attributes) - refute OpenTelemetry::Sampler::XRay::Utils.attribute_match?({ 'string' => 'string' }, rule_attributes) + refute OpenTelemetry::Sampler::XRay::Utils.attribute_match(nil, rule_attributes) + refute OpenTelemetry::Sampler::XRay::Utils.attribute_match({}, rule_attributes) + refute OpenTelemetry::Sampler::XRay::Utils.attribute_match({ 'string' => 'string' }, rule_attributes) end it 'test_attribute_match_with_undefined_rule_attributes' do @@ -111,19 +111,19 @@ 'undefined' => nil, 'boolean' => true } - assert OpenTelemetry::Sampler::XRay::Utils.attribute_match?(attr, nil) + assert OpenTelemetry::Sampler::XRay::Utils.attribute_match(attr, nil) end it 'test_attribute_match_successful_match' do attr = { 'language' => 'english' } rule_attribute = { 'language' => 'en*sh' } - assert OpenTelemetry::Sampler::XRay::Utils.attribute_match?(attr, rule_attribute) + assert OpenTelemetry::Sampler::XRay::Utils.attribute_match(attr, rule_attribute) end it 'test_attribute_match_failed_match' do attr = { 'language' => 'french' } rule_attribute = { 'language' => 'en*sh' } - refute OpenTelemetry::Sampler::XRay::Utils.attribute_match?(attr, rule_attribute) + refute OpenTelemetry::Sampler::XRay::Utils.attribute_match(attr, rule_attribute) end it 'test_attribute_match_extra_attributes_success' do @@ -134,7 +134,7 @@ 'boolean' => true } rule_attribute = { 'string' => 'string' } - assert OpenTelemetry::Sampler::XRay::Utils.attribute_match?(attr, rule_attribute) + assert OpenTelemetry::Sampler::XRay::Utils.attribute_match(attr, rule_attribute) end it 'test_attribute_match_extra_attributes_failure' do @@ -145,6 +145,6 @@ 'boolean' => true } rule_attribute = { 'string' => 'string', 'number' => '1' } - refute OpenTelemetry::Sampler::XRay::Utils.attribute_match?(attr, rule_attribute) + refute OpenTelemetry::Sampler::XRay::Utils.attribute_match(attr, rule_attribute) end end