opentracing-instrumentation 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|