gitlab-labkit 0.13.4 → 0.16.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/.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
|