Skip to content

Commit ca200a9

Browse files
committed
feat: WIP semcon file re-structure
1 parent 51f6328 commit ca200a9

File tree

15 files changed

+935
-118
lines changed

15 files changed

+935
-118
lines changed

instrumentation/http/lib/opentelemetry/instrumentation/http/instrumentation.rb

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ module HTTP
1010
# The Instrumentation class contains logic to detect and install the Http instrumentation
1111
class Instrumentation < OpenTelemetry::Instrumentation::Base
1212
install do |_config|
13-
require_dependencies
14-
patch
13+
patch_type = determine_semconv
14+
send(:"require_dependencies_#{patch_type}")
15+
send(:"patch_#{patch_type}")
1516
end
1617

1718
present do
@@ -20,16 +21,47 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base
2021

2122
option :span_name_formatter, default: nil, validate: :callable
2223

23-
def patch
24-
::HTTP::Client.prepend(Patches::Client)
25-
::HTTP::Connection.prepend(Patches::Connection)
24+
def determine_semconv
25+
case ENV.fetch('OTEL_SEMCONV_STABILITY_OPT_IN', nil)
26+
when 'http/dup'
27+
'dup'
28+
when 'http'
29+
'stable'
30+
else
31+
'old'
32+
end
2633
end
2734

28-
def require_dependencies
29-
require_relative 'patches/client'
30-
require_relative 'patches/connection'
35+
def patch_old
36+
::HTTP::Client.prepend(Patches::Old::Client)
37+
::HTTP::Connection.prepend(Patches::Old::Connection)
38+
end
39+
40+
def patch_dup
41+
::HTTP::Client.prepend(Patches::Dup::Client)
42+
::HTTP::Connection.prepend(Patches::Dup::Connection)
43+
end
44+
45+
def patch_stable
46+
::HTTP::Client.prepend(Patches::Stable::Client)
47+
::HTTP::Connection.prepend(Patches::Stable::Connection)
48+
end
49+
50+
def require_dependencies_dup
51+
require_relative 'patches/dup/client'
52+
require_relative 'patches/dup/connection'
53+
end
54+
55+
def require_dependencies_old
56+
require_relative 'patches/old/client'
57+
require_relative 'patches/old/connection'
58+
end
59+
60+
def require_dependencies_stable
61+
require_relative 'patches/stable/client'
62+
require_relative 'patches/stable/connection'
3163
end
3264
end
3365
end
3466
end
35-
end
67+
end

instrumentation/http/lib/opentelemetry/instrumentation/http/patches/client.rb

Lines changed: 0 additions & 70 deletions
This file was deleted.

