opentracing-instrumentation 0.1.15 → 0.2.1
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/.BUNDLER_VERSION +1 -1
- data/.drone.jsonnet +3 -3
- data/.gitlab-ci.yml +12 -11
- data/.rubocop.yml +7 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +7 -0
- data/GEM_VERSION +1 -1
- data/Gemfile +7 -7
- data/Gemfile.lock +80 -60
- data/bin/check_gemfile_lock +18 -0
- data/lib/opentracing/instrumentation/bunny.rb +11 -11
- data/lib/opentracing/instrumentation/bunny/regexp_routing_key_sanitazer.rb +1 -1
- data/lib/opentracing/instrumentation/common.rb +2 -0
- data/lib/opentracing/instrumentation/common/error_writer.rb +2 -2
- data/lib/opentracing/instrumentation/common/operation_name_builder.rb +23 -0
- data/lib/opentracing/instrumentation/faraday/response_logger.rb +4 -4
- data/lib/opentracing/instrumentation/faraday/trace_middleware.rb +1 -1
- data/lib/opentracing/instrumentation/hutch.rb +6 -6
- data/lib/opentracing/instrumentation/mongo.rb +2 -0
- data/lib/opentracing/instrumentation/mongo/query_sanitazer.rb +48 -5
- data/lib/opentracing/instrumentation/mongo/sample_safety_argument_checker.rb +30 -0
- data/lib/opentracing/instrumentation/mongo/trace_subscriber.rb +5 -5
- data/lib/opentracing/instrumentation/rack/http_tagger.rb +3 -3
- data/lib/opentracing/instrumentation/rack/trace_middleware.rb +5 -5
- data/lib/opentracing/instrumentation/redis/config.rb +5 -5
- data/lib/opentracing/instrumentation/redis/tracing_driver_wrapper.rb +4 -4
- data/lib/opentracing/instrumentation/sidekiq/client_middleware.rb +41 -18
- data/lib/opentracing/instrumentation/sidekiq/job_tagger.rb +7 -7
- data/lib/opentracing/instrumentation/sidekiq/server_middleware.rb +41 -15
- data/lib/opentracing/instrumentation/thrift.rb +9 -9
- data/lib/opentracing/instrumentation/thrift/traced_processor.rb +2 -2
- data/lib/opentracing/instrumentation/thrift/traced_processor_config.rb +1 -1
- data/lib/opentracing/instrumentation/thrift/traced_processor_tags_builder.rb +1 -0
- data/lib/opentracing/instrumentation/thrift/traced_protocol.rb +3 -3
- data/lib/opentracing/instrumentation/thrift/traced_protocol_factory.rb +1 -0
- data/lib/opentracing/instrumentation/thrift/traced_protocol_tags_builder.rb +1 -1
- data/opentracing-instrumentation.gemspec +11 -7
- metadata +42 -23
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Common
|
6
|
+
# Build operation name by template and tags
|
7
|
+
class OperationNameBuilder
|
8
|
+
def initialize(operation_name_template:)
|
9
|
+
@operation_name_template = operation_name_template
|
10
|
+
end
|
11
|
+
|
12
|
+
# build operation name with tags
|
13
|
+
def build(tags)
|
14
|
+
format(operation_name_template, **tags)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :operation_name_template
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -20,10 +20,10 @@ module OpenTracing
|
|
20
20
|
content_type: 'Content-Type',
|
21
21
|
}.freeze
|
22
22
|
|
23
|
-
attr_reader :request_tag_headers
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
attr_reader :request_tag_headers,
|
24
|
+
:request_log_headers,
|
25
|
+
:response_tag_headers,
|
26
|
+
:response_log_headers
|
27
27
|
|
28
28
|
def initialize(
|
29
29
|
request_log_headers: DEFAULT_REQUEST_LOG_HEADERS,
|
@@ -12,17 +12,17 @@ module OpenTracing
|
|
12
12
|
module_path = 'opentracing/instrumentation/hutch'
|
13
13
|
|
14
14
|
autoload :ConsumeOperationNameBuilder,
|
15
|
-
module_path
|
15
|
+
"#{module_path}/consume_operation_name_builder"
|
16
16
|
autoload :ConsumeTagsBuilder,
|
17
|
-
module_path
|
17
|
+
"#{module_path}/consume_tags_builder"
|
18
18
|
autoload :ConsumeTracer,
|
19
|
-
module_path
|
19
|
+
"#{module_path}/consume_tracer"
|
20
20
|
autoload :ConsumeTracerBuilder,
|
21
|
-
module_path
|
21
|
+
"#{module_path}/consume_tracer_builder"
|
22
22
|
autoload :ConsumeTracerConfig,
|
23
|
-
module_path
|
23
|
+
"#{module_path}/consume_tracer_config"
|
24
24
|
autoload :GlobalPropertiesBuilder,
|
25
|
-
module_path
|
25
|
+
"#{module_path}/global_properties_builder"
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -9,6 +9,8 @@ module OpenTracing
|
|
9
9
|
'opentracing/instrumentation/mongo/operation_name_builder'
|
10
10
|
autoload :TraceSubscriber, 'opentracing/instrumentation/mongo/trace_subscriber'
|
11
11
|
autoload :QuerySanitazer, 'opentracing/instrumentation/mongo/query_sanitazer'
|
12
|
+
autoload :SampleSafetyArgumentChecker,
|
13
|
+
'opentracing/instrumentation/mongo/sample_safety_argument_checker'
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
@@ -19,10 +19,15 @@ module OpenTracing
|
|
19
19
|
DEFAULT_EXCLUDE_KEYS = %w[lsid].freeze
|
20
20
|
|
21
21
|
def initialize(
|
22
|
+
safety_argument_checker: SampleSafetyArgumentChecker.new,
|
22
23
|
safe_classes: DEFAULT_SAFE_CLASSES,
|
24
|
+
max_array_size: 4,
|
23
25
|
exclude_keys: DEFAULT_EXCLUDE_KEYS
|
24
26
|
)
|
27
|
+
super()
|
28
|
+
@safety_argument_checker = safety_argument_checker
|
25
29
|
@safe_classes = safe_classes
|
30
|
+
@max_array_size = max_array_size
|
26
31
|
@exclude_keys = exclude_keys
|
27
32
|
end
|
28
33
|
|
@@ -36,8 +41,10 @@ module OpenTracing
|
|
36
41
|
|
37
42
|
private
|
38
43
|
|
39
|
-
attr_reader :safe_classes
|
40
|
-
|
44
|
+
attr_reader :safe_classes,
|
45
|
+
:exclude_keys,
|
46
|
+
:max_array_size,
|
47
|
+
:safety_argument_checker
|
41
48
|
|
42
49
|
OBJECT_ID_PLACEHOLDER = '$oid'
|
43
50
|
STRING_PLACEHOLDER = '$string'
|
@@ -54,30 +61,66 @@ module OpenTracing
|
|
54
61
|
end
|
55
62
|
end
|
56
63
|
|
64
|
+
# rubocop:disable Metrics/MethodLength
|
57
65
|
def sanitaze_simple(value)
|
58
66
|
case value
|
59
67
|
when BSON::ObjectId
|
60
68
|
OBJECT_ID_PLACEHOLDER
|
61
69
|
when String
|
62
70
|
STRING_PLACEHOLDER
|
71
|
+
when ArrayItemPlaceholder
|
72
|
+
value.to_s
|
63
73
|
when *safe_classes
|
64
74
|
value
|
65
75
|
else
|
66
76
|
PLACEHOLDER
|
67
77
|
end
|
68
78
|
end
|
79
|
+
# rubocop:enable Metrics/MethodLength
|
69
80
|
|
70
81
|
def sanitaze_hash(hash)
|
71
|
-
hash.
|
72
|
-
|
82
|
+
hash.map do |(key, value)|
|
83
|
+
# TODO: pass command name.
|
84
|
+
# TODO: recursive build path to key
|
85
|
+
safe_value =
|
86
|
+
if safety_argument_checker.argument_safe?(nil, key, value)
|
87
|
+
value
|
88
|
+
else
|
89
|
+
sanitaze_value(value)
|
90
|
+
end
|
91
|
+
|
92
|
+
[key, safe_value]
|
93
|
+
end.to_h
|
94
|
+
end
|
95
|
+
|
96
|
+
# Placehoder for skipped array items
|
97
|
+
class ArrayItemPlaceholder
|
98
|
+
def initialize(skipped_items)
|
99
|
+
@skipped_items = skipped_items
|
100
|
+
end
|
101
|
+
|
102
|
+
def to_s
|
103
|
+
"SKIPPED #{@skipped_items} ITEMS"
|
73
104
|
end
|
74
105
|
end
|
75
106
|
|
76
107
|
def sanitaze_array(array)
|
77
|
-
array.
|
108
|
+
if max_array_size&.positive? && array.size > max_array_size
|
109
|
+
array_with_placeholder(array)
|
110
|
+
else
|
111
|
+
array
|
112
|
+
end.map do |value|
|
78
113
|
sanitaze_value(value)
|
79
114
|
end
|
80
115
|
end
|
116
|
+
|
117
|
+
def array_with_placeholder(array)
|
118
|
+
prefix_size = (max_array_size / 2).ceil
|
119
|
+
suffix_size = max_array_size - prefix_size
|
120
|
+
array[0...prefix_size] \
|
121
|
+
+ [ArrayItemPlaceholder.new(array.size - max_array_size)] \
|
122
|
+
+ array[-suffix_size..-1]
|
123
|
+
end
|
81
124
|
end
|
82
125
|
end
|
83
126
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Mongo
|
6
|
+
# SampleSafetyArgumentChecker check argument to safety
|
7
|
+
# Draft implementation
|
8
|
+
class SampleSafetyArgumentChecker
|
9
|
+
DEFAULT_SAFE_ARGUMENTS = [
|
10
|
+
'$readPreference',
|
11
|
+
'$clusterTime',
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
attr_reader :safe_arguments
|
15
|
+
|
16
|
+
def initialize(safe_arguments: DEFAULT_SAFE_ARGUMENTS)
|
17
|
+
@safe_arguments = safe_arguments
|
18
|
+
end
|
19
|
+
|
20
|
+
# check
|
21
|
+
#
|
22
|
+
# @return (TrueClass, FalseClass) `true`, if argument safe and not
|
23
|
+
# not should be cleaned. Otherwise return `false``.
|
24
|
+
def argument_safe?(_command_name, argument_path, _argument_value)
|
25
|
+
safe_arguments.include?(argument_path)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -43,11 +43,11 @@ module OpenTracing
|
|
43
43
|
|
44
44
|
private
|
45
45
|
|
46
|
-
attr_reader :tracer
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
attr_reader :tracer,
|
47
|
+
:scope_store,
|
48
|
+
:monitor,
|
49
|
+
:operation_name_builder,
|
50
|
+
:sanitazer
|
51
51
|
|
52
52
|
def build_operation_name(event)
|
53
53
|
operation_name_builder.build_operation_name(event)
|
@@ -50,15 +50,15 @@ module OpenTracing
|
|
50
50
|
|
51
51
|
def prepare_request_mapping(source_mapping)
|
52
52
|
source_mapping.map do |key, header|
|
53
|
-
rack_header =
|
54
|
-
tag_name =
|
53
|
+
rack_header = "HTTP_#{header.tr('-', '_').upcase}"
|
54
|
+
tag_name = "http.request.#{key}"
|
55
55
|
[tag_name, rack_header]
|
56
56
|
end.to_h
|
57
57
|
end
|
58
58
|
|
59
59
|
def prepare_response_mapping(source_mapping)
|
60
60
|
source_mapping.map do |key, header|
|
61
|
-
tag_name =
|
61
|
+
tag_name = "http.response.#{key}"
|
62
62
|
header_regexp = /^#{header}$/i
|
63
63
|
[tag_name, header_regexp]
|
64
64
|
end.to_h
|
@@ -36,10 +36,10 @@ module OpenTracing
|
|
36
36
|
|
37
37
|
private
|
38
38
|
|
39
|
-
attr_reader :app
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
attr_reader :app,
|
40
|
+
:http_tagger,
|
41
|
+
:tracer,
|
42
|
+
:logger
|
43
43
|
|
44
44
|
def trace_request(env)
|
45
45
|
extracted_ctx = tracer.extract(OpenTracing::FORMAT_RACK, env)
|
@@ -84,7 +84,7 @@ module OpenTracing
|
|
84
84
|
def set_header_tags(span, headers)
|
85
85
|
http_tagger
|
86
86
|
.response_tags(headers)
|
87
|
-
.each(
|
87
|
+
.each { |(key, value)| span.set_tag(key, value) }
|
88
88
|
end
|
89
89
|
|
90
90
|
def error_tag(span, error)
|
@@ -14,11 +14,11 @@ module OpenTracing
|
|
14
14
|
DEFAULT_LOG_REPLY = false
|
15
15
|
DEFAULT_COMPONENT = 'kv'
|
16
16
|
|
17
|
-
attr_accessor :tracer
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
attr_accessor :tracer,
|
18
|
+
:operation_name_pattern,
|
19
|
+
:log_args,
|
20
|
+
:log_reply,
|
21
|
+
:component
|
22
22
|
|
23
23
|
def initialize(
|
24
24
|
tracer: OpenTracing.global_tracer,
|
@@ -35,8 +35,8 @@ module OpenTracing
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
attr_reader :connection
|
39
|
-
|
38
|
+
attr_reader :connection,
|
39
|
+
:span_builder
|
40
40
|
|
41
41
|
def initialize(
|
42
42
|
connection:,
|
@@ -80,8 +80,8 @@ module OpenTracing
|
|
80
80
|
|
81
81
|
private
|
82
82
|
|
83
|
-
attr_reader :pipeline_scope
|
84
|
-
|
83
|
+
attr_reader :pipeline_scope,
|
84
|
+
:error_writer
|
85
85
|
|
86
86
|
def peer_addr
|
87
87
|
"#{@host}:#{@port}"
|
@@ -7,41 +7,66 @@ module OpenTracing
|
|
7
7
|
class ClientMiddleware
|
8
8
|
extend Forwardable
|
9
9
|
|
10
|
-
DEFAULT_SPAN_NAME = 'sidekiq_enqueue'
|
11
10
|
DEFAULT_SPAN_KIND = 'producer'
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
DEFAULT_OPERATION_NAME_TEMPLATE = \
|
13
|
+
'sidekiq_enqueue(%<sidekiq.class>s)'
|
14
|
+
DEFAULT_OPERATION_NAME_BUILDER = \
|
15
|
+
Common::OperationNameBuilder.new(
|
16
|
+
operation_name_template: DEFAULT_OPERATION_NAME_TEMPLATE,
|
17
|
+
)
|
18
18
|
|
19
|
+
attr_reader :tracer,
|
20
|
+
:tagger,
|
21
|
+
:error_writter,
|
22
|
+
:logger,
|
23
|
+
:span_kind,
|
24
|
+
:operation_name_builder
|
25
|
+
|
26
|
+
# rubocop:disable Metrics/ParameterLists
|
19
27
|
def initialize(
|
20
28
|
tracer: OpenTracing.global_tracer,
|
21
29
|
tagger: JobTagger.new,
|
22
30
|
error_writter: Common::ErrorWriter.new,
|
31
|
+
logger: nil,
|
23
32
|
span_kind: DEFAULT_SPAN_KIND,
|
24
|
-
|
33
|
+
operation_name_builder: DEFAULT_OPERATION_NAME_BUILDER
|
25
34
|
)
|
26
35
|
@tracer = tracer
|
27
36
|
@tagger = tagger
|
28
37
|
@error_writter = error_writter
|
38
|
+
@logger = logger
|
29
39
|
@span_kind = span_kind
|
30
|
-
@
|
40
|
+
@operation_name_builder = operation_name_builder
|
31
41
|
end
|
42
|
+
# rubocop:enable Metrics/ParameterLists
|
32
43
|
|
33
|
-
def call(_worker_class, job, _queue, _redis_pool)
|
34
|
-
scope =
|
44
|
+
def call(_worker_class, job, _queue, _redis_pool, &block)
|
45
|
+
scope = safe_start_scope(job)
|
35
46
|
inject(scope.span.context, job)
|
36
|
-
log(scope.span, job)
|
37
|
-
yield
|
38
|
-
end
|
47
|
+
log(scope.span, job, &block)
|
39
48
|
ensure
|
40
|
-
scope
|
49
|
+
safe_close_scope(scope)
|
41
50
|
end
|
42
51
|
|
43
52
|
private
|
44
53
|
|
54
|
+
def safe_start_scope(job)
|
55
|
+
tags = build_tags(job)
|
56
|
+
operation_name = operation_name_builder.build(tags)
|
57
|
+
tracer.start_active_span(operation_name, tags: tags)
|
58
|
+
rescue StandardError => e
|
59
|
+
logger&.error(e)
|
60
|
+
end
|
61
|
+
|
62
|
+
def safe_close_scope(scope)
|
63
|
+
return unless scope
|
64
|
+
|
65
|
+
scope.close
|
66
|
+
rescue StandardError => e
|
67
|
+
logger&.error(e)
|
68
|
+
end
|
69
|
+
|
45
70
|
def log(span, job)
|
46
71
|
tagger.write_args_log(span, job['jid'], job['args'])
|
47
72
|
|
@@ -51,10 +76,8 @@ module OpenTracing
|
|
51
76
|
raise
|
52
77
|
end
|
53
78
|
|
54
|
-
def
|
55
|
-
|
56
|
-
tags: tagger.build_tags(job, span_kind),
|
57
|
-
}
|
79
|
+
def build_tags(job)
|
80
|
+
tagger.build_tags(job, span_kind)
|
58
81
|
end
|
59
82
|
|
60
83
|
def inject(span_context, carrier)
|
@@ -12,8 +12,8 @@ module OpenTracing
|
|
12
12
|
|
13
13
|
DEFAULT_COMPONENT = 'sidekiq'
|
14
14
|
|
15
|
-
attr_accessor :component
|
16
|
-
|
15
|
+
attr_accessor :component,
|
16
|
+
:log_args
|
17
17
|
|
18
18
|
# @param component [String] component name
|
19
19
|
# @param log_args [TrueClass, FalseClass] enable attribute logging
|
@@ -30,11 +30,11 @@ module OpenTracing
|
|
30
30
|
# build tags from job data and static attributes
|
31
31
|
def build_tags(job, span_kind)
|
32
32
|
{
|
33
|
-
|
34
|
-
'span.kind'
|
35
|
-
'sidekiq.queue'
|
36
|
-
'sidekiq.class'
|
37
|
-
'sidekiq.retry'
|
33
|
+
component: component,
|
34
|
+
'span.kind': span_kind,
|
35
|
+
'sidekiq.queue': job['queue'],
|
36
|
+
'sidekiq.class': job['class'],
|
37
|
+
'sidekiq.retry': job['retry'],
|
38
38
|
}
|
39
39
|
end
|
40
40
|
|
@@ -9,41 +9,66 @@ module OpenTracing
|
|
9
9
|
class ServerMiddleware
|
10
10
|
extend Forwardable
|
11
11
|
|
12
|
-
DEFAULT_SPAN_NAME = 'sidekiq_perform'
|
13
12
|
DEFAULT_SPAN_KIND = 'consumer'
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
DEFAULT_OPERATION_NAME_TEMPLATE = \
|
15
|
+
'sidekiq_perform(%<sidekiq.class>s)'
|
16
|
+
DEFAULT_OPERATION_NAME_BUILDER = \
|
17
|
+
Common::OperationNameBuilder.new(
|
18
|
+
operation_name_template: DEFAULT_OPERATION_NAME_TEMPLATE,
|
19
|
+
)
|
20
20
|
|
21
|
+
attr_reader :tracer,
|
22
|
+
:tagger,
|
23
|
+
:error_writter,
|
24
|
+
:logger,
|
25
|
+
:span_kind,
|
26
|
+
:operation_name_builder
|
27
|
+
|
28
|
+
# rubocop:disable Metrics/ParameterLists
|
21
29
|
def initialize(
|
22
30
|
tracer: OpenTracing.global_tracer,
|
23
31
|
tagger: JobTagger.new,
|
24
32
|
error_writter: Common::ErrorWriter.new,
|
33
|
+
logger: nil,
|
25
34
|
span_kind: DEFAULT_SPAN_KIND,
|
26
|
-
|
35
|
+
operation_name_builder: DEFAULT_OPERATION_NAME_BUILDER
|
27
36
|
)
|
28
37
|
@tracer = tracer
|
29
38
|
@tagger = tagger
|
30
39
|
@error_writter = error_writter
|
40
|
+
@logger = logger
|
31
41
|
@span_kind = span_kind
|
32
|
-
@
|
42
|
+
@operation_name_builder = operation_name_builder
|
33
43
|
end
|
44
|
+
# rubocop:enable Metrics/ParameterLists
|
34
45
|
|
35
|
-
def call(_worker, job, _queue)
|
36
|
-
scope =
|
46
|
+
def call(_worker, job, _queue, &block)
|
47
|
+
scope = safe_start_scope(job)
|
37
48
|
|
38
|
-
log(scope.span, job)
|
39
|
-
yield
|
40
|
-
end
|
49
|
+
log(scope.span, job, &block)
|
41
50
|
ensure
|
42
|
-
scope
|
51
|
+
scope&.close
|
43
52
|
end
|
44
53
|
|
45
54
|
private
|
46
55
|
|
56
|
+
def safe_start_scope(job)
|
57
|
+
tags = tagger.build_tags(job, span_kind)
|
58
|
+
operation_name = operation_name_builder.build(tags)
|
59
|
+
tracer.start_active_span(operation_name, tags: tags, **build_span_args(job))
|
60
|
+
rescue StandardError => e
|
61
|
+
logger&.error(e)
|
62
|
+
end
|
63
|
+
|
64
|
+
def safe_close_scope(scope)
|
65
|
+
return unless socpe
|
66
|
+
|
67
|
+
scope.close
|
68
|
+
rescue StandardError => e
|
69
|
+
logger&.error(e)
|
70
|
+
end
|
71
|
+
|
47
72
|
def log(span, job)
|
48
73
|
tagger.write_args_log(span, job['jid'], job['args'])
|
49
74
|
|
@@ -56,12 +81,13 @@ module OpenTracing
|
|
56
81
|
def build_span_args(job)
|
57
82
|
{
|
58
83
|
references: extract_references(job),
|
59
|
-
tags: tagger.build_tags(job, span_kind),
|
60
84
|
}
|
61
85
|
end
|
62
86
|
|
63
87
|
def extract_references(job)
|
64
88
|
span_context = tracer.extract(OpenTracing::FORMAT_TEXT_MAP, job)
|
89
|
+
return unless span_context
|
90
|
+
|
65
91
|
[OpenTracing::Reference.follows_from(span_context)]
|
66
92
|
end
|
67
93
|
end
|