gitlab-labkit 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/gitlab-labkit.gemspec +3 -1
- data/lib/gitlab-labkit.rb +2 -0
- data/lib/labkit/context.rb +133 -0
- data/lib/labkit/correlation/correlation_id.rb +6 -23
- data/lib/labkit/correlation/grpc.rb +1 -0
- data/lib/labkit/correlation/grpc/client_interceptor.rb +52 -0
- data/lib/labkit/middleware.rb +9 -0
- data/lib/labkit/middleware/rack.rb +34 -0
- data/lib/labkit/middleware/sidekiq.rb +11 -0
- data/lib/labkit/middleware/sidekiq/client.rb +20 -0
- data/lib/labkit/middleware/sidekiq/server.rb +17 -0
- metadata +39 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c306478521702991b9c5ba1d80e6ab1c3bcb42b70562890a48204ab9e320c6b8
|
4
|
+
data.tar.gz: 5b4fdf319fa79405c89c0de7d91617602a6aec6bf784223a6d8e86830c6900ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f88db3bf552afa6f20e95e8760d91b97149d41e4b1cfe995c0e64bdc852ca0490713ba52a5bdcadebea1c827b83b344df61695386741c37d2dd8458243bd0144
|
7
|
+
data.tar.gz: a1ab50bd164cd46da510b03ac53aa3e148a6b8720611ef380b288d282072446b06772c43777c019da4fd93d5d9b1e1f197704fc36bf0b6e47985fc35535e2a9b
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.6.3
|
data/gitlab-labkit.gemspec
CHANGED
@@ -28,11 +28,13 @@ Gem::Specification.new do |spec|
|
|
28
28
|
|
29
29
|
# Please maintain alphabetical order for dev dependencies
|
30
30
|
spec.add_development_dependency "grpc-tools", "~> 1.19"
|
31
|
+
spec.add_development_dependency "pry", "~> 0.12"
|
31
32
|
spec.add_development_dependency "rack", "~> 2.0"
|
32
33
|
spec.add_development_dependency "rake", "~> 12.3"
|
33
|
-
spec.add_development_dependency "rspec", "~> 3.
|
34
|
+
spec.add_development_dependency "rspec", "~> 3.8.0"
|
34
35
|
spec.add_development_dependency "rspec-parameterized", "~> 0.4"
|
35
36
|
spec.add_development_dependency "rubocop", "~> 0.65.0"
|
36
37
|
spec.add_development_dependency "rubocop-rspec", "~> 1.22.1"
|
37
38
|
spec.add_development_dependency "rufo", "~> 0.6"
|
39
|
+
spec.add_development_dependency "sidekiq", "~> 5.2.7"
|
38
40
|
end
|
data/lib/gitlab-labkit.rb
CHANGED
@@ -8,8 +8,10 @@ require "active_support/all"
|
|
8
8
|
# observability.
|
9
9
|
module Labkit
|
10
10
|
autoload :Correlation, "labkit/correlation"
|
11
|
+
autoload :Context, "labkit/context"
|
11
12
|
autoload :Tracing, "labkit/tracing"
|
12
13
|
autoload :Logging, "labkit/logging"
|
14
|
+
autoload :Middleware, "labkit/middleware"
|
13
15
|
end
|
14
16
|
|
15
17
|
# rubocop:enable Naming/FileName
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labkit
|
4
|
+
# A context can be used to provide structured information on what resources
|
5
|
+
# GitLab is working on within a service.
|
6
|
+
# The currently supported keys are defined in the `KNOWN_KEYS` constant.
|
7
|
+
#
|
8
|
+
# Values can be provided by passing a hash. If one of the values is a Proc
|
9
|
+
# the proc will only be called when the value is actually needed.
|
10
|
+
#
|
11
|
+
# Multiple contexts can be nested, the nested context will inherit the values
|
12
|
+
# from the closest outer one.
|
13
|
+
# All contexts will have the same correlation id.
|
14
|
+
#
|
15
|
+
# Usage:
|
16
|
+
# Labkit::Context.with_context(user: 'username', root_namespace: -> { get_root_namespace } do |context|
|
17
|
+
# logger.info(context.to_h)
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
class Context
|
21
|
+
LOG_KEY = "meta"
|
22
|
+
CORRELATION_ID_KEY = "correlation_id"
|
23
|
+
RAW_KEYS = [CORRELATION_ID_KEY].freeze
|
24
|
+
KNOWN_KEYS = %w[user project root_namespace].freeze
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def with_context(attributes = {})
|
28
|
+
context = push(attributes)
|
29
|
+
|
30
|
+
begin
|
31
|
+
yield(context)
|
32
|
+
ensure
|
33
|
+
pop(context)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def push(new_attributes = {})
|
38
|
+
new_context = current&.merge(new_attributes) || new(new_attributes)
|
39
|
+
|
40
|
+
contexts.push(new_context)
|
41
|
+
|
42
|
+
new_context
|
43
|
+
end
|
44
|
+
|
45
|
+
def pop(context)
|
46
|
+
contexts.pop while contexts.include?(context)
|
47
|
+
end
|
48
|
+
|
49
|
+
def correlation_id
|
50
|
+
contexts.last&.correlation_id
|
51
|
+
end
|
52
|
+
|
53
|
+
def current
|
54
|
+
contexts.last
|
55
|
+
end
|
56
|
+
|
57
|
+
def log_key(key)
|
58
|
+
key = key.to_s
|
59
|
+
return key if RAW_KEYS.include?(key)
|
60
|
+
return key if key.starts_with?("#{LOG_KEY}.")
|
61
|
+
|
62
|
+
"#{LOG_KEY}.#{key}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def known_log_keys
|
66
|
+
@known_log_keys ||= (KNOWN_KEYS.map(&method(:log_key)) + RAW_KEYS).freeze
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def contexts
|
72
|
+
Thread.current[:labkit_contexts] ||= []
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def initialize(values = {})
|
77
|
+
@data = {}
|
78
|
+
|
79
|
+
assign_attributes(values)
|
80
|
+
end
|
81
|
+
|
82
|
+
def merge(new_attributes)
|
83
|
+
new_context = self.class.new(data.dup)
|
84
|
+
new_context.assign_attributes(new_attributes)
|
85
|
+
|
86
|
+
new_context
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_h
|
90
|
+
expand_data
|
91
|
+
end
|
92
|
+
|
93
|
+
def correlation_id
|
94
|
+
data[CORRELATION_ID_KEY]
|
95
|
+
end
|
96
|
+
|
97
|
+
protected
|
98
|
+
|
99
|
+
def assign_attributes(attributes)
|
100
|
+
attributes = attributes.transform_keys(&method(:log_key))
|
101
|
+
attributes = attributes.slice(*known_log_keys)
|
102
|
+
|
103
|
+
data.merge!(attributes)
|
104
|
+
|
105
|
+
# Remove keys that had their values set to `nil` in the new attributes
|
106
|
+
data.keep_if { |_, value| value.present? }
|
107
|
+
|
108
|
+
# Assign a correlation if it was missing in the first context or when
|
109
|
+
# explicitly removed
|
110
|
+
data[CORRELATION_ID_KEY] ||= new_id
|
111
|
+
|
112
|
+
data
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
delegate :log_key, :known_log_keys, to: :class
|
118
|
+
|
119
|
+
attr_reader :data
|
120
|
+
|
121
|
+
def expand_data
|
122
|
+
data.transform_values do |value|
|
123
|
+
value = value.respond_to?(:call) ? value.call : value
|
124
|
+
|
125
|
+
value.presence
|
126
|
+
end.compact
|
127
|
+
end
|
128
|
+
|
129
|
+
def new_id
|
130
|
+
SecureRandom.hex
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -5,38 +5,21 @@ module Labkit
|
|
5
5
|
# CorrelationId module provides access the Correlation-ID
|
6
6
|
# of the current request
|
7
7
|
module CorrelationId
|
8
|
-
LOG_KEY =
|
8
|
+
LOG_KEY = Labkit::Context::CORRELATION_ID_KEY
|
9
9
|
|
10
10
|
class << self
|
11
|
-
def use_id(correlation_id
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
ids.push(correlation_id || new_id)
|
16
|
-
|
17
|
-
begin
|
18
|
-
yield(current_id)
|
19
|
-
ensure
|
20
|
-
ids.pop
|
11
|
+
def use_id(correlation_id)
|
12
|
+
Labkit::Context.with_context(LOG_KEY => correlation_id) do |context|
|
13
|
+
yield(context.correlation_id)
|
21
14
|
end
|
22
15
|
end
|
23
16
|
|
24
17
|
def current_id
|
25
|
-
|
18
|
+
Labkit::Context.correlation_id
|
26
19
|
end
|
27
20
|
|
28
21
|
def current_or_new_id
|
29
|
-
current_id ||
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def ids
|
35
|
-
Thread.current[:correlation_id] ||= []
|
36
|
-
end
|
37
|
-
|
38
|
-
def new_id
|
39
|
-
SecureRandom.uuid
|
22
|
+
current_id || Labkit::Context.push.correlation_id
|
40
23
|
end
|
41
24
|
end
|
42
25
|
end
|
@@ -4,6 +4,7 @@ module Labkit
|
|
4
4
|
module Correlation
|
5
5
|
# The GRPC module contains functionality for instrumenting GRPC calls
|
6
6
|
module GRPC
|
7
|
+
autoload :ClientInterceptor, "labkit/correlation/grpc/client_interceptor"
|
7
8
|
autoload :GRPCCommon, "labkit/correlation/grpc/grpc_common"
|
8
9
|
autoload :ServerInterceptor, "labkit/correlation/grpc/server_interceptor"
|
9
10
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Disable the UnusedMethodArgument linter, since we need to declare the kwargs
|
4
|
+
# in the methods, but we don't actually use them.
|
5
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
6
|
+
|
7
|
+
require "grpc"
|
8
|
+
|
9
|
+
module Labkit
|
10
|
+
module Correlation
|
11
|
+
module GRPC
|
12
|
+
# ClientInterceptor is used to inject the correlation_id into the metadata
|
13
|
+
# or a GRPC call for onward propagation to the server
|
14
|
+
class ClientInterceptor < ::GRPC::ClientInterceptor
|
15
|
+
include Labkit::Correlation::GRPC::GRPCCommon
|
16
|
+
include Singleton
|
17
|
+
|
18
|
+
def request_response(request:, call:, method:, metadata:)
|
19
|
+
inject_correlation_id_into_metadata(metadata)
|
20
|
+
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
|
24
|
+
def client_streamer(requests:, call:, method:, metadata:)
|
25
|
+
inject_correlation_id_into_metadata(metadata)
|
26
|
+
|
27
|
+
yield
|
28
|
+
end
|
29
|
+
|
30
|
+
def server_streamer(request:, call:, method:, metadata:)
|
31
|
+
inject_correlation_id_into_metadata(metadata)
|
32
|
+
|
33
|
+
yield
|
34
|
+
end
|
35
|
+
|
36
|
+
def bidi_streamer(requests:, call:, method:, metadata:)
|
37
|
+
inject_correlation_id_into_metadata(metadata)
|
38
|
+
|
39
|
+
yield
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def inject_correlation_id_into_metadata(metadata, &block)
|
45
|
+
metadata[CORRELATION_METADATA_KEY] = Labkit::Correlation::CorrelationId.current_id if Labkit::Correlation::CorrelationId.current_id
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_dispatch"
|
4
|
+
|
5
|
+
module Labkit
|
6
|
+
module Middleware
|
7
|
+
# This is a rack middleware to be inserted in GitLab-rails
|
8
|
+
# It makes sure that there's always a root context containing the correlation
|
9
|
+
# id.
|
10
|
+
# Since this context always get's cleaned up by this middleware, we can be
|
11
|
+
# sure that any nested contexts will also be cleaned up.
|
12
|
+
class Rack
|
13
|
+
def initialize(app)
|
14
|
+
@app = app
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
Labkit::Context.with_context(Labkit::Context::CORRELATION_ID_KEY => correlation_id(env)) do
|
19
|
+
@app.call(env)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def correlation_id(env)
|
26
|
+
request(env).request_id
|
27
|
+
end
|
28
|
+
|
29
|
+
def request(env)
|
30
|
+
ActionDispatch::Request.new(env)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labkit
|
4
|
+
module Middleware
|
5
|
+
module Sidekiq
|
6
|
+
# This middleware for Sidekiq-client wraps scheduling jobs in a context
|
7
|
+
# The context will also be added to the sidekiq job in redis so it can
|
8
|
+
# be reinstantiated by Sidekiq-server when running the job.
|
9
|
+
class Client
|
10
|
+
def call(_worker_class, job, _queue, _redis_pool)
|
11
|
+
Labkit::Context.with_context do |context|
|
12
|
+
job.merge!(context.to_h)
|
13
|
+
|
14
|
+
yield
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Labkit
|
4
|
+
module Middleware
|
5
|
+
module Sidekiq
|
6
|
+
# This middleware for Sidekiq-client uses the values stored on a job to
|
7
|
+
# reinstantiate a context in which the job will run.
|
8
|
+
class Server
|
9
|
+
def call(_worker_class, job, _queue)
|
10
|
+
Labkit::Context.with_context(job) do |_context|
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
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.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Newdigate
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -126,6 +126,20 @@ dependencies:
|
|
126
126
|
- - "~>"
|
127
127
|
- !ruby/object:Gem::Version
|
128
128
|
version: '1.19'
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
name: pry
|
131
|
+
requirement: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0.12'
|
136
|
+
type: :development
|
137
|
+
prerelease: false
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - "~>"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0.12'
|
129
143
|
- !ruby/object:Gem::Dependency
|
130
144
|
name: rack
|
131
145
|
requirement: !ruby/object:Gem::Requirement
|
@@ -160,14 +174,14 @@ dependencies:
|
|
160
174
|
requirements:
|
161
175
|
- - "~>"
|
162
176
|
- !ruby/object:Gem::Version
|
163
|
-
version: 3.
|
177
|
+
version: 3.8.0
|
164
178
|
type: :development
|
165
179
|
prerelease: false
|
166
180
|
version_requirements: !ruby/object:Gem::Requirement
|
167
181
|
requirements:
|
168
182
|
- - "~>"
|
169
183
|
- !ruby/object:Gem::Version
|
170
|
-
version: 3.
|
184
|
+
version: 3.8.0
|
171
185
|
- !ruby/object:Gem::Dependency
|
172
186
|
name: rspec-parameterized
|
173
187
|
requirement: !ruby/object:Gem::Requirement
|
@@ -224,6 +238,20 @@ dependencies:
|
|
224
238
|
- - "~>"
|
225
239
|
- !ruby/object:Gem::Version
|
226
240
|
version: '0.6'
|
241
|
+
- !ruby/object:Gem::Dependency
|
242
|
+
name: sidekiq
|
243
|
+
requirement: !ruby/object:Gem::Requirement
|
244
|
+
requirements:
|
245
|
+
- - "~>"
|
246
|
+
- !ruby/object:Gem::Version
|
247
|
+
version: 5.2.7
|
248
|
+
type: :development
|
249
|
+
prerelease: false
|
250
|
+
version_requirements: !ruby/object:Gem::Requirement
|
251
|
+
requirements:
|
252
|
+
- - "~>"
|
253
|
+
- !ruby/object:Gem::Version
|
254
|
+
version: 5.2.7
|
227
255
|
description:
|
228
256
|
email:
|
229
257
|
- andrew@gitlab.com
|
@@ -243,13 +271,20 @@ files:
|
|
243
271
|
- Rakefile
|
244
272
|
- gitlab-labkit.gemspec
|
245
273
|
- lib/gitlab-labkit.rb
|
274
|
+
- lib/labkit/context.rb
|
246
275
|
- lib/labkit/correlation.rb
|
247
276
|
- lib/labkit/correlation/correlation_id.rb
|
248
277
|
- lib/labkit/correlation/grpc.rb
|
278
|
+
- lib/labkit/correlation/grpc/client_interceptor.rb
|
249
279
|
- lib/labkit/correlation/grpc/grpc_common.rb
|
250
280
|
- lib/labkit/correlation/grpc/server_interceptor.rb
|
251
281
|
- lib/labkit/logging.rb
|
252
282
|
- lib/labkit/logging/sanitizer.rb
|
283
|
+
- lib/labkit/middleware.rb
|
284
|
+
- lib/labkit/middleware/rack.rb
|
285
|
+
- lib/labkit/middleware/sidekiq.rb
|
286
|
+
- lib/labkit/middleware/sidekiq/client.rb
|
287
|
+
- lib/labkit/middleware/sidekiq/server.rb
|
253
288
|
- lib/labkit/tracing.rb
|
254
289
|
- lib/labkit/tracing/factory.rb
|
255
290
|
- lib/labkit/tracing/grpc.rb
|