gitlab-labkit 0.4.2 → 0.5.0

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: a12f0cfece810e841d6e90af209518aedb4f419b56bb8bdf2718e3dd13c4c4e0
4
- data.tar.gz: ec955a4d6c7e119f774ec78636a92f3991d052f29e2ca8c51c4b17e5dbda433f
3
+ metadata.gz: 1bf18910dd8b5fe524da8c6c935423a9aa059e48ba35a8773d1b5aaa85ac6dd4
4
+ data.tar.gz: 5793dbbe30934d2b4799fa6295e5a7994bbaeb172bcc18c85c062d83552eb1c3
5
5
  SHA512:
6
- metadata.gz: 3e95164f20400532ca86c1b832a1c723925a917cc23d7c2ac093fd63525c215c02c2f9f90822ac0010342553dff5d46a60403a29149b5a11f89d2d80d51b64d1
7
- data.tar.gz: a873c80f7bef4706394ea583a0b69d3576ffacad7f10caf0c3996bc2bfc4f229ccf76dd2fddf6e028deee09d7a876f36de75de8164e8409890993c5d77cb2b14
6
+ metadata.gz: 13e32000497293b6bc57c4114db05d13eac4ed928e7111f9f30e4ade7bfa0ad173143577cb8fe503b069903752ae200fc32c8341a23db469c4aca6a27af320b0
7
+ data.tar.gz: 93f1ad1a7f292732ad9c73f5b618aab676cb16d991ac55561e3e9f269ab58ff22d6c29dfd6452ea89e8b5bafc5d5b7d73f2456ac02af42047199fb689eef2958
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
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", "~> 0.10"
26
26
  spec.add_runtime_dependency "opentracing", "~> 0.4"
27
+ spec.add_runtime_dependency "redis", "~> 3.2"
27
28
 
28
29
  # Please maintain alphabetical order for dev dependencies
29
30
  spec.add_development_dependency "grpc-tools", "~> 1.19"
@@ -11,6 +11,7 @@ module Labkit
11
11
  autoload :JaegerFactory, "labkit/tracing/jaeger_factory"
12
12
  autoload :RackMiddleware, "labkit/tracing/rack_middleware"
13
13
  autoload :Rails, "labkit/tracing/rails"
14
+ autoload :Redis, "labkit/tracing/redis"
14
15
  autoload :Sidekiq, "labkit/tracing/sidekiq"
15
16
  autoload :TracingUtils, "labkit/tracing/tracing_utils"
