From 9fcf6d858b4c6e4905c24677ca84ed3391913502 Mon Sep 17 00:00:00 2001 From: Tiago Date: Sun, 5 Nov 2023 15:13:16 +0000 Subject: [PATCH 1/7] added httpx opentelemetry adapter (#681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added httpx opentelemetry adapter * Update instrumentation/httpx/CHANGELOG.md Co-authored-by: Ariel Valentin * Update instrumentation/httpx/README.md Co-authored-by: Ariel Valentin * Update instrumentation/httpx/README.md Co-authored-by: Ariel Valentin --------- Co-authored-by: Ariel Valentin Co-authored-by: Josef Šimánek --- .../workflows/ci-instrumentation-canary.yml | 1 + .github/workflows/ci-instrumentation.yml | 1 + .toys/.data/releases.yml | 4 + instrumentation/httpx/.yardopts | 9 + instrumentation/httpx/Appraisals | 13 ++ instrumentation/httpx/CHANGELOG.md | 0 instrumentation/httpx/Gemfile | 14 ++ instrumentation/httpx/LICENSE | 201 ++++++++++++++++++ instrumentation/httpx/README.md | 49 +++++ instrumentation/httpx/Rakefile | 28 +++ .../httpx/example/trace_demonstration.rb | 27 +++ .../opentelemetry-instrumentation-httpx.rb | 7 + .../lib/opentelemetry/instrumentation.rb | 19 ++ .../opentelemetry/instrumentation/httpx.rb | 19 ++ .../instrumentation/httpx/instrumentation.rb | 40 ++++ .../instrumentation/httpx/plugin.rb | 92 ++++++++ .../instrumentation/httpx/version.rb | 13 ++ ...pentelemetry-instrumentation-httpx.gemspec | 50 +++++ .../httpx/instrumentation_test.rb | 28 +++ .../httpx/test/instrumentation/plugin_test.rb | 139 ++++++++++++ instrumentation/httpx/test/test_helper.rb | 22 ++ 21 files changed, 776 insertions(+) create mode 100644 instrumentation/httpx/.yardopts create mode 100644 instrumentation/httpx/Appraisals create mode 100644 instrumentation/httpx/CHANGELOG.md create mode 100644 instrumentation/httpx/Gemfile create mode 100644 instrumentation/httpx/LICENSE create mode 100644 instrumentation/httpx/README.md create mode 100644 instrumentation/httpx/Rakefile create mode 100644 instrumentation/httpx/example/trace_demonstration.rb create mode 100644 instrumentation/httpx/lib/opentelemetry-instrumentation-httpx.rb create mode 100644 instrumentation/httpx/lib/opentelemetry/instrumentation.rb create mode 100644 instrumentation/httpx/lib/opentelemetry/instrumentation/httpx.rb create mode 100644 instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/instrumentation.rb create mode 100644 instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/plugin.rb create mode 100644 instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb create mode 100644 instrumentation/httpx/opentelemetry-instrumentation-httpx.gemspec create mode 100644 instrumentation/httpx/test/instrumentation/httpx/instrumentation_test.rb create mode 100644 instrumentation/httpx/test/instrumentation/plugin_test.rb create mode 100644 instrumentation/httpx/test/test_helper.rb diff --git a/.github/workflows/ci-instrumentation-canary.yml b/.github/workflows/ci-instrumentation-canary.yml index 4dd45a722..ae32dd9bb 100644 --- a/.github/workflows/ci-instrumentation-canary.yml +++ b/.github/workflows/ci-instrumentation-canary.yml @@ -33,6 +33,7 @@ jobs: - koala - lmdb - net_http + - httpx - rack - rails - restclient diff --git a/.github/workflows/ci-instrumentation.yml b/.github/workflows/ci-instrumentation.yml index b5bacdeb2..d06fe5d5b 100644 --- a/.github/workflows/ci-instrumentation.yml +++ b/.github/workflows/ci-instrumentation.yml @@ -34,6 +34,7 @@ jobs: - gruf - http - http_client + - httpx - koala - lmdb - net_http diff --git a/.toys/.data/releases.yml b/.toys/.data/releases.yml index 4cb72bc97..7d689c7a4 100644 --- a/.toys/.data/releases.yml +++ b/.toys/.data/releases.yml @@ -106,6 +106,10 @@ gems: directory: instrumentation/http_client version_constant: [OpenTelemetry, Instrumentation, HttpClient, VERSION] + - name: opentelemetry-instrumentation-httpx + directory: instrumentation/httpx + version_constant: [OpenTelemetry, Instrumentation, HTTPX, VERSION] + - name: opentelemetry-instrumentation-koala directory: instrumentation/koala version_constant: [OpenTelemetry, Instrumentation, Koala, VERSION] diff --git a/instrumentation/httpx/.yardopts b/instrumentation/httpx/.yardopts new file mode 100644 index 000000000..66530b20f --- /dev/null +++ b/instrumentation/httpx/.yardopts @@ -0,0 +1,9 @@ +--no-private +--title=OpenTelemetry HTTPX Instrumentation +--markup=markdown +--main=README.md +./lib/opentelemetry/instrumentation/**/*.rb +./lib/opentelemetry/instrumentation.rb +- +README.md +CHANGELOG.md diff --git a/instrumentation/httpx/Appraisals b/instrumentation/httpx/Appraisals new file mode 100644 index 000000000..6d5b4793c --- /dev/null +++ b/instrumentation/httpx/Appraisals @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +appraise 'httpx-1' do + gem 'httpx', '~> 1.0' +end + +appraise 'httpx-0' do + gem 'httpx', '~> 0.24' +end diff --git a/instrumentation/httpx/CHANGELOG.md b/instrumentation/httpx/CHANGELOG.md new file mode 100644 index 000000000..e69de29bb diff --git a/instrumentation/httpx/Gemfile b/instrumentation/httpx/Gemfile new file mode 100644 index 000000000..8b038cdcb --- /dev/null +++ b/instrumentation/httpx/Gemfile @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +source 'https://rubygems.org' + +gemspec + +group :test do + gem 'opentelemetry-instrumentation-base', path: '../base' + gem 'pry-byebug', platform: 'ruby' +end diff --git a/instrumentation/httpx/LICENSE b/instrumentation/httpx/LICENSE new file mode 100644 index 000000000..1ef7dad2c --- /dev/null +++ b/instrumentation/httpx/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright The OpenTelemetry Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/instrumentation/httpx/README.md b/instrumentation/httpx/README.md new file mode 100644 index 000000000..2053e8ab1 --- /dev/null +++ b/instrumentation/httpx/README.md @@ -0,0 +1,49 @@ +# OpenTelemetry Http Instrumentation + +The HTTPX instrumentation is a community-maintained instrumentation for the [HTTPX][httpx-home] gem. + +## How do I get started? + +Install the gem using: + +``` +gem install opentelemetry-instrumentation-httpx +``` + +Or, if you use [bundler][bundler-home], include `opentelemetry-instrumentation-httpx` in your `Gemfile`. + +## Usage + +To use the instrumentation, call `use` with the name of the instrumentation: + +```ruby +OpenTelemetry::SDK.configure do |c| + c.use 'OpenTelemetry::Instrumentation::HTTPX' +end +``` + +Alternatively, you can also call `use_all` to install all the available instrumentation. + +```ruby +OpenTelemetry::SDK.configure do |c| + c.use_all +end +``` + +## How can I get involved? + +The `opentelemetry-instrumentation-httpx` gem source is [on github][repo-github], along with related gems including `opentelemetry-api` and `opentelemetry-sdk`. + +The OpenTelemetry Ruby gems are maintained by the OpenTelemetry-Ruby special interest group (SIG). You can get involved by joining us in [GitHub Discussions][discussions-url] 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]. + +## License + +The `opentelemetry-instrumentation-httpx` gem is distributed under the Apache 2.0 license. See [LICENSE][license-github] for more information. + +[http-home]: https://gitlab.com/os85/httpx +[bundler-home]: https://bundler.io +[repo-github]: https://github.com/open-telemetry/opentelemetry-ruby +[license-github]: https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/LICENSE +[ruby-sig]: https://github.com/open-telemetry/community#ruby-sig +[community-meetings]: https://github.com/open-telemetry/community#community-meetings +[discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions diff --git a/instrumentation/httpx/Rakefile b/instrumentation/httpx/Rakefile new file mode 100644 index 000000000..1a64ba842 --- /dev/null +++ b/instrumentation/httpx/Rakefile @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'bundler/gem_tasks' +require 'rake/testtask' +require 'yard' +require 'rubocop/rake_task' + +RuboCop::RakeTask.new + +Rake::TestTask.new :test do |t| + t.libs << 'test' + t.libs << 'lib' + t.test_files = FileList['test/**/*_test.rb'] +end + +YARD::Rake::YardocTask.new do |t| + t.stats_options = ['--list-undoc'] +end + +if RUBY_ENGINE == 'truffleruby' + task default: %i[test] +else + task default: %i[test rubocop yard] +end diff --git a/instrumentation/httpx/example/trace_demonstration.rb b/instrumentation/httpx/example/trace_demonstration.rb new file mode 100644 index 000000000..f0afdbf11 --- /dev/null +++ b/instrumentation/httpx/example/trace_demonstration.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'bundler/inline' + +gemfile(true) do + source 'https://rubygems.org' + gem 'opentelemetry-api' + gem 'opentelemetry-instrumentation-base' + gem 'opentelemetry-instrumentation-httpx' + gem 'opentelemetry-sdk' + gem 'httpx' +end + +require 'opentelemetry-api' +require 'opentelemetry-sdk' +require 'opentelemetry-instrumentation-httpx' +require 'httpx' + +# Export traces to console by default +ENV['OTEL_TRACES_EXPORTER'] ||= 'console' + +OpenTelemetry::SDK.configure do |c| + c.use 'OpenTelemetry::Instrumentation::HTTPX' +end + +# A basic HTTP example +HTTPX.get('https://github.com') diff --git a/instrumentation/httpx/lib/opentelemetry-instrumentation-httpx.rb b/instrumentation/httpx/lib/opentelemetry-instrumentation-httpx.rb new file mode 100644 index 000000000..c034f140f --- /dev/null +++ b/instrumentation/httpx/lib/opentelemetry-instrumentation-httpx.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require_relative 'opentelemetry/instrumentation' diff --git a/instrumentation/httpx/lib/opentelemetry/instrumentation.rb b/instrumentation/httpx/lib/opentelemetry/instrumentation.rb new file mode 100644 index 000000000..b9459a853 --- /dev/null +++ b/instrumentation/httpx/lib/opentelemetry/instrumentation.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +# OpenTelemetry is an open source observability framework, providing a +# general-purpose API, SDK, and related tools required for the instrumentation +# of cloud-native software, frameworks, and libraries. +# +# The OpenTelemetry module provides global accessors for telemetry objects. +# See the documentation for the `opentelemetry-api` gem for details. +module OpenTelemetry + # Instrumentation should be able to handle the case when the library is not installed on a user's system. + module Instrumentation + end +end + +require_relative 'instrumentation/httpx' diff --git a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx.rb b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx.rb new file mode 100644 index 000000000..70e00f6cc --- /dev/null +++ b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'opentelemetry' +require 'opentelemetry-instrumentation-base' + +module OpenTelemetry + module Instrumentation + # Contains the OpenTelemetry instrumentation for the Http gem + module HTTPX + end + end +end + +require_relative 'httpx/instrumentation' +require_relative 'httpx/version' diff --git a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/instrumentation.rb b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/instrumentation.rb new file mode 100644 index 000000000..9174343b4 --- /dev/null +++ b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/instrumentation.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module HTTPX + # The Instrumentation class contains logic to detect and install the Http instrumentation + class Instrumentation < OpenTelemetry::Instrumentation::Base + install do |_config| + require_dependencies + patch + end + + compatible do + Gem::Version.new(::HTTPX::VERSION) >= Gem::Version.new('0.24.7') + end + + present do + defined?(::HTTPX) + end + + option :peer_service, default: nil, validate: :string + + def patch + otel_session = ::HTTPX.plugin(Plugin) + + ::HTTPX.send(:remove_const, :Session) + ::HTTPX.send(:const_set, :Session, otel_session.class) + end + + def require_dependencies + require_relative 'plugin' + end + end + end + end +end diff --git a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/plugin.rb b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/plugin.rb new file mode 100644 index 000000000..10738e1ed --- /dev/null +++ b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/plugin.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module HTTPX + module Plugin + # Instruments around HTTPX's request/response lifecycle in order to generate + # an OTEL trace. + class RequestTracer + def initialize(request) + @request = request + end + + def call + @request.on(:response, &method(:finish)) + + uri = @request.uri + request_method = @request.verb + span_name = "HTTP #{request_method}" + + attributes = { + OpenTelemetry::SemanticConventions::Trace::HTTP_HOST => uri.host, + OpenTelemetry::SemanticConventions::Trace::HTTP_METHOD => request_method, + OpenTelemetry::SemanticConventions::Trace::HTTP_SCHEME => uri.scheme, + OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET => uri.path, + OpenTelemetry::SemanticConventions::Trace::HTTP_URL => "#{uri.scheme}://#{uri.host}", + OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => uri.host, + OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => uri.port + } + config = HTTPX::Instrumentation.instance.config + attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] if config[:peer_service] + attributes.merge!( + OpenTelemetry::Common::HTTP::ClientContext.attributes + ) + + @span = tracer.start_span(span_name, attributes: attributes, kind: :client) + trace_ctx = OpenTelemetry::Trace.context_with_span(@span) + @trace_token = OpenTelemetry::Context.attach(trace_ctx) + + OpenTelemetry.propagation.inject(@request.headers) + rescue StandardError => e + OpenTelemetry.handle_error(exception: e) + end + + def finish(response) + return unless @span + + if response.is_a?(::HTTPX::ErrorResponse) + @span.record_exception(response.error) + @span.status = Trace::Status.error("Unhandled exception of type: #{response.error.class}") + else + @span.set_attribute(OpenTelemetry::SemanticConventions::Trace::HTTP_STATUS_CODE, response.status) + @span.status = Trace::Status.error unless (100..399).include?(response.status) + end + + OpenTelemetry::Context.detach(@trace_token) if @trace_token + @span.finish + end + + private + + def tracer + HTTPX::Instrumentation.instance.tracer + end + end + + # HTTPX::Request overrides + module RequestMethods + def __otel_enable_trace! + return if @__otel_enable_trace + + RequestTracer.new(self).call + @__otel_enable_trace = true + end + end + + # HTTPX::Connection overrides + module ConnectionMethods + def send(request) + request.__otel_enable_trace! + + super + end + end + end + end + end +end diff --git a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb new file mode 100644 index 000000000..b05472d1e --- /dev/null +++ b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Instrumentation + module HTTPX + VERSION = '0.1.0' + end + end +end diff --git a/instrumentation/httpx/opentelemetry-instrumentation-httpx.gemspec b/instrumentation/httpx/opentelemetry-instrumentation-httpx.gemspec new file mode 100644 index 000000000..6531619a7 --- /dev/null +++ b/instrumentation/httpx/opentelemetry-instrumentation-httpx.gemspec @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +lib = File.expand_path('lib', __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'opentelemetry/instrumentation/httpx/version' + +Gem::Specification.new do |spec| + spec.name = 'opentelemetry-instrumentation-httpx' + spec.version = OpenTelemetry::Instrumentation::HTTPX::VERSION + spec.authors = ['OpenTelemetry Authors'] + spec.email = ['cncf-opentelemetry-contributors@lists.cncf.io'] + + spec.summary = 'HTTPX instrumentation for the OpenTelemetry framework' + spec.description = 'HTTPX instrumentation for the OpenTelemetry framework' + spec.homepage = 'https://github.com/open-telemetry/opentelemetry-ruby-contrib' + spec.license = 'Apache-2.0' + + spec.files = Dir.glob('lib/**/*.rb') + + Dir.glob('*.md') + + ['LICENSE', '.yardopts'] + spec.require_paths = ['lib'] + spec.required_ruby_version = '>= 3.0' + + spec.add_dependency 'opentelemetry-api', '~> 1.0' + spec.add_dependency 'opentelemetry-instrumentation-base', '~> 0.22.1' + + spec.add_development_dependency 'appraisal', '~> 2.5' + spec.add_development_dependency 'bundler', '~> 2.4' + spec.add_development_dependency 'httpx' + spec.add_development_dependency 'minitest', '~> 5.0' + spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' + spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' + spec.add_development_dependency 'rake', '~> 13.0' + spec.add_development_dependency 'rspec-mocks' + spec.add_development_dependency 'rubocop', '~> 1.56.1' + spec.add_development_dependency 'simplecov', '~> 0.17.1' + spec.add_development_dependency 'webmock', '~> 3.19' + spec.add_development_dependency 'yard', '~> 0.9' + + if spec.respond_to?(:metadata) + spec.metadata['changelog_uri'] = "https://rubydoc.info/gems/#{spec.name}/#{spec.version}/file/CHANGELOG.md" + spec.metadata['source_code_uri'] = 'https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/http' + spec.metadata['bug_tracker_uri'] = 'https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues' + spec.metadata['documentation_uri'] = "https://rubydoc.info/gems/#{spec.name}/#{spec.version}" + end +end diff --git a/instrumentation/httpx/test/instrumentation/httpx/instrumentation_test.rb b/instrumentation/httpx/test/instrumentation/httpx/instrumentation_test.rb new file mode 100644 index 000000000..70dda9013 --- /dev/null +++ b/instrumentation/httpx/test/instrumentation/httpx/instrumentation_test.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +require_relative '../../../lib/opentelemetry/instrumentation/httpx' + +describe OpenTelemetry::Instrumentation::HTTPX do + let(:instrumentation) { OpenTelemetry::Instrumentation::HTTPX::Instrumentation.instance } + + it 'has #name' do + _(instrumentation.name).must_equal 'OpenTelemetry::Instrumentation::HTTPX' + end + + it 'has #version' do + _(instrumentation.version).wont_be_nil + _(instrumentation.version).wont_be_empty + end + + describe '#install' do + it 'accepts argument' do + _(instrumentation.install({})).must_equal(true) + end + end +end diff --git a/instrumentation/httpx/test/instrumentation/plugin_test.rb b/instrumentation/httpx/test/instrumentation/plugin_test.rb new file mode 100644 index 000000000..585e8f50f --- /dev/null +++ b/instrumentation/httpx/test/instrumentation/plugin_test.rb @@ -0,0 +1,139 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +require_relative '../../lib/opentelemetry/instrumentation/httpx' +require_relative '../../lib/opentelemetry/instrumentation/httpx/plugin' + +describe OpenTelemetry::Instrumentation::HTTPX::Plugin do + let(:instrumentation) { OpenTelemetry::Instrumentation::HTTPX::Instrumentation.instance } + let(:exporter) { EXPORTER } + let(:span) { exporter.finished_spans.first } + + before do + exporter.reset + stub_request(:get, 'http://example.com/success').to_return(status: 200) + stub_request(:get, 'http://example.com/failure').to_return(status: 500) + stub_request(:get, 'http://example.com/timeout').to_timeout + end + + # Force re-install of instrumentation + after { instrumentation.instance_variable_set(:@installed, false) } + + describe 'tracing' do + before do + instrumentation.install + end + + it 'before request' do + _(exporter.finished_spans.size).must_equal 0 + end + + it 'after request with success code' do + HTTPX.get('http://example.com/success') + + _(exporter.finished_spans.size).must_equal 1 + _(span.name).must_equal 'HTTP GET' + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.status_code']).must_equal 200 + _(span.attributes['http.scheme']).must_equal 'http' + _(span.attributes['http.host']).must_equal 'example.com' + _(span.attributes['http.target']).must_equal '/success' + 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 + HTTPX.get('http://example.com/failure') + + _(exporter.finished_spans.size).must_equal 1 + _(span.name).must_equal 'HTTP GET' + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.status_code']).must_equal 500 + _(span.attributes['http.scheme']).must_equal 'http' + _(span.attributes['http.host']).must_equal 'example.com' + _(span.attributes['http.target']).must_equal '/failure' + assert_requested( + :get, + 'http://example.com/failure', + headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } + ) + end + + it 'after request timeout' do + response = HTTPX.get('http://example.com/timeout') + assert response.is_a?(HTTPX::ErrorResponse) + assert response.error.is_a?(HTTPX::TimeoutError) + + _(exporter.finished_spans.size).must_equal 1 + _(span.name).must_equal 'HTTP GET' + _(span.attributes['http.method']).must_equal 'GET' + _(span.attributes['http.scheme']).must_equal 'http' + _(span.attributes['http.host']).must_equal 'example.com' + _(span.attributes['http.target']).must_equal '/timeout' + _(span.status.code).must_equal( + OpenTelemetry::Trace::Status::ERROR + ) + _(span.status.description).must_equal( + 'Unhandled exception of type: HTTPX::TimeoutError' + ) + assert_requested( + :get, + 'http://example.com/timeout', + headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } + ) + end + + it 'merges HTTP client context' do + client_context_attrs = { + 'test.attribute' => 'test.value', 'http.method' => 'OVERRIDE' + } + + OpenTelemetry::Common::HTTP::ClientContext.with_attributes(client_context_attrs) do + HTTPX.get('http://example.com/success') + end + + _(exporter.finished_spans.size).must_equal 1 + _(span.name).must_equal 'HTTP GET' + _(span.attributes['http.method']).must_equal 'OVERRIDE' + _(span.attributes['http.status_code']).must_equal 200 + _(span.attributes['http.scheme']).must_equal 'http' + _(span.attributes['http.host']).must_equal 'example.com' + _(span.attributes['http.target']).must_equal '/success' + _(span.attributes['test.attribute']).must_equal 'test.value' + assert_requested( + :get, + 'http://example.com/success', + headers: { 'Traceparent' => "00-#{span.hex_trace_id}-#{span.hex_span_id}-01" } + ) + end + + it 'accepts peer service name from config' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install(peer_service: 'example:httpx') + + HTTPX.get('http://example.com/success') + + _(span.attributes['peer.service']).must_equal 'example:httpx' + end + + it 'prioritizes context attributes over config for peer service name' do + instrumentation.instance_variable_set(:@installed, false) + instrumentation.install(peer_service: 'example:static') + + client_context_attrs = { 'peer.service' => 'example:custom' } + OpenTelemetry::Common::HTTP::ClientContext.with_attributes(client_context_attrs) do + HTTPX.get('http://example.com/success') + end + + _(span.attributes['peer.service']).must_equal 'example:custom' + end + end +end diff --git a/instrumentation/httpx/test/test_helper.rb b/instrumentation/httpx/test/test_helper.rb new file mode 100644 index 000000000..10c09f2da --- /dev/null +++ b/instrumentation/httpx/test/test_helper.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'bundler/setup' +Bundler.require(:default, :development, :test) + +require 'minitest/autorun' +require 'httpx/adapters/webmock' +require 'webmock/minitest' + +# global opentelemetry-sdk setup: +EXPORTER = OpenTelemetry::SDK::Trace::Export::InMemorySpanExporter.new +span_processor = OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(EXPORTER) + +OpenTelemetry::SDK.configure do |c| + c.error_handler = ->(exception:, message:) { raise(exception || message) } + c.logger = Logger.new($stderr, level: ENV.fetch('OTEL_LOG_LEVEL', 'fatal').to_sym) + c.add_span_processor span_processor +end From 09f72945e37815adbd1f5d240f37b7721a51b391 Mon Sep 17 00:00:00 2001 From: Ariel Valentin Date: Sun, 5 Nov 2023 20:14:38 -0600 Subject: [PATCH 2/7] chore: Fix HTTPx attribute and changelog (#711) --- CODEOWNERS | 2 ++ instrumentation/httpx/CHANGELOG.md | 1 + 2 files changed, 3 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index ff2a9eb21..8c2435bb4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -22,6 +22,8 @@ instrumentation/grape/ @muripic @fbogsany @mwear @robertlaurin @dazuma @ericmust instrumentation/graphql/ @swalkinshaw @rmosolgo @fbogsany @mwear @robertlaurin @dazuma @ericmustin @arielvalentin @ahayworth @plantfansam @robbkidd +instrumentation/httpx/ @HoneyryderChuck @fbogsany @mwear @robertlaurin @dazuma @ericmustin @arielvalentin @ahayworth @plantfansam @robbkidd + instrumentation/mongo/ @johnnyshields @fbogsany @mwear @robertlaurin @dazuma @ericmustin @arielvalentin @ahayworth @plantfansam @robbkidd instrumentation/racecar/ @chrisholmes @fbogsany @mwear @robertlaurin @dazuma @ericmustin @arielvalentin @ahayworth @plantfansam @robbkidd diff --git a/instrumentation/httpx/CHANGELOG.md b/instrumentation/httpx/CHANGELOG.md index e69de29bb..47ddf384d 100644 --- a/instrumentation/httpx/CHANGELOG.md +++ b/instrumentation/httpx/CHANGELOG.md @@ -0,0 +1 @@ +# Release History: opentelemetry-instrumentation-httpx From 7e47bcc739012c255c9dafe7ff9440bf3f9c310a Mon Sep 17 00:00:00 2001 From: Ariel Valentin Date: Mon, 6 Nov 2023 20:33:33 -0600 Subject: [PATCH 3/7] chore: Change release restrictions The toys gem checks that all actions are passing before allowing a release request to be opened, however only the CI builds are actually required. This change limits the release request requirements to look specifically for CI builds --- .toys/.data/releases.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.toys/.data/releases.yml b/.toys/.data/releases.yml index 7d689c7a4..30d6cde6c 100644 --- a/.toys/.data/releases.yml +++ b/.toys/.data/releases.yml @@ -6,6 +6,7 @@ repo: open-telemetry/opentelemetry-ruby-contrib main_branch: main # Time in seconds for release scripts to wait for CI to complete. required_checks_timeout: 1200 +required_jobs: "^(ci|CI).*" # Git user attached to commits for release pull requests. git_user_name: Ariel Valentin git_user_email: ariel@arielvalentin.com From 626d9b1f732b66e14a6c8b7b7b0f39b630ee9231 Mon Sep 17 00:00:00 2001 From: Ariel Valentin Date: Mon, 6 Nov 2023 20:51:00 -0600 Subject: [PATCH 4/7] chore: Fix httpx version --- .../httpx/lib/opentelemetry/instrumentation/httpx/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb index b05472d1e..204eefefa 100644 --- a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb +++ b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module HTTPX - VERSION = '0.1.0' + VERSION = '0.0.0' end end end From 7f92d2418c71fc33c6ed49b64114c99eb348b903 Mon Sep 17 00:00:00 2001 From: Ariel Valentin Date: Mon, 6 Nov 2023 21:57:32 -0600 Subject: [PATCH 5/7] chore: bump toys --- .github/workflows/release-hook-on-closed.yml | 2 +- .github/workflows/release-hook-on-push.yml | 2 +- .github/workflows/release-perform.yml | 2 +- .github/workflows/release-request.yml | 2 +- .github/workflows/release-retry.yml | 2 +- .toys/.toys.rb | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release-hook-on-closed.yml b/.github/workflows/release-hook-on-closed.yml index 7b00cdc54..6a80f4146 100644 --- a/.github/workflows/release-hook-on-closed.yml +++ b/.github/workflows/release-hook-on-closed.yml @@ -18,7 +18,7 @@ jobs: - name: Checkout repo uses: actions/checkout@v4 - name: Install Toys - run: "gem install --no-document toys -v 0.15.1" + run: "gem install --no-document toys -v 0.15.3" - name: Process release request env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-hook-on-push.yml b/.github/workflows/release-hook-on-push.yml index 23ed4912c..d3a85043d 100644 --- a/.github/workflows/release-hook-on-push.yml +++ b/.github/workflows/release-hook-on-push.yml @@ -19,7 +19,7 @@ jobs: - name: Checkout repo uses: actions/checkout@v4 - name: Install Toys - run: "gem install --no-document toys -v 0.15.1" + run: "gem install --no-document toys -v 0.15.3" - name: Update open releases env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-perform.yml b/.github/workflows/release-perform.yml index 105ae542c..60ebeaee5 100644 --- a/.github/workflows/release-perform.yml +++ b/.github/workflows/release-perform.yml @@ -28,7 +28,7 @@ jobs: - name: Checkout repo uses: actions/checkout@v4 - name: Install Toys - run: "gem install --no-document toys -v 0.15.1" + run: "gem install --no-document toys -v 0.15.3" - name: Perform release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-request.yml b/.github/workflows/release-request.yml index f0ab20957..00997a9ba 100644 --- a/.github/workflows/release-request.yml +++ b/.github/workflows/release-request.yml @@ -22,7 +22,7 @@ jobs: - name: Checkout repo uses: actions/checkout@v4 - name: Install Toys - run: "gem install --no-document toys -v 0.15.1" + run: "gem install --no-document toys -v 0.15.3" - name: Open release pull request env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-retry.yml b/.github/workflows/release-retry.yml index 7b8d42afe..381987aec 100644 --- a/.github/workflows/release-retry.yml +++ b/.github/workflows/release-retry.yml @@ -25,7 +25,7 @@ jobs: - name: Checkout repo uses: actions/checkout@v4 - name: Install Toys - run: "gem install --no-document toys -v 0.15.1" + run: "gem install --no-document toys -v 0.15.3" - name: Retry release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.toys/.toys.rb b/.toys/.toys.rb index 11f265b72..d723a7a4a 100644 --- a/.toys/.toys.rb +++ b/.toys/.toys.rb @@ -1,7 +1,7 @@ -toys_version! "0.15.1" +toys_version! "0.15.3" load_git remote: "https://github.com/dazuma/toys.git", path: ".toys/release", as: "release", - commit: "toys/v0.15.1", + commit: "toys/v0.15.3", update: 3600 From 7ba26160ec240f27bd763507ab1c3664eeb2107e Mon Sep 17 00:00:00 2001 From: Ariel Valentin Date: Mon, 6 Nov 2023 22:49:17 -0600 Subject: [PATCH 6/7] release: Release opentelemetry-instrumentation-httpx 0.1.0 (initial release) (#713) * release: Release opentelemetry-instrumentation-httpx 0.1.0 (initial release) * Update instrumentation/httpx/CHANGELOG.md --- instrumentation/httpx/CHANGELOG.md | 4 ++++ .../httpx/lib/opentelemetry/instrumentation/httpx/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/instrumentation/httpx/CHANGELOG.md b/instrumentation/httpx/CHANGELOG.md index 47ddf384d..8f13d82f7 100644 --- a/instrumentation/httpx/CHANGELOG.md +++ b/instrumentation/httpx/CHANGELOG.md @@ -1 +1,5 @@ # Release History: opentelemetry-instrumentation-httpx + +### v0.1.0 / 2023-11-06 + +* Initial Release. diff --git a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb index 204eefefa..b05472d1e 100644 --- a/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb +++ b/instrumentation/httpx/lib/opentelemetry/instrumentation/httpx/version.rb @@ -7,7 +7,7 @@ module OpenTelemetry module Instrumentation module HTTPX - VERSION = '0.0.0' + VERSION = '0.1.0' end end end From 3f44472230964017d1831a47ea0661dc92d55909 Mon Sep 17 00:00:00 2001 From: Ariel Valentin Date: Wed, 8 Nov 2023 19:51:51 -0600 Subject: [PATCH 7/7] feat!: Drop Rails 6.0 EOL (#680) * feat!: Drop Rails 6.0 EOL 6.0 is no longer receiving maintenance, security, or feature updates as of 01 Jun 2023 Users who want to continue instrumentating Rails applications should pin to earlier versions of the instrumentation. * squash: Fix test * squash: gem version object instead of string * Update README.md Co-authored-by: Kayla Reopelle (she/her) <87386821+kaylareopelle@users.noreply.github.com> * Update instrumentation/README.md Co-authored-by: Kayla Reopelle (she/her) <87386821+kaylareopelle@users.noreply.github.com> --------- Co-authored-by: Kayla Reopelle (she/her) <87386821+kaylareopelle@users.noreply.github.com> --- README.md | 13 +++++++++++++ instrumentation/README.md | 9 +++++++++ instrumentation/action_pack/Appraisals | 4 ---- .../instrumentation/action_pack/instrumentation.rb | 2 +- ...pentelemetry-instrumentation-action_pack.gemspec | 2 +- .../action_pack/test/test_helpers/app_config.rb | 9 --------- instrumentation/action_view/Appraisals | 4 ---- .../instrumentation/action_view/instrumentation.rb | 2 +- ...pentelemetry-instrumentation-action_view.gemspec | 2 +- instrumentation/active_job/Appraisals | 2 +- .../instrumentation/active_job/instrumentation.rb | 2 +- ...opentelemetry-instrumentation-active_job.gemspec | 2 +- instrumentation/active_record/Appraisals | 4 ---- .../active_record/instrumentation.rb | 9 ++------- ...ntelemetry-instrumentation-active_record.gemspec | 2 +- .../active_record/instrumentation_test.rb | 12 ------------ instrumentation/active_support/Appraisals | 4 ---- .../active_support/instrumentation.rb | 10 ++++++++++ ...telemetry-instrumentation-active_support.gemspec | 2 +- instrumentation/rails/Appraisals | 4 ---- instrumentation/rails/README.md | 4 ++-- .../instrumentation/rails/instrumentation.rb | 4 ++-- .../opentelemetry-instrumentation-rails.gemspec | 2 +- .../test/instrumentation/test_helpers/app_config.rb | 9 --------- 24 files changed, 48 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 67216b2b9..d7de85310 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,19 @@ This repository also contains libraries to aid with interoperablity with vendor OpenTelemetry Ruby follows the [versioning and stability document][otel-versioning] in the OpenTelemetry specification. Notably, we adhere to the outlined version numbering exception, which states that experimental signals may have a `0.x` version number. +### Library Compatability + +This project is managed on a volunteer basis and therefore we have limited capacity to support compatability with unmaintained or EOL libraries. + +We will regularly review the instrumentations to drop compatability for any versions of Ruby or gems that reach EOL or no longer receive regular maintenance. + +Should you need instrumentation for _older_ versions of a library then you must pin to a specific version of the instrumentation that supports it, +however, you will no longer receive any updates for the instrumentation from this repository. + +> When a release series is no longer supported, it's your own responsibility to deal with bugs and security issues. We may provide backports of the fixes and publish them to git, however there will be no new versions released. If you are not comfortable maintaining your own versions, you should upgrade to a supported version. + +Consult instrumentation gem's README file and gemspec for details about library compatability. + ### 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] diff --git a/instrumentation/README.md b/instrumentation/README.md index 1ebae6a59..a20b8b1f9 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -37,6 +37,15 @@ Instrumentation-specific documentation can be found in each subdirectory's `READ You also have the option of installing all of the instrumentation libraries by installing `opentelemetry-instrumentation-all`. See that gem's [README](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/all) for more. +### Maintenance and Version Compatability + +We are a community of volunteers who do our best to provide our users with up to date support for instrumentations, +however we have limited capacity and are unable to support compatability with EOL or unmaintained libraries. + +Should you need to instrument an _older_ version of a library you will have to ensure to pin to an instrumentation version that is compatible with that library. + +Please review the individual instrumentation READMEs for more information about version compatability. + ## How can I get involved? The source for all OpenTelemetry Ruby instrumentation gems is [on github](https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation). diff --git a/instrumentation/action_pack/Appraisals b/instrumentation/action_pack/Appraisals index 895a185d4..018ce75b2 100644 --- a/instrumentation/action_pack/Appraisals +++ b/instrumentation/action_pack/Appraisals @@ -4,10 +4,6 @@ # # SPDX-License-Identifier: Apache-2.0 -appraise 'rails-6.0' do - gem 'rails', '~> 6.0.0' -end - appraise 'rails-6.1' do gem 'rails', '~> 6.1.0' end diff --git a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/instrumentation.rb b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/instrumentation.rb index 52252ff24..4b547a7e9 100644 --- a/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/instrumentation.rb +++ b/instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/instrumentation.rb @@ -9,7 +9,7 @@ module Instrumentation module ActionPack # The Instrumentation class contains logic to detect and install the ActionPack instrumentation class Instrumentation < OpenTelemetry::Instrumentation::Base - MINIMUM_VERSION = Gem::Version.new('6.0.0') + MINIMUM_VERSION = Gem::Version.new('6.1.0') install do |_config| require_railtie diff --git a/instrumentation/action_pack/opentelemetry-instrumentation-action_pack.gemspec b/instrumentation/action_pack/opentelemetry-instrumentation-action_pack.gemspec index f12531d06..2e23f7fef 100644 --- a/instrumentation/action_pack/opentelemetry-instrumentation-action_pack.gemspec +++ b/instrumentation/action_pack/opentelemetry-instrumentation-action_pack.gemspec @@ -34,7 +34,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'rails', '>= 6' + spec.add_development_dependency 'rails', '>= 6.1' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rubocop', '~> 1.56.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' diff --git a/instrumentation/action_pack/test/test_helpers/app_config.rb b/instrumentation/action_pack/test/test_helpers/app_config.rb index b62d198de..8874d61e2 100644 --- a/instrumentation/action_pack/test/test_helpers/app_config.rb +++ b/instrumentation/action_pack/test/test_helpers/app_config.rb @@ -28,8 +28,6 @@ def initialize_app(use_exceptions_app: false, remove_rack_tracer_middleware: fal new_app.config.filter_parameters = [:param_to_be_filtered] case Rails.version - when /^6\.0/ - apply_rails_6_0_configs(new_app) when /^6\.1/ apply_rails_6_1_configs(new_app) when /^7\./ @@ -73,13 +71,6 @@ def add_middlewares(application) ) end - def apply_rails_6_0_configs(application) - # Required in Rails 6 - application.config.hosts << 'example.org' - # Creates a lot of deprecation warnings on subsequent app initializations if not explicitly set. - application.config.action_view.finalize_compiled_template_methods = ActionView::Railtie::NULL_OPTION - end - def apply_rails_6_1_configs(application) # Required in Rails 6 application.config.hosts << 'example.org' diff --git a/instrumentation/action_view/Appraisals b/instrumentation/action_view/Appraisals index 895a185d4..018ce75b2 100644 --- a/instrumentation/action_view/Appraisals +++ b/instrumentation/action_view/Appraisals @@ -4,10 +4,6 @@ # # SPDX-License-Identifier: Apache-2.0 -appraise 'rails-6.0' do - gem 'rails', '~> 6.0.0' -end - appraise 'rails-6.1' do gem 'rails', '~> 6.1.0' end diff --git a/instrumentation/action_view/lib/opentelemetry/instrumentation/action_view/instrumentation.rb b/instrumentation/action_view/lib/opentelemetry/instrumentation/action_view/instrumentation.rb index fe5b74781..9087d4475 100644 --- a/instrumentation/action_view/lib/opentelemetry/instrumentation/action_view/instrumentation.rb +++ b/instrumentation/action_view/lib/opentelemetry/instrumentation/action_view/instrumentation.rb @@ -9,7 +9,7 @@ module Instrumentation module ActionView # The Instrumentation class contains logic to detect and install the ActionView instrumentation class Instrumentation < OpenTelemetry::Instrumentation::Base - MINIMUM_VERSION = Gem::Version.new('6.0.0') + MINIMUM_VERSION = Gem::Version.new('6.1.0') install do |_config| require_dependencies end diff --git a/instrumentation/action_view/opentelemetry-instrumentation-action_view.gemspec b/instrumentation/action_view/opentelemetry-instrumentation-action_view.gemspec index 26502b714..fe22f24db 100644 --- a/instrumentation/action_view/opentelemetry-instrumentation-action_view.gemspec +++ b/instrumentation/action_view/opentelemetry-instrumentation-action_view.gemspec @@ -34,7 +34,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' - spec.add_development_dependency 'rails', '>= 6' + spec.add_development_dependency 'rails', '>= 6.1' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rubocop', '~> 1.56.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' diff --git a/instrumentation/active_job/Appraisals b/instrumentation/active_job/Appraisals index a318df014..05429cd62 100644 --- a/instrumentation/active_job/Appraisals +++ b/instrumentation/active_job/Appraisals @@ -4,7 +4,7 @@ # # SPDX-License-Identifier: Apache-2.0 -%w[6.0.0 6.1.0 7.0.0 7.1.0].each do |version| +%w[6.1.0 7.0.0 7.1.0].each do |version| appraise "activejob-#{version}" do gem 'activejob', "~> #{version}" end diff --git a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/instrumentation.rb b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/instrumentation.rb index 9178e51ce..20f3cac57 100644 --- a/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/instrumentation.rb +++ b/instrumentation/active_job/lib/opentelemetry/instrumentation/active_job/instrumentation.rb @@ -9,7 +9,7 @@ module Instrumentation module ActiveJob # The Instrumentation class contains logic to detect and install the ActiveJob instrumentation class Instrumentation < OpenTelemetry::Instrumentation::Base - MINIMUM_VERSION = Gem::Version.new('6.0.0') + MINIMUM_VERSION = Gem::Version.new('6.1.0') install do |_config| require_dependencies diff --git a/instrumentation/active_job/opentelemetry-instrumentation-active_job.gemspec b/instrumentation/active_job/opentelemetry-instrumentation-active_job.gemspec index 2e0ab8892..0699b8621 100644 --- a/instrumentation/active_job/opentelemetry-instrumentation-active_job.gemspec +++ b/instrumentation/active_job/opentelemetry-instrumentation-active_job.gemspec @@ -28,7 +28,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'opentelemetry-api', '~> 1.0' spec.add_dependency 'opentelemetry-instrumentation-base', '~> 0.22.1' - spec.add_development_dependency 'activejob', '>= 6.0.0' + spec.add_development_dependency 'activejob', '>= 6.1' spec.add_development_dependency 'appraisal', '~> 2.5' spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' diff --git a/instrumentation/active_record/Appraisals b/instrumentation/active_record/Appraisals index 75952e9f4..36f3effee 100644 --- a/instrumentation/active_record/Appraisals +++ b/instrumentation/active_record/Appraisals @@ -4,10 +4,6 @@ # # SPDX-License-Identifier: Apache-2.0 -appraise 'activerecord-6.0' do - gem 'activerecord', '~> 6.0.0' -end - appraise 'activerecord-6.1' do gem 'activerecord', '~> 6.1.0' end diff --git a/instrumentation/active_record/lib/opentelemetry/instrumentation/active_record/instrumentation.rb b/instrumentation/active_record/lib/opentelemetry/instrumentation/active_record/instrumentation.rb index 423d6b3f5..fb8b2f19f 100644 --- a/instrumentation/active_record/lib/opentelemetry/instrumentation/active_record/instrumentation.rb +++ b/instrumentation/active_record/lib/opentelemetry/instrumentation/active_record/instrumentation.rb @@ -9,8 +9,7 @@ module Instrumentation module ActiveRecord # The Instrumentation class contains logic to detect and install the ActiveRecord instrumentation class Instrumentation < OpenTelemetry::Instrumentation::Base - MINIMUM_VERSION = Gem::Version.new('6.0.0') - MAX_MAJOR_VERSION = 7 + MINIMUM_VERSION = Gem::Version.new('6.1.0') install do |_config| require_dependencies @@ -22,11 +21,7 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base end compatible do - # We know that releases after MAX_MAJOR_VERSION are unstable so we - # check the major version number of the gem installed to make sure we - # do not install on a pre-release or full release of the latest - # if it exceeds the MAX_MAJOR_VERSION version. - gem_version >= MINIMUM_VERSION && gem_version.segments[0] <= MAX_MAJOR_VERSION + gem_version >= MINIMUM_VERSION end private diff --git a/instrumentation/active_record/opentelemetry-instrumentation-active_record.gemspec b/instrumentation/active_record/opentelemetry-instrumentation-active_record.gemspec index b9351875f..dcfa69779 100644 --- a/instrumentation/active_record/opentelemetry-instrumentation-active_record.gemspec +++ b/instrumentation/active_record/opentelemetry-instrumentation-active_record.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'opentelemetry-instrumentation-base', '~> 0.22.1' spec.add_dependency 'ruby2_keywords' - spec.add_development_dependency 'activerecord' + spec.add_development_dependency 'activerecord', '>= 6.1' spec.add_development_dependency 'appraisal', '~> 2.5' spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' diff --git a/instrumentation/active_record/test/instrumentation/active_record/instrumentation_test.rb b/instrumentation/active_record/test/instrumentation/active_record/instrumentation_test.rb index 546ac39a9..95848825e 100644 --- a/instrumentation/active_record/test/instrumentation/active_record/instrumentation_test.rb +++ b/instrumentation/active_record/test/instrumentation/active_record/instrumentation_test.rb @@ -28,18 +28,6 @@ end end - it 'when a version above the maximum supported gem version is installed' do - ActiveRecord.stub(:version, Gem::Version.new('8.0.0')) do - _(instrumentation.compatible?).must_equal false - end - end - - it 'it treats pre releases as being equivalent to a full release' do - ActiveRecord.stub(:version, Gem::Version.new('8.0.0.alpha')) do - _(instrumentation.compatible?).must_equal false - end - end - it 'when supported gem version installed' do _(instrumentation.compatible?).must_equal true end diff --git a/instrumentation/active_support/Appraisals b/instrumentation/active_support/Appraisals index aaad18a9c..086c10ee9 100644 --- a/instrumentation/active_support/Appraisals +++ b/instrumentation/active_support/Appraisals @@ -4,10 +4,6 @@ # # SPDX-License-Identifier: Apache-2.0 -appraise 'activesupport-6.0' do - gem 'activesupport', '~> 6.0.0' -end - appraise 'activesupport-6.1' do gem 'activesupport', '~> 6.1.0' end diff --git a/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/instrumentation.rb b/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/instrumentation.rb index f5d91e2d3..d10c3cbac 100644 --- a/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/instrumentation.rb +++ b/instrumentation/active_support/lib/opentelemetry/instrumentation/active_support/instrumentation.rb @@ -9,6 +9,8 @@ module Instrumentation module ActiveSupport # The Instrumentation class contains logic to detect and install the ActiveSupport instrumentation class Instrumentation < OpenTelemetry::Instrumentation::Base + MINIMUM_VERSION = Gem::Version.new('6.1.0') + install do |_config| require_dependencies end @@ -17,8 +19,16 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base defined?(::ActiveSupport) end + compatible do + gem_version >= MINIMUM_VERSION + end + private + def gem_version + ::ActiveSupport.version + end + def require_dependencies require_relative 'span_subscriber' end diff --git a/instrumentation/active_support/opentelemetry-instrumentation-active_support.gemspec b/instrumentation/active_support/opentelemetry-instrumentation-active_support.gemspec index 6b6aaa7d3..f9fdb4027 100644 --- a/instrumentation/active_support/opentelemetry-instrumentation-active_support.gemspec +++ b/instrumentation/active_support/opentelemetry-instrumentation-active_support.gemspec @@ -36,7 +36,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'pry' spec.add_development_dependency 'pry-byebug' - spec.add_development_dependency 'rails', '>= 6' + spec.add_development_dependency 'rails', '>= 6.1' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rubocop', '~> 1.56.1' spec.add_development_dependency 'simplecov', '~> 0.17.1' diff --git a/instrumentation/rails/Appraisals b/instrumentation/rails/Appraisals index 895a185d4..018ce75b2 100644 --- a/instrumentation/rails/Appraisals +++ b/instrumentation/rails/Appraisals @@ -4,10 +4,6 @@ # # SPDX-License-Identifier: Apache-2.0 -appraise 'rails-6.0' do - gem 'rails', '~> 6.0.0' -end - appraise 'rails-6.1' do gem 'rails', '~> 6.1.0' end diff --git a/instrumentation/rails/README.md b/instrumentation/rails/README.md index aec56238f..330db609f 100644 --- a/instrumentation/rails/README.md +++ b/instrumentation/rails/README.md @@ -14,7 +14,7 @@ Or, if you use [bundler][bundler-home], include `opentelemetry-instrumentation-r ### Version Compatibility -EOL versions of Rails are not supported by the latest version of this instrumentation. If you are using an EOL version of Rails and need an earlier version of this instrumentation, then consider installing and pinning the compatible gem version, e.g.: +EOL versions of Rails are not supported by the latest version of this instrumentation. If you are using an EOL version of Rails and need an earlier version of this instrumentation, then consider installing and pinning the compatible gem version, e.g.: ```console gem opentelemetry-instrumentation-rails, "" @@ -23,7 +23,7 @@ gem opentelemetry-instrumentation-rails, "" | Rails Version | Instrumentation Version | | --- | --- | | `5.2` | `= 0.24.1` | -| `6.0` | `~> 0.24.1` | +| `6.0` | `= 0.28.0` | | `6.1` | `~> 0.24` | | `7.x` | `~> 0.24` | diff --git a/instrumentation/rails/lib/opentelemetry/instrumentation/rails/instrumentation.rb b/instrumentation/rails/lib/opentelemetry/instrumentation/rails/instrumentation.rb index c424dc58f..c928c0192 100644 --- a/instrumentation/rails/lib/opentelemetry/instrumentation/rails/instrumentation.rb +++ b/instrumentation/rails/lib/opentelemetry/instrumentation/rails/instrumentation.rb @@ -12,7 +12,7 @@ module Rails # The Instrumentation class contains logic to detect and install the Rails # instrumentation class Instrumentation < OpenTelemetry::Instrumentation::Base - MINIMUM_VERSION = Gem::Version.new('6.0.0') + MINIMUM_VERSION = Gem::Version.new('6.1.0') # This gem requires the instrumentantion gems for the different # components of Rails, as a result it does not have any explicit @@ -24,7 +24,7 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base private def gem_version - ::ActionPack.version + ::Rails.gem_version end end end diff --git a/instrumentation/rails/opentelemetry-instrumentation-rails.gemspec b/instrumentation/rails/opentelemetry-instrumentation-rails.gemspec index c49f43e70..af60bd48f 100644 --- a/instrumentation/rails/opentelemetry-instrumentation-rails.gemspec +++ b/instrumentation/rails/opentelemetry-instrumentation-rails.gemspec @@ -39,7 +39,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1' spec.add_development_dependency 'opentelemetry-test-helpers', '~> 0.3' spec.add_development_dependency 'rack-test', '~> 2.1.0' - spec.add_development_dependency 'rails', '>= 6' + spec.add_development_dependency 'rails', '>= 6.1' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rubocop', '~> 1.56.1' spec.add_development_dependency 'simplecov', '~> 0.22.0' diff --git a/instrumentation/rails/test/instrumentation/test_helpers/app_config.rb b/instrumentation/rails/test/instrumentation/test_helpers/app_config.rb index 1bb3fe564..3e8c23ee1 100644 --- a/instrumentation/rails/test/instrumentation/test_helpers/app_config.rb +++ b/instrumentation/rails/test/instrumentation/test_helpers/app_config.rb @@ -26,8 +26,6 @@ def initialize_app(use_exceptions_app: false, remove_rack_tracer_middleware: fal new_app.config.log_level = level case Rails.version - when /^6\.0/ - apply_rails_6_0_configs(new_app) when /^6\.1/ apply_rails_6_1_configs(new_app) when /^7\./ @@ -71,13 +69,6 @@ def add_middlewares(application) ) end - def apply_rails_6_0_configs(application) - # Required in Rails 6 - application.config.hosts << 'example.org' - # Creates a lot of deprecation warnings on subsequent app initializations if not explicitly set. - application.config.action_view.finalize_compiled_template_methods = ActionView::Railtie::NULL_OPTION - end - def apply_rails_6_1_configs(application) # Required in Rails 6 application.config.hosts << 'example.org'