-
Notifications
You must be signed in to change notification settings - Fork 248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Net:HTTP
instrumentation adapter
#187
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
AllCops: | ||
TargetRubyVersion: '2.4.0' | ||
|
||
Bundler/OrderedGems: | ||
Exclude: | ||
- gemfiles/**/* | ||
Lint/UnusedMethodArgument: | ||
Enabled: false | ||
Metrics/AbcSize: | ||
Max: 18 | ||
Metrics/LineLength: | ||
Enabled: false | ||
Metrics/MethodLength: | ||
Max: 20 | ||
Metrics/ParameterLists: | ||
Enabled: false | ||
Naming/FileName: | ||
Exclude: | ||
- "lib/opentelemetry-adapters-net-http.rb" | ||
Style/FrozenStringLiteralComment: | ||
Exclude: | ||
- gemfiles/**/* | ||
Style/ModuleFunction: | ||
Enabled: false | ||
Style/StringLiterals: | ||
Exclude: | ||
- gemfiles/**/* |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright 2020 OpenTelemetry Authors | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
source 'https://rubygems.org' | ||
|
||
gemspec | ||
|
||
gem 'opentelemetry-api', path: '../../api' | ||
|
||
group :test do | ||
gem 'opentelemetry-sdk', path: '../../sdk' | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright 2020 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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
source 'https://rubygems.org' | ||
|
||
gem 'opentelemetry-adapters-net-http', path: '../../../adapters/net_http' | ||
gem 'opentelemetry-api', path: '../../../api' | ||
gem 'opentelemetry-sdk', path: '../../../sdk' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rubygems' | ||
require 'bundler/setup' | ||
require 'net/http' | ||
|
||
Bundler.require | ||
|
||
OpenTelemetry::SDK.configure do |c| | ||
c.use 'OpenTelemetry::Adapters::Net::HTTP' | ||
end | ||
|
||
Net::HTTP.get(URI('http://example.com')) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright 2020 OpenTelemetry Authors | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
require_relative './opentelemetry/adapters' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright 2020 OpenTelemetry Authors | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
module OpenTelemetry | ||
# "Instrumentation adapters" are specified by | ||
# https://github.com/open-telemetry/opentelemetry-specification/blob/57714f7547fe4dcb342ad0ad10a80d86118431c7/specification/overview.md#instrumentation-adapters | ||
# | ||
# Adapters should be able to handle the case when the library is not installed on a user's system. | ||
module Adapters | ||
end | ||
end | ||
|
||
require_relative './adapters/net/http' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright 2020 OpenTelemetry Authors | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
require 'opentelemetry' | ||
|
||
module OpenTelemetry | ||
module Adapters | ||
module Net | ||
# Contains the OpenTelemetry adapter for the Net::HTTP gem | ||
module HTTP | ||
end | ||
end | ||
end | ||
end | ||
|
||
require_relative './http/adapter' | ||
require_relative './http/version' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright 2020 OpenTelemetry Authors | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
module OpenTelemetry | ||
module Adapters | ||
module Net | ||
module HTTP | ||
# The Adapter class contains logic to detect and install the Net::HTTP | ||
# instrumentation adapter | ||
class Adapter < OpenTelemetry::Instrumentation::Adapter | ||
install do |_config| | ||
require_dependencies | ||
patch | ||
end | ||
|
||
present do | ||
defined?(::Net::HTTP) | ||
end | ||
|
||
private | ||
|
||
def require_dependencies | ||
require_relative 'patches/instrumentation' | ||
end | ||
|
||
def patch | ||
::Net::HTTP.prepend(Patches::Instrumentation) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright 2020 OpenTelemetry Authors | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
module OpenTelemetry | ||
module Adapters | ||
module Net | ||
module HTTP | ||
module Patches | ||
# Module to prepend to Net::HTTP for instrumentation | ||
module Instrumentation | ||
HTTP_METHODS_TO_SPAN_NAMES = Hash.new { |h, k| h[k] = "HTTP #{k}" } | ||
USE_SSL_TO_SCHEME = { false => 'http', true => 'https' }.freeze | ||
|
||
def request(req, body = nil, &block) | ||
# Do not trace recursive call for starting the connection | ||
return super(req, body, &block) unless started? | ||
|
||
tracer.in_span( | ||
HTTP_METHODS_TO_SPAN_NAMES[req.method], | ||
attributes: { | ||
'component' => 'http', | ||
'http.method' => req.method, | ||
'http.scheme' => USE_SSL_TO_SCHEME[use_ssl?], | ||
'http.target' => req.path, | ||
'peer.hostname' => @address, | ||
'peer.port' => @port | ||
}, | ||
kind: :client | ||
) do |span| | ||
OpenTelemetry.propagation.inject(req) | ||
|
||
super(req, body, &block).tap do |response| | ||
annotate_span_with_response!(span, response) | ||
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def annotate_span_with_response!(span, response) | ||
return unless response&.code | ||
|
||
status_code = response.code.to_i | ||
|
||
span.set_attribute('http.status_code', status_code) | ||
span.status = OpenTelemetry::Trace::Status.http_to_status( | ||
status_code | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have any semantic conventions around identifying errors based on response codes? Or are we only flagging spans as errors if an exception is raised? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are not semantic conventions for errors at all yet. Our There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
end | ||
|
||
def tracer | ||
Net::HTTP::Adapter.instance.tracer | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright 2020 OpenTelemetry Authors | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
module OpenTelemetry | ||
module Adapters | ||
module Net | ||
module HTTP | ||
VERSION = '0.0.0' | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright 2020 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/adapters/net/http/version' | ||
|
||
Gem::Specification.new do |spec| | ||
spec.name = 'opentelemetry-adapters-net-http' | ||
spec.version = OpenTelemetry::Adapters::Net::HTTP::VERSION | ||
spec.authors = ['OpenTelemetry Authors'] | ||
spec.email = ['[email protected]'] | ||
|
||
spec.summary = 'Net::HTTP instrumentation adapter for the OpenTelemetry framework' | ||
spec.description = 'Net::HTTP instrumentation adapter for the OpenTelemetry framework' | ||
spec.homepage = 'https://github.com/open-telemetry/opentelemetry-ruby' | ||
spec.license = 'Apache-2.0' | ||
|
||
spec.files = ::Dir.glob('lib/**/*.rb') + | ||
::Dir.glob('*.md') + | ||
['LICENSE'] | ||
spec.require_paths = ['lib'] | ||
spec.required_ruby_version = '>= 2.4.0' | ||
|
||
spec.add_dependency 'opentelemetry-api', '~> 0.0' | ||
|
||
spec.add_development_dependency 'bundler', '>= 1.17' | ||
spec.add_development_dependency 'minitest', '~> 5.0' | ||
spec.add_development_dependency 'opentelemetry-sdk', '~> 0.0' | ||
spec.add_development_dependency 'rake', '~> 13.0.1' | ||
spec.add_development_dependency 'rubocop', '~> 0.73.0' | ||
spec.add_development_dependency 'simplecov', '~> 0.17.1' | ||
spec.add_development_dependency 'webmock', '~> 3.7.6' | ||
spec.add_development_dependency 'yard', '~> 0.9' | ||
spec.add_development_dependency 'yard-doctest', '~> 0.1.6' | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
inherit_from: ../.rubocop.yml | ||
|
||
Metrics/BlockLength: | ||
Enabled: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little concerned about the lazy initialization here. I'd prefer to eagerly init this and freeze the hash. I'm sort of on the fence, so just flagging the concern.