aspecto-opentelemetry 0.1.2 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -4
- data/lib/aspecto/opentelemetry/config/remote_config.rb +29 -15
- data/lib/aspecto/opentelemetry/configurator.rb +4 -1
- data/lib/aspecto/opentelemetry/version.rb +1 -1
- data/lib/aspecto/opentelemetry.rb +10 -1
- metadata +12 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8d67f2909e02b637a0342f01aaab45d1cbb0b5fae5cc27271b76113fe7af183
|
4
|
+
data.tar.gz: 1615052d3f62bb92ac80f91e3bc5a4f5f035ed9f361cefd4e7f459b6b3849d77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7133ce0b64d98585b535fac5791f77b84850ed98c561ec820ea5ba9ebd282b04249810eae0af36cb34f7d52dcd0eb54c020432d03a0d0d967884362d49401f94
|
7
|
+
data.tar.gz: 8686004ce06bb37f4b4e92623b708d7905e1b9dfdf26220853f0887bfb19293123e58b3a633b251f92f6c91bce788ee5b4bb5879b37ce36176a163488b2c3c36
|
data/README.md
CHANGED
@@ -26,7 +26,7 @@ Add this code to a new file `aspecto.rb` under `config/initializers/`:
|
|
26
26
|
require 'aspecto/opentelemetry'
|
27
27
|
|
28
28
|
Aspecto::OpenTelemetry::configure do |c|
|
29
|
-
c.service_name = '<
|
29
|
+
c.service_name = '<YOUR_SERVICE_NAME>'
|
30
30
|
c.aspecto_auth = '<YOUR_ASPECTO_TOKEN>'
|
31
31
|
# c.sampling_ratio = 1.0 # [optional]: defaults to 1.0, use aspecto app to configure remotely
|
32
32
|
end
|
@@ -43,7 +43,7 @@ gem 'aspecto-opentelemetry', require: 'aspecto/auto_instrument'
|
|
43
43
|
And set environment variables:
|
44
44
|
|
45
45
|
```
|
46
|
-
OTEL_SERVICE_NAME=<
|
46
|
+
OTEL_SERVICE_NAME=<YOUR_SERVICE_NAME>
|
47
47
|
ASPECTO_AUTH=<YOUR_ASPECTO_TOKEN>
|
48
48
|
# ASPECTO_SAMPLING_RATIO=1.0 # [optional]: defaults to 1.0, use aspecto app to configure remotely
|
49
49
|
```
|
@@ -58,7 +58,7 @@ Add this code after your require other gems:
|
|
58
58
|
require 'aspecto/opentelemetry'
|
59
59
|
|
60
60
|
Aspecto::OpenTelemetry::configure do |c|
|
61
|
-
c.service_name = '<
|
61
|
+
c.service_name = '<YOUR_SERVICE_NAME>'
|
62
62
|
c.aspecto_auth = '<YOUR_ASPECTO_TOKEN>'
|
63
63
|
# c.env = '<CURRENT_ENVIRONMENT>' # [optional]: automatically detected for rails and sinatra
|
64
64
|
# c.sampling_ratio = 1.0 # [optional]: defaults to 1.0, use aspecto app to configure remotely
|
@@ -76,7 +76,7 @@ require 'aspecto/auto_instrument'
|
|
76
76
|
And set environment variables:
|
77
77
|
|
78
78
|
```
|
79
|
-
OTEL_SERVICE_NAME=<
|
79
|
+
OTEL_SERVICE_NAME=<YOUR_SERVICE_NAME>
|
80
80
|
ASPECTO_AUTH=<YOUR_ASPECTO_TOKEN>
|
81
81
|
# ASPECTO_ENV=<CURRENT_ENVIRONMENT> # [optional]: automatically detected for rails and sinatra
|
82
82
|
# ASPECTO_SAMPLING_RATIO=1.0 # [optional]: defaults to 1.0, use aspecto app to configure remotely
|
@@ -105,6 +105,8 @@ The only required config options are [`aspecto_auth`](https://app.aspecto.io/app
|
|
105
105
|
| `log_level` | `OTEL_LOG_LEVEL` | string | `ERROR` | `ERROR` / `WARN` / `INFO`, etc. |
|
106
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
107
|
| `otel_exporter_otlp_traces_endpoint` | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | URL | "https://otelcol.aspecto.io/v1/trace" | Url |
|
108
|
+
| `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.
|
109
|
+
|
|
108
110
|
|
109
111
|
## Contributing
|
110
112
|
|
@@ -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,6 +4,8 @@ module Aspecto
|
|
4
4
|
module OpenTelemetry
|
5
5
|
# Aspecto OpenTelemetry Distro Configurator
|
6
6
|
class Configurator
|
7
|
+
TRUTHY_VALUES = %w[1 T t true TRUE True].freeze
|
8
|
+
|
7
9
|
def initialize
|
8
10
|
# initialize config options from environment variables.
|
9
11
|
# they can later be overwritten with configurator attribute setters
|
@@ -14,6 +16,7 @@ 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 = TRUTHY_VALUES.include?(ENV["ASPECTO_REQUIRE_CONFIG_FOR_TRACES"]&.strip)
|
17
20
|
end
|
18
21
|
|
19
22
|
def service_name=(service_name)
|
@@ -24,7 +27,7 @@ module Aspecto
|
|
24
27
|
@override_resource_attributes[::OpenTelemetry::SemanticConventions::Resource::DEPLOYMENT_ENVIRONMENT] = env
|
25
28
|
end
|
26
29
|
|
27
|
-
attr_accessor :sampling_ratio, :log_level, :otel_exporter_otlp_traces_endpoint
|
30
|
+
attr_accessor :sampling_ratio, :log_level, :otel_exporter_otlp_traces_endpoint, :require_config_for_traces
|
28
31
|
attr_reader :aspecto_auth
|
29
32
|
|
30
33
|
def aspecto_auth=(aspecto_auth)
|
@@ -30,7 +30,11 @@ module Aspecto
|
|
30
30
|
c.resource = Aspecto::OpenTelemetry::Resource::Detectors::Deployment.detect
|
31
31
|
c.resource = configurator.config_override_resource # must be last
|
32
32
|
c.use_all "OpenTelemetry::Instrumentation::ActionPack" => { enable_recognize_route: true },
|
33
|
-
"OpenTelemetry::Instrumentation::AwsSdk" => {
|
33
|
+
"OpenTelemetry::Instrumentation::AwsSdk" => {
|
34
|
+
suppress_internal_instrumentation: true,
|
35
|
+
inject_messaging_context: true,
|
36
|
+
extract_messaging_context: true
|
37
|
+
}
|
34
38
|
|
35
39
|
otlp_exporter = ::OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: configurator.otel_exporter_otlp_traces_endpoint, headers: {
|
36
40
|
"Authorization" => configurator.aspecto_auth
|
@@ -46,6 +50,11 @@ module Aspecto
|
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
53
|
+
if configurator.require_config_for_traces
|
54
|
+
::OpenTelemetry.logger.info "[Aspecto] Require config for traces. Applying ALWAYS_OFF sampler"
|
55
|
+
::OpenTelemetry.tracer_provider.sampler = ::OpenTelemetry::SDK::Trace::Samplers::ALWAYS_OFF
|
56
|
+
end
|
57
|
+
|
49
58
|
fallback_sampler = ::OpenTelemetry::SDK::Trace::Samplers.trace_id_ratio_based(configurator.sampling_ratio)
|
50
59
|
# TODO: how to properly extract the data from resource?
|
51
60
|
_, 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.6
|
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-23 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,56 @@ 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.
|
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
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '1.2'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.2'
|
26
|
+
version: 0.1.8
|
55
27
|
- !ruby/object:Gem::Dependency
|
56
28
|
name: opentelemetry-exporter-otlp
|
57
29
|
requirement: !ruby/object:Gem::Requirement
|
58
30
|
requirements:
|
59
31
|
- - '='
|
60
32
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
33
|
+
version: 0.21.0
|
62
34
|
type: :runtime
|
63
35
|
prerelease: false
|
64
36
|
version_requirements: !ruby/object:Gem::Requirement
|
65
37
|
requirements:
|
66
38
|
- - '='
|
67
39
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
40
|
+
version: 0.21.0
|
69
41
|
- !ruby/object:Gem::Dependency
|
70
42
|
name: opentelemetry-instrumentation-all
|
71
43
|
requirement: !ruby/object:Gem::Requirement
|
72
44
|
requirements:
|
73
45
|
- - '='
|
74
46
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
47
|
+
version: 0.22.0
|
76
48
|
type: :runtime
|
77
49
|
prerelease: false
|
78
50
|
version_requirements: !ruby/object:Gem::Requirement
|
79
51
|
requirements:
|
80
52
|
- - '='
|
81
53
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
54
|
+
version: 0.22.0
|
83
55
|
- !ruby/object:Gem::Dependency
|
84
56
|
name: opentelemetry-sdk
|
85
57
|
requirement: !ruby/object:Gem::Requirement
|
86
58
|
requirements:
|
87
59
|
- - '='
|
88
60
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
61
|
+
version: 1.0.2
|
90
62
|
type: :runtime
|
91
63
|
prerelease: false
|
92
64
|
version_requirements: !ruby/object:Gem::Requirement
|
93
65
|
requirements:
|
94
66
|
- - '='
|
95
67
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
68
|
+
version: 1.0.2
|
97
69
|
- !ruby/object:Gem::Dependency
|
98
70
|
name: rufus-scheduler
|
99
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,14 +100,14 @@ dependencies:
|
|
128
100
|
requirements:
|
129
101
|
- - '='
|
130
102
|
- !ruby/object:Gem::Version
|
131
|
-
version: 0.19.
|
103
|
+
version: 0.19.3
|
132
104
|
type: :development
|
133
105
|
prerelease: false
|
134
106
|
version_requirements: !ruby/object:Gem::Requirement
|
135
107
|
requirements:
|
136
108
|
- - '='
|
137
109
|
- !ruby/object:Gem::Version
|
138
|
-
version: 0.19.
|
110
|
+
version: 0.19.3
|
139
111
|
- !ruby/object:Gem::Dependency
|
140
112
|
name: rake
|
141
113
|
requirement: !ruby/object:Gem::Requirement
|