gitlab-labkit 0.12.1 → 0.13.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3267849e09cf37b1f72c5c7cf0f25ac43066edd06b09ff7b8a3b93f2ee5a4f45
4
- data.tar.gz: ae8f6710ada3fc3791ae54cba82a4f8b73c5d67003782285264246032c22328e
3
+ metadata.gz: f7365b2f12b026f6b497d56738197b66e34014676dc284f568e97fad669cecef
4
+ data.tar.gz: ca9da033595aed9506edd7ba376a1bdd0b15c8e880a5e6b3edc52dc72b5a5570
5
5
  SHA512:
6
- metadata.gz: 33ec95dfe61241476125e718e9ae3d3145ba2d76244076cfbe164dd9b61b841d1e832dc27ef71846476ca32abe1057165f35c2b44abb3ff83bd09693a354f00b
7
- data.tar.gz: cb7abc95873cae4e981348c28533f3c894e50b696ed87822cca9b65a6db689a4e0453b83297b667eaa88c7a879e80dfc520e56e75959431a1388bc1db622aaf3
6
+ metadata.gz: 87aaa07295098883563e77694fdb1401ba9e2e5fbc26569ee0b87f8ce7bc329f0d26b78df5d2e1c2e97b86f3d7ec3c41200406eb2b7028aba8ce8bdec4001ab4
7
+ data.tar.gz: 42f5dcee07855cd347b9585b96e44ac3e36e05a5fd634db55ddea02676b82df9c35e0ba3d6bbbbf0e4c6b4ec16906ff8a86f041db67d392485008d811f3d20b2
@@ -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:
@@ -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", "~> 0.10"
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"
@@ -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
@@ -4,6 +4,7 @@ module Labkit
4
4
  # Logging provides functionality for logging, such as
5
5
  # sanitization
6
6
  module Logging
7
+ autoload :GRPC, "labkit/logging/grpc"
7
8
  autoload :Sanitizer, "labkit/logging/sanitizer"
8
9
  end
9
10
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labkit
4
+ module Logging
5
+ module GRPC
6
+ autoload :ServerInterceptor, "labkit/logging/grpc/server_interceptor"
7
+ end
8
+ end
9
+ end
@@ -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
@@ -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 = route_from_method(method)
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" => payload[:sql],
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.12.1
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-07-16 00:00:00.000000000 Z
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: '0.10'
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: '0.10'
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