gitlab-labkit 0.4.2 → 0.5.0

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 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