aspecto-opentelemetry 0.1.3 → 0.1.7.rc0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -8
- data/lib/aspecto/opentelemetry/config/remote_config.rb +29 -15
- data/lib/aspecto/opentelemetry/configurator.rb +19 -2
- data/lib/aspecto/opentelemetry/propagator/aspecto.rb +30 -0
- data/lib/aspecto/opentelemetry/version.rb +1 -1
- data/lib/aspecto/opentelemetry.rb +15 -1
- metadata +22 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96878fe3288dcffacdf45867d12864608617b5b18a5b108b6a3a765f6fba667d
|
4
|
+
data.tar.gz: 20cacce2828f81bc7a2d828d041dcb14eb05b085a2b888cd3b8b6a04d2eb5463
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01045ec39c7a9375f4fb0c7503ca48ac3b6110005e53b747986af05633aa1b57a8568ddecad9a129b68d832255fa787354536ea1be14577fd394dca48cdcc99e
|
7
|
+
data.tar.gz: 670c6c00d5bfcceccb1784ed960fbf9c0a6103a6b308a7271eaefd2a5dba73e0cec00f0504ea003868e5c3e83b399dd52b6ac01f944f5f47dff7b919bb27f890
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Aspecto::OpenTelemetry
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/aspecto-opentelemetry.svg)](https://badge.fury.io/rb/aspecto-opentelemetry)
|
4
|
+
|
3
5
|
Aspecto's SDK for ruby.
|
4
6
|
This gem is a distribution of OpenTelemetry pre-configured to use all available instrumentations and export trace data to Aspecto.
|
5
7
|
|
@@ -97,14 +99,20 @@ The only required config options are [`aspecto_auth`](https://app.aspecto.io/app
|
|
97
99
|
|
98
100
|
### Configuration Options
|
99
101
|
|
100
|
-
| Option Name | Environment Variable
|
101
|
-
| ------------------------------------ |
|
102
|
-
| `aspecto_auth` | `ASPECTO_AUTH`
|
103
|
-
| `service_name` | `OTEL_SERVICE_NAME`
|
104
|
-
| `env` | `ASPECTO_ENV`
|
105
|
-
| `log_level` | `OTEL_LOG_LEVEL`
|
106
|
-
| `sampling_ratio` | `ASPECTO_SAMPLING_RATIO`
|
107
|
-
| `otel_exporter_otlp_traces_endpoint` | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`
|
102
|
+
| Option Name | Environment Variable | Type | Default | Description |
|
103
|
+
| ------------------------------------ | ----------------------------------------- | ----------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
104
|
+
| `aspecto_auth` | `ASPECTO_AUTH` | UUID string | - | Aspecto's [API key for authentication](https://app.aspecto.io/app/integration/api-key) |
|
105
|
+
| `service_name` | `OTEL_SERVICE_NAME` | string | - | name of the service which is sending telemetry |
|
106
|
+
| `env` | `ASPECTO_ENV` | string | extracted from rails or sinatra if used | deployment environment: `production` / `staging` / `development`, etc. |
|
107
|
+
| `log_level` | `OTEL_LOG_LEVEL` | string | `ERROR` | `ERROR` / `WARN` / `INFO`, etc. |
|
108
|
+
| `sampling_ratio` | `ASPECTO_SAMPLING_RATIO` | float | 1.0 | How many of the traces starting in this service should be sampled. set to number in range [0.0, 1.0] where 0.0 is no sampling, and 1.0 is sample all |
|
109
|
+
| `otel_exporter_otlp_traces_endpoint` | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | URL | "https://otelcol.aspecto.io/v1/trace" | Url |
|
110
|
+
| `require_config_for_traces` | `ASPECTO_REQUIRE_CONFIG_FOR_TRACES` | boolean | False | When `True`, the SDK will not trace anything until remote sampling configuration arrives (few hundreds ms). Can be used to enforce sampling configuration is always applied, with the cost of losing traces generated during service startup. |
|
111
|
+
| `extract_b3_context` | `ASPECTO_EXTRACT_B3_CONTEXT` | boolean | False | set to `True` when the service receives requests from another instrumented component that propagate context via B3 protocol multi or single header. for example: envoy proxy, ambassador and istio |
|
112
|
+
| `inject_b3_context_single_header` | `ASPECTO_INJECT_B3_CONTEXT_SINGLE_HEADER` | boolean | False | should be `True` when the service send traffic to another instrumented component that propagate context via B3 **single header** protocol |
|
113
|
+
| `inject_b3_context_multi_header` | `ASPECTO_INJECT_B3_CONTEXT_MULTI_HEADER` | boolean | False | should be `True` when the service send traffic to another instrumented component that propagate context via B3 **multi header** protocol. for example: envoy proxy, istio |
|
114
|
+
|
115
|
+
| |
|
108
116
|
|
109
117
|
## Contributing
|
110
118
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "faraday"
|
4
|
-
require "faraday_middleware"
|
5
3
|
require "rufus/scheduler"
|
4
|
+
require "net/http"
|
5
|
+
require "json"
|
6
6
|
|
7
7
|
require_relative "../sampler/rules_sampler"
|
8
8
|
require_relative "../sampler/message_process_sampler"
|
@@ -17,12 +17,9 @@ module Aspecto
|
|
17
17
|
@service_name = service_name
|
18
18
|
@env = env
|
19
19
|
@fallback_sampler = fallback_sampler
|
20
|
-
|
21
|
-
aspecto_config_url =
|
22
|
-
|
23
|
-
f.response :json # decode response bodies as JSON
|
24
|
-
end
|
25
|
-
@http_client.options.timeout = 10
|
20
|
+
aspecto_config_host = ENV.fetch("ASPECTO_CONFIG_HOST", "https://config.aspecto.io")
|
21
|
+
@aspecto_config_url = URI("#{aspecto_config_host}/config/#{aspecto_auth}")
|
22
|
+
init_http_client
|
26
23
|
|
27
24
|
@scheduler = Rufus::Scheduler.new
|
28
25
|
@remote_config_poll_frequency = ENV.fetch("ASPECTO_REMOTE_CONFIG_POLL_FREQUENCY", "30s")
|
@@ -39,19 +36,36 @@ module Aspecto
|
|
39
36
|
|
40
37
|
private
|
41
38
|
|
39
|
+
def init_http_client
|
40
|
+
write_timeout_supported = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.6")
|
41
|
+
|
42
|
+
@http_client = Net::HTTP.new(@aspecto_config_url.host, @aspecto_config_url.port)
|
43
|
+
@http_client.read_timeout = 10
|
44
|
+
@http_client.open_timeout = 10
|
45
|
+
@http_client.write_timeout = 10 if write_timeout_supported
|
46
|
+
@http_client.max_retries = 0
|
47
|
+
|
48
|
+
# use uri.scheme == 'https' instead
|
49
|
+
@http_client.use_ssl = true
|
50
|
+
@http_client.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
51
|
+
end
|
52
|
+
|
42
53
|
def update_config # rubocop:disable Metrics/AbcSize
|
43
54
|
::OpenTelemetry::Common::Utilities.untraced do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
return if response.status == 304
|
55
|
+
request = Net::HTTP::Get.new(@aspecto_config_url.path)
|
56
|
+
request["If-None-Match"] = @latest_config_etag unless @latest_config_etag.nil?
|
57
|
+
response = @http_client.request(request)
|
58
|
+
response_code = response.code.to_i
|
49
59
|
|
50
|
-
if
|
60
|
+
return if response_code == 304
|
61
|
+
|
62
|
+
if response_code >= 400
|
51
63
|
::OpenTelemetry.logger.error("[Aspecto] error when trying to get remote config. will try again in #{@remote_config_poll_frequency}")
|
52
64
|
return
|
53
65
|
end
|
54
|
-
|
66
|
+
|
67
|
+
@latest_config_etag = response["etag"]
|
68
|
+
handle_new_config JSON.parse(response.body) if response_code < 300
|
55
69
|
end
|
56
70
|
rescue StandardError => e
|
57
71
|
::OpenTelemetry.logger.error "[Aspecto] updating remote config failed. using previous remote config"
|
@@ -4,7 +4,9 @@ module Aspecto
|
|
4
4
|
module OpenTelemetry
|
5
5
|
# Aspecto OpenTelemetry Distro Configurator
|
6
6
|
class Configurator
|
7
|
-
|
7
|
+
TRUTHY_VALUES = %w[1 T t true TRUE True].freeze
|
8
|
+
|
9
|
+
def initialize # rubocop:disable Metrics/AbcSize
|
8
10
|
# initialize config options from environment variables.
|
9
11
|
# they can later be overwritten with configurator attribute setters
|
10
12
|
# that have precedence over env
|
@@ -14,6 +16,12 @@ module Aspecto
|
|
14
16
|
self.env = ENV["ASPECTO_ENV"] if ENV["ASPECTO_ENV"]
|
15
17
|
self.sampling_ratio = Float(ENV.fetch("ASPECTO_SAMPLING_RATIO", 1.0))
|
16
18
|
self.otel_exporter_otlp_traces_endpoint = ENV.fetch("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", "https://otelcol.aspecto.io/v1/trace")
|
19
|
+
self.require_config_for_traces = self.class.bool_env_variable "ASPECTO_REQUIRE_CONFIG_FOR_TRACES", false
|
20
|
+
|
21
|
+
# b3 propagattor
|
22
|
+
self.extract_b3_context = self.class.bool_env_variable "ASPECTO_EXTRACT_B3_CONTEXT", false
|
23
|
+
self.inject_b3_context_single_header = self.class.bool_env_variable "ASPECTO_INJECT_B3_CONTEXT_SINGLE_HEADER", false
|
24
|
+
self.inject_b3_context_multi_header = self.class.bool_env_variable "ASPECTO_INJECT_B3_CONTEXT_MULTI_HEADER", false
|
17
25
|
end
|
18
26
|
|
19
27
|
def service_name=(service_name)
|
@@ -24,7 +32,7 @@ module Aspecto
|
|
24
32
|
@override_resource_attributes[::OpenTelemetry::SemanticConventions::Resource::DEPLOYMENT_ENVIRONMENT] = env
|
25
33
|
end
|
26
34
|
|
27
|
-
attr_accessor :sampling_ratio, :log_level, :otel_exporter_otlp_traces_endpoint
|
35
|
+
attr_accessor :sampling_ratio, :log_level, :otel_exporter_otlp_traces_endpoint, :require_config_for_traces, :extract_b3_context, :inject_b3_context_single_header, :inject_b3_context_multi_header
|
28
36
|
attr_reader :aspecto_auth
|
29
37
|
|
30
38
|
def aspecto_auth=(aspecto_auth)
|
@@ -35,6 +43,15 @@ module Aspecto
|
|
35
43
|
def config_override_resource
|
36
44
|
::OpenTelemetry::SDK::Resources::Resource.create(@override_resource_attributes)
|
37
45
|
end
|
46
|
+
|
47
|
+
def self.bool_env_variable(env_variable_name, default_value)
|
48
|
+
env_value = ENV[env_variable_name]
|
49
|
+
if env_value.nil?
|
50
|
+
default_value
|
51
|
+
else
|
52
|
+
TRUTHY_VALUES.include?(env_value.strip)
|
53
|
+
end
|
54
|
+
end
|
38
55
|
end
|
39
56
|
end
|
40
57
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "opentelemetry"
|
4
|
+
require "opentelemetry-propagator-b3"
|
5
|
+
|
6
|
+
module Aspecto
|
7
|
+
module OpenTelemetry
|
8
|
+
module Propagator
|
9
|
+
# Aspecto OpenTelemetry Propagator Configuration
|
10
|
+
module Aspecto
|
11
|
+
extend self
|
12
|
+
|
13
|
+
W3C_PROPAGATOR = ::OpenTelemetry::Trace::Propagation::TraceContext.text_map_propagator
|
14
|
+
B3_SINGLE_PROPAGATOR = ::OpenTelemetry::Propagator::B3::Single.text_map_propagator
|
15
|
+
B3_MULTI_PROPAGATOR = ::OpenTelemetry::Propagator::B3::Multi.text_map_propagator
|
16
|
+
|
17
|
+
def from_configurator(configurator)
|
18
|
+
injectors = [W3C_PROPAGATOR]
|
19
|
+
injectors.push(B3_SINGLE_PROPAGATOR) if configurator.inject_b3_context_single_header
|
20
|
+
injectors.push(B3_MULTI_PROPAGATOR) if configurator.inject_b3_context_multi_header
|
21
|
+
|
22
|
+
extractors = [W3C_PROPAGATOR]
|
23
|
+
extractors.push(B3_SINGLE_PROPAGATOR, B3_MULTI_PROPAGATOR) if configurator.extract_b3_context
|
24
|
+
|
25
|
+
::OpenTelemetry::Context::Propagation::CompositeTextMapPropagator.compose(injectors: injectors, extractors: extractors)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "opentelemetry/version"
|
4
4
|
require_relative "opentelemetry/configurator"
|
5
|
+
require_relative "opentelemetry/propagator/aspecto"
|
5
6
|
require_relative "opentelemetry/resource/detectors/aspecto"
|
6
7
|
require_relative "opentelemetry/resource/detectors/deployment"
|
7
8
|
require_relative "opentelemetry/config/remote_config"
|
@@ -30,7 +31,11 @@ module Aspecto
|
|
30
31
|
c.resource = Aspecto::OpenTelemetry::Resource::Detectors::Deployment.detect
|
31
32
|
c.resource = configurator.config_override_resource # must be last
|
32
33
|
c.use_all "OpenTelemetry::Instrumentation::ActionPack" => { enable_recognize_route: true },
|
33
|
-
"OpenTelemetry::Instrumentation::AwsSdk" => {
|
34
|
+
"OpenTelemetry::Instrumentation::AwsSdk" => {
|
35
|
+
suppress_internal_instrumentation: true,
|
36
|
+
inject_messaging_context: true,
|
37
|
+
extract_messaging_context: true
|
38
|
+
}
|
34
39
|
|
35
40
|
otlp_exporter = ::OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: configurator.otel_exporter_otlp_traces_endpoint, headers: {
|
36
41
|
"Authorization" => configurator.aspecto_auth
|
@@ -46,6 +51,15 @@ module Aspecto
|
|
46
51
|
end
|
47
52
|
end
|
48
53
|
|
54
|
+
# Propagation
|
55
|
+
::OpenTelemetry.propagation = ::Aspecto::OpenTelemetry::Propagator::Aspecto.from_configurator configurator
|
56
|
+
|
57
|
+
# Sampling
|
58
|
+
if configurator.require_config_for_traces
|
59
|
+
::OpenTelemetry.logger.info "[Aspecto] Require config for traces. Applying ALWAYS_OFF sampler"
|
60
|
+
::OpenTelemetry.tracer_provider.sampler = ::OpenTelemetry::SDK::Trace::Samplers::ALWAYS_OFF
|
61
|
+
end
|
62
|
+
|
49
63
|
fallback_sampler = ::OpenTelemetry::SDK::Trace::Samplers.trace_id_ratio_based(configurator.sampling_ratio)
|
50
64
|
# TODO: how to properly extract the data from resource?
|
51
65
|
_, service_name = ::OpenTelemetry.tracer_provider.resource.attribute_enumerator.detect { |elem| elem[0] == ::OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aspecto-opentelemetry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7.rc0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aspecto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aspecto-opentelemetry-instrumentation-aws_sdk
|
@@ -16,84 +16,70 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.1.
|
19
|
+
version: 0.1.8
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.1.
|
26
|
+
version: 0.1.8
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.8'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.8'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: faraday_middleware
|
28
|
+
name: opentelemetry-exporter-otlp
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
|
-
- -
|
31
|
+
- - '='
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
33
|
+
version: 0.21.0
|
48
34
|
type: :runtime
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
|
-
- -
|
38
|
+
- - '='
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
40
|
+
version: 0.21.0
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: opentelemetry-
|
42
|
+
name: opentelemetry-instrumentation-all
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - '='
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
47
|
+
version: 0.22.0
|
62
48
|
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - '='
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
54
|
+
version: 0.22.0
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
|
-
name: opentelemetry-
|
56
|
+
name: opentelemetry-propagator-b3
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - '='
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
61
|
+
version: 0.19.2
|
76
62
|
type: :runtime
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - '='
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
68
|
+
version: 0.19.2
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: opentelemetry-sdk
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - '='
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
75
|
+
version: 1.0.2
|
90
76
|
type: :runtime
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
80
|
- - '='
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
82
|
+
version: 1.0.2
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rufus-scheduler
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,14 +114,14 @@ dependencies:
|
|
128
114
|
requirements:
|
129
115
|
- - '='
|
130
116
|
- !ruby/object:Gem::Version
|
131
|
-
version: 0.19.
|
117
|
+
version: 0.19.3
|
132
118
|
type: :development
|
133
119
|
prerelease: false
|
134
120
|
version_requirements: !ruby/object:Gem::Requirement
|
135
121
|
requirements:
|
136
122
|
- - '='
|
137
123
|
- !ruby/object:Gem::Version
|
138
|
-
version: 0.19.
|
124
|
+
version: 0.19.3
|
139
125
|
- !ruby/object:Gem::Dependency
|
140
126
|
name: rake
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -195,6 +181,7 @@ files:
|
|
195
181
|
- lib/aspecto/opentelemetry.rb
|
196
182
|
- lib/aspecto/opentelemetry/config/remote_config.rb
|
197
183
|
- lib/aspecto/opentelemetry/configurator.rb
|
184
|
+
- lib/aspecto/opentelemetry/propagator/aspecto.rb
|
198
185
|
- lib/aspecto/opentelemetry/resource/detectors/aspecto.rb
|
199
186
|
- lib/aspecto/opentelemetry/resource/detectors/deployment.rb
|
200
187
|
- lib/aspecto/opentelemetry/sampler/condition.rb
|
@@ -221,9 +208,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
221
208
|
version: 2.5.0
|
222
209
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
210
|
requirements:
|
224
|
-
- - "
|
211
|
+
- - ">"
|
225
212
|
- !ruby/object:Gem::Version
|
226
|
-
version:
|
213
|
+
version: 1.3.1
|
227
214
|
requirements: []
|
228
215
|
rubygems_version: 3.1.6
|
229
216
|
signing_key:
|