opentracing-instrumentation 0.1.0
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 +7 -0
- data/.BUNDLER_VERSION +1 -0
- data/.drone.jsonnet +35 -0
- data/.gitignore +1 -0
- data/.gitlab-ci.yml +80 -0
- data/.rubocop.yml +36 -0
- data/.ruby-version +1 -0
- data/GEM_VERSION +1 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +101 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +11 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/lib/opentracing/instrumentation.rb +23 -0
- data/lib/opentracing/instrumentation/common.rb +13 -0
- data/lib/opentracing/instrumentation/common/error_writer.rb +56 -0
- data/lib/opentracing/instrumentation/faraday.rb +10 -0
- data/lib/opentracing/instrumentation/faraday/response_logger.rb +76 -0
- data/lib/opentracing/instrumentation/faraday/trace_middleware.rb +202 -0
- data/lib/opentracing/instrumentation/mongo.rb +12 -0
- data/lib/opentracing/instrumentation/mongo/direct_sanitazer.rb +16 -0
- data/lib/opentracing/instrumentation/mongo/query_sanitazer.rb +84 -0
- data/lib/opentracing/instrumentation/mongo/trace_subscriber.rb +107 -0
- data/lib/opentracing/instrumentation/object_wrapper.rb +59 -0
- data/lib/opentracing/instrumentation/rack.rb +11 -0
- data/lib/opentracing/instrumentation/rack/http_tagger.rb +69 -0
- data/lib/opentracing/instrumentation/rack/trace_middleware.rb +94 -0
- data/lib/opentracing/instrumentation/redis.rb +18 -0
- data/lib/opentracing/instrumentation/redis/config.rb +40 -0
- data/lib/opentracing/instrumentation/redis/span_builder.rb +85 -0
- data/lib/opentracing/instrumentation/redis/tracing_driver_wrapper.rb +117 -0
- data/lib/opentracing/instrumentation/sidekiq.rb +17 -0
- data/lib/opentracing/instrumentation/sidekiq/client_middleware.rb +66 -0
- data/lib/opentracing/instrumentation/sidekiq/job_tagger.rb +61 -0
- data/lib/opentracing/instrumentation/sidekiq/server_middleware.rb +70 -0
- data/lib/opentracing/instrumentation/sinatra.rb +11 -0
- data/lib/opentracing/instrumentation/sinatra/trace_middleware.rb +64 -0
- data/lib/opentracing/instrumentation/thrift.rb +15 -0
- data/lib/opentracing/instrumentation/thrift/config.rb +24 -0
- data/lib/opentracing/instrumentation/thrift/traced_protocol.rb +145 -0
- data/lib/opentracing/instrumentation/thrift/traced_protocol_factory.rb +48 -0
- data/lib/opentracing/instrumentation/version.rb +7 -0
- data/opentracing-instrumentation.gemspec +40 -0
- metadata +255 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'redis/connection/ruby'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module OpenTracing
|
7
|
+
module Instrumentation
|
8
|
+
module Redis
|
9
|
+
# TracingDriverWrapper wrap redis driver
|
10
|
+
class TracingDriverWrapper
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
class << self
|
14
|
+
DEAFULT_BACKGROUND_DRIVER = ::Redis::Connection::Ruby
|
15
|
+
|
16
|
+
def connect(options)
|
17
|
+
connection = connect_backround_driver(options)
|
18
|
+
|
19
|
+
span_builder = options.fetch(:span_builder, SpanBuilder.new)
|
20
|
+
|
21
|
+
new(
|
22
|
+
connection: connection,
|
23
|
+
span_builder: span_builder,
|
24
|
+
host: options[:host],
|
25
|
+
port: options[:port],
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def connect_backround_driver(options)
|
32
|
+
background_driver =
|
33
|
+
options.fetch(:background_driver, DEAFULT_BACKGROUND_DRIVER)
|
34
|
+
background_driver.connect(options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_reader :connection
|
39
|
+
attr_reader :span_builder
|
40
|
+
|
41
|
+
def initialize(
|
42
|
+
connection:,
|
43
|
+
span_builder:,
|
44
|
+
host:,
|
45
|
+
port:
|
46
|
+
)
|
47
|
+
@connection = connection
|
48
|
+
@span_builder = span_builder
|
49
|
+
@host = host
|
50
|
+
@port = port
|
51
|
+
end
|
52
|
+
|
53
|
+
def_delegators :connection,
|
54
|
+
:connected?,
|
55
|
+
:disconnect,
|
56
|
+
:timeout=
|
57
|
+
|
58
|
+
def write(command)
|
59
|
+
scope = start_pipeline_scope
|
60
|
+
connection.write(command).tap do
|
61
|
+
span_builder.write_log_command(scope.span, command) if scope
|
62
|
+
end
|
63
|
+
rescue StandardError => e
|
64
|
+
span_builder.write_error(scope.span, e, event: EVENT_WRITE) if scope
|
65
|
+
close_pipeline_scope
|
66
|
+
raise
|
67
|
+
end
|
68
|
+
|
69
|
+
def read
|
70
|
+
scope = pipeline_scope
|
71
|
+
connection.read.tap do |reply|
|
72
|
+
span_builder.write_log_reply(scope.span, reply) if scope
|
73
|
+
end
|
74
|
+
rescue StandardError => e
|
75
|
+
span_builder.write_error(scope.span, e, event: EVENT_READ) if scope
|
76
|
+
raise
|
77
|
+
ensure
|
78
|
+
close_pipeline_scope
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
attr_reader :pipeline_scope
|
84
|
+
attr_reader :error_writer
|
85
|
+
|
86
|
+
def peer_addr
|
87
|
+
"#{@host}:#{@port}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def start_pipeline_scope
|
91
|
+
if @pipeline_scope
|
92
|
+
@pipeline_queue_size += 1
|
93
|
+
return @pipeline_scope
|
94
|
+
end
|
95
|
+
|
96
|
+
@pipeline_queue_size = 1
|
97
|
+
@pipeline_scope =
|
98
|
+
span_builder.start_active_scope(
|
99
|
+
connection.class,
|
100
|
+
peer_addr,
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def close_pipeline_scope
|
105
|
+
return unless @pipeline_scope
|
106
|
+
|
107
|
+
@pipeline_queue_size -= 1
|
108
|
+
|
109
|
+
return if @pipeline_queue_size.positive?
|
110
|
+
|
111
|
+
@pipeline_scope.close
|
112
|
+
@pipeline_scope = nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
# Sidekiq instrumentation
|
6
|
+
module Sidekiq
|
7
|
+
autoload :ClientMiddleware,
|
8
|
+
'opentracing/instrumentation/sidekiq/client_middleware'
|
9
|
+
|
10
|
+
autoload :JobTagger,
|
11
|
+
'opentracing/instrumentation/sidekiq/job_tagger'
|
12
|
+
|
13
|
+
autoload :ServerMiddleware,
|
14
|
+
'opentracing/instrumentation/sidekiq/server_middleware'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Sidekiq
|
6
|
+
# Sidekiq producer middleware
|
7
|
+
class ClientMiddleware
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
DEFAULT_SPAN_NAME = 'sidekiq_enqueue'
|
11
|
+
DEFAULT_SPAN_KIND = 'producer'
|
12
|
+
|
13
|
+
attr_reader :tracer
|
14
|
+
attr_reader :tagger
|
15
|
+
attr_reader :error_writter
|
16
|
+
attr_reader :span_kind
|
17
|
+
attr_reader :span_name
|
18
|
+
|
19
|
+
def initialize(
|
20
|
+
tracer: OpenTracing.global_tracer,
|
21
|
+
tagger: JobTagger.new,
|
22
|
+
error_writter: Common::ErrorWriter.new,
|
23
|
+
span_kind: DEFAULT_SPAN_KIND,
|
24
|
+
span_name: DEFAULT_SPAN_NAME
|
25
|
+
)
|
26
|
+
@tracer = tracer
|
27
|
+
@tagger = tagger
|
28
|
+
@error_writter = error_writter
|
29
|
+
@span_kind = span_kind
|
30
|
+
@span_name = span_name
|
31
|
+
end
|
32
|
+
|
33
|
+
def call(_worker_class, job, _queue, _redis_pool)
|
34
|
+
scope = tracer.start_active_span(span_name, **build_span_args(job))
|
35
|
+
inject(scope.span.context, job)
|
36
|
+
log(scope.span, job) do
|
37
|
+
yield
|
38
|
+
end
|
39
|
+
ensure
|
40
|
+
scope.close
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def log(span, job)
|
46
|
+
tagger.write_args_log(span, job['jid'], job['args'])
|
47
|
+
|
48
|
+
yield
|
49
|
+
rescue StandardError => e
|
50
|
+
error_writter.write_error(span, e)
|
51
|
+
raise
|
52
|
+
end
|
53
|
+
|
54
|
+
def build_span_args(job)
|
55
|
+
{
|
56
|
+
tags: tagger.build_tags(job, span_kind),
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def inject(span_context, carrier)
|
61
|
+
tracer.inject(span_context, OpenTracing::FORMAT_TEXT_MAP, carrier)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module OpenTracing
|
6
|
+
module Instrumentation
|
7
|
+
module Sidekiq
|
8
|
+
# Span tags and logs building mixin
|
9
|
+
class JobTagger
|
10
|
+
LOG_JID_EVENT = 'job_id'
|
11
|
+
LOG_ARGS_EVENT = 'job_args'
|
12
|
+
|
13
|
+
DEFAULT_COMPONENT = 'sidekiq'
|
14
|
+
|
15
|
+
attr_accessor :component
|
16
|
+
attr_accessor :log_args
|
17
|
+
|
18
|
+
# @param component [String] component name
|
19
|
+
# @param log_args [TrueClass, FalseClass] enable attribute logging
|
20
|
+
def initialize(
|
21
|
+
component: DEFAULT_COMPONENT,
|
22
|
+
log_args: false
|
23
|
+
)
|
24
|
+
@component = component
|
25
|
+
@log_args = log_args
|
26
|
+
|
27
|
+
yield self if block_given?
|
28
|
+
end
|
29
|
+
|
30
|
+
# build tags from job data and static attributes
|
31
|
+
def build_tags(job, span_kind)
|
32
|
+
{
|
33
|
+
'component' => component,
|
34
|
+
'span.kind' => span_kind,
|
35
|
+
'sidekiq.queue' => job['queue'],
|
36
|
+
'sidekiq.class' => job['class'],
|
37
|
+
'sidekiq.retry' => job['retry'],
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
# write job jid and args if log_args enabled
|
42
|
+
# @param span [OpenTracing::Span] target span
|
43
|
+
# @param jid [String] job id
|
44
|
+
# @param args [Array<Object>] argument list
|
45
|
+
def write_args_log(span, jid, args)
|
46
|
+
span.log_kv(
|
47
|
+
event: LOG_JID_EVENT,
|
48
|
+
jid: jid,
|
49
|
+
)
|
50
|
+
|
51
|
+
return unless log_args
|
52
|
+
|
53
|
+
span.log_kv(
|
54
|
+
event: LOG_ARGS_EVENT,
|
55
|
+
args: JSON.dump(args),
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module OpenTracing
|
6
|
+
module Instrumentation
|
7
|
+
module Sidekiq
|
8
|
+
# Sidekiq server middleware
|
9
|
+
class ServerMiddleware
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
DEFAULT_SPAN_NAME = 'sidekiq_perform'
|
13
|
+
DEFAULT_SPAN_KIND = 'consumer'
|
14
|
+
|
15
|
+
attr_reader :tracer
|
16
|
+
attr_reader :tagger
|
17
|
+
attr_reader :error_writter
|
18
|
+
attr_reader :span_kind
|
19
|
+
attr_reader :span_name
|
20
|
+
|
21
|
+
def initialize(
|
22
|
+
tracer: OpenTracing.global_tracer,
|
23
|
+
tagger: JobTagger.new,
|
24
|
+
error_writter: Common::ErrorWriter.new,
|
25
|
+
span_kind: DEFAULT_SPAN_KIND,
|
26
|
+
span_name: DEFAULT_SPAN_NAME
|
27
|
+
)
|
28
|
+
@tracer = tracer
|
29
|
+
@tagger = tagger
|
30
|
+
@error_writter = error_writter
|
31
|
+
@span_kind = span_kind
|
32
|
+
@span_name = span_name
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(_worker, job, _queue)
|
36
|
+
scope = tracer.start_active_span(span_name, **build_span_args(job))
|
37
|
+
|
38
|
+
log(scope.span, job) do
|
39
|
+
yield
|
40
|
+
end
|
41
|
+
ensure
|
42
|
+
scope.close
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def log(span, job)
|
48
|
+
tagger.write_args_log(span, job['jid'], job['args'])
|
49
|
+
|
50
|
+
yield
|
51
|
+
rescue StandardError => e
|
52
|
+
error_writter.write_error(span, e)
|
53
|
+
raise
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_span_args(job)
|
57
|
+
{
|
58
|
+
references: extract_references(job),
|
59
|
+
tags: tagger.build_tags(job, span_kind),
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def extract_references(job)
|
64
|
+
span_context = tracer.extract(OpenTracing::FORMAT_TEXT_MAP, job)
|
65
|
+
[OpenTracing::Reference.follows_from(span_context)]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sinatra/base'
|
4
|
+
|
5
|
+
module OpenTracing
|
6
|
+
module Instrumentation
|
7
|
+
module Sinatra
|
8
|
+
# TraceMiddleware for sinatra
|
9
|
+
#
|
10
|
+
# Usage
|
11
|
+
# class MyApp < Sinatra::Base
|
12
|
+
# use OpenTracing::Instrumentation::Sinatra::TraceMiddleware
|
13
|
+
# set :tracer, MyTracer.instance # optionaly
|
14
|
+
# end
|
15
|
+
module TraceMiddleware
|
16
|
+
def self.registered(app)
|
17
|
+
app.helpers self
|
18
|
+
|
19
|
+
app.set :tracer, OpenTracing.global_tracer
|
20
|
+
app.set :command_name, 'sinatra_request'
|
21
|
+
|
22
|
+
app.before do
|
23
|
+
start_span
|
24
|
+
end
|
25
|
+
|
26
|
+
app.after do
|
27
|
+
close_span
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def start_span
|
34
|
+
@scope = settings.tracer.start_active_span(
|
35
|
+
settings.command_name,
|
36
|
+
tags: build_base_tags,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def close_span
|
41
|
+
set_response_span_tags(@scope.span, env)
|
42
|
+
@scope.close
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_base_tags
|
46
|
+
{
|
47
|
+
'sinatra.app' => self.class.to_s,
|
48
|
+
'sinatra.environment' => settings.environment,
|
49
|
+
'sinatra.threaded' => settings.threaded,
|
50
|
+
'sinatra.show_exceptions' => settings.show_exceptions,
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def set_response_span_tags(span, env)
|
55
|
+
sinatra_route = env['sinatra.route']
|
56
|
+
span.set_tag 'sinatra.route', sinatra_route
|
57
|
+
|
58
|
+
sinatra_error = env['sinatra.error']
|
59
|
+
span.set_tag('error', true) if sinatra_error
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
# OpenTracing instrumentation for Thrift client and server
|
6
|
+
module Thrift
|
7
|
+
autoload :Config,
|
8
|
+
'opentracing/instrumentation/thrift/config'
|
9
|
+
autoload :TracedProtocol,
|
10
|
+
'opentracing/instrumentation/thrift/traced_protocol'
|
11
|
+
autoload :TracedProtocolFactory,
|
12
|
+
'opentracing/instrumentation/thrift/traced_protocol_factory'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenTracing
|
4
|
+
module Instrumentation
|
5
|
+
module Thrift
|
6
|
+
# Config for TracedProtocol
|
7
|
+
class Config
|
8
|
+
attr_accessor :tracer,
|
9
|
+
:write_operation_name,
|
10
|
+
:read_operation_name
|
11
|
+
|
12
|
+
def initialize(
|
13
|
+
tracer: OpenTracing.global_tracer,
|
14
|
+
write_operation_name: 'thrift_write',
|
15
|
+
read_operation_name: 'thrift_read'
|
16
|
+
)
|
17
|
+
@tracer = tracer
|
18
|
+
@write_operation_name = write_operation_name
|
19
|
+
@read_operation_name = read_operation_name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|