instrumentation/http/lib/opentelemetry/instrumentation/http/patches/connection.rb

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright The OpenTelemetry Authors
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
module OpenTelemetry
8+
module Instrumentation
9+
module HTTP
10+
module Patches
11+
# Module using old and stable HTTP semantic conventions
12+
module Dup
13+
# Module to prepend to HTTP::Client for instrumentation
14+
module Client
15+
# Constant for the HTTP status range
16+
HTTP_STATUS_SUCCESS_RANGE = (100..399)
17+
18+
def perform(req, options)
19+
uri = req.uri
20+
request_method = req.verb.to_s.upcase
21+
span_name = create_request_span_name(request_method, uri.path)
22+
23+
attributes = {
24+
# old semconv
25+
'http.method' => request_method,
26+
'http.scheme' => uri.scheme,
27+
'http.target' => uri.path,
28+
'http.url' => "#{uri.scheme}://#{uri.host}",
29+
'net.peer.name' => uri.host,
30+
'net.peer.port' => uri.port,
31+
# stable semconv
32+
'http.request.method' => request_method,
33+
'url.scheme' => uri.scheme,
34+
'url.path' => uri.path,
35+
'url.full' => "#{uri.scheme}://#{uri.host}",
36+
'server.address' => uri.host,
37+
'server.port' => uri.port
38+
}
39+
attributes['url.query'] = uri.query unless uri.query.nil?
40+
attributes.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes)
41+
42+
tracer.in_span(span_name, attributes: attributes, kind: :client) do |span|
43+
OpenTelemetry.propagation.inject(req.headers)
44+
super.tap do |response|
45+
annotate_span_with_response!(span, response)
46+
end
47+
end
48+
end
49+
50+
private
51+
52+
def config
53+
OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance.config
54+
end
55+
56+
def annotate_span_with_response!(span, response)
57+
return unless response&.status
58+
59+
status_code = response.status.to_i
60+
span.set_attribute('http.status_code', status_code) #old semconv
61+
span.set_attribute('http.response.status_code', status_code) #stable semconv
62+
span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status_code)
63+
end
64+
65+
def create_request_span_name(request_method, request_path)
66+
if (implementation = config[:span_name_formatter])
67+
updated_span_name = implementation.call(request_method, request_path)
68+
updated_span_name.is_a?(String) ? updated_span_name : "HTTP #{request_method}"
69+
else
70+
"HTTP #{request_method}"
71+
end
72+
rescue StandardError
73+
"HTTP #{request_method}"
74+
end
75+
76+
def tracer
77+
HTTP::Instrumentation.instance.tracer
78+
end
79+
end
80+
end
81+
end
82+
end
83+
end
84+
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright The OpenTelemetry Authors
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
module OpenTelemetry
8+
module Instrumentation
9+
module HTTP
10+
module Patches
11+
# Module using old and stable HTTP semantic conventions
12+
module Dup
13+
# Module to prepend to HTTP::Connection for instrumentation
14+
module Connection
15+
def initialize(req, options)
16+
attributes = {
17+
# old semconv
18+
'net.peer.name' => req.uri.host,
19+
'net.peer.port' => req.uri.port,
20+
# stable semconv
21+
'server.address' => req.uri.host,
22+
'server.port' => req.uri.port
23+
}.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes)
24+
25+
tracer.in_span('HTTP CONNECT', attributes: attributes) do
26+
super
27+
end
28+
end
29+
30+
private
31+
32+
def tracer
33+
HTTP::Instrumentation.instance.tracer
34+
end
35+
end
36+
end
37+
end
38+
end
39+
end
40+
end
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright The OpenTelemetry Authors
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
module OpenTelemetry
8+
module Instrumentation
9+
module HTTP
10+
module Patches
11+
# Module using old HTTP semantic conventions
12+
module Old
13+
# Module to prepend to HTTP::Client for instrumentation
14+
module Client
15+
# Constant for the HTTP status range
16+
HTTP_STATUS_SUCCESS_RANGE = (100..399)
17+
18+
def perform(req, options)
19+
uri = req.uri
20+
request_method = req.verb.to_s.upcase
21+
span_name = create_request_span_name(request_method, uri.path)
22+
23+
attributes = {
24+
'http.method' => request_method,
25+
'http.scheme' => uri.scheme,
26+
'http.target' => uri.path,
27+
'http.url' => "#{uri.scheme}://#{uri.host}",
28+
'net.peer.name' => uri.host,
29+
'net.peer.port' => uri.port
30+
}.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes)
31+
32+
tracer.in_span(span_name, attributes: attributes, kind: :client) do |span|
33+
OpenTelemetry.propagation.inject(req.headers)
34+
super.tap do |response|
35+
annotate_span_with_response!(span, response)
36+
end
37+
end
38+
end
39+
40+
private
41+
42+
def config
43+
OpenTelemetry::Instrumentation::HTTP::Instrumentation.instance.config
44+
end
45+
46+
def annotate_span_with_response!(span, response)
47+
return unless response&.status
48+
49+
status_code = response.status.to_i
50+
span.set_attribute('http.status_code', status_code)
51+
span.status = OpenTelemetry::Trace::Status.error unless HTTP_STATUS_SUCCESS_RANGE.cover?(status_code)
52+
end
53+
54+
def create_request_span_name(request_method, request_path)
55+
if (implementation = config[:span_name_formatter])
56+
updated_span_name = implementation.call(request_method, request_path)
57+
updated_span_name.is_a?(String) ? updated_span_name : "HTTP #{request_method}"
58+
else
59+
"HTTP #{request_method}"
60+
end
61+
rescue StandardError
62+
"HTTP #{request_method}"
63+
end
64+
65+
def tracer
66+
HTTP::Instrumentation.instance.tracer
67+
end
68+
end
69+
end
70+
end
71+
end
72+
end
73+
end

0 commit comments

Comments
 (0)