opentelemetry-instrumentation-action_view 0.1.0 → 0.2.0

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: e198a53133979f37a449a32a0b46c1480a96fd425961ef58b58ccf1c63546a21
4
- data.tar.gz: aa648e7dbbbb7f39aaabb88c88eabbe1ebd1baf1f8a075f0f2b5a74bb3169c5b
3
+ metadata.gz: 52213cc69860a40c5c84fc88b32f585458285d463500c38a608b8684aef576c9
4
+ data.tar.gz: 12d0053a8a39b0ed6fc83cc5b6b0a5de86b18210ae9ce996a58bd5b416b97698
5
5
  SHA512:
6
- metadata.gz: 23a59f8b97c874a4e35b01ce08eaa2a09d0874727cdbd775f3aaea369df989bb95d6ce8760470121cad414cc3c7597d2ecd25e74145da47a4fe8a544cbb4ff24
7
- data.tar.gz: 43e28a1c3b3a96c191cd3665ad930a6ebe4f2ef8bbad39e4bd3796713f25dffe2a7e80d3a2c3c2b50814f79ecd4c91b6553b7c797cf7e4f9f71c6772263e6c7d
6
+ metadata.gz: b0dbd124ffe15d87bf11c464bd8b4f5b1641aedfdf6f5581f4ae71f27a3d8f14dd8da43f85ca8a5568904bf36858c35e166e57c02fc5709d6c008cdb37cb773e
7
+ data.tar.gz: e1c6cd8cf9d832bf1733bd682a65ef0e9a0967a102786334ec9832edef104c297c76eea086a1146a5c9f6d83941cfe2803dee5d29ba47e70f313b289d8ec650f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Release History: opentelemetry-instrumentation-action_view
2
2
 
3
+ ### v0.2.0 / 2021-12-01
4
+
5
+ * ADDED: Move activesupport notification subsciber out of action_view gem
6
+ * FIXED: Instrumentation of Rails 7
7
+
8
+ ### v0.1.3 / 2021-10-06
9
+
10
+ * FIXED: Do not replace fanout
11
+
12
+ ### v0.1.2 / 2021-09-29
13
+
14
+ * (No significant changes)
15
+
16
+ ### v0.1.1 / 2021-09-09
17
+
18
+ * FIXED: Keep Active Support subscriptions intact when patching
19
+
3
20
  ### v0.1.0 / 2021-08-12
4
21
 
5
22
  * Initial release.
data/README.md CHANGED
@@ -36,6 +36,22 @@ end
36
36
 
