gitlab-labkit 0.10.1 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/labkit/context.rb +2 -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 +84 -0
- data/lib/labkit/tracing.rb +4 -0
- data/lib/labkit/tracing/grpc/server_interceptor.rb +3 -8
- data/lib/labkit/tracing/rails/abstract_instrumenter.rb +2 -0
- data/lib/labkit/tracing/redis/redis_interceptor_helper.rb +2 -1
- data/lib/labkit/tracing/tracing_utils.rb +17 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54ad7f3ed011ed85b6f0c090f05cd47a4bf7c738fabd2a165bad85b6e4d288c0
|
4
|
+
data.tar.gz: c833a07fa745fe8286b9c000879de8b0f338c0d24b722e71dc5044c60dcc3b79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c724e7322119314f35831c726900220842e2f473a48d81241a94cc2eb4f34da39bb38c843ba72b724a1b5d0dff5e1b115cec704468d49797d4c681c309cf7ba
|
7
|
+
data.tar.gz: 91e870d9af690c2b5f6ce7659954616880ee3313f710b49c89505cbe915c4606ef3d1032d905cbfd1be4e547d98c846baa6fed052836833e71dc7a59444c0727
|
data/lib/labkit/context.rb
CHANGED
@@ -21,7 +21,8 @@ module Labkit
|
|
21
21
|
LOG_KEY = "meta"
|
22
22
|
CORRELATION_ID_KEY = "correlation_id"
|
23
23
|
RAW_KEYS = [CORRELATION_ID_KEY].freeze
|
24
|
-
KNOWN_KEYS = %w[user project root_namespace subscription_plan caller_id
|
24
|
+
KNOWN_KEYS = %w[user project root_namespace subscription_plan caller_id
|
25
|
+
related_class feature_category].freeze
|
25
26
|
|
26
27
|
class << self
|
27
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,84 @@
|
|
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.time_ms': ((Time.now - start) * 1000.0).truncate(3),
|
71
|
+
'grpc.code': CODE_STRINGS.fetch(code, code.to_s),
|
72
|
+
'grpc.method': method_name,
|
73
|
+
'grpc.service': service_name,
|
74
|
+
pid: Process.pid,
|
75
|
+
correlation_id: Labkit::Correlation::CorrelationId.current_id.to_s,
|
76
|
+
time: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ"),
|
77
|
+
)
|
78
|
+
|
79
|
+
@log_file.puts(JSON.dump(message))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/labkit/tracing.rb
CHANGED
@@ -28,6 +28,10 @@ module Labkit
|
|
28
28
|
ENV["GITLAB_TRACING_URL"]
|
29
29
|
end
|
30
30
|
|
31
|
+
def self.stacktrace_operations
|
32
|
+
@stacktrace_operations ||= Set.new(ENV["GITLAB_TRACING_INCLUDE_STACKTRACE"].to_s.split(",").map(&:strip))
|
33
|
+
end
|
34
|
+
|
31
35
|
def self.tracing_url_enabled?
|
32
36
|
enabled? && tracing_url_template.present?
|
33
37
|
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",
|
@@ -17,6 +17,8 @@ module Labkit
|
|
17
17
|
scope = scope_stack.pop
|
18
18
|
span = scope.span
|
19
19
|
|
20
|
+
Labkit::Tracing::TracingUtils.log_common_fields_on_span(span, span_name(payload))
|
21
|
+
|
20
22
|
exception = payload[:exception]
|
21
23
|
Labkit::Tracing::TracingUtils.log_exception_on_span(span, exception) if exception
|
22
24
|
|
@@ -8,7 +8,7 @@ module Labkit
|
|
8
8
|
# RedisInterceptorHelper is a helper for the RedisInterceptor. This is not a public API
|
9
9
|
class RedisInterceptorHelper
|
10
10
|
# For optimization, compile this once
|
11
|
-
MASK_REDIS_RE = /^([\w-]+(?:\W+[\w-]+(?:\W+[\w-]+)?)?)(.?)/.freeze
|
11
|
+
MASK_REDIS_RE = /^([\w{}-]+(?:\W+[\w{}-]+(?:\W+[\w{}-]+)?)?)(.?)/.freeze
|
12
12
|
|
13
13
|
def self.call_with_tracing(command, client)
|
14
14
|
Labkit::Tracing::TracingUtils.with_tracing(operation_name: "redis.call", tags: tags_from_command(command, client)) do |_span|
|
@@ -99,6 +99,7 @@ module Labkit
|
|
99
99
|
return "" if argument.empty?
|
100
100
|
|
101
101
|
matches = argument.match(MASK_REDIS_RE)
|
102
|
+
|
102
103
|
matches[2].empty? ? matches[0] : matches[0] + "*****"
|
103
104
|
end
|
104
105
|
private_class_method :mask_redis_arg
|
@@ -12,9 +12,7 @@ module Labkit
|
|
12
12
|
scope = tracer.start_active_span(operation_name, child_of: child_of, tags: tags)
|
13
13
|
span = scope.span
|
14
14
|
|
15
|
-
|
16
|
-
correlation_id = Labkit::Correlation::CorrelationId.current_id
|
17
|
-
span.set_tag("correlation_id", correlation_id) if correlation_id
|
15
|
+
log_common_fields_on_span(span, operation_name)
|
18
16
|
|
19
17
|
begin
|
20
18
|
yield span
|
@@ -35,11 +33,19 @@ module Labkit
|
|
35
33
|
def self.postnotify_span(operation_name, start_time, end_time, tags: nil, child_of: nil, exception: nil)
|
36
34
|
span = OpenTracing.start_span(operation_name, start_time: start_time, tags: tags, child_of: child_of)
|
37
35
|
|
36
|
+
log_common_fields_on_span(span, operation_name)
|
38
37
|
log_exception_on_span(span, exception) if exception
|
39
38
|
|
40
39
|
span.finish(end_time: end_time)
|
41
40
|
end
|
42
41
|
|
42
|
+
# Add common fields to a span
|
43
|
+
def self.log_common_fields_on_span(span, operation_name)
|
44
|
+
correlation_id = Labkit::Correlation::CorrelationId.current_id
|
45
|
+
span.set_tag("correlation_id", correlation_id) if correlation_id
|
46
|
+
span.log_kv(stack: caller.join('\n')) if include_stacktrace?(operation_name)
|
47
|
+
end
|
48
|
+
|
43
49
|
# Add exception logging to a span
|
44
50
|
def self.log_exception_on_span(span, exception)
|
45
51
|
span.set_tag("error", true)
|
@@ -60,6 +66,14 @@ module Labkit
|
|
60
66
|
{ :"event" => "error", :"error.kind" => exception.class.to_s, :"error.object" => Labkit::Logging::Sanitizer.sanitize_field(exception.to_s) }
|
61
67
|
end
|
62
68
|
end
|
69
|
+
|
70
|
+
def self.include_stacktrace?(operation_name)
|
71
|
+
@include_stacktrace ||= Hash.new do |result, name|
|
72
|
+
result[name] = Tracing.stacktrace_operations.any? { |stacktrace_operation| name.starts_with?(stacktrace_operation) }
|
73
|
+
end
|
74
|
+
|
75
|
+
@include_stacktrace[operation_name]
|
76
|
+
end
|
63
77
|
end
|
64
78
|
end
|
65
79
|
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.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: 2020-
|
11
|
+
date: 2020-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -279,6 +279,8 @@ files:
|
|
279
279
|
- lib/labkit/correlation/grpc/grpc_common.rb
|
280
280
|
- lib/labkit/correlation/grpc/server_interceptor.rb
|
281
281
|
- lib/labkit/logging.rb
|
282
|
+
- lib/labkit/logging/grpc.rb
|
283
|
+
- lib/labkit/logging/grpc/server_interceptor.rb
|
282
284
|
- lib/labkit/logging/sanitizer.rb
|
283
285
|
- lib/labkit/middleware.rb
|
284
286
|
- lib/labkit/middleware/rack.rb
|