gitlab-labkit 0.12.1 → 0.13.3
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-ci.yml +13 -4
- data/gitlab-labkit.gemspec +2 -1
- data/lib/labkit/context.rb +1 -1
- data/lib/labkit/correlation/grpc/grpc_common.rb +10 -0
- data/lib/labkit/logging.rb +1 -0
- data/lib/labkit/logging/grpc.rb +9 -0
- data/lib/labkit/logging/grpc/server_interceptor.rb +85 -0
- data/lib/labkit/logging/sanitizer.rb +8 -0
- data/lib/labkit/tracing.rb +6 -0
- data/lib/labkit/tracing/grpc/server_interceptor.rb +3 -8
- data/lib/labkit/tracing/jaeger_factory.rb +3 -0
- data/lib/labkit/tracing/rails/active_record/sql_instrumenter.rb +2 -1
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7365b2f12b026f6b497d56738197b66e34014676dc284f568e97fad669cecef
|
4
|
+
data.tar.gz: ca9da033595aed9506edd7ba376a1bdd0b15c8e880a5e6b3edc52dc72b5a5570
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87aaa07295098883563e77694fdb1401ba9e2e5fbc26569ee0b87f8ce7bc329f0d26b78df5d2e1c2e97b86f3d7ec3c41200406eb2b7028aba8ce8bdec4001ab4
|
7
|
+
data.tar.gz: 42f5dcee07855cd347b9585b96e44ac3e36e05a5fd634db55ddea02676b82df9c35e0ba3d6bbbbf0e4c6b4ec16906ff8a86f041db67d392485008d811f3d20b2
|
data/.gitlab-ci.yml
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
workflow:
|
2
|
+
rules:
|
3
|
+
# For merge requests, create a pipeline.
|
4
|
+
- if: '$CI_MERGE_REQUEST_IID'
|
5
|
+
# For `master` branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
|
6
|
+
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
7
|
+
# For tags, create a pipeline.
|
8
|
+
- if: '$CI_COMMIT_TAG'
|
9
|
+
|
1
10
|
.test_template: &test_definition
|
2
11
|
stage: test
|
3
12
|
script:
|
@@ -5,6 +14,10 @@
|
|
5
14
|
- bundle install
|
6
15
|
- bundle exec rake verify build install
|
7
16
|
|
17
|
+
test:2.7:
|
18
|
+
image: ruby:2.7
|
19
|
+
<<: *test_definition
|
20
|
+
|
8
21
|
test:2.6:
|
9
22
|
image: ruby:2.6
|
10
23
|
<<: *test_definition
|
@@ -13,10 +26,6 @@ test:2.5:
|
|
13
26
|
image: ruby:2.5
|
14
27
|
<<: *test_definition
|
15
28
|
|
16
|
-
test:2.4:
|
17
|
-
image: ruby:2.4
|
18
|
-
<<: *test_definition
|
19
|
-
|
20
29
|
deploy:
|
21
30
|
stage: deploy
|
22
31
|
script:
|
data/gitlab-labkit.gemspec
CHANGED
@@ -22,9 +22,10 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_runtime_dependency "actionpack", ">= 5.0.0", "< 6.1.0"
|
23
23
|
spec.add_runtime_dependency "activesupport", ">= 5.0.0", "< 6.1.0"
|
24
24
|
spec.add_runtime_dependency "grpc", "~> 1.19" # Be sure to update the "grpc-tools" dev_depenency too
|
25
|
-
spec.add_runtime_dependency "jaeger-client", "~>
|
25
|
+
spec.add_runtime_dependency "jaeger-client", "~> 1.1"
|
26
26
|
spec.add_runtime_dependency "opentracing", "~> 0.4"
|
27
27
|
spec.add_runtime_dependency "redis", ">3.0.0", "<5.0.0"
|
28
|
+
spec.add_runtime_dependency "gitlab-pg_query", "~> 1.3"
|
28
29
|
|
29
30
|
# Please maintain alphabetical order for dev dependencies
|
30
31
|
spec.add_development_dependency "grpc-tools", "~> 1.19"
|
data/lib/labkit/context.rb
CHANGED
@@ -22,7 +22,7 @@ module Labkit
|
|
22
22
|
CORRELATION_ID_KEY = "correlation_id"
|
23
23
|
RAW_KEYS = [CORRELATION_ID_KEY].freeze
|
24
24
|
KNOWN_KEYS = %w[user project root_namespace subscription_plan caller_id
|
25
|
-
related_class].freeze
|
25
|
+
related_class feature_category].freeze
|
26
26
|
|
27
27
|
class << self
|
28
28
|
def with_context(attributes = {})
|
@@ -7,6 +7,16 @@ module Labkit
|
|
7
7
|
# It is not part of the public API
|
8
8
|
module GRPCCommon
|
9
9
|
CORRELATION_METADATA_KEY = "x-gitlab-correlation-id"
|
10
|
+
|
11
|
+
def rpc_split(method)
|
12
|
+
owner = method.owner
|
13
|
+
method_name, = owner.rpc_descs.find do |k, _|
|
14
|
+
::GRPC::GenericService.underscore(k.to_s) == method.name.to_s
|
15
|
+
end
|
16
|
+
method_name ||= "(unknown)"
|
17
|
+
|
18
|
+
[owner.service_name, method_name]
|
19
|
+
end
|
10
20
|
end
|
11
21
|
end
|
12
22
|
end
|
data/lib/labkit/logging.rb
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "grpc"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
module Labkit
|
7
|
+
module Logging
|
8
|
+
module GRPC
|
9
|
+
class ServerInterceptor < ::GRPC::ServerInterceptor
|
10
|
+
include Labkit::Correlation::GRPC::GRPCCommon
|
11
|
+
|
12
|
+
CODE_STRINGS = {
|
13
|
+
::GRPC::Core::StatusCodes::OK => "OK",
|
14
|
+
::GRPC::Core::StatusCodes::CANCELLED => "Canceled",
|
15
|
+
::GRPC::Core::StatusCodes::UNKNOWN => "Unknown",
|
16
|
+
::GRPC::Core::StatusCodes::INVALID_ARGUMENT => "InvalidArgument",
|
17
|
+
::GRPC::Core::StatusCodes::DEADLINE_EXCEEDED => "DeadlineExceeded",
|
18
|
+
::GRPC::Core::StatusCodes::NOT_FOUND => "NotFound",
|
19
|
+
::GRPC::Core::StatusCodes::ALREADY_EXISTS => "AlreadyExists",
|
20
|
+
::GRPC::Core::StatusCodes::PERMISSION_DENIED => "PermissionDenied",
|
21
|
+
::GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED => "ResourceExhausted",
|
22
|
+
::GRPC::Core::StatusCodes::FAILED_PRECONDITION => "FailedPrecondition",
|
23
|
+
::GRPC::Core::StatusCodes::ABORTED => "Aborted",
|
24
|
+
::GRPC::Core::StatusCodes::OUT_OF_RANGE => "OutOfRange",
|
25
|
+
::GRPC::Core::StatusCodes::UNIMPLEMENTED => "Unimplemented",
|
26
|
+
::GRPC::Core::StatusCodes::INTERNAL => "Internal",
|
27
|
+
::GRPC::Core::StatusCodes::UNAVAILABLE => "Unavailable",
|
28
|
+
::GRPC::Core::StatusCodes::DATA_LOSS => "DataLoss",
|
29
|
+
::GRPC::Core::StatusCodes::UNAUTHENTICATED => "Unauthenticated",
|
30
|
+
}.freeze
|
31
|
+
|
32
|
+
def initialize(log_file, default_tags)
|
33
|
+
@log_file = log_file
|
34
|
+
@log_file.sync = true
|
35
|
+
@default_tags = default_tags
|
36
|
+
|
37
|
+
super()
|
38
|
+
end
|
39
|
+
|
40
|
+
def request_response(request: nil, call: nil, method: nil)
|
41
|
+
log_request(method, call) { yield }
|
42
|
+
end
|
43
|
+
|
44
|
+
def server_streamer(request: nil, call: nil, method: nil)
|
45
|
+
log_request(method, call) { yield }
|
46
|
+
end
|
47
|
+
|
48
|
+
def client_streamer(call: nil, method: nil)
|
49
|
+
log_request(method, call) { yield }
|
50
|
+
end
|
51
|
+
|
52
|
+
def bidi_streamer(requests: nil, call: nil, method: nil)
|
53
|
+
log_request(method, call) { yield }
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def log_request(method, call)
|
59
|
+
start = Time.now
|
60
|
+
code = ::GRPC::Core::StatusCodes::OK
|
61
|
+
|
62
|
+
yield
|
63
|
+
rescue StandardError => ex
|
64
|
+
code = ex.is_a?(::GRPC::BadStatus) ? ex.code : ::GRPC::Core::StatusCodes::UNKNOWN
|
65
|
+
|
66
|
+
raise
|
67
|
+
ensure
|
68
|
+
service_name, method_name = rpc_split(method)
|
69
|
+
message = @default_tags.merge(
|
70
|
+
'grpc.start_time': start.utc.rfc3339,
|
71
|
+
'grpc.time_ms': ((Time.now - start) * 1000.0).truncate(3),
|
72
|
+
'grpc.code': CODE_STRINGS.fetch(code, code.to_s),
|
73
|
+
'grpc.method': method_name,
|
74
|
+
'grpc.service': service_name,
|
75
|
+
pid: Process.pid,
|
76
|
+
correlation_id: Labkit::Correlation::CorrelationId.current_id.to_s,
|
77
|
+
time: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ"),
|
78
|
+
)
|
79
|
+
|
80
|
+
@log_file.puts(JSON.dump(message))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "pg_query"
|
4
|
+
|
3
5
|
module Labkit
|
4
6
|
module Logging
|
5
7
|
# Sanitizer provides log message sanitization, removing
|
@@ -22,6 +24,12 @@ module Labkit
|
|
22
24
|
content
|
23
25
|
end
|
24
26
|
|
27
|
+
def self.sanitize_sql(sql)
|
28
|
+
PgQuery.normalize(sql)
|
29
|
+
rescue PgQuery::ParseError
|
30
|
+
""
|
31
|
+
end
|
32
|
+
|
25
33
|
# Ensures that URLS are sanitized to hide credentials
|
26
34
|
def self.mask_url(url)
|
27
35
|
url = url.to_s.strip
|
data/lib/labkit/tracing.rb
CHANGED
@@ -28,6 +28,12 @@ module Labkit
|
|
28
28
|
ENV["GITLAB_TRACING_URL"]
|
29
29
|
end
|
30
30
|
|
31
|
+
# Check if the current request is being traced.
|
32
|
+
def self.sampled?
|
33
|
+
context = OpenTracing.active_span&.context
|
34
|
+
context && context.respond_to?(:sampled?) && context.sampled?
|
35
|
+
end
|
36
|
+
|
31
37
|
def self.stacktrace_operations
|
32
38
|
@stacktrace_operations ||= Set.new(ENV["GITLAB_TRACING_INCLUDE_STACKTRACE"].to_s.split(",").map(&:strip))
|
33
39
|
end
|
@@ -14,6 +14,8 @@ module Labkit
|
|
14
14
|
# for instrumenting GRPC calls with distributed tracing
|
15
15
|
# in a GRPC Ruby server
|
16
16
|
class ServerInterceptor < ::GRPC::ServerInterceptor
|
17
|
+
include Labkit::Correlation::GRPC::GRPCCommon
|
18
|
+
|
17
19
|
def request_response(request: nil, call: nil, method: nil)
|
18
20
|
wrap_with_tracing(call, method, "unary") do
|
19
21
|
yield
|
@@ -40,16 +42,9 @@ module Labkit
|
|
40
42
|
|
41
43
|
private
|
42
44
|
|
43
|
-
def route_from_method(method)
|
44
|
-
service_class = method.owner
|
45
|
-
rpc_method = method.name.to_s.split("_").map(&:capitalize).join("")
|
46
|
-
|
47
|
-
"/#{service_class.service_name}/#{rpc_method}"
|
48
|
-
end
|
49
|
-
|
50
45
|
def wrap_with_tracing(call, method, grpc_type)
|
51
46
|
context = TracingUtils.tracer.extract(OpenTracing::FORMAT_TEXT_MAP, call.metadata)
|
52
|
-
method_name =
|
47
|
+
method_name = "/#{rpc_split(method).join("/")}"
|
53
48
|
tags = {
|
54
49
|
"component" => "grpc",
|
55
50
|
"span.kind" => "server",
|
@@ -19,6 +19,9 @@ module Labkit
|
|
19
19
|
FLUSH_INTERVAL = 5
|
20
20
|
|
21
21
|
def self.create_tracer(service_name, options)
|
22
|
+
# The service_name parameter from GITLAB_TRACING takes precedence over the application one
|
23
|
+
service_name = options[:service_name] if options[:service_name]
|
24
|
+
|
22
25
|
kwargs = {
|
23
26
|
service_name: service_name,
|
24
27
|
sampler: get_sampler(options[:sampler], options[:sampler_param]),
|
@@ -14,13 +14,14 @@ module Labkit
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def tags(payload)
|
17
|
+
sql = Labkit::Logging::Sanitizer.sanitize_sql(payload[:sql]) if Labkit::Tracing.sampled? && payload[:sql]
|
17
18
|
{
|
18
19
|
"component" => COMPONENT_TAG,
|
19
20
|
"span.kind" => "client",
|
20
21
|
"db.type" => "sql",
|
21
22
|
"db.connection_id" => payload[:connection_id],
|
22
23
|
"db.cached" => payload[:cached] || false,
|
23
|
-
"db.statement" =>
|
24
|
+
"db.statement" => sql,
|
24
25
|
}
|
25
26
|
end
|
26
27
|
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.13.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Newdigate
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -70,14 +70,14 @@ dependencies:
|
|
70
70
|
requirements:
|
71
71
|
- - "~>"
|
72
72
|
- !ruby/object:Gem::Version
|
73
|
-
version: '
|
73
|
+
version: '1.1'
|
74
74
|
type: :runtime
|
75
75
|
prerelease: false
|
76
76
|
version_requirements: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
78
|
- - "~>"
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: '
|
80
|
+
version: '1.1'
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: opentracing
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,6 +112,20 @@ dependencies:
|
|
112
112
|
- - "<"
|
113
113
|
- !ruby/object:Gem::Version
|
114
114
|
version: 5.0.0
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: gitlab-pg_query
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - "~>"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '1.3'
|
122
|
+
type: :runtime
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - "~>"
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '1.3'
|
115
129
|
- !ruby/object:Gem::Dependency
|
116
130
|
name: grpc-tools
|
117
131
|
requirement: !ruby/object:Gem::Requirement
|
@@ -279,6 +293,8 @@ files:
|
|
279
293
|
- lib/labkit/correlation/grpc/grpc_common.rb
|
280
294
|
- lib/labkit/correlation/grpc/server_interceptor.rb
|
281
295
|
- lib/labkit/logging.rb
|
296
|
+
- lib/labkit/logging/grpc.rb
|
297
|
+
- lib/labkit/logging/grpc/server_interceptor.rb
|
282
298
|
- lib/labkit/logging/sanitizer.rb
|
283
299
|
- lib/labkit/middleware.rb
|
284
300
|
- lib/labkit/middleware/rack.rb
|