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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6dee5a275fa074df1631085fffe8b50e8dad84bd7a2b483acd533f9d8da5926
4
- data.tar.gz: c39cfe665ff096cb679559b9069abb90e82651d15841d00a2a8db3d2bb2175b7
3
+ metadata.gz: 96878fe3288dcffacdf45867d12864608617b5b18a5b108b6a3a765f6fba667d
4
+ data.tar.gz: 20cacce2828f81bc7a2d828d041dcb14eb05b085a2b888cd3b8b6a04d2eb5463
5
5
  SHA512:
6
- metadata.gz: 95ea7936861a80fcf3fd7184b94ce828f27c3e2c671d4312d4bcdad4c998d47c9e9447eca62a4e3b1051143a9fb77402b20ecb78f84a2cb352e4d393a7688cae
7
- data.tar.gz: 85dd4bffc0ee69a849105ee9c7841932e0ed571fa9facea15154d5215bde1a360dc7e048452867a7c63d8f7fc16de936db1e9e17ddbb749c4b88bcb02af1187c
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 | Type | Default | Description |
101
- | ------------------------------------ | ------------------------------------ | ----------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
102
- | `aspecto_auth` | `ASPECTO_AUTH` | UUID string | - | Aspecto's [API key for authentication](https://app.aspecto.io/app/integration/api-key) |
103
- | `service_name` | `OTEL_SERVICE_NAME` | string | - | name of the service which is sending telemetry |
104
- | `env` | `ASPECTO_ENV` | string | extracted from rails or sinatra if used | deployment environment: `production` / `staging` / `development`, etc. |
105
- | `log_level` | `OTEL_LOG_LEVEL` | string | `ERROR` | `ERROR` / `WARN` / `INFO`, etc. |
106
- | `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 |
107
- | `otel_exporter_otlp_traces_endpoint` | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | URL | "https://otelcol.aspecto.io/v1/trace" | Url |
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 = ENV.fetch("ASPECTO_CONFIG_HOST", "https://config.aspecto.io")
22
- @http_client = Faraday.new "#{aspecto_config_url}/config/#{aspecto_auth}" do |f|
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
- response = @http_client.get do |req|
45
- req.headers["If-None-Match"] = @latest_config_etag unless @latest_config_etag.nil?
46
- end
47
- @latest_config_etag = response.headers["etag"]
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 response.status >= 400
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
- handle_new_config response.body if response.status < 300
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
- def initialize
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,6 @@
2
2
 
3
3
  module Aspecto
4
4
  module OpenTelemetry
5
- VERSION = "0.1.3"
5
+ VERSION = "0.1.7.rc0"
6
6
  end
7
7
  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" => { suppress_internal_instrumentation: true }
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.3
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-30 00:00:00.000000000 Z
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.6
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.6
26
+ version: 0.1.8
27
27
  - !ruby/object:Gem::Dependency
28
- name: faraday
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: '1.2'
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: '1.2'
40
+ version: 0.21.0
55
41
  - !ruby/object:Gem::Dependency
56
- name: opentelemetry-exporter-otlp
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.20.6
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.20.6
54
+ version: 0.22.0
69
55
  - !ruby/object:Gem::Dependency
70
- name: opentelemetry-instrumentation-all
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.21.3
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.21.3
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: '1.0'
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: '1.0'
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.2
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.2
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: '0'
213
+ version: 1.3.1
227
214
  requirements: []
228
215
  rubygems_version: 3.1.6
229
216
  signing_key: