gitlab-labkit 0.13.4 → 0.16.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab/CODEOWNERS +1 -0
- data/.rubocop.yml +3 -0
- data/gitlab-labkit.gemspec +8 -3
- data/lib/gitlab-labkit.rb +29 -0
- data/lib/labkit/context.rb +12 -2
- data/lib/labkit/excon_publisher.rb +148 -0
- data/lib/labkit/httpclient_publisher.rb +66 -0
- data/lib/labkit/logging/grpc/server_interceptor.rb +6 -1
- data/lib/labkit/middleware/sidekiq/tracing/client.rb +1 -1
- data/lib/labkit/middleware/sidekiq/tracing/server.rb +1 -1
- data/lib/labkit/middleware/sidekiq/tracing/sidekiq_common.rb +14 -1
- data/lib/labkit/net_http_publisher.rb +88 -0
- data/lib/labkit/system.rb +13 -0
- data/lib/labkit/tracing.rb +4 -1
- data/lib/labkit/tracing/abstract_instrumenter.rb +47 -0
- data/lib/labkit/tracing/external_http.rb +26 -0
- data/lib/labkit/tracing/external_http/request_instrumenter.rb +33 -0
- data/lib/labkit/tracing/rails.rb +0 -2
- data/lib/labkit/tracing/rails/action_view.rb +14 -0
- data/lib/labkit/tracing/rails/action_view/render_collection_instrumenter.rb +7 -2
- data/lib/labkit/tracing/rails/action_view/render_partial_instrumenter.rb +7 -2
- data/lib/labkit/tracing/rails/action_view/render_template_instrumenter.rb +7 -2
- data/lib/labkit/tracing/rails/action_view/subscriber.rb +1 -1
- data/lib/labkit/tracing/rails/active_record/sql_instrumenter.rb +1 -1
- data/lib/labkit/tracing/rails/active_record/subscriber.rb +1 -1
- data/lib/labkit/tracing/rails/active_support/cache_delete_instrumenter.rb +1 -1
- data/lib/labkit/tracing/rails/active_support/cache_fetch_hit_instrumenter.rb +1 -1
- data/lib/labkit/tracing/rails/active_support/cache_generate_instrumenter.rb +1 -1
- data/lib/labkit/tracing/rails/active_support/cache_read_instrumenter.rb +1 -1
- data/lib/labkit/tracing/rails/active_support/cache_write_instrumenter.rb +1 -1
- data/lib/labkit/tracing/rails/active_support/subscriber.rb +1 -1
- data/lib/labkit/tracing/tracing_common.rb +20 -0
- data/lib/labkit/tracing/tracing_utils.rb +2 -0
- metadata +89 -12
- data/lib/labkit/tracing/rails/abstract_instrumenter.rb +0 -46
- data/lib/labkit/tracing/rails/rails_common.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1af5bacbedb8ce602015ad3de86ac23ddd28e2e17e78fac4dfb9d232ebe164f
|
4
|
+
data.tar.gz: caa3cb59ed0f1521530b7edfaa17234dcee23f7cdfca628d6aa2aac183fb3b4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36c847453715c4e1206839927383371369cfca346e1c2736f28b37a1425530047ea6d6c16bb5a7b732c7aa5d29eb2ab7a86f443b316d2abfbeae22828dcf04a9
|
7
|
+
data.tar.gz: f6c53e51b35f5e504f8f01d5b38578cc9ebdf41b34239385df4c7c0b8499be7ddfb375614e922297cff52affff96d8287477681153e854bf2fd86aa7ade9a425
|
data/.gitlab/CODEOWNERS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* @andrewn @ayufan @reprazent
|
data/.rubocop.yml
CHANGED
data/gitlab-labkit.gemspec
CHANGED
@@ -19,19 +19,24 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.required_ruby_version = ">= 2.4.0"
|
20
20
|
|
21
21
|
# Please maintain alphabetical order for dependencies
|
22
|
-
spec.add_runtime_dependency "actionpack", ">= 5.0.0", "<
|
23
|
-
spec.add_runtime_dependency "activesupport", ">= 5.0.0", "<
|
22
|
+
spec.add_runtime_dependency "actionpack", ">= 5.0.0", "< 7.0.0"
|
23
|
+
spec.add_runtime_dependency "activesupport", ">= 5.0.0", "< 7.0.0"
|
24
24
|
spec.add_runtime_dependency "grpc", "~> 1.19" # Be sure to update the "grpc-tools" dev_depenency too
|
25
25
|
spec.add_runtime_dependency "jaeger-client", "~> 1.1"
|
26
26
|
spec.add_runtime_dependency "opentracing", "~> 0.4"
|
27
|
+
spec.add_runtime_dependency "pg_query", "~> 1.3"
|
27
28
|
spec.add_runtime_dependency "redis", ">3.0.0", "<5.0.0"
|
28
|
-
spec.add_runtime_dependency "gitlab-pg_query", "~> 1.3"
|
29
29
|
|
30
30
|
# Please maintain alphabetical order for dev dependencies
|
31
|
+
spec.add_development_dependency "excon", "~> 0.78.1"
|
32
|
+
spec.add_development_dependency "faraday", "~> 1.2.0"
|
31
33
|
spec.add_development_dependency "grpc-tools", "~> 1.19"
|
34
|
+
spec.add_development_dependency "httparty", "~> 0.17.3"
|
35
|
+
spec.add_development_dependency "httpclient", "~> 2.8.3"
|
32
36
|
spec.add_development_dependency "pry", "~> 0.12"
|
33
37
|
spec.add_development_dependency "rack", "~> 2.0"
|
34
38
|
spec.add_development_dependency "rake", "~> 12.3"
|
39
|
+
spec.add_development_dependency "rest-client", "~> 2.1.0"
|
35
40
|
spec.add_development_dependency "rspec", "~> 3.8.0"
|
36
41
|
spec.add_development_dependency "rspec-parameterized", "~> 0.4"
|
37
42
|
spec.add_development_dependency "rubocop", "~> 0.65.0"
|
data/lib/gitlab-labkit.rb
CHANGED
@@ -7,11 +7,40 @@ require "active_support/all"
|
|
7
7
|
# infrastructural concerns, partcularly related to
|
8
8
|
# observability.
|
9
9
|
module Labkit
|
10
|
+
autoload :System, "labkit/system"
|
11
|
+
|
10
12
|
autoload :Correlation, "labkit/correlation"
|
11
13
|
autoload :Context, "labkit/context"
|
12
14
|
autoload :Tracing, "labkit/tracing"
|
13
15
|
autoload :Logging, "labkit/logging"
|
14
16
|
autoload :Middleware, "labkit/middleware"
|
17
|
+
|
18
|
+
# Publishers to publish notifications whenever a HTTP reqeust is made.
|
19
|
+
# A broadcasted notification's payload in topic "request.external_http" includes:
|
20
|
+
# + method (String): "GET"
|
21
|
+
# + code (String): "200" # This is the status code read directly from HTTP response
|
22
|
+
# + duration (Float - seconds): 0.234
|
23
|
+
# + host (String): "gitlab.com"
|
24
|
+
# + port (Integer): 80,
|
25
|
+
# + path (String): "/gitlab-org/gitlab"
|
26
|
+
# + scheme (String): "https"
|
27
|
+
# + query (String): "field_a=1&field_b=2"
|
28
|
+
# + fragment (String): "issue-number-1"
|
29
|
+
# + proxy_host (String - Optional): "proxy.gitlab.com"
|
30
|
+
# + proxy_port (Integer - Optional): 80
|
31
|
+
# + exception (Array<String> - Optional): ["Net::ReadTimeout", "Net::ReadTimeout with #<TCPSocket:(closed)>"]
|
32
|
+
# + exception_object (Error Object - Optional): #<Net::ReadTimeout: Net::ReadTimeout>
|
33
|
+
#
|
34
|
+
# Usage:
|
35
|
+
#
|
36
|
+
# ActiveSupport::Notifications.subscribe "request.external_http" do |name, started, finished, unique_id, data|
|
37
|
+
# puts "#{name} | #{started} | #{finished} | #{unique_id} | #{data.inspect}"
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
EXTERNAL_HTTP_NOTIFICATION_TOPIC = "request.external_http"
|
41
|
+
autoload :NetHttpPublisher, "labkit/net_http_publisher"
|
42
|
+
autoload :ExconPublisher, "labkit/excon_publisher"
|
43
|
+
autoload :HTTPClientPublisher, "labkit/httpclient_publisher"
|
15
44
|
end
|
16
45
|
|
17
46
|
# rubocop:enable Naming/FileName
|
data/lib/labkit/context.rb
CHANGED
@@ -23,7 +23,7 @@ module Labkit
|
|
23
23
|
RAW_KEYS = [CORRELATION_ID_KEY].freeze
|
24
24
|
HEADER_PREFIX = "X-Gitlab-"
|
25
25
|
KNOWN_KEYS = %w[user project root_namespace subscription_plan caller_id
|
26
|
-
related_class feature_category].freeze
|
26
|
+
remote_ip related_class feature_category client_id].freeze
|
27
27
|
|
28
28
|
class << self
|
29
29
|
def with_context(attributes = {})
|
@@ -106,6 +106,12 @@ module Labkit
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
+
def get_attribute(attribute)
|
110
|
+
raw = call_or_value(data[log_key(attribute)])
|
111
|
+
|
112
|
+
call_or_value(raw)
|
113
|
+
end
|
114
|
+
|
109
115
|
protected
|
110
116
|
|
111
117
|
def assign_attributes(attributes)
|
@@ -130,9 +136,13 @@ module Labkit
|
|
130
136
|
|
131
137
|
attr_reader :data
|
132
138
|
|
139
|
+
def call_or_value(value)
|
140
|
+
value.respond_to?(:call) ? value.call : value
|
141
|
+
end
|
142
|
+
|
133
143
|
def expand_data
|
134
144
|
data.transform_values do |value|
|
135
|
-
value = value
|
145
|
+
value = call_or_value(value)
|
136
146
|
|
137
147
|
value.presence
|
138
148
|
end.compact
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labkit
|
4
|
+
##
|
5
|
+
# A middleware for Excon HTTP library to publish a notification
|
6
|
+
# whenever a HTTP request is triggered.
|
7
|
+
#
|
8
|
+
# Excon supports a middleware system that allows request/response
|
9
|
+
# interception freely. Whenever a new Excon connection is created, a list of
|
10
|
+
# default middlewares is injected. This list of middlewares can be altered
|
11
|
+
# thanks to Excon.defaults accessor. ExconPublisher is inserted into this
|
12
|
+
# list. It affects all connections created in future. There is a limitation
|
13
|
+
# that this approach doesn't work if a user decides to override the default
|
14
|
+
# middleware list. It is unlikely though, at least in the dependency tree of
|
15
|
+
# GitLab.
|
16
|
+
#
|
17
|
+
# ExconPublisher instance is created once and shared between all Excon
|
18
|
+
# connections later. Each connection may be triggered by different threads in
|
19
|
+
# parallel. In such cases, a connection objects creates multiple sockets for
|
20
|
+
# each thread. Therfore in the implementation of this middleware, the
|
21
|
+
# instrumation payload for each connection is stored inside a thread-isolated
|
22
|
+
# storage.
|
23
|
+
#
|
24
|
+
# For more information:
|
25
|
+
# https://github.com/excon/excon/blob/81a0130537f2f8cd00d6daafb05d02d9a90dc9f7/lib/excon/middlewares/base.rb
|
26
|
+
# https://github.com/excon/excon/blob/fa3ec51e9bb062a12846a1cfff09534e76c99f4b/lib/excon/constants.rb#L146
|
27
|
+
# https://github.com/excon/excon/blob/fa3ec51e9bb062a12846a1cfff09534e76c99f4b/lib/excon/connection.rb#L474
|
28
|
+
class ExconPublisher
|
29
|
+
@prepend_mutex = Mutex.new
|
30
|
+
|
31
|
+
def self.labkit_prepend!
|
32
|
+
@prepend_mutex.synchronize do
|
33
|
+
return if !defined?(Excon) || @prepended
|
34
|
+
|
35
|
+
defaults = Excon.defaults
|
36
|
+
defaults[:middlewares] << ExconPublisher
|
37
|
+
|
38
|
+
@prepended = true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(stack)
|
43
|
+
@stack = stack
|
44
|
+
@instrumenter = ActiveSupport::Notifications.instrumenter
|
45
|
+
end
|
46
|
+
|
47
|
+
def request_call(datum)
|
48
|
+
payload = start_payload(datum)
|
49
|
+
store_connection_payload(datum, payload)
|
50
|
+
@instrumenter.start(::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, payload)
|
51
|
+
@stack.request_call(datum)
|
52
|
+
end
|
53
|
+
|
54
|
+
def response_call(datum)
|
55
|
+
payload = fetch_connection_payload(datum)
|
56
|
+
|
57
|
+
return @stack.response_call(datum) if payload.nil?
|
58
|
+
|
59
|
+
calculate_duration(payload)
|
60
|
+
payload[:code] = datum[:response][:status].to_s
|
61
|
+
|
62
|
+
@instrumenter.finish(::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, payload)
|
63
|
+
@stack.response_call(datum)
|
64
|
+
ensure
|
65
|
+
remove_connection_payload(datum)
|
66
|
+
end
|
67
|
+
|
68
|
+
def error_call(datum)
|
69
|
+
payload = fetch_connection_payload(datum)
|
70
|
+
|
71
|
+
return @stack.error_call(datum) if payload.nil?
|
72
|
+
|
73
|
+
calculate_duration(payload)
|
74
|
+
|
75
|
+
if datum[:error].is_a?(Exception)
|
76
|
+
payload[:exception] = [datum[:error].class.name, datum[:error].message]
|
77
|
+
payload[:exception_object] = datum[:error]
|
78
|
+
elsif datum[:error].is_a?(String)
|
79
|
+
exception = StandardError.new(datum[:error])
|
80
|
+
payload[:exception] = [exception.class.name, exception.message]
|
81
|
+
payload[:exception_object] = exception
|
82
|
+
end
|
83
|
+
|
84
|
+
@instrumenter.finish(::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, payload)
|
85
|
+
@stack.error_call(datum)
|
86
|
+
ensure
|
87
|
+
remove_connection_payload(datum)
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def start_payload(datum)
|
93
|
+
payload = {
|
94
|
+
method: datum[:method].to_s.upcase,
|
95
|
+
host: nil_or_string(datum[:host]),
|
96
|
+
path: nil_or_string(datum[:path]),
|
97
|
+
port: nil_or_int(datum[:port]),
|
98
|
+
scheme: nil_or_string(datum[:scheme]),
|
99
|
+
query: generate_query_string(datum[:query]),
|
100
|
+
start_time: ::Labkit::System.monotonic_time,
|
101
|
+
}
|
102
|
+
unless datum[:proxy].nil?
|
103
|
+
payload[:proxy_host] = datum[:proxy][:host]
|
104
|
+
payload[:proxy_port] = datum[:proxy][:port]
|
105
|
+
end
|
106
|
+
payload
|
107
|
+
end
|
108
|
+
|
109
|
+
def calculate_duration(payload)
|
110
|
+
start_time = payload.delete(:start_time) || ::Labkit::System.monotonic_time
|
111
|
+
payload[:duration] = (::Labkit::System.monotonic_time - start_time).to_f
|
112
|
+
end
|
113
|
+
|
114
|
+
def connection_payload
|
115
|
+
Thread.current[:__labkit_http_excon_payload] ||= {}
|
116
|
+
end
|
117
|
+
|
118
|
+
def store_connection_payload(datum, payload)
|
119
|
+
connection_payload[datum[:connection]] = payload
|
120
|
+
end
|
121
|
+
|
122
|
+
def fetch_connection_payload(datum)
|
123
|
+
connection_payload.fetch(datum[:connection], nil)
|
124
|
+
end
|
125
|
+
|
126
|
+
def remove_connection_payload(datum)
|
127
|
+
connection_payload.delete(datum[:connection])
|
128
|
+
end
|
129
|
+
|
130
|
+
def nil_or_string(str)
|
131
|
+
str&.to_s
|
132
|
+
end
|
133
|
+
|
134
|
+
def nil_or_int(int)
|
135
|
+
int&.to_i
|
136
|
+
rescue
|
137
|
+
nil
|
138
|
+
end
|
139
|
+
|
140
|
+
def generate_query_string(query)
|
141
|
+
if query.is_a?(Hash)
|
142
|
+
query.to_query
|
143
|
+
else
|
144
|
+
nil_or_string(query)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labkit
|
4
|
+
##
|
5
|
+
# Prepend to HTTPClient class to publish an ActiveSupport::Notifcation
|
6
|
+
# whenever a HTTP request is triggered.
|
7
|
+
#
|
8
|
+
# Similar to Net::HTTP, this HTTP client redirects all calls to
|
9
|
+
# HTTPClient#do_get_block. HTTPClient is prepended with HTTPClientPublisher.
|
10
|
+
# Although HTTPClient supports request filter (a kind of middleware), its
|
11
|
+
# support is strictly limited. The request and response passed into the
|
12
|
+
# filter don't contain connection information. The response doesn't even
|
13
|
+
# contain any link to the request object. It's impossible to fit this filter
|
14
|
+
# mechanism into our subscribing model.
|
15
|
+
#
|
16
|
+
# For more information;
|
17
|
+
# https://github.com/nahi/httpclient/blob/d3091b095a1b29f65f4531a70a8e581e75be035e/lib/httpclient.rb#L1233
|
18
|
+
module HTTPClientPublisher
|
19
|
+
@prepend_mutex = Mutex.new
|
20
|
+
|
21
|
+
def self.labkit_prepend!
|
22
|
+
@prepend_mutex.synchronize do
|
23
|
+
return if !defined?(HTTPClient) || @prepended
|
24
|
+
|
25
|
+
HTTPClient.prepend(self)
|
26
|
+
@prepended = true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def do_get_block(req, proxy, conn, &block)
|
31
|
+
start_time = ::Labkit::System.monotonic_time
|
32
|
+
ActiveSupport::Notifications.instrument ::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, create_request_payload(req, proxy) do |payload|
|
33
|
+
response =
|
34
|
+
begin
|
35
|
+
super
|
36
|
+
ensure
|
37
|
+
payload[:duration] = (::Labkit::System.monotonic_time - start_time).to_f
|
38
|
+
end
|
39
|
+
payload[:code] = response.status_code.to_s
|
40
|
+
response
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def create_request_payload(request, proxy)
|
47
|
+
http_header = request.http_header
|
48
|
+
payload = {
|
49
|
+
method: http_header.request_method,
|
50
|
+
host: http_header.request_uri.host,
|
51
|
+
path: http_header.request_uri.path,
|
52
|
+
port: http_header.request_uri.port,
|
53
|
+
scheme: http_header.request_uri.scheme,
|
54
|
+
query: http_header.request_uri.query,
|
55
|
+
fragment: http_header.request_uri.fragment,
|
56
|
+
}
|
57
|
+
|
58
|
+
unless proxy.nil?
|
59
|
+
payload[:proxy_host] = proxy.host
|
60
|
+
payload[:proxy_port] = proxy.port
|
61
|
+
end
|
62
|
+
|
63
|
+
payload
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -55,7 +55,7 @@ module Labkit
|
|
55
55
|
|
56
56
|
private
|
57
57
|
|
58
|
-
def log_request(method,
|
58
|
+
def log_request(method, _call)
|
59
59
|
start = Time.now
|
60
60
|
code = ::GRPC::Core::StatusCodes::OK
|
61
61
|
|
@@ -77,6 +77,11 @@ module Labkit
|
|
77
77
|
time: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ"),
|
78
78
|
)
|
79
79
|
|
80
|
+
if ex
|
81
|
+
message["exception"] = ex.message
|
82
|
+
message["exception_backtrace"] = ex.backtrace[0..5] if ex.backtrace
|
83
|
+
end
|
84
|
+
|
80
85
|
@log_file.puts(JSON.dump(message))
|
81
86
|
end
|
82
87
|
end
|
@@ -15,7 +15,7 @@ module Labkit
|
|
15
15
|
SPAN_KIND = "client"
|
16
16
|
|
17
17
|
def call(_worker_class, job, _queue, _redis_pool)
|
18
|
-
Labkit::Tracing::TracingUtils.with_tracing(operation_name: "sidekiq:#{job
|
18
|
+
Labkit::Tracing::TracingUtils.with_tracing(operation_name: "sidekiq:#{job_class(job)}", tags: tags_from_job(job, SPAN_KIND)) do |span|
|
19
19
|
# Inject the details directly into the job
|
20
20
|
Labkit::Tracing::TracingUtils.tracer.inject(span.context, OpenTracing::FORMAT_TEXT_MAP, job)
|
21
21
|
|
@@ -17,7 +17,7 @@ module Labkit
|
|
17
17
|
def call(_worker, job, _queue)
|
18
18
|
context = Labkit::Tracing::TracingUtils.tracer.extract(OpenTracing::FORMAT_TEXT_MAP, job)
|
19
19
|
|
20
|
-
Labkit::Tracing::TracingUtils.with_tracing(operation_name: "sidekiq:#{job
|
20
|
+
Labkit::Tracing::TracingUtils.with_tracing(operation_name: "sidekiq:#{job_class(job)}", child_of: context, tags: tags_from_job(job, SPAN_KIND)) { |_span| yield }
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -6,15 +6,28 @@ module Labkit
|
|
6
6
|
module Tracing
|
7
7
|
# SidekiqCommon is a mixin for the sidekiq middleware components
|
8
8
|
module SidekiqCommon
|
9
|
+
def job_class(job)
|
10
|
+
# Active Job wrapping can be found at
|
11
|
+
# https://github.com/rails/rails/blob/v6.0.3.1/activejob/lib/active_job/queue_adapters/sidekiq_adapter.rb
|
12
|
+
job["wrapped"].presence || job["class"].presence || "undefined"
|
13
|
+
end
|
14
|
+
|
15
|
+
def wrapped?(job)
|
16
|
+
job["wrapped"].present?
|
17
|
+
end
|
18
|
+
|
9
19
|
def tags_from_job(job, kind)
|
10
|
-
{
|
20
|
+
tags = {
|
11
21
|
"component" => "sidekiq",
|
12
22
|
"span.kind" => kind,
|
23
|
+
"sidekiq.wrapped" => wrapped?(job),
|
13
24
|
"sidekiq.queue" => job["queue"],
|
14
25
|
"sidekiq.jid" => job["jid"],
|
15
26
|
"sidekiq.retry" => job["retry"].to_s,
|
16
27
|
"sidekiq.args" => job["args"]&.join(", "),
|
17
28
|
}
|
29
|
+
tags["sidekiq.at"] = job["at"] if job["at"]
|
30
|
+
tags
|
18
31
|
end
|
19
32
|
end
|
20
33
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labkit
|
4
|
+
##
|
5
|
+
# Prepend to Ruby's Net/HTTP standard HTTP library to publish a notification
|
6
|
+
# whenever a HTTP request is triggered. Net::HTTP has different class methods
|
7
|
+
# for each http method. Those methods are delegated to corresponding instance
|
8
|
+
# methods. Eventually, `request` method is call to dispatch the HTTP request.
|
9
|
+
# Therefore, a prepender that override `request` method covers all HTTP
|
10
|
+
# calls.
|
11
|
+
#
|
12
|
+
# For more information:
|
13
|
+
# https://github.com/ruby/ruby/blob/9b9cbbbc17bb5840581c7da37fd0feb0a7d4c1f3/lib/net/http.rb#L1510
|
14
|
+
#
|
15
|
+
# Note: some use cases to take care of
|
16
|
+
# - Create a request from input URI
|
17
|
+
# - Create a request from input host, port, and path string
|
18
|
+
# - Create a singular request and closes the connection immediately
|
19
|
+
# - Create a persistent connection and perform multiple HTTP requests
|
20
|
+
# - Notification payload must separate URI components
|
21
|
+
# - Create a post request with a body
|
22
|
+
# - Create a post request with form data
|
23
|
+
# - Create a request with basic authentication
|
24
|
+
# - Make a request via a proxy server
|
25
|
+
# - Streaming
|
26
|
+
module NetHttpPublisher
|
27
|
+
@prepend_mutex = Mutex.new
|
28
|
+
|
29
|
+
def self.labkit_prepend!
|
30
|
+
@prepend_mutex.synchronize do
|
31
|
+
return if @prepended
|
32
|
+
|
33
|
+
require "net/http"
|
34
|
+
Net::HTTP.prepend(self)
|
35
|
+
@prepended = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def request(request, *args, &block)
|
40
|
+
return super unless started?
|
41
|
+
|
42
|
+
start_time = ::Labkit::System.monotonic_time
|
43
|
+
|
44
|
+
ActiveSupport::Notifications.instrument ::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, create_request_payload(request) do |payload|
|
45
|
+
response =
|
46
|
+
begin
|
47
|
+
super
|
48
|
+
ensure
|
49
|
+
payload[:duration] = (::Labkit::System.monotonic_time - start_time).to_f
|
50
|
+
end
|
51
|
+
payload[:code] = response.code
|
52
|
+
response
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def create_request_payload(request)
|
59
|
+
payload = {
|
60
|
+
method: request.method,
|
61
|
+
}
|
62
|
+
|
63
|
+
if request.uri.nil?
|
64
|
+
path_uri = URI(request.path)
|
65
|
+
payload[:host] = address
|
66
|
+
payload[:path] = path_uri.path
|
67
|
+
payload[:port] = port
|
68
|
+
payload[:scheme] = use_ssl? ? "https" : "http"
|
69
|
+
payload[:query] = path_uri.query
|
70
|
+
payload[:fragment] = path_uri.fragment
|
71
|
+
else
|
72
|
+
payload[:host] = request.uri.host
|
73
|
+
payload[:path] = request.uri.path
|
74
|
+
payload[:port] = request.uri.port
|
75
|
+
payload[:scheme] = request.uri.scheme
|
76
|
+
payload[:query] = request.uri.query
|
77
|
+
payload[:fragment] = request.uri.fragment
|
78
|
+
end
|
79
|
+
|
80
|
+
if proxy?
|
81
|
+
payload[:proxy_host] = proxy_address
|
82
|
+
payload[:proxy_port] = proxy_port
|
83
|
+
end
|
84
|
+
|
85
|
+
payload
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labkit
|
4
|
+
# A helper class to store system-related methods used in metrics, tracing, and logging
|
5
|
+
module System
|
6
|
+
# Returns the current monotonic clock time as seconds with microseconds precision.
|
7
|
+
#
|
8
|
+
# Returns the time as a Float.
|
9
|
+
def self.monotonic_time
|
10
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/labkit/tracing.rb
CHANGED
@@ -5,6 +5,8 @@ require "active_support/all"
|
|
5
5
|
module Labkit
|
6
6
|
# Tracing provides distributed tracing functionality
|
7
7
|
module Tracing
|
8
|
+
autoload :AbstractInstrumenter, "labkit/tracing/abstract_instrumenter"
|
9
|
+
autoload :TracingCommon, "labkit/tracing/tracing_common"
|
8
10
|
autoload :Factory, "labkit/tracing/factory"
|
9
11
|
autoload :GRPC, "labkit/tracing/grpc"
|
10
12
|
autoload :GRPCInterceptor, "labkit/tracing/grpc_interceptor" # Deprecated
|
@@ -12,6 +14,7 @@ module Labkit
|
|
12
14
|
autoload :RackMiddleware, "labkit/tracing/rack_middleware"
|
13
15
|
autoload :Rails, "labkit/tracing/rails"
|
14
16
|
autoload :Redis, "labkit/tracing/redis"
|
17
|
+
autoload :ExternalHttp, "labkit/tracing/external_http"
|
15
18
|
autoload :Sidekiq, "labkit/tracing/sidekiq"
|
16
19
|
autoload :TracingUtils, "labkit/tracing/tracing_utils"
|
17
20
|
|
@@ -31,7 +34,7 @@ module Labkit
|
|
31
34
|
# Check if the current request is being traced.
|
32
35
|
def self.sampled?
|
33
36
|
context = OpenTracing.active_span&.context
|
34
|
-
context
|
37
|
+
context&.respond_to?(:sampled?) && context&.sampled?
|
35
38
|
end
|
36
39
|
|
37
40
|
def self.stacktrace_operations
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "opentracing"
|
4
|
+
require "active_support/all"
|
5
|
+
|
6
|
+
module Labkit
|
7
|
+
module Tracing
|
8
|
+
# https://edgeapi.rubyonrails.org/classes/ActiveSupport/Notifications/Instrumenter.html#method-c-new
|
9
|
+
class AbstractInstrumenter
|
10
|
+
def start(_name, _id, payload)
|
11
|
+
scope = OpenTracing.start_active_span(span_name(payload))
|
12
|
+
|
13
|
+
scope_stack.push scope
|
14
|
+
end
|
15
|
+
|
16
|
+
def finish(_name, _id, payload)
|
17
|
+
scope = scope_stack.pop
|
18
|
+
span = scope.span
|
19
|
+
|
20
|
+
Labkit::Tracing::TracingUtils.log_common_fields_on_span(span, span_name(payload))
|
21
|
+
|
22
|
+
# exception_object is the standard exception payload from ActiveSupport::Notifications
|
23
|
+
# https://github.com/rails/rails/blob/v6.0.3.1/activesupport/lib/active_support/notifications/instrumenter.rb#L26
|
24
|
+
exception = payload[:exception_object].presence || payload[:exception].presence
|
25
|
+
Labkit::Tracing::TracingUtils.log_exception_on_span(span, exception)
|
26
|
+
|
27
|
+
tags(payload).each do |k, v|
|
28
|
+
span.set_tag(k, v)
|
29
|
+
end
|
30
|
+
|
31
|
+
scope.close
|
32
|
+
end
|
33
|
+
|
34
|
+
def scope_stack
|
35
|
+
Thread.current[:_labkit_trace_scope_stack] ||= []
|
36
|
+
end
|
37
|
+
|
38
|
+
def span_name(_payload)
|
39
|
+
raise "span_name not implemented"
|
40
|
+
end
|
41
|
+
|
42
|
+
def tags(_payload)
|
43
|
+
{}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labkit
|
4
|
+
module Tracing
|
5
|
+
# Instrument external HTTP calls made by the HTTP client libraries. This
|
6
|
+
# tracing instrumenter listens to the events broadcasted from the
|
7
|
+
# publishers injected into the libraries whenever there is a request.
|
8
|
+
module ExternalHttp
|
9
|
+
include Labkit::Tracing::TracingCommon
|
10
|
+
|
11
|
+
autoload :RequestInstrumenter, "labkit/tracing/external_http/request_instrumenter"
|
12
|
+
|
13
|
+
def self.instrument
|
14
|
+
Labkit::NetHttpPublisher.labkit_prepend!
|
15
|
+
Labkit::ExconPublisher.labkit_prepend!
|
16
|
+
Labkit::HTTPClientPublisher.labkit_prepend!
|
17
|
+
|
18
|
+
subscriptions = [
|
19
|
+
::ActiveSupport::Notifications.subscribe(::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, RequestInstrumenter.new),
|
20
|
+
]
|
21
|
+
|
22
|
+
create_unsubscriber subscriptions
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labkit
|
4
|
+
module Tracing
|
5
|
+
module ExternalHttp
|
6
|
+
# For more information on the payloads: lib/labkit/net_http_publisher.rb
|
7
|
+
class RequestInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
8
|
+
def span_name(_payload)
|
9
|
+
"external_http:request"
|
10
|
+
end
|
11
|
+
|
12
|
+
def tags(payload)
|
13
|
+
# Duration is calculated by start and end time
|
14
|
+
# Exception is already captured in lib/labkit/tracing/tracing_utils.rb
|
15
|
+
tags = {
|
16
|
+
"component" => "external_http",
|
17
|
+
"method" => payload[:method],
|
18
|
+
"code" => payload[:code],
|
19
|
+
"host" => payload[:host],
|
20
|
+
"port" => payload[:port],
|
21
|
+
"path" => payload[:path],
|
22
|
+
"scheme" => payload[:scheme],
|
23
|
+
}
|
24
|
+
unless payload[:proxy_host].nil?
|
25
|
+
tags["proxy_host"] = payload[:proxy_host]
|
26
|
+
tags["proxy_port"] = payload[:proxy_port]
|
27
|
+
end
|
28
|
+
tags
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/labkit/tracing/rails.rb
CHANGED
@@ -4,11 +4,9 @@ module Labkit
|
|
4
4
|
module Tracing
|
5
5
|
# Rails provides classes for instrumenting Rails events
|
6
6
|
module Rails
|
7
|
-
autoload :AbstractInstrumenter, "labkit/tracing/rails/abstract_instrumenter"
|
8
7
|
autoload :ActionView, "labkit/tracing/rails/action_view"
|
9
8
|
autoload :ActiveRecord, "labkit/tracing/rails/active_record"
|
10
9
|
autoload :ActiveSupport, "labkit/tracing/rails/active_support"
|
11
|
-
autoload :RailsCommon, "labkit/tracing/rails/rails_common"
|
12
10
|
|
13
11
|
ActionViewSubscriber = ActionView::Subscriber
|
14
12
|
ActiveRecordSubscriber = ActiveRecord::Subscriber
|
@@ -10,6 +10,20 @@ module Labkit
|
|
10
10
|
autoload :Subscriber, "labkit/tracing/rails/action_view/subscriber"
|
11
11
|
|
12
12
|
COMPONENT_TAG = "ActionView"
|
13
|
+
|
14
|
+
# Returns identifier relative to Rails.root. Rails supports different template types and returns corresponding identifiers:
|
15
|
+
# - Text template: the identifier is "text template"
|
16
|
+
# - Html template: the identifier is "html template"
|
17
|
+
# - Inline template: the identifier is "inline template"
|
18
|
+
# - Raw template: the identifier is the file path of the template
|
19
|
+
# Therefore, the amount of returned identifiers is static.
|
20
|
+
def self.template_identifier(payload)
|
21
|
+
return if !defined?(::Rails.root) || payload[:identifier].nil?
|
22
|
+
|
23
|
+
# Rails.root returns a Pathname object, whose `to_s` methods returns an absolute path without ending "/"
|
24
|
+
# Source: https://github.com/rails/rails/blob/v6.0.3.1/railties/lib/rails.rb#L64
|
25
|
+
payload[:identifier].sub("#{::Rails.root}/", "")
|
26
|
+
end
|
13
27
|
end
|
14
28
|
end
|
15
29
|
end
|
@@ -5,9 +5,14 @@ module Labkit
|
|
5
5
|
module Rails
|
6
6
|
module ActionView
|
7
7
|
# For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
|
8
|
-
class RenderCollectionInstrumenter < AbstractInstrumenter
|
8
|
+
class RenderCollectionInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
9
9
|
def span_name(payload)
|
10
|
-
|
10
|
+
identifier = ActionView.template_identifier(payload)
|
11
|
+
if identifier.nil?
|
12
|
+
"render_collection"
|
13
|
+
else
|
14
|
+
"render_collection:#{identifier}"
|
15
|
+
end
|
11
16
|
end
|
12
17
|
|
13
18
|
def tags(payload)
|
@@ -5,9 +5,14 @@ module Labkit
|
|
5
5
|
module Rails
|
6
6
|
module ActionView
|
7
7
|
# For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
|
8
|
-
class RenderPartialInstrumenter < AbstractInstrumenter
|
8
|
+
class RenderPartialInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
9
9
|
def span_name(payload)
|
10
|
-
|
10
|
+
identifier = ActionView.template_identifier(payload)
|
11
|
+
if identifier.nil?
|
12
|
+
"render_partial"
|
13
|
+
else
|
14
|
+
"render_partial:#{identifier}"
|
15
|
+
end
|
11
16
|
end
|
12
17
|
|
13
18
|
def tags(payload)
|
@@ -5,9 +5,14 @@ module Labkit
|
|
5
5
|
module Rails
|
6
6
|
module ActionView
|
7
7
|
# For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
|
8
|
-
class RenderTemplateInstrumenter < AbstractInstrumenter
|
8
|
+
class RenderTemplateInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
9
9
|
def span_name(payload)
|
10
|
-
|
10
|
+
identifier = ActionView.template_identifier(payload)
|
11
|
+
if identifier.nil?
|
12
|
+
"render_template"
|
13
|
+
else
|
14
|
+
"render_template:#{identifier}"
|
15
|
+
end
|
11
16
|
end
|
12
17
|
|
13
18
|
def tags(payload)
|
@@ -7,7 +7,7 @@ module Labkit
|
|
7
7
|
# ActionView bridges action view notifications to
|
8
8
|
# the distributed tracing subsystem
|
9
9
|
class Subscriber
|
10
|
-
include
|
10
|
+
include Labkit::Tracing::TracingCommon
|
11
11
|
|
12
12
|
RENDER_TEMPLATE_NOTIFICATION_TOPIC = "render_template.action_view"
|
13
13
|
RENDER_COLLECTION_NOTIFICATION_TOPIC = "render_collection.action_view"
|
@@ -5,7 +5,7 @@ module Labkit
|
|
5
5
|
module Rails
|
6
6
|
module ActiveRecord
|
7
7
|
# For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
|
8
|
-
class SqlInstrumenter < AbstractInstrumenter
|
8
|
+
class SqlInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
9
9
|
OPERATION_NAME_PREFIX = "active_record:"
|
10
10
|
DEFAULT_OPERATION_NAME = "sqlquery"
|
11
11
|
|
@@ -5,7 +5,7 @@ module Labkit
|
|
5
5
|
module Rails
|
6
6
|
module ActiveSupport
|
7
7
|
# For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
|
8
|
-
class CacheDeleteInstrumenter < AbstractInstrumenter
|
8
|
+
class CacheDeleteInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
9
9
|
def span_name(payload)
|
10
10
|
"cache_delete"
|
11
11
|
end
|
@@ -5,7 +5,7 @@ module Labkit
|
|
5
5
|
module Rails
|
6
6
|
module ActiveSupport
|
7
7
|
# For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
|
8
|
-
class CacheFetchHitInstrumenter < AbstractInstrumenter
|
8
|
+
class CacheFetchHitInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
9
9
|
def span_name(payload)
|
10
10
|
"cache_fetch_hit"
|
11
11
|
end
|
@@ -5,7 +5,7 @@ module Labkit
|
|
5
5
|
module Rails
|
6
6
|
module ActiveSupport
|
7
7
|
# For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
|
8
|
-
class CacheGenerateInstrumenter < AbstractInstrumenter
|
8
|
+
class CacheGenerateInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
9
9
|
def span_name(payload)
|
10
10
|
"cache_generate"
|
11
11
|
end
|
@@ -5,7 +5,7 @@ module Labkit
|
|
5
5
|
module Rails
|
6
6
|
module ActiveSupport
|
7
7
|
# For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
|
8
|
-
class CacheReadInstrumenter < AbstractInstrumenter
|
8
|
+
class CacheReadInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
9
9
|
def span_name(payload)
|
10
10
|
"cache_read"
|
11
11
|
end
|
@@ -5,7 +5,7 @@ module Labkit
|
|
5
5
|
module Rails
|
6
6
|
module ActiveSupport
|
7
7
|
# For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
|
8
|
-
class CacheWriteInstrumenter < AbstractInstrumenter
|
8
|
+
class CacheWriteInstrumenter < Labkit::Tracing::AbstractInstrumenter
|
9
9
|
def span_name(payload)
|
10
10
|
"cache_write"
|
11
11
|
end
|
@@ -7,7 +7,7 @@ module Labkit
|
|
7
7
|
# ActiveSupport bridges action active support notifications to
|
8
8
|
# the distributed tracing subsystem
|
9
9
|
class Subscriber
|
10
|
-
include
|
10
|
+
include Labkit::Tracing::TracingCommon
|
11
11
|
|
12
12
|
CACHE_READ_TOPIC = "cache_read.active_support"
|
13
13
|
CACHE_GENERATE_TOPIC = "cache_generate.active_support"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/all"
|
4
|
+
|
5
|
+
module Labkit
|
6
|
+
module Tracing
|
7
|
+
# TracingCommon is a mixin for providing instrumentation
|
8
|
+
# functionality for the instrumentation classes based on
|
9
|
+
# ActiveSupport::Notifications
|
10
|
+
module TracingCommon
|
11
|
+
extend ::ActiveSupport::Concern
|
12
|
+
|
13
|
+
class_methods do
|
14
|
+
def create_unsubscriber(subscriptions)
|
15
|
+
-> { subscriptions.each { |subscriber| ::ActiveSupport::Notifications.unsubscribe(subscriber) } }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-labkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Newdigate
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 5.0.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 7.0.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: 5.0.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 7.0.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: activesupport
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
version: 5.0.0
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
42
|
+
version: 7.0.0
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,7 +49,7 @@ dependencies:
|
|
49
49
|
version: 5.0.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version:
|
52
|
+
version: 7.0.0
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: grpc
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,6 +92,20 @@ dependencies:
|
|
92
92
|
- - "~>"
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0.4'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: pg_query
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '1.3'
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - "~>"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '1.3'
|
95
109
|
- !ruby/object:Gem::Dependency
|
96
110
|
name: redis
|
97
111
|
requirement: !ruby/object:Gem::Requirement
|
@@ -113,19 +127,33 @@ dependencies:
|
|
113
127
|
- !ruby/object:Gem::Version
|
114
128
|
version: 5.0.0
|
115
129
|
- !ruby/object:Gem::Dependency
|
116
|
-
name:
|
130
|
+
name: excon
|
117
131
|
requirement: !ruby/object:Gem::Requirement
|
118
132
|
requirements:
|
119
133
|
- - "~>"
|
120
134
|
- !ruby/object:Gem::Version
|
121
|
-
version:
|
122
|
-
type: :
|
135
|
+
version: 0.78.1
|
136
|
+
type: :development
|
123
137
|
prerelease: false
|
124
138
|
version_requirements: !ruby/object:Gem::Requirement
|
125
139
|
requirements:
|
126
140
|
- - "~>"
|
127
141
|
- !ruby/object:Gem::Version
|
128
|
-
version:
|
142
|
+
version: 0.78.1
|
143
|
+
- !ruby/object:Gem::Dependency
|
144
|
+
name: faraday
|
145
|
+
requirement: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - "~>"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 1.2.0
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - "~>"
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: 1.2.0
|
129
157
|
- !ruby/object:Gem::Dependency
|
130
158
|
name: grpc-tools
|
131
159
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,6 +168,34 @@ dependencies:
|
|
140
168
|
- - "~>"
|
141
169
|
- !ruby/object:Gem::Version
|
142
170
|
version: '1.19'
|
171
|
+
- !ruby/object:Gem::Dependency
|
172
|
+
name: httparty
|
173
|
+
requirement: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - "~>"
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: 0.17.3
|
178
|
+
type: :development
|
179
|
+
prerelease: false
|
180
|
+
version_requirements: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - "~>"
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: 0.17.3
|
185
|
+
- !ruby/object:Gem::Dependency
|
186
|
+
name: httpclient
|
187
|
+
requirement: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - "~>"
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: 2.8.3
|
192
|
+
type: :development
|
193
|
+
prerelease: false
|
194
|
+
version_requirements: !ruby/object:Gem::Requirement
|
195
|
+
requirements:
|
196
|
+
- - "~>"
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
version: 2.8.3
|
143
199
|
- !ruby/object:Gem::Dependency
|
144
200
|
name: pry
|
145
201
|
requirement: !ruby/object:Gem::Requirement
|
@@ -182,6 +238,20 @@ dependencies:
|
|
182
238
|
- - "~>"
|
183
239
|
- !ruby/object:Gem::Version
|
184
240
|
version: '12.3'
|
241
|
+
- !ruby/object:Gem::Dependency
|
242
|
+
name: rest-client
|
243
|
+
requirement: !ruby/object:Gem::Requirement
|
244
|
+
requirements:
|
245
|
+
- - "~>"
|
246
|
+
- !ruby/object:Gem::Version
|
247
|
+
version: 2.1.0
|
248
|
+
type: :development
|
249
|
+
prerelease: false
|
250
|
+
version_requirements: !ruby/object:Gem::Requirement
|
251
|
+
requirements:
|
252
|
+
- - "~>"
|
253
|
+
- !ruby/object:Gem::Version
|
254
|
+
version: 2.1.0
|
185
255
|
- !ruby/object:Gem::Dependency
|
186
256
|
name: rspec
|
187
257
|
requirement: !ruby/object:Gem::Requirement
|
@@ -275,6 +345,7 @@ extra_rdoc_files: []
|
|
275
345
|
files:
|
276
346
|
- ".gitignore"
|
277
347
|
- ".gitlab-ci.yml"
|
348
|
+
- ".gitlab/CODEOWNERS"
|
278
349
|
- ".rspec"
|
279
350
|
- ".rubocop.yml"
|
280
351
|
- ".ruby-version"
|
@@ -292,6 +363,8 @@ files:
|
|
292
363
|
- lib/labkit/correlation/grpc/client_interceptor.rb
|
293
364
|
- lib/labkit/correlation/grpc/grpc_common.rb
|
294
365
|
- lib/labkit/correlation/grpc/server_interceptor.rb
|
366
|
+
- lib/labkit/excon_publisher.rb
|
367
|
+
- lib/labkit/httpclient_publisher.rb
|
295
368
|
- lib/labkit/logging.rb
|
296
369
|
- lib/labkit/logging/grpc.rb
|
297
370
|
- lib/labkit/logging/grpc/server_interceptor.rb
|
@@ -308,7 +381,12 @@ files:
|
|
308
381
|
- lib/labkit/middleware/sidekiq/tracing/client.rb
|
309
382
|
- lib/labkit/middleware/sidekiq/tracing/server.rb
|
310
383
|
- lib/labkit/middleware/sidekiq/tracing/sidekiq_common.rb
|
384
|
+
- lib/labkit/net_http_publisher.rb
|
385
|
+
- lib/labkit/system.rb
|
311
386
|
- lib/labkit/tracing.rb
|
387
|
+
- lib/labkit/tracing/abstract_instrumenter.rb
|
388
|
+
- lib/labkit/tracing/external_http.rb
|
389
|
+
- lib/labkit/tracing/external_http/request_instrumenter.rb
|
312
390
|
- lib/labkit/tracing/factory.rb
|
313
391
|
- lib/labkit/tracing/grpc.rb
|
314
392
|
- lib/labkit/tracing/grpc/client_interceptor.rb
|
@@ -317,7 +395,6 @@ files:
|
|
317
395
|
- lib/labkit/tracing/jaeger_factory.rb
|
318
396
|
- lib/labkit/tracing/rack_middleware.rb
|
319
397
|
- lib/labkit/tracing/rails.rb
|
320
|
-
- lib/labkit/tracing/rails/abstract_instrumenter.rb
|
321
398
|
- lib/labkit/tracing/rails/action_view.rb
|
322
399
|
- lib/labkit/tracing/rails/action_view/render_collection_instrumenter.rb
|
323
400
|
- lib/labkit/tracing/rails/action_view/render_partial_instrumenter.rb
|
@@ -333,10 +410,10 @@ files:
|
|
333
410
|
- lib/labkit/tracing/rails/active_support/cache_read_instrumenter.rb
|
334
411
|
- lib/labkit/tracing/rails/active_support/cache_write_instrumenter.rb
|
335
412
|
- lib/labkit/tracing/rails/active_support/subscriber.rb
|
336
|
-
- lib/labkit/tracing/rails/rails_common.rb
|
337
413
|
- lib/labkit/tracing/redis.rb
|
338
414
|
- lib/labkit/tracing/redis/redis_interceptor.rb
|
339
415
|
- lib/labkit/tracing/redis/redis_interceptor_helper.rb
|
416
|
+
- lib/labkit/tracing/tracing_common.rb
|
340
417
|
- lib/labkit/tracing/tracing_utils.rb
|
341
418
|
homepage: https://gitlab.com/gitlab-org/labkit-ruby
|
342
419
|
licenses:
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "active_support/all"
|
4
|
-
|
5
|
-
module Labkit
|
6
|
-
module Tracing
|
7
|
-
module Rails
|
8
|
-
# https://edgeapi.rubyonrails.org/classes/ActiveSupport/Notifications/Instrumenter.html#method-c-new
|
9
|
-
class AbstractInstrumenter
|
10
|
-
def start(name, id, payload)
|
11
|
-
scope = OpenTracing.start_active_span(span_name(payload))
|
12
|
-
|
13
|
-
scope_stack.push scope
|
14
|
-
end
|
15
|
-
|
16
|
-
def finish(name, id, payload)
|
17
|
-
scope = scope_stack.pop
|
18
|
-
span = scope.span
|
19
|
-
|
20
|
-
Labkit::Tracing::TracingUtils.log_common_fields_on_span(span, span_name(payload))
|
21
|
-
|
22
|
-
exception = payload[:exception]
|
23
|
-
Labkit::Tracing::TracingUtils.log_exception_on_span(span, exception) if exception
|
24
|
-
|
25
|
-
tags(payload).each do |k, v|
|
26
|
-
span.set_tag(k, v)
|
27
|
-
end
|
28
|
-
|
29
|
-
scope.close
|
30
|
-
end
|
31
|
-
|
32
|
-
def scope_stack
|
33
|
-
Thread.current[:_labkit_trace_scope_stack] ||= []
|
34
|
-
end
|
35
|
-
|
36
|
-
def span_name(payload)
|
37
|
-
raise "span_name not implemented"
|
38
|
-
end
|
39
|
-
|
40
|
-
def tags(payload)
|
41
|
-
{}
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "active_support/all"
|
4
|
-
|
5
|
-
module Labkit
|
6
|
-
module Tracing
|
7
|
-
module Rails
|
8
|
-
# RailsCommon is a mixin for providing instrumentation
|
9
|
-
# functionality for the rails instrumentation classes
|
10
|
-
module RailsCommon
|
11
|
-
extend ::ActiveSupport::Concern
|
12
|
-
|
13
|
-
class_methods do
|
14
|
-
def create_unsubscriber(subscriptions)
|
15
|
-
-> { subscriptions.each { |subscriber| ::ActiveSupport::Notifications.unsubscribe(subscriber) } }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|