16
17
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "redis"
4
+
5
+ module Labkit
6
+ module Tracing
7
+ # The Redis interceptor will intercept all calls to Redis and instrument them for distributed tracing
8
+ module Redis
9
+ autoload :RedisInterceptor, "labkit/tracing/redis/redis_interceptor"
10
+ autoload :RedisInterceptorHelper, "labkit/tracing/redis/redis_interceptor_helper"
11
+
12
+ def self.instrument
13
+ ::Redis::Client.prepend RedisInterceptor
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "redis"
4
+
5
+ module Labkit
6
+ module Tracing
7
+ module Redis
8
+ # RedisInterceptor is an interceptor for Redis to add distributed tracing.
9
+ # It should be installed using the `Labkit::Tracing.instrument` method
10
+ module RedisInterceptor
11
+ def call(command)
12
+ RedisInterceptorHelper.call_with_tracing(command, self) do
13
+ # Note: when used without any arguments super uses the arguments given to the subclass method.
14
+ super
15
+ end
16
+ end
17
+
18
+ def call_pipeline(pipeline)
19
+ RedisInterceptorHelper.call_pipeline_with_tracing(pipeline, self) do
20
+ # Note: when used without any arguments super uses the arguments given to the subclass method.
21
+ super
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "redis"
4
+
5
+ module Labkit
6
+ module Tracing
7
+ module Redis
8
+ # RedisInterceptorHelper is a helper for the RedisInterceptor. This is not a public API
9
+ class RedisInterceptorHelper
10
+ # For optimization, compile this once
11
+ MASK_REDIS_RE = /^([\w-]+(?:\W+[\w-]+(?:\W+[\w-]+)?)?)(.?)/.freeze
12
+
13
+ def self.call_with_tracing(command, client)
14
+ Labkit::Tracing::TracingUtils.with_tracing(operation_name: "redis.call", tags: tags_from_command(command, client)) do |_span|
15
+ yield
16
+ end
17
+ end
18
+
19
+ def self.call_pipeline_with_tracing(pipeline, client)
20
+ Labkit::Tracing::TracingUtils.with_tracing(operation_name: "redis.call_pipeline", tags: tags_from_pipeline(pipeline, client)) do |_span|
21
+ yield
22
+ end
23
+ end
24
+
25
+ def self.common_tags_for_client(client)
26
+ {
27
+ "component" => "redis",
28
+ "span.kind" => "client",
29
+ "redis.scheme" => client.scheme,
30
+ "redis.host" => client.host,
31
+ "redis.port" => client.port,
32
+ "redis.path" => client.path,
33
+ }
34
+ end
35
+
36
+ def self.tags_from_command(command, client)
37
+ tags = common_tags_for_client(client)
38
+
39
+ tags["redis.command"] = command_serialized(command)
40
+
41
+ tags
42
+ end
43
+
44
+ def self.command_serialized(command)
45
+ command_name, *arguments = command
46
+
47
+ info = [command_name]
48
+ info << sanitize_argument_for_command(command_name, arguments.first) unless arguments.empty?
49
+
50
+ # Additional arguments? Only include the number
51
+ info << "...#{arguments.size - 1} more value(s)" if arguments.size > 1
52
+
53
+ info.join(" ")
54
+ end
55
+
56
+ def self.tags_from_pipeline(pipeline, client)
57
+ tags = common_tags_for_client(client)
58
+
59
+ commands = pipeline.commands
60
+
61
+ # Limit to the first 5 commands
62
+ commands.first(5).each_with_index do |command, index|
63
+ tags["redis.command.#{index}"] = command_serialized(command)
64
+ end
65
+ tags["redis.pipeline.commands.length"] = commands.length
66
+
67
+ tags
68
+ end
69
+
70
+ # get_first_argument_for_command returns a masked value representing the first argument
71
+ # from a redis command, taking care of certain sensitive commands
72
+ def self.sanitize_argument_for_command(command_name, first_argument)
73
+ return "*****" if command_is_sensitive(command_name)
74
+
75
+ return "nil" if first_argument.nil?
76
+ return first if first_argument.is_a?(Numeric)
77
+ return "*****" unless first_argument.is_a?(String)
78
+
79
+ mask_redis_arg(first_argument)
80
+ end
81
+
82
+ def self.command_is_sensitive(command_name)
83
+ return true if command_name == :auth || "auth".casecmp(command_name).zero?
84
+ return true if command_name == :eval || "eval".casecmp(command_name).zero?
85
+
86
+ false
87
+ end
88
+
89
+ def self.mask_redis_arg(argument)
90
+ return "" if argument.empty?
91
+
92
+ matches = argument.match(MASK_REDIS_RE)
93
+ matches[2].empty? ? matches[0] : matches[0] + "*****"
94
+ end
95
+ private_class_method :mask_redis_arg
96
+ end
97
+ end
98
+ end
99
+ 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.2
4
+ version: 0.5.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-07-29 00:00:00.000000000 Z
11
+ date: 2019-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: redis
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.2'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.2'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: grpc-tools
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -228,6 +242,9 @@ files:
228
242
  - lib/labkit/tracing/rails/active_record_subscriber.rb
229
243
  - lib/labkit/tracing/rails/active_support_subscriber.rb
230
244
  - lib/labkit/tracing/rails/rails_common.rb
245
+ - lib/labkit/tracing/redis.rb
246
+ - lib/labkit/tracing/redis/redis_interceptor.rb
247
+ - lib/labkit/tracing/redis/redis_interceptor_helper.rb
231
248
  - lib/labkit/tracing/sidekiq.rb
232
249
  - lib/labkit/tracing/sidekiq/client_middleware.rb
233
250
  - lib/labkit/tracing/sidekiq/server_middleware.rb