opentracing-instrumentation 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/GEM_VERSION +1 -1
- data/Gemfile.lock +26 -1
- data/lib/opentracing/instrumentation.rb +2 -0
- data/lib/opentracing/instrumentation/bunny.rb +36 -0
- data/lib/opentracing/instrumentation/bunny/consume_operation_name_builder.rb +53 -0
- data/lib/opentracing/instrumentation/bunny/consume_tags_builder.rb +55 -0
- data/lib/opentracing/instrumentation/bunny/consume_tracer.rb +107 -0
- data/lib/opentracing/instrumentation/bunny/consume_tracer_config.rb +29 -0
- data/lib/opentracing/instrumentation/bunny/headers_builder.rb +28 -0
- data/lib/opentracing/instrumentation/bunny/headers_injector.rb +29 -0
- data/lib/opentracing/instrumentation/bunny/publish_operation_name_builder.rb +50 -0
- data/lib/opentracing/instrumentation/bunny/publish_tags_builder.rb +78 -0
- data/lib/opentracing/instrumentation/bunny/publish_tracer.rb +122 -0
- data/lib/opentracing/instrumentation/bunny/publish_tracer_config.rb +31 -0
- data/lib/opentracing/instrumentation/bunny/regexp_routing_key_sanitazer.rb +52 -0
- data/lib/opentracing/instrumentation/hutch.rb +28 -0
- data/lib/opentracing/instrumentation/hutch/consume_operation_name_builder.rb +60 -0
- data/lib/opentracing/instrumentation/hutch/consume_tags_builder.rb +52 -0
- data/lib/opentracing/instrumentation/hutch/consume_tracer.rb +84 -0
- data/lib/opentracing/instrumentation/hutch/consume_tracer_builder.rb +38 -0
- data/lib/opentracing/instrumentation/hutch/consume_tracer_config.rb +33 -0
- data/lib/opentracing/instrumentation/hutch/global_properties_builder.rb +44 -0
- data/opentracing-instrumentation.gemspec +2 -0
- metadata +49 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 106a9dbe45448a23d7f3ae81c6088e48eeb3e5758b9092315d1c2e81ed3e27de
|
4
|
+
data.tar.gz: '0268cc6d0f0db99d52b447bda20115ea1fd04820ec14e2a59d8e941d29782797'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9292a2dd9483d8c34138eb68d5d4a8cd94cedc5d666d1df55a06af4acf7b1d4508deab4dc83436db798cd879cab1f6f9f014be0611b2efddf7a0990896a7ffaf
|
7
|
+
data.tar.gz: deb16198328e487a0d3200e6f5083c5c78ede07e3aaa75be1b25828ae2b817904cc39c268d39559f9518adc2c02108eb371a481bfc31ca7c48d0c357ac2be4ae
|
data/GEM_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/Gemfile.lock
CHANGED
@@ -18,23 +18,43 @@ GIT
|
|
18
18
|
PATH
|
19
19
|
remote: .
|
20
20
|
specs:
|
21
|
-
opentracing-instrumentation (0.1.
|
21
|
+
opentracing-instrumentation (0.1.3)
|
22
22
|
json
|
23
23
|
opentracing (~> 0.5.0)
|
24
24
|
|
25
25
|
GEM
|
26
26
|
remote: https://rubygems.org/
|
27
27
|
specs:
|
28
|
+
activesupport (5.2.4.2)
|
29
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
30
|
+
i18n (>= 0.7, < 2)
|
31
|
+
minitest (~> 5.1)
|
32
|
+
tzinfo (~> 1.1)
|
33
|
+
amq-protocol (2.3.0)
|
28
34
|
ast (2.4.0)
|
29
35
|
bson (4.8.0)
|
36
|
+
bunny (2.14.4)
|
37
|
+
amq-protocol (~> 2.3, >= 2.3.0)
|
30
38
|
byebug (11.1.1)
|
39
|
+
carrot-top (0.0.7)
|
40
|
+
json
|
31
41
|
coderay (1.1.2)
|
42
|
+
concurrent-ruby (1.1.6)
|
32
43
|
diff-lcs (1.3)
|
33
44
|
faraday (0.9.2)
|
34
45
|
multipart-post (>= 1.2, < 3)
|
46
|
+
hutch (0.26.0)
|
47
|
+
activesupport (>= 4.2, < 6)
|
48
|
+
bunny (>= 2.12, < 2.15)
|
49
|
+
carrot-top (~> 0.0.7)
|
50
|
+
multi_json (~> 1.12)
|
51
|
+
i18n (1.8.2)
|
52
|
+
concurrent-ruby (~> 1.0)
|
35
53
|
jaro_winkler (1.5.4)
|
36
54
|
json (2.3.0)
|
37
55
|
method_source (0.9.2)
|
56
|
+
minitest (5.14.0)
|
57
|
+
multi_json (1.14.1)
|
38
58
|
multipart-post (2.1.1)
|
39
59
|
opentracing (0.5.0)
|
40
60
|
parallel (1.19.1)
|
@@ -75,7 +95,10 @@ GEM
|
|
75
95
|
rubocop-rspec (1.38.1)
|
76
96
|
rubocop (>= 0.68.1)
|
77
97
|
ruby-progressbar (1.10.1)
|
98
|
+
thread_safe (0.3.6)
|
78
99
|
thrift (0.11.0.0)
|
100
|
+
tzinfo (1.2.6)
|
101
|
+
thread_safe (~> 0.1)
|
79
102
|
unicode-display_width (1.6.1)
|
80
103
|
|
81
104
|
PLATFORMS
|
@@ -84,7 +107,9 @@ PLATFORMS
|
|
84
107
|
DEPENDENCIES
|
85
108
|
bson (~> 4.0)
|
86
109
|
bundler (= 2.1.4)
|
110
|
+
bunny (~> 2.0)
|
87
111
|
faraday (~> 0.9.2)
|
112
|
+
hutch (~> 0.26.0)
|
88
113
|
opentracing-instrumentation!
|
89
114
|
pry-byebug (~> 3.8)
|
90
115
|
rack (~> 2.2.2)
|
@@ -19,5 +19,7 @@ module OpenTracing
|
|
19
19
|
autoload :Thrift, 'opentracing/instrumentation/thrift'
|
20
20
|
autoload :Redis, 'opentracing/instrumentation/redis'
|
21
21
|
autoload :Sidekiq, 'opentracing/instrumentation/sidekiq'
|
22
|
+
autoload :Hutch, 'opentracing/instrumentation/hutch'
|
23
|
+
autoload :Bunny, 'opentracing/instrumentation/bunny'
|
22
24
|
end
|
23
25
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
# Bunny tracing instrumentation
|
6
|
+
#
|
7
|
+
# @see ConsumeTracer
|
8
|
+
# @see PublishTracer
|
9
|
+
module Bunny
|
10
|
+
module_path = 'opentracing/instrumentation/bunny'
|
11
|
+
|
12
|
+
autoload :ConsumeOperationNameBuilder,
|
13
|
+
module_path + '/consume_operation_name_builder'
|
14
|
+
autoload :ConsumeTagsBuilder,
|
15
|
+
module_path + '/consume_tags_builder'
|
16
|
+
autoload :ConsumeTracer,
|
17
|
+
module_path + '/consume_tracer'
|
18
|
+
autoload :ConsumeTracerConfig,
|
19
|
+
module_path + '/consume_tracer_config'
|
20
|
+
autoload :HeadersBuilder,
|
21
|
+
module_path + '/headers_builder'
|
22
|
+
autoload :HeadersInjector,
|
23
|
+
module_path + '/headers_injector'
|
24
|
+
autoload :PublishOperationNameBuilder,
|
25
|
+
module_path + '/publish_operation_name_builder'
|
26
|
+
autoload :PublishTagsBuilder,
|
27
|
+
module_path + '/publish_tags_builder'
|
28
|
+
autoload :PublishTracer,
|
29
|
+
module_path + '/publish_tracer'
|
30
|
+
autoload :PublishTracerConfig,
|
31
|
+
module_path + '/publish_tracer_config'
|
32
|
+
autoload :RegexpRoutingKeySanitazer,
|
33
|
+
module_path + '/regexp_routing_key_sanitazer'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# ConsumeOperationNameBuilder build consume command name from
|
7
|
+
# queue and delivery_info
|
8
|
+
class ConsumeOperationNameBuilder
|
9
|
+
DEFAULT_OPERATION_NAME_PATTERN = \
|
10
|
+
'bunny_consume(' \
|
11
|
+
'routing_key=%<routing_key>s, ' \
|
12
|
+
'exchange=%<exchange>s, ' \
|
13
|
+
'queue=%<queue>s' \
|
14
|
+
')'
|
15
|
+
|
16
|
+
# @param routing_key_sanitazer [RegexpRoutingKeySanitazer]
|
17
|
+
# @param operation_name_pattern [String]
|
18
|
+
def initialize(
|
19
|
+
routing_key_sanitazer: RegexpRoutingKeySanitazer.new,
|
20
|
+
operation_name_pattern: DEFAULT_OPERATION_NAME_PATTERN
|
21
|
+
)
|
22
|
+
@routing_key_sanitazer = routing_key_sanitazer
|
23
|
+
@operation_name_pattern = operation_name_pattern
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param delivery_info [Bunny::DeliveryInfo]
|
27
|
+
# @return [String] bunny consume operation name
|
28
|
+
def build_operation_name(delivery_info)
|
29
|
+
format_args = build_format_args(delivery_info)
|
30
|
+
format(@operation_name_pattern, format_args)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def build_format_args(delivery_info)
|
36
|
+
queue = delivery_info[:consumer].queue
|
37
|
+
routing_key = \
|
38
|
+
sanitaze_routing_key(delivery_info[:routing_key])
|
39
|
+
delivery_info.to_h.merge(
|
40
|
+
routing_key: routing_key,
|
41
|
+
queue: queue.name,
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def sanitaze_routing_key(routing_key)
|
46
|
+
return if routing_key.nil?
|
47
|
+
|
48
|
+
@routing_key_sanitazer.sanitaze_routing_key(routing_key)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# ConsumeTagsBuidler build consume tags from delivery_info and
|
7
|
+
# properties
|
8
|
+
class ConsumeTagsBuilder
|
9
|
+
DEFAULT_STATIC_TAGS = {
|
10
|
+
'span.kind' => 'consumer',
|
11
|
+
'component' => 'bunny',
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
# @param static_tags [Hash<String, String>]
|
15
|
+
def initialize(static_tags: DEFAULT_STATIC_TAGS)
|
16
|
+
@static_tags = static_tags
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param delivery_info [Bunny::DeliveryInfo]
|
20
|
+
# @param properties [Bunny::MessageProperties]
|
21
|
+
# @return [Hash] consume span tags
|
22
|
+
def build_tags(delivery_info, properties)
|
23
|
+
@static_tags
|
24
|
+
.merge(build_properties_tags(properties))
|
25
|
+
.merge(build_delivery_info_tags(delivery_info))
|
26
|
+
.merge(build_consumer_tags(delivery_info[:consumer]))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def build_properties_tags(properties)
|
32
|
+
{
|
33
|
+
'amqp.content_type' => properties[:content_type],
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_delivery_info_tags(delivery_info)
|
38
|
+
{
|
39
|
+
'amqp.redelivered' => delivery_info[:redelivered],
|
40
|
+
'amqp.exchange' => delivery_info[:exchange],
|
41
|
+
'amqp.routing_key' => delivery_info[:routing_key],
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_consumer_tags(consumer)
|
46
|
+
{
|
47
|
+
'amqp.queue' => consumer.queue.name,
|
48
|
+
'amqp.no_ack' => consumer.no_ack,
|
49
|
+
'amqp.exclusive' => consumer.exclusive,
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# ConsumeTracer extract parent span from message headers and
|
7
|
+
# create span around passed block
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
# consumer_tracer = \
|
11
|
+
# OpenTracing::Instrumentation::Bunny::ConsumeTracer.new
|
12
|
+
#
|
13
|
+
# consumer_tracer = \
|
14
|
+
# OpenTracing::Instrumentation::Bunny::ConsumeTracer.new do |config|
|
15
|
+
# config.tracer = custom_tracer
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# queue.subscribe(block: true) do |delivery_info, properties, payload|
|
19
|
+
# consume_tracer.consume(delivery_info, properties) do
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
class ConsumeTracer
|
23
|
+
extend Forwardable
|
24
|
+
|
25
|
+
# @param config [ConsumeTracerConfig]
|
26
|
+
def initialize(config: ConsumeTracerConfig.new)
|
27
|
+
yield config if block_given?
|
28
|
+
@config = config
|
29
|
+
end
|
30
|
+
|
31
|
+
# Extract tracing parent from headers. Create span with tags.
|
32
|
+
# If block passed, then span closed after block exit, otherwise
|
33
|
+
# return active scope.
|
34
|
+
#
|
35
|
+
# @param delivery_info [Bunny::DeliveryInfo]
|
36
|
+
# @param properties [Bunny::MessageProperties]
|
37
|
+
# @yield if block passed, then it called and after scope closed
|
38
|
+
# @yieldparam scope [OpenTracing::Scope]
|
39
|
+
# @return [OpenTracing::Scope, nil] return active scope if called
|
40
|
+
# without block, otherwise return block result
|
41
|
+
def consume(delivery_info, properties)
|
42
|
+
span_scope = safe_start_active_span(delivery_info, properties)
|
43
|
+
return span_scope unless block_given?
|
44
|
+
|
45
|
+
handle_error(span_scope) do
|
46
|
+
yield span_scope
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def_delegators(
|
53
|
+
:@config,
|
54
|
+
:tracer,
|
55
|
+
:operation_name_builder,
|
56
|
+
:tags_builder,
|
57
|
+
:error_writer,
|
58
|
+
:logger,
|
59
|
+
)
|
60
|
+
|
61
|
+
def handle_error(span_scope)
|
62
|
+
yield
|
63
|
+
rescue StandardError => e
|
64
|
+
error_writer.write_error(span_scope.span, e)
|
65
|
+
raise e
|
66
|
+
ensure
|
67
|
+
# Close span if exists
|
68
|
+
span_scope&.close
|
69
|
+
end
|
70
|
+
|
71
|
+
def safe_start_active_span(delivery_info, properties)
|
72
|
+
start_active_span(delivery_info, properties)
|
73
|
+
rescue StandardError => e
|
74
|
+
logger&.error(e)
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def start_active_span(delivery_info, properties)
|
79
|
+
operation_name = build_operation_name(delivery_info)
|
80
|
+
tags = build_tags(delivery_info, properties)
|
81
|
+
references = build_references(properties[:headers])
|
82
|
+
tracer.start_active_span(
|
83
|
+
operation_name,
|
84
|
+
tags: tags,
|
85
|
+
references: references,
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
def build_operation_name(delivery_info)
|
90
|
+
operation_name_builder.build_operation_name(delivery_info)
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_tags(delivery_info, properties)
|
94
|
+
tags_builder.build_tags(delivery_info, properties)
|
95
|
+
end
|
96
|
+
|
97
|
+
def build_references(headers)
|
98
|
+
span_context = tracer.extract(
|
99
|
+
OpenTracing::FORMAT_TEXT_MAP,
|
100
|
+
headers,
|
101
|
+
)
|
102
|
+
[OpenTracing::Reference.follows_from(span_context)]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# ConsumeTracerConfig for ConsumeTracer
|
7
|
+
class ConsumeTracerConfig
|
8
|
+
# @return [ConsumeOperationNameBuilder]
|
9
|
+
attr_accessor :operation_name_builder
|
10
|
+
# @return [ConsumeTagsBuilder]
|
11
|
+
attr_accessor :tags_builder
|
12
|
+
# @return [OpenTracing::Tracer]
|
13
|
+
attr_accessor :tracer
|
14
|
+
# @return [Common::ErrorWriter]
|
15
|
+
attr_accessor :error_writer
|
16
|
+
# @return [::Logger]
|
17
|
+
attr_accessor :logger
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@operation_name_builder = ConsumeOperationNameBuilder.new
|
21
|
+
@tags_builder = ConsumeTagsBuilder.new
|
22
|
+
@tracer = OpenTracing.global_tracer
|
23
|
+
@error_writer = Common::ErrorWriter.new
|
24
|
+
@logger = nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# HeadersBuilder build AMQP headers
|
7
|
+
class HeadersBuilder
|
8
|
+
# @param tracer [OpenTracing::Tracer]
|
9
|
+
# @param injector [HeadersInjector]
|
10
|
+
def initialize(
|
11
|
+
tracer: OpenTracing.global_tracer,
|
12
|
+
injector: HeadersInjector.new(tracer: tracer)
|
13
|
+
)
|
14
|
+
@tracer = tracer
|
15
|
+
@injector = injector
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param active_span [OpenTracing::Span]
|
19
|
+
# @return [Hash<String, String>] return injected headers
|
20
|
+
def build(active_span: @tracer.active_span)
|
21
|
+
headers = {}
|
22
|
+
@injector.inject(headers, active_span: active_span)
|
23
|
+
headers
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# HeadersInjector inject tracing headers into bunny message headers
|
7
|
+
class HeadersInjector
|
8
|
+
# @param trace [OpenTracing::Tracer]
|
9
|
+
def initialize(tracer: OpenTracing.global_tracer)
|
10
|
+
@tracer = tracer
|
11
|
+
end
|
12
|
+
|
13
|
+
# inject tracing headers
|
14
|
+
# @param headers [Hash<String,String>]
|
15
|
+
# @param active_span [OpenTracing::Span]
|
16
|
+
def inject(
|
17
|
+
headers,
|
18
|
+
active_span: @tracer.active_span
|
19
|
+
)
|
20
|
+
@tracer.inject(
|
21
|
+
active_span.context,
|
22
|
+
OpenTracing::FORMAT_TEXT_MAP,
|
23
|
+
headers,
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# PublishOperationNameBuilder build publish command name from
|
7
|
+
# exchange and publish options
|
8
|
+
class PublishOperationNameBuilder
|
9
|
+
DEFAULT_OPERATION_NAME_PATTERN = \
|
10
|
+
'bunny_publish(' \
|
11
|
+
'routing_key=%<routing_key>s, ' \
|
12
|
+
'exchange=%<exchange>s' \
|
13
|
+
')'
|
14
|
+
|
15
|
+
# @param routing_key_sanitazer [RegexpRoutingKeySanitazer]
|
16
|
+
# @param operation_name_pattern [String]
|
17
|
+
def initialize(
|
18
|
+
routing_key_sanitazer: RegexpRoutingKeySanitazer.new,
|
19
|
+
operation_name_pattern: DEFAULT_OPERATION_NAME_PATTERN
|
20
|
+
)
|
21
|
+
@routing_key_sanitazer = routing_key_sanitazer
|
22
|
+
@operation_name_pattern = operation_name_pattern
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param exchange [Bunny::Exchange]
|
26
|
+
# @param opts [Hash<Symbol, Object>]
|
27
|
+
# @option opts [String] :routing_key
|
28
|
+
# @return [String]
|
29
|
+
def build_operation_name(exchange, opts)
|
30
|
+
format_args = build_format_args(exchange, opts)
|
31
|
+
format(@operation_name_pattern, **format_args)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def build_format_args(exchange, opts)
|
37
|
+
opts
|
38
|
+
.merge(exchange: exchange.name)
|
39
|
+
.merge(routing_key: sanitaze_routing_key(opts[:routing_key]))
|
40
|
+
end
|
41
|
+
|
42
|
+
def sanitaze_routing_key(routing_key)
|
43
|
+
return if routing_key.nil?
|
44
|
+
|
45
|
+
@routing_key_sanitazer.sanitaze_routing_key(routing_key)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bunny'
|
4
|
+
|
5
|
+
module OpenTracing
|
6
|
+
module Instrumentation
|
7
|
+
module Bunny
|
8
|
+
# PublishTagsBuilder build span tags for Bunny::PublishTracer
|
9
|
+
class PublishTagsBuilder
|
10
|
+
DEFAULT_STATIC_TAGS = {
|
11
|
+
'span.kind' => 'publiser',
|
12
|
+
'component' => 'bunny',
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
DEFAULT_CONTENT_TYPE = ::Bunny::Channel::DEFAULT_CONTENT_TYPE
|
16
|
+
DEFAULT_PERSISTENT = true
|
17
|
+
DEFAAUL_PRIORITY = 0
|
18
|
+
|
19
|
+
# @param static_tags [Hash<String, String>]
|
20
|
+
def initialize(static_tags: DEFAULT_STATIC_TAGS)
|
21
|
+
@static_tags = static_tags
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param exchange [Bunny::Exchange]
|
25
|
+
# @param opts [Hash<>]
|
26
|
+
# @option opts [String, nil] :routing_key
|
27
|
+
# @option opts [String, nil] :content_type
|
28
|
+
# @option opts [String, nil] :message_id
|
29
|
+
# @option opts [Integer, nil] :expiration
|
30
|
+
# @option opts [String, nil] :content_encoding
|
31
|
+
# @option opts [Boolean, nil] :persistent
|
32
|
+
# @option opts [Boolean, nil] :mandatory
|
33
|
+
# @option opts [Integer, nil] :priority
|
34
|
+
# @option opts [String, nil] :app_id
|
35
|
+
# @return [Hash<String, String>]
|
36
|
+
def build_tags(exchange, opts)
|
37
|
+
@static_tags
|
38
|
+
.merge(exchange_tags(exchange))
|
39
|
+
.merge(meta_tags(opts))
|
40
|
+
.merge(extended_tags(opts))
|
41
|
+
.compact
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def exchange_tags(exchange)
|
47
|
+
{
|
48
|
+
'amqp.exchange' => exchange.name,
|
49
|
+
'amqp.exchange_type' => exchange.type,
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def meta_tags(opts)
|
54
|
+
content_type = opts.fetch(:content_type, DEFAULT_CONTENT_TYPE)
|
55
|
+
{
|
56
|
+
'amqp.routing_key' => opts[:routing_key],
|
57
|
+
'amqp.content_type' => content_type,
|
58
|
+
'amqp.message_id' => opts[:message_id],
|
59
|
+
'amqp.expiration' => opts[:expiration],
|
60
|
+
'amqp.content_encoding' => opts[:content_encoding],
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def extended_tags(opts)
|
65
|
+
persistent = opts.fetch(:persistent, DEFAULT_PERSISTENT)
|
66
|
+
priority = opts.fetch(:priority, DEFAAUL_PRIORITY)
|
67
|
+
|
68
|
+
{
|
69
|
+
'amqp.persistent' => persistent,
|
70
|
+
'amqp.mandatory' => opts[:mandatory],
|
71
|
+
'amqp.priority' => priority,
|
72
|
+
'amqp.app_id' => opts[:app_id],
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# PublishTracer trace publishing and inject trace headers into
|
7
|
+
# AMQP message
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
# exchange = channel.topic(BUNNY_EXCHANGE_NAME)
|
11
|
+
# default_publisher \
|
12
|
+
# = OpenTracing::Instrumentation::Bunny::PublishTracer.new(exchange)
|
13
|
+
# configured_publisher = \
|
14
|
+
# OpenTracing::Instrumentation::Bunny::PublishTracer.new(exchange) do |c|
|
15
|
+
# c.tracer = custom_tracer
|
16
|
+
# end
|
17
|
+
# publisher.publish(
|
18
|
+
# '{"message": 123}',
|
19
|
+
# routing_key: 'key',
|
20
|
+
# )
|
21
|
+
class PublishTracer
|
22
|
+
extend Forwardable
|
23
|
+
|
24
|
+
# @param exchange [Bunny::Exchange]
|
25
|
+
def initialize(exchange, config: PublishTracerConfig.new)
|
26
|
+
@exchange = exchange
|
27
|
+
yield config if block_given?
|
28
|
+
@config = config.dup
|
29
|
+
end
|
30
|
+
|
31
|
+
# Publish message via call `exchange.publish`, with injecting tracing
|
32
|
+
# into headers and create span around publising call.
|
33
|
+
#
|
34
|
+
# For deatils see:
|
35
|
+
# https://www.rubydoc.info/gems/bunny/Bunny/Exchange#publish-instance_method
|
36
|
+
#
|
37
|
+
# @param active [OpenTracing::Span] allow overide span
|
38
|
+
# @return [Bunny::Exchange]
|
39
|
+
def publish(
|
40
|
+
payload,
|
41
|
+
active_span: tracer.active_span,
|
42
|
+
**opts
|
43
|
+
)
|
44
|
+
trace_publish(span: active_span, **opts) do |scope|
|
45
|
+
publish_with_headers(
|
46
|
+
payload,
|
47
|
+
span: scope&.span || active_span,
|
48
|
+
**opts,
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
attr_reader :exchange
|
56
|
+
|
57
|
+
def_delegators(
|
58
|
+
:@config,
|
59
|
+
:tracer,
|
60
|
+
:operation_name_builder,
|
61
|
+
:tags_builder,
|
62
|
+
:injector,
|
63
|
+
:error_writer,
|
64
|
+
:logger,
|
65
|
+
)
|
66
|
+
|
67
|
+
def safe_inject_headers(span:, headers:)
|
68
|
+
injector.inject(headers, active_span: span)
|
69
|
+
end
|
70
|
+
|
71
|
+
def publish_with_headers(
|
72
|
+
payload,
|
73
|
+
span:,
|
74
|
+
headers: {},
|
75
|
+
**opts
|
76
|
+
)
|
77
|
+
safe_inject_headers(span: span, headers: headers)
|
78
|
+
exchange.publish(
|
79
|
+
payload,
|
80
|
+
headers: headers,
|
81
|
+
**opts,
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def trace_publish(span:, **opts)
|
86
|
+
scope = safe_start_active_span(span: span, **opts)
|
87
|
+
yield scope
|
88
|
+
rescue StandardError => e
|
89
|
+
error_writer.write_error(scope.span, e) if scope
|
90
|
+
logger&.error(e)
|
91
|
+
raise e
|
92
|
+
ensure
|
93
|
+
scope&.close
|
94
|
+
end
|
95
|
+
|
96
|
+
def safe_start_active_span(span:, **opts)
|
97
|
+
start_active_span(span: span, **opts)
|
98
|
+
rescue StandardError
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def start_active_span(span:, **opts)
|
103
|
+
operation_name = build_operation_name(opts)
|
104
|
+
tags = build_tags(opts)
|
105
|
+
tracer.start_active_span(
|
106
|
+
operation_name,
|
107
|
+
tags: tags,
|
108
|
+
child_of: span,
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
def build_operation_name(opts)
|
113
|
+
operation_name_builder.build_operation_name(exchange, opts)
|
114
|
+
end
|
115
|
+
|
116
|
+
def build_tags(opts)
|
117
|
+
tags_builder.build_tags(exchange, opts)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# PublishTracerConfig for PublishTracer
|
7
|
+
class PublishTracerConfig
|
8
|
+
# @return [OpenTracing::Tracer]
|
9
|
+
attr_accessor :tracer
|
10
|
+
# @return [PublishOperationNameBuilder]
|
11
|
+
attr_accessor :operation_name_builder
|
12
|
+
# @return [PublishTagsBuilder]
|
13
|
+
attr_accessor :tags_builder
|
14
|
+
# @return [HeadersInjector]
|
15
|
+
attr_accessor :injector
|
16
|
+
# @return [Common::ErrorWriter]
|
17
|
+
attr_accessor :error_writer
|
18
|
+
# @return [::Logger]
|
19
|
+
attr_accessor :logger
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@tracer = OpenTracing.global_tracer
|
23
|
+
@operation_name_builder = PublishOperationNameBuilder.new
|
24
|
+
@tags_builder = PublishTagsBuilder.new
|
25
|
+
@injector = HeadersInjector.new
|
26
|
+
@error_writer = Common::ErrorWriter.new
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Bunny
|
6
|
+
# Replace id into routing key with placeholder
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# sanitazer = RegexpRoutingKeySanitazer.new
|
10
|
+
# sanitazer.sanitaze_routing_key('prefix.1234567890abcdef12345678')
|
11
|
+
#
|
12
|
+
# # 'prefix.:object_id'
|
13
|
+
#
|
14
|
+
#
|
15
|
+
# sanitazer.sanitaze_routing_key('prefix.123.suffix')
|
16
|
+
#
|
17
|
+
# # 'prefix.:sequence_id.suffis'
|
18
|
+
class RegexpRoutingKeySanitazer
|
19
|
+
ROUTING_KEY_SEPARATOR = '.'
|
20
|
+
DEFAULT_REPLCE_REGEXP_MAP = {
|
21
|
+
':sequence_id' => /^\d+$/,
|
22
|
+
':object_id' => /^[0-9a-f]{24}$/,
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
# @param replace_regexp_map [Hash<String, String>]
|
26
|
+
def initialize(replace_regexp_map: DEFAULT_REPLCE_REGEXP_MAP)
|
27
|
+
@replace_regexp_map = replace_regexp_map
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param routing_key [String] souce routing key
|
31
|
+
# @return [String] sanitazed routing key
|
32
|
+
def sanitaze_routing_key(routing_key)
|
33
|
+
routing_key
|
34
|
+
.split(ROUTING_KEY_SEPARATOR)
|
35
|
+
.map(&method(:filter_part))
|
36
|
+
.join(ROUTING_KEY_SEPARATOR)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
attr_reader :replace_regexp_map
|
42
|
+
|
43
|
+
def filter_part(routing_key_part)
|
44
|
+
replace_regexp_map.each do |placeholder, regexp|
|
45
|
+
return placeholder if regexp =~ routing_key_part
|
46
|
+
end
|
47
|
+
routing_key_part
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
# Module Hutch allow tracing Hutch consuming and inject
|
6
|
+
# tracing headers on publishing
|
7
|
+
#
|
8
|
+
# @see ConsumeTracer
|
9
|
+
# @see ConsumeTracerBuilder
|
10
|
+
# @see GlobalPropertiesBuilder
|
11
|
+
module Hutch
|
12
|
+
module_path = 'opentracing/instrumentation/hutch'
|
13
|
+
|
14
|
+
autoload :ConsumeOperationNameBuilder,
|
15
|
+
module_path + '/consume_operation_name_builder'
|
16
|
+
autoload :ConsumeTagsBuilder,
|
17
|
+
module_path + '/consume_tags_builder'
|
18
|
+
autoload :ConsumeTracer,
|
19
|
+
module_path + '/consume_tracer'
|
20
|
+
autoload :ConsumeTracerBuilder,
|
21
|
+
module_path + '/consume_tracer_builder'
|
22
|
+
autoload :ConsumeTracerConfig,
|
23
|
+
module_path + '/consume_tracer_config'
|
24
|
+
autoload :GlobalPropertiesBuilder,
|
25
|
+
module_path + '/global_properties_builder'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Hutch
|
6
|
+
# ConsumeOperationNameBuilder build span operation name of
|
7
|
+
# Hutch ConsumeTracer
|
8
|
+
class ConsumeOperationNameBuilder
|
9
|
+
DEFAULT_OPERATION_NAME_PATTERN = \
|
10
|
+
'hutch_consume(consumer_class=%<consumer_class>s)'
|
11
|
+
|
12
|
+
# @param routing_key_sanitazer [Bunny::RegexpRoutingKeySanitazer]
|
13
|
+
# @param operation_name_pattern [String]
|
14
|
+
def initialize(
|
15
|
+
routing_key_sanitazer: Bunny::RegexpRoutingKeySanitazer.new,
|
16
|
+
operation_name_pattern: DEFAULT_OPERATION_NAME_PATTERN
|
17
|
+
)
|
18
|
+
@routing_key_sanitazer = routing_key_sanitazer
|
19
|
+
@operation_name_pattern = operation_name_pattern
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param consume [Object] instance of consumer
|
23
|
+
# @param message [Hutch::Message]
|
24
|
+
# @return [String] operation_name
|
25
|
+
def build_operation_name(consumer, message)
|
26
|
+
format_args = build_format_args(consumer, message)
|
27
|
+
format(@operation_name_pattern, format_args)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def build_format_args(consumer, message)
|
33
|
+
consumer_format_args(consumer)
|
34
|
+
.merge(delivery_info_format_args(message.delivery_info))
|
35
|
+
.merge(message.properties.to_h)
|
36
|
+
end
|
37
|
+
|
38
|
+
def delivery_info_format_args(delivery_info)
|
39
|
+
routing_key = delivery_info[:routing_key]
|
40
|
+
sanitazed_routing_key = sanitaze_routing_key(routing_key)
|
41
|
+
delivery_info
|
42
|
+
.to_h
|
43
|
+
.merge(routing_key: sanitazed_routing_key)
|
44
|
+
end
|
45
|
+
|
46
|
+
def sanitaze_routing_key(routing_key)
|
47
|
+
return if routing_key.nil?
|
48
|
+
|
49
|
+
@routing_key_sanitazer.sanitaze_routing_key(routing_key)
|
50
|
+
end
|
51
|
+
|
52
|
+
def consumer_format_args(consumer)
|
53
|
+
{
|
54
|
+
consumer_class: consumer.class.to_s,
|
55
|
+
}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Hutch
|
6
|
+
# ConsumeTagsBuilder build span tags for Hutch ConsumerTrace.
|
7
|
+
# Its use Bunny::ComsumerTagsBuilde for common tags and add
|
8
|
+
# hutch specific tags
|
9
|
+
class ConsumeTagsBuilder
|
10
|
+
DEFAULT_STATIC_TAGS = {
|
11
|
+
'component' => 'hutch',
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
# @param bunny_consume_tags_builder [Bunny::ConsumeTagsBuilder]
|
15
|
+
# @param static_tags [Hash<String, String>]
|
16
|
+
def initialize(
|
17
|
+
bunny_consume_tags_builder: Bunny::ConsumeTagsBuilder.new,
|
18
|
+
static_tags: DEFAULT_STATIC_TAGS
|
19
|
+
)
|
20
|
+
@bunny_consume_tags_builder = bunny_consume_tags_builder
|
21
|
+
@static_tags = static_tags
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param consumer [Object] instance of consumer
|
25
|
+
# @param message [Hutch::Message]
|
26
|
+
# @return [Hash<String, String>] tags
|
27
|
+
def build_tags(consumer, message)
|
28
|
+
build_bunny_tags(message)
|
29
|
+
.merge(hutch_tags(consumer))
|
30
|
+
.merge(@static_tags)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :static_tags
|
36
|
+
|
37
|
+
def build_bunny_tags(message)
|
38
|
+
@bunny_consume_tags_builder.build_tags(
|
39
|
+
message.delivery_info,
|
40
|
+
message.properties,
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def hutch_tags(consumer)
|
45
|
+
{
|
46
|
+
'hutch.consumer_class' => consumer.class.to_s,
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Hutch
|
6
|
+
# ConsumeTracer trace Hutch consumer. Cannot be configured,
|
7
|
+
# Use ConsumeTracerBuilder for configuration.
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
# Hutch::Config.set(
|
11
|
+
# :tracer,
|
12
|
+
# OpenTracing::Instrumentation::Hutch::ConsumeTracer,
|
13
|
+
# )
|
14
|
+
class ConsumeTracer
|
15
|
+
extend Forwardable
|
16
|
+
|
17
|
+
def initialize(consumer, config: ConsumeTracerConfig.new)
|
18
|
+
@consumer = consumer
|
19
|
+
@config = config
|
20
|
+
end
|
21
|
+
|
22
|
+
# Method handle called by Hutch on message. This method
|
23
|
+
# start active span, process consumer and close span.
|
24
|
+
def handle(message)
|
25
|
+
scope = safe_start_active_span(message)
|
26
|
+
consumer.process(message)
|
27
|
+
rescue StandardError => e
|
28
|
+
error_writer.write_error(scope.span, e) if scope
|
29
|
+
raise e
|
30
|
+
ensure
|
31
|
+
# Close scope if exists
|
32
|
+
scope&.close
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :consumer
|
38
|
+
|
39
|
+
def_delegators(
|
40
|
+
:@config,
|
41
|
+
:tracer,
|
42
|
+
:error_writer,
|
43
|
+
:operation_name_builder,
|
44
|
+
:tags_builder,
|
45
|
+
:logger,
|
46
|
+
)
|
47
|
+
|
48
|
+
def safe_start_active_span(message)
|
49
|
+
start_active_span(message)
|
50
|
+
rescue StandardError => e
|
51
|
+
logger.error(e)
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def start_active_span(message)
|
56
|
+
operation_name = build_operation_name(message)
|
57
|
+
tags = tags_builder.build_tags(consumer, message)
|
58
|
+
references = build_references(message.properties[:headers])
|
59
|
+
|
60
|
+
tracer.start_active_span(
|
61
|
+
operation_name,
|
62
|
+
tags: tags,
|
63
|
+
references: references,
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
def build_operation_name(message)
|
68
|
+
operation_name_builder.build_operation_name(
|
69
|
+
consumer,
|
70
|
+
message,
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def build_references(headers)
|
75
|
+
span_context = tracer.extract(
|
76
|
+
OpenTracing::FORMAT_TEXT_MAP,
|
77
|
+
headers,
|
78
|
+
)
|
79
|
+
[OpenTracing::Reference.follows_from(span_context)]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Hutch
|
6
|
+
# ConsumeTracerBuilder build and configure ConsumeTracer.
|
7
|
+
# Should be used for configuration of ConsumeTracer.
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
# hutch_tracer_builder = \
|
11
|
+
# OpenTracing::Instrumentation::Hutch::ConsumeTracerBuilder.new do |config|
|
12
|
+
# config.tracer = CustomTracer.new
|
13
|
+
# end
|
14
|
+
# Hutch::Config.set(:tracer, hutch_tracer_builder)
|
15
|
+
#
|
16
|
+
# @param config [ConsumeTracerConfig]
|
17
|
+
# @yield [ConsumeTracerConfig]
|
18
|
+
class ConsumeTracerBuilder
|
19
|
+
def initialize(config: ConsumeTracerConfig.new)
|
20
|
+
yield config if block_given?
|
21
|
+
@config = config.dup
|
22
|
+
end
|
23
|
+
|
24
|
+
# Build conifgured ConsumeTracer
|
25
|
+
#
|
26
|
+
# ! Its not constructor
|
27
|
+
#
|
28
|
+
# @return ConsumeTracer
|
29
|
+
def new(consumer)
|
30
|
+
ConsumeTracer.new(
|
31
|
+
consumer,
|
32
|
+
config: @config,
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Hutch
|
6
|
+
# Config for ConsumeTracer
|
7
|
+
class ConsumeTracerConfig
|
8
|
+
# @return [ConsumeOperationNameBuilder]
|
9
|
+
attr_accessor :operation_name_builder
|
10
|
+
|
11
|
+
# @return [ConsumeTagsBuilder]
|
12
|
+
attr_accessor :tags_builder
|
13
|
+
|
14
|
+
# @return [OpenTracing::Tracer]
|
15
|
+
attr_accessor :tracer
|
16
|
+
|
17
|
+
# @return [Common::ErrorWriter]
|
18
|
+
attr_accessor :error_writer
|
19
|
+
|
20
|
+
# @return [::Logger]
|
21
|
+
attr_accessor :logger
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@operation_name_builder = ConsumeOperationNameBuilder.new
|
25
|
+
@tags_builder = ConsumeTagsBuilder.new
|
26
|
+
@tracer = OpenTracing.global_tracer
|
27
|
+
@error_writer = Common::ErrorWriter.new
|
28
|
+
@logger = ::Hutch::Logging.logger
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Hutch
|
6
|
+
# GlobalPropertiesBuilder build hutch global properties with
|
7
|
+
# tracing headers
|
8
|
+
#
|
9
|
+
# Can extend other global properties builders.
|
10
|
+
# Usage:
|
11
|
+
# Hutch.global_properties = \
|
12
|
+
# OpenTracing::Instrumentation::Hutch::GlobalPropertiesBuilder.new
|
13
|
+
#
|
14
|
+
class GlobalPropertiesBuilder
|
15
|
+
# EmptyPropertiesBuilder is deafult properties build. It return
|
16
|
+
# empty properties.
|
17
|
+
class EmptyPropertiesBuilder
|
18
|
+
def call
|
19
|
+
{}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param headers_injector [Bunny::HeadersInjector]
|
24
|
+
# @param global_properties_builder [EmptyPropertiesBuilder]
|
25
|
+
def initialize(
|
26
|
+
headers_injector: Bunny::HeadersInjector.new,
|
27
|
+
global_properties_builder: EmptyPropertiesBuilder.new
|
28
|
+
)
|
29
|
+
@headers_injector = headers_injector
|
30
|
+
@global_properties_builder = global_properties_builder
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Hash<String, String>] properties with injected tracing
|
34
|
+
# headers
|
35
|
+
def call
|
36
|
+
properties = @global_properties_builder.call
|
37
|
+
headers = (properties[:headers] ||= {})
|
38
|
+
@headers_injector.inject(headers)
|
39
|
+
properties
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -29,7 +29,9 @@ Gem::Specification.new do |spec|
|
|
29
29
|
|
30
30
|
spec.add_development_dependency 'bson', '~> 4.0'
|
31
31
|
spec.add_development_dependency 'bundler', File.read('.BUNDLER_VERSION').strip
|
32
|
+
spec.add_development_dependency 'bunny', '~> 2.0'
|
32
33
|
spec.add_development_dependency 'faraday', '~> 0.9.2'
|
34
|
+
spec.add_development_dependency 'hutch', '~> 0.26.0'
|
33
35
|
spec.add_development_dependency 'rack', '~> 2.2.2'
|
34
36
|
spec.add_development_dependency 'rake', '~> 10.0'
|
35
37
|
spec.add_development_dependency 'redis', '~> 3.3.5'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opentracing-instrumentation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fedorenko Dmitrij
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 2.1.4
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bunny
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: faraday
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +94,20 @@ dependencies:
|
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: 0.9.2
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: hutch
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.26.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.26.0
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: rack
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -200,11 +228,30 @@ files:
|
|
200
228
|
- bin/console
|
201
229
|
- bin/setup
|
202
230
|
- lib/opentracing/instrumentation.rb
|
231
|
+
- lib/opentracing/instrumentation/bunny.rb
|
232
|
+
- lib/opentracing/instrumentation/bunny/consume_operation_name_builder.rb
|
233
|
+
- lib/opentracing/instrumentation/bunny/consume_tags_builder.rb
|
234
|
+
- lib/opentracing/instrumentation/bunny/consume_tracer.rb
|
235
|
+
- lib/opentracing/instrumentation/bunny/consume_tracer_config.rb
|
236
|
+
- lib/opentracing/instrumentation/bunny/headers_builder.rb
|
237
|
+
- lib/opentracing/instrumentation/bunny/headers_injector.rb
|
238
|
+
- lib/opentracing/instrumentation/bunny/publish_operation_name_builder.rb
|
239
|
+
- lib/opentracing/instrumentation/bunny/publish_tags_builder.rb
|
240
|
+
- lib/opentracing/instrumentation/bunny/publish_tracer.rb
|
241
|
+
- lib/opentracing/instrumentation/bunny/publish_tracer_config.rb
|
242
|
+
- lib/opentracing/instrumentation/bunny/regexp_routing_key_sanitazer.rb
|
203
243
|
- lib/opentracing/instrumentation/common.rb
|
204
244
|
- lib/opentracing/instrumentation/common/error_writer.rb
|
205
245
|
- lib/opentracing/instrumentation/faraday.rb
|
206
246
|
- lib/opentracing/instrumentation/faraday/response_logger.rb
|
207
247
|
- lib/opentracing/instrumentation/faraday/trace_middleware.rb
|
248
|
+
- lib/opentracing/instrumentation/hutch.rb
|
249
|
+
- lib/opentracing/instrumentation/hutch/consume_operation_name_builder.rb
|
250
|
+
- lib/opentracing/instrumentation/hutch/consume_tags_builder.rb
|
251
|
+
- lib/opentracing/instrumentation/hutch/consume_tracer.rb
|
252
|
+
- lib/opentracing/instrumentation/hutch/consume_tracer_builder.rb
|
253
|
+
- lib/opentracing/instrumentation/hutch/consume_tracer_config.rb
|
254
|
+
- lib/opentracing/instrumentation/hutch/global_properties_builder.rb
|
208
255
|
- lib/opentracing/instrumentation/mongo.rb
|
209
256
|
- lib/opentracing/instrumentation/mongo/direct_sanitazer.rb
|
210
257
|
- lib/opentracing/instrumentation/mongo/query_sanitazer.rb
|