37
37
  Example usage can be seen in the `./example/trace_request_demonstration.ru` file [here](https://github.com/open-telemetry/opentelemetry-ruby/blob/main/instrumentation/action_view/example/trace_request_demonstration.ru)
38
38
 
39
+ ## Known issues
40
+
41
+ ActionView instrumentation uses ActiveSupport notifications and in the case when a subscriber raises in start method an unclosed span would break successive spans ends. Example:
42
+
43
+ ```ruby
44
+ class CrashingEndSubscriber
45
+ def start(name, id, payload)
46
+ raise 'boom'
47
+ end
48
+
49
+ def finish(name, id, payload) end
50
+ end
51
+
52
+ ::ActiveSupport::Notifications.subscribe('render_template.action_view', CrashingStartSubscriber.new)
53
+ ```
54
+
39
55
  ## How can I get involved?
40
56
 
41
57
  The `opentelemetry-instrumentation-action_view` gem source is [on github][repo-github], along with related gems including `opentelemetry-api` and `opentelemetry-sdk`.
@@ -28,8 +28,6 @@ module OpenTelemetry
28
28
  private
29
29
 
30
30
  def require_dependencies
31
- require_relative 'fanout'
32
- require_relative 'span_subscriber'
33
31
  require_relative 'railtie'
34
32
  end
35
33
  end
@@ -15,17 +15,12 @@ module OpenTelemetry
15
15
 
16
16
  # This Railtie sets up subscriptions to relevant ActionView notifications
17
17
  class Railtie < ::Rails::Railtie
18
- config.before_initialize do
19
- ::ActiveSupport::Notifications.notifier = Fanout.new
20
- end
21
-
22
18
  config.after_initialize do
19
+ ::OpenTelemetry::Instrumentation::ActiveSupport::Instrumentation.instance.install({})
20
+
23
21
  SUBSCRIPTIONS.each do |subscription_name|
24
- subscriber = OpenTelemetry::Instrumentation::ActionView::SpanSubscriber.new(
25
- name: subscription_name,
26
- tracer: ActionView::Instrumentation.instance.tracer
27
- )
28
- ::ActiveSupport::Notifications.notifier.subscribe(subscription_name, subscriber)
22
+ config = ActionView::Instrumentation.instance.config
23
+ ::OpenTelemetry::Instrumentation::ActiveSupport.subscribe(ActionView::Instrumentation.instance.tracer, subscription_name, config[:notification_payload_transform], config[:disallowed_notification_payload_keys])
29
24
  end
30
25
  end
31
26
  end
@@ -7,7 +7,7 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module ActionView
10
- VERSION = '0.1.0'
10
+ VERSION = '0.2.0'
11
11
  end
12
12
  end
13
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-instrumentation-action_view
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-16 00:00:00.000000000 Z
11
+ date: 2021-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -16,28 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.0.rc1
19
+ version: 1.0.0
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: 1.0.0.rc1
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: opentelemetry-instrumentation-active_support
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: opentelemetry-instrumentation-base
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: 0.18.0
47
+ version: 0.19.0
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: 0.18.0
54
+ version: 0.19.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: appraisal
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -84,16 +98,16 @@ dependencies:
84
98
  name: opentelemetry-sdk
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - ">="
101
+ - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '0'
103
+ version: '1.0'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - ">="
108
+ - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '0'
110
+ version: '1.0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rails
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -206,19 +220,17 @@ files:
206
220
  - lib/opentelemetry-instrumentation-action_view.rb
207
221
  - lib/opentelemetry/instrumentation.rb
208
222
  - lib/opentelemetry/instrumentation/action_view.rb
209
- - lib/opentelemetry/instrumentation/action_view/fanout.rb
210
223
  - lib/opentelemetry/instrumentation/action_view/instrumentation.rb
211
224
  - lib/opentelemetry/instrumentation/action_view/railtie.rb
212
- - lib/opentelemetry/instrumentation/action_view/span_subscriber.rb
213
225
  - lib/opentelemetry/instrumentation/action_view/version.rb
214
226
  homepage: https://github.com/open-telemetry/opentelemetry-ruby
215
227
  licenses:
216
228
  - Apache-2.0
217
229
  metadata:
218
- changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-instrumentation-action_view/v0.1.0/file.CHANGELOG.html
230
+ changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-instrumentation-action_view/v0.2.0/file.CHANGELOG.html
219
231
  source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/instrumentation/action_view
220
232
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
221
- documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-instrumentation-action_view/v0.1.0
233
+ documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-instrumentation-action_view/v0.2.0
222
234
  post_install_message:
223
235
  rdoc_options: []
224
236
  require_paths:
@@ -1,53 +0,0 @@
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 ActionView
10
- # This is a replacement for the default Fanout notifications queue, which adds special
11
- # handling around returned context from the SpanSubscriber notification handlers.
12
- # Used together, it allows us to trace arbitrary ActiveSupport::Notifications safely.
13
- class Fanout < ::ActiveSupport::Notifications::Fanout
14
- def start(name, id, payload)
15
- listeners_for(name).map do |s|
16
- result = [s]
17
- state = s.start(name, id, payload)
18
- if state.is_a?(Array) && state[0].is_a?(OpenTelemetry::Trace::Span) && state[1] # rubocop:disable Style/IfUnlessModifier
19
- result << state
20
- end
21
-
22
- result
23
- end
24
- end
25
-
26
- def finish(name, id, payload, listeners = listeners_for(name))
27
- listeners.each do |(s, arr)|
28
- span, token = arr
29
- if span.is_a?(OpenTelemetry::Trace::Span) && token
30
- s.finish(
31
- name,
32
- id,
33
- payload.merge(
34
- __opentelemetry_span: span,
35
- __opentelemetry_ctx_token: token
36
- )
37
- )
38
- else
39
- s.finish(name, id, payload)
40
- end
41
- end
42
- end
43
-
44
- def listeners_for(name)
45
- listeners = super
46
- listeners.sort_by do |l|
47
- l.instance_variable_get(:@delegate).is_a?(SpanSubscriber) ? -1 : 1
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,89 +0,0 @@
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 ActionView
10
- # The SpanSubscriber is a special ActiveSupport::Notification subscription
11
- # handler which turns notifications into generic spans, taking care to handle
12
- # context appropriately.
13
- class SpanSubscriber
14
- ALWAYS_VALID_PAYLOAD_TYPES = [TrueClass, FalseClass, String, Numeric, Symbol].freeze
15
-
16
- def initialize(name:, tracer:)
17
- @span_name = name.split('.')[0..1].reverse.join(' ').freeze
18
- @tracer = tracer
19
- end
20
-
21
- def start(_name, _id, payload)
22
- span = @tracer.start_span(@span_name, kind: :internal)
23
- token = OpenTelemetry::Context.attach(
24
- OpenTelemetry::Trace.context_with_span(span)
25
- )
26
-
27
- [span, token]
28
- end
29
-
30
- def finish(_name, _id, payload) # rubocop:disable Metrics/AbcSize
31
- span = payload.delete(:__opentelemetry_span)
32
- token = payload.delete(:__opentelemetry_ctx_token)
33
- return unless span && token
34
-
35
- payload = transform_payload(payload)
36
- attrs = payload.map do |k, v|
37
- [k.to_s, sanitized_value(v)] if valid_payload_key?(k) && valid_payload_value?(v)
38
- end
39
- span.add_attributes(attrs.compact.to_h)
40
-
41
- if (e = payload[:exception_object])
42
- span.record_exception(e)
43
- span.status = OpenTelemetry::Trace::Status.error("Unhandled exception of type: #{e.class}")
44
- end
45
-
46
- span.finish
47
- OpenTelemetry::Context.detach(token)
48
- end
49
-
50
- private
51
-
52
- def instrumentation_config
53
- ActionView::Instrumentation.instance.config
54
- end
55
-
56
- def transform_payload(payload)
57
- return payload if instrumentation_config[:notification_payload_transform].nil?
58
-
59
- instrumentation_config[:notification_payload_transform].call(payload)
60
- end
61
-
62
- def valid_payload_key?(key)
63
- %i[exception exception_object].none?(key) && instrumentation_config[:disallowed_notification_payload_keys].none?(key)
64
- end
65
-
66
- def valid_payload_value?(value)
67
- if value.is_a?(Array)
68
- return true if value.empty?
69
-
70
- value.map(&:class).uniq.size == 1 && ALWAYS_VALID_PAYLOAD_TYPES.any? { |t| value.first.is_a?(t) }
71
- else
72
- ALWAYS_VALID_PAYLOAD_TYPES.any? { |t| value.is_a?(t) }
73
- end
74
- end
75
-
76
- # We'll accept symbols as values, but stringify them; and we'll stringify symbols within an array.
77
- def sanitized_value(value)
78
- if value.is_a?(Array)
79
- value.map { |v| v.is_a?(Symbol) ? v.to_s : v }
80
- elsif value.is_a?(Symbol)
81
- value.to_s
82
- else
83
- value
84
- end
85
- end
86
- end
87
- end
88
- end
89
- end