mnemosyne-ruby 1.15.0 → 1.17.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 +4 -4
- data/.github/workflows/test.yml +32 -0
- data/Appraisals +17 -0
- data/CHANGELOG.md +23 -1
- data/Gemfile +2 -1
- data/gemfiles/rails_71.gemfile +27 -0
- data/gemfiles/sidekiq_70.gemfile +27 -0
- data/lib/mnemosyne/probes/action_dispatch/show_exceptions.rb +6 -1
- data/lib/mnemosyne/probes/redis/command.rb +4 -136
- data/lib/mnemosyne/probes/redis-client/command.rb +29 -0
- data/lib/mnemosyne/support/redis.rb +128 -0
- data/lib/mnemosyne/version.rb +1 -1
- data/lib/mnemosyne.rb +5 -0
- metadata +7 -4
- data/.github/workflows/lint.yml +0 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8cc4eb9f402b3b0b6bff2303ab053db952748357a70353db3bfcd095d7c5c3b8
|
|
4
|
+
data.tar.gz: 2285a82061c02625dffc6bc660249cf5bc6c950c70968d858a4a2689711dca83
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7378f99a3b5d170a027cd971234eb4256a7260d1d4ba5dffd7e0d7a3b94e2f3c3425fc1b920964dae34057b11a93043ef02dac97b8cdc6b779d46626e00a2224
|
|
7
|
+
data.tar.gz: f3190633b22cd474a4fdc365984dc4a26516637243b2f446345cf6ca4862ed7af456fde353f11babf2a5d4b79870d4102056d7077e7106b887cb16b22d04654b
|
data/.github/workflows/test.yml
CHANGED
|
@@ -26,11 +26,14 @@ jobs:
|
|
|
26
26
|
- rails-6.0
|
|
27
27
|
- rails-6.1
|
|
28
28
|
- rails-7.0
|
|
29
|
+
- rails-7.1
|
|
29
30
|
- redis-4.0
|
|
30
31
|
- redis-5.0
|
|
32
|
+
- redis-client
|
|
31
33
|
- restify
|
|
32
34
|
- sidekiq-5
|
|
33
35
|
- sidekiq-6
|
|
36
|
+
- sidekiq-7
|
|
34
37
|
include:
|
|
35
38
|
- suite: core
|
|
36
39
|
spec: --tag ~probe
|
|
@@ -59,12 +62,18 @@ jobs:
|
|
|
59
62
|
- suite: rails-7.0
|
|
60
63
|
spec: --tag probe:rails --tag ~probe
|
|
61
64
|
gemfile: gemfiles/rails_70.gemfile
|
|
65
|
+
- suite: rails-7.1
|
|
66
|
+
spec: --tag probe:rails --tag ~probe
|
|
67
|
+
gemfile: gemfiles/rails_71.gemfile
|
|
62
68
|
- suite: redis-4.0
|
|
63
69
|
spec: --tag probe:redis
|
|
64
70
|
gemfile: gemfiles/redis_40.gemfile
|
|
65
71
|
- suite: redis-5.0
|
|
66
72
|
spec: --tag probe:redis
|
|
67
73
|
gemfile: gemfiles/redis_50.gemfile
|
|
74
|
+
- suite: redis-client
|
|
75
|
+
spec: --tag probe:redis_client
|
|
76
|
+
gemfile: gemfiles/core.gemfile
|
|
68
77
|
- suite: restify
|
|
69
78
|
spec: --tag probe:restify
|
|
70
79
|
gemfile: gemfiles/core.gemfile
|
|
@@ -74,6 +83,9 @@ jobs:
|
|
|
74
83
|
- suite: sidekiq-6
|
|
75
84
|
spec: --tag probe:sidekiq
|
|
76
85
|
gemfile: gemfiles/sidekiq_60.gemfile
|
|
86
|
+
- suite: sidekiq-7
|
|
87
|
+
spec: --tag probe:sidekiq
|
|
88
|
+
gemfile: gemfiles/sidekiq_70.gemfile
|
|
77
89
|
exclude:
|
|
78
90
|
- suite: rails-5.2
|
|
79
91
|
ruby: '3.2'
|
|
@@ -110,3 +122,23 @@ jobs:
|
|
|
110
122
|
env:
|
|
111
123
|
AMQP_SERVER: amqp://localhost:${{ job.services.rabbitmq.ports[5672] }}
|
|
112
124
|
run: bundle exec rspec --color ${{ matrix.spec }}
|
|
125
|
+
|
|
126
|
+
rubocop:
|
|
127
|
+
name: rubocop
|
|
128
|
+
runs-on: ubuntu-22.04
|
|
129
|
+
|
|
130
|
+
env:
|
|
131
|
+
BUNDLE_WITHOUT: development test
|
|
132
|
+
|
|
133
|
+
steps:
|
|
134
|
+
- uses: actions/checkout@master
|
|
135
|
+
- uses: ruby/setup-ruby@v1
|
|
136
|
+
env:
|
|
137
|
+
BUNDLE_JOBS: 4
|
|
138
|
+
BUNDLE_RETRY: 3
|
|
139
|
+
with:
|
|
140
|
+
ruby-version: 3.1
|
|
141
|
+
bundler-cache: true
|
|
142
|
+
|
|
143
|
+
- name: Run rubocop
|
|
144
|
+
run: bundle exec rubocop --parallel --color
|
data/Appraisals
CHANGED
|
@@ -20,6 +20,15 @@ appraise 'faraday-10' do
|
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
appraise 'rails-71' do
|
|
24
|
+
remove_gem 'rubocop'
|
|
25
|
+
|
|
26
|
+
group :test do
|
|
27
|
+
gem 'rails', '~> 7.1.0'
|
|
28
|
+
gem 'sqlite3', '~> 1.4'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
23
32
|
appraise 'rails-70' do
|
|
24
33
|
remove_gem 'rubocop'
|
|
25
34
|
|
|
@@ -87,3 +96,11 @@ appraise 'sidekiq-60' do
|
|
|
87
96
|
gem 'sidekiq', '~> 6.0'
|
|
88
97
|
end
|
|
89
98
|
end
|
|
99
|
+
|
|
100
|
+
appraise 'sidekiq-70' do
|
|
101
|
+
remove_gem 'rubocop'
|
|
102
|
+
|
|
103
|
+
group :test do
|
|
104
|
+
gem 'sidekiq', '~> 7.0'
|
|
105
|
+
end
|
|
106
|
+
end
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.17.0] - 2023-11-28
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Add testing for Rails 7.1 by @MrSerth
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Invalid exception class for ActionDispatch::ExceptionWrapper by @jgraichen
|
|
18
|
+
|
|
19
|
+
## [1.16.0] - 2023-08-24
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Separate new tracing for `redis-client` gem
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- `NoMethodError` when `RedisClient` is used directly
|
|
28
|
+
|
|
9
29
|
## [1.15.0] - 2023-08-23
|
|
10
30
|
|
|
11
31
|
### Added
|
|
@@ -192,7 +212,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
192
212
|
|
|
193
213
|
- Add platform identifier
|
|
194
214
|
|
|
195
|
-
[Unreleased]: https://github.com/mnemosyne-mon/mnemosyne-ruby/compare/v1.
|
|
215
|
+
[Unreleased]: https://github.com/mnemosyne-mon/mnemosyne-ruby/compare/v1.17.0...HEAD
|
|
216
|
+
[1.17.0]: https://github.com/mnemosyne-mon/mnemosyne-ruby/compare/v1.16.0...v1.17.0
|
|
217
|
+
[1.16.0]: https://github.com/mnemosyne-mon/mnemosyne-ruby/compare/v1.15.0...v1.16.0
|
|
196
218
|
[1.15.0]: https://github.com/mnemosyne-mon/mnemosyne-ruby/compare/v1.14.0...v1.15.0
|
|
197
219
|
[1.14.0]: https://github.com/mnemosyne-mon/mnemosyne-ruby/compare/v1.14.0...v1.13.0
|
|
198
220
|
[1.13.0]: https://github.com/mnemosyne-mon/mnemosyne-ruby/compare/v1.13.0...v1.12.1
|
data/Gemfile
CHANGED
|
@@ -6,7 +6,7 @@ source 'https://rubygems.org'
|
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
8
|
gem 'rake', '~> 13.0'
|
|
9
|
-
gem 'rubocop', '~> 1.
|
|
9
|
+
gem 'rubocop', '~> 1.57.0'
|
|
10
10
|
|
|
11
11
|
group :test do
|
|
12
12
|
gem 'rspec', '~> 3.6'
|
|
@@ -16,6 +16,7 @@ group :test do
|
|
|
16
16
|
gem 'msgr'
|
|
17
17
|
gem 'rails'
|
|
18
18
|
gem 'redis'
|
|
19
|
+
gem 'redis-client'
|
|
19
20
|
gem 'restify'
|
|
20
21
|
gem 'sidekiq'
|
|
21
22
|
gem 'sqlite3'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
|
|
7
|
+
group :test do
|
|
8
|
+
gem "rspec", "~> 3.6"
|
|
9
|
+
gem "timecop", "~> 0.9.1"
|
|
10
|
+
gem "faraday"
|
|
11
|
+
gem "msgr"
|
|
12
|
+
gem "rails", "~> 7.1.0"
|
|
13
|
+
gem "redis"
|
|
14
|
+
gem "restify"
|
|
15
|
+
gem "sidekiq"
|
|
16
|
+
gem "sqlite3", "~> 1.4"
|
|
17
|
+
gem "webmock"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
group :development do
|
|
21
|
+
gem "appraisal"
|
|
22
|
+
gem "rake-release", "~> 1.3.0"
|
|
23
|
+
gem "pry", require: false
|
|
24
|
+
gem "pry-byebug", require: false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
|
|
7
|
+
group :test do
|
|
8
|
+
gem "rspec", "~> 3.6"
|
|
9
|
+
gem "timecop", "~> 0.9.1"
|
|
10
|
+
gem "faraday"
|
|
11
|
+
gem "msgr"
|
|
12
|
+
gem "rails"
|
|
13
|
+
gem "redis"
|
|
14
|
+
gem "restify"
|
|
15
|
+
gem "sidekiq", "~> 7.0"
|
|
16
|
+
gem "sqlite3"
|
|
17
|
+
gem "webmock"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
group :development do
|
|
21
|
+
gem "appraisal"
|
|
22
|
+
gem "rake-release", "~> 1.3.0"
|
|
23
|
+
gem "pry", require: false
|
|
24
|
+
gem "pry-byebug", require: false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
gemspec path: "../"
|
|
@@ -12,7 +12,12 @@ module Mnemosyne
|
|
|
12
12
|
module Instrumentation
|
|
13
13
|
def render_exception(env, exception)
|
|
14
14
|
if (trace = ::Mnemosyne::Instrumenter.current_trace)
|
|
15
|
-
|
|
15
|
+
if exception.respond_to?(:unwrapped_exception) && exception.respond_to?(:exception)
|
|
16
|
+
# ActionDispatch::ExceptionWrapper
|
|
17
|
+
trace.attach_error(exception.exception)
|
|
18
|
+
else
|
|
19
|
+
trace.attach_error(exception)
|
|
20
|
+
end
|
|
16
21
|
end
|
|
17
22
|
|
|
18
23
|
super
|
|
@@ -6,147 +6,15 @@ module Mnemosyne
|
|
|
6
6
|
module Command
|
|
7
7
|
class Probe < ::Mnemosyne::Probe
|
|
8
8
|
def setup
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
else
|
|
12
|
-
::Redis::Client.prepend ClientPatch
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
module Instrumentation
|
|
17
|
-
def call(command, redis_config)
|
|
18
|
-
Instrumentation.instrument([command], client.server_url) { super }
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def call_pipelined(commands, redis_config)
|
|
22
|
-
Instrumentation.instrument(commands, client.server_url) { super }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
class << self
|
|
26
|
-
def instrument(commands, server_url)
|
|
27
|
-
trace = ::Mnemosyne::Instrumenter.current_trace
|
|
28
|
-
return yield unless trace
|
|
29
|
-
|
|
30
|
-
span = ::Mnemosyne::Span.new 'db.query.redis',
|
|
31
|
-
meta: extract_span_meta(commands, server_url)
|
|
32
|
-
|
|
33
|
-
span.start!
|
|
34
|
-
|
|
35
|
-
begin
|
|
36
|
-
yield.tap do |retval|
|
|
37
|
-
span.meta[:error] = retval.message if retval.is_a?(::Redis::CommandError)
|
|
38
|
-
|
|
39
|
-
trace << span.finish!
|
|
40
|
-
end
|
|
41
|
-
rescue StandardError => e
|
|
42
|
-
span.meta[:error] = e.message
|
|
43
|
-
trace << span.finish!
|
|
44
|
-
raise
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
private
|
|
9
|
+
# Redis v5+ used redis-client, which has it's own probe
|
|
10
|
+
return if Gem::Version.new(::Redis::VERSION) >= Gem::Version.new('5')
|
|
49
11
|
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
server: server_url,
|
|
53
|
-
|
|
54
|
-
# Each command is an array, consisting of the command name and any
|
|
55
|
-
# arguments. We are only interested in the command name.
|
|
56
|
-
commands: extract_command_names(commands),
|
|
57
|
-
|
|
58
|
-
# If there are multiple commands, that must mean they were pipelined
|
|
59
|
-
# (i.e. run in parallel).
|
|
60
|
-
pipelined: commands.length > 1
|
|
61
|
-
}
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def extract_command_names(commands)
|
|
65
|
-
commands.map do |c|
|
|
66
|
-
# Depending on how the methods on the Redis gem are called,
|
|
67
|
-
# there may be an additional level of nesting.
|
|
68
|
-
c = c[0] if c[0].is_a?(Array)
|
|
69
|
-
|
|
70
|
-
# For some commands, we also extract *some* of the arguments.
|
|
71
|
-
name, args = parse_name_and_args(c)
|
|
72
|
-
|
|
73
|
-
"#{name} #{args}".strip
|
|
74
|
-
end.join("\n")
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
##
|
|
78
|
-
# A map of known commands to the arguments (identified by position)
|
|
79
|
-
# that should be included verbatim in the metadata. Arguments not
|
|
80
|
-
# listed here will be replaced by a "?" character.
|
|
81
|
-
#
|
|
82
|
-
# The value can be a list of safe argument indices, or "*" (all).
|
|
83
|
-
#
|
|
84
|
-
KNOWN_ARGUMENTS = {
|
|
85
|
-
'BLPOP' => '*',
|
|
86
|
-
'BRPOP' => '*',
|
|
87
|
-
'EVALSHA' => [0, 1],
|
|
88
|
-
'EXISTS' => '*',
|
|
89
|
-
'EXPIRE' => '*',
|
|
90
|
-
'GET' => '*',
|
|
91
|
-
'HGET' => '*',
|
|
92
|
-
'HGETALL' => '*',
|
|
93
|
-
'HMGET' => '*',
|
|
94
|
-
'HMSET' => [0, 1],
|
|
95
|
-
'HSCAN' => '*',
|
|
96
|
-
'INCRBY' => '*',
|
|
97
|
-
'LLEN' => '*',
|
|
98
|
-
'LPUSH' => [0],
|
|
99
|
-
'LRANGE' => '*',
|
|
100
|
-
'LREM' => [0, 1],
|
|
101
|
-
'MGET' => '*',
|
|
102
|
-
'MSET' => [0],
|
|
103
|
-
'RPUSH' => [0],
|
|
104
|
-
'RPOP' => '*',
|
|
105
|
-
'SADD' => [0],
|
|
106
|
-
'SCARD' => '*',
|
|
107
|
-
'SCAN' => '*',
|
|
108
|
-
'SCRIPT LOAD' => [],
|
|
109
|
-
'SET' => [0],
|
|
110
|
-
'SREM' => [0],
|
|
111
|
-
'SSCAN' => '*',
|
|
112
|
-
'UNLINK' => '*',
|
|
113
|
-
'ZADD' => [0],
|
|
114
|
-
'ZCARD' => '*',
|
|
115
|
-
'ZINCRBY' => [0, 1],
|
|
116
|
-
'ZRANGE' => '*',
|
|
117
|
-
'ZRANGEBYSCORE' => '*',
|
|
118
|
-
'ZREM' => [0],
|
|
119
|
-
'ZREMRANGEBYSCORE' => '*',
|
|
120
|
-
'ZREVRANGE' => '*',
|
|
121
|
-
'ZSCAN' => '*'
|
|
122
|
-
}.freeze
|
|
123
|
-
|
|
124
|
-
def parse_name_and_args(command)
|
|
125
|
-
command = command.dup
|
|
126
|
-
|
|
127
|
-
# Symbols and lower-case names are allowed
|
|
128
|
-
name = command.delete_at(0).to_s.upcase
|
|
129
|
-
|
|
130
|
-
allowed = KNOWN_ARGUMENTS[name] || []
|
|
131
|
-
args = case allowed
|
|
132
|
-
when '*' # All arguments considered safe
|
|
133
|
-
command
|
|
134
|
-
when Array # A list of allowed argument indices
|
|
135
|
-
command.each_with_index.map do |arg, index|
|
|
136
|
-
allowed.include?(index) ? arg : '?'
|
|
137
|
-
end
|
|
138
|
-
else # Unknown command - assume nothing is safe
|
|
139
|
-
Array.new(command.length, '?')
|
|
140
|
-
end.join(' ')
|
|
141
|
-
|
|
142
|
-
[name, args]
|
|
143
|
-
end
|
|
144
|
-
end
|
|
12
|
+
::Redis::Client.prepend ClientPatch
|
|
145
13
|
end
|
|
146
14
|
|
|
147
15
|
module ClientPatch
|
|
148
16
|
def process(commands)
|
|
149
|
-
|
|
17
|
+
::Mnemosyne::Support::Redis.instrument(commands, id) { super }
|
|
150
18
|
end
|
|
151
19
|
end
|
|
152
20
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mnemosyne
|
|
4
|
+
module Probes
|
|
5
|
+
module RedisClient
|
|
6
|
+
module Command
|
|
7
|
+
class Probe < ::Mnemosyne::Probe
|
|
8
|
+
def setup
|
|
9
|
+
::RedisClient.register Instrumentation
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module Instrumentation
|
|
13
|
+
def call(command, redis_config)
|
|
14
|
+
::Mnemosyne::Support::Redis.instrument([command], redis_config.server_url) { super }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def call_pipelined(commands, redis_config)
|
|
18
|
+
::Mnemosyne::Support::Redis.instrument(commands, redis_config.server_url) { super }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
register 'RedisClient',
|
|
26
|
+
'redis_client',
|
|
27
|
+
RedisClient::Command::Probe.new
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mnemosyne
|
|
4
|
+
module Support
|
|
5
|
+
module Redis
|
|
6
|
+
##
|
|
7
|
+
# A map of known commands to the arguments (identified by position)
|
|
8
|
+
# that should be included verbatim in the metadata. Arguments not
|
|
9
|
+
# listed here will be replaced by a "?" character.
|
|
10
|
+
#
|
|
11
|
+
# The value can be a list of safe argument indices, or "*" (all).
|
|
12
|
+
#
|
|
13
|
+
KNOWN_ARGUMENTS = {
|
|
14
|
+
'BLPOP' => '*',
|
|
15
|
+
'BRPOP' => '*',
|
|
16
|
+
'EVALSHA' => [0, 1],
|
|
17
|
+
'EXISTS' => '*',
|
|
18
|
+
'EXPIRE' => '*',
|
|
19
|
+
'GET' => '*',
|
|
20
|
+
'HGET' => '*',
|
|
21
|
+
'HGETALL' => '*',
|
|
22
|
+
'HMGET' => '*',
|
|
23
|
+
'HMSET' => [0, 1],
|
|
24
|
+
'HSCAN' => '*',
|
|
25
|
+
'INCRBY' => '*',
|
|
26
|
+
'LLEN' => '*',
|
|
27
|
+
'LPUSH' => [0],
|
|
28
|
+
'LRANGE' => '*',
|
|
29
|
+
'LREM' => [0, 1],
|
|
30
|
+
'MGET' => '*',
|
|
31
|
+
'MSET' => [0],
|
|
32
|
+
'RPUSH' => [0],
|
|
33
|
+
'RPOP' => '*',
|
|
34
|
+
'SADD' => [0],
|
|
35
|
+
'SCARD' => '*',
|
|
36
|
+
'SCAN' => '*',
|
|
37
|
+
'SCRIPT LOAD' => [],
|
|
38
|
+
'SET' => [0],
|
|
39
|
+
'SREM' => [0],
|
|
40
|
+
'SSCAN' => '*',
|
|
41
|
+
'UNLINK' => '*',
|
|
42
|
+
'ZADD' => [0],
|
|
43
|
+
'ZCARD' => '*',
|
|
44
|
+
'ZINCRBY' => [0, 1],
|
|
45
|
+
'ZRANGE' => '*',
|
|
46
|
+
'ZRANGEBYSCORE' => '*',
|
|
47
|
+
'ZREM' => [0],
|
|
48
|
+
'ZREMRANGEBYSCORE' => '*',
|
|
49
|
+
'ZREVRANGE' => '*',
|
|
50
|
+
'ZSCAN' => '*'
|
|
51
|
+
}.freeze
|
|
52
|
+
|
|
53
|
+
class << self
|
|
54
|
+
def instrument(commands, server_url)
|
|
55
|
+
trace = ::Mnemosyne::Instrumenter.current_trace
|
|
56
|
+
return yield unless trace
|
|
57
|
+
|
|
58
|
+
span = ::Mnemosyne::Span.new 'db.query.redis',
|
|
59
|
+
meta: extract_span_meta(commands, server_url)
|
|
60
|
+
|
|
61
|
+
span.start!
|
|
62
|
+
|
|
63
|
+
begin
|
|
64
|
+
yield.tap do |retval|
|
|
65
|
+
if defined?(::Redis::CommandError) && retval.is_a?(::Redis::CommandError)
|
|
66
|
+
span.meta[:error] = retval.message
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
trace << span.finish!
|
|
70
|
+
end
|
|
71
|
+
rescue StandardError => e
|
|
72
|
+
span.meta[:error] = e.message
|
|
73
|
+
trace << span.finish!
|
|
74
|
+
raise
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def extract_span_meta(commands, server_url)
|
|
79
|
+
{
|
|
80
|
+
server: server_url,
|
|
81
|
+
|
|
82
|
+
# Each command is an array, consisting of the command name and any
|
|
83
|
+
# arguments. We are only interested in the command name.
|
|
84
|
+
commands: extract_command_names(commands),
|
|
85
|
+
|
|
86
|
+
# If there are multiple commands, that must mean they were pipelined
|
|
87
|
+
# (i.e. run in parallel).
|
|
88
|
+
pipelined: commands.length > 1
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def parse_name_and_args(command)
|
|
93
|
+
command = command.dup
|
|
94
|
+
|
|
95
|
+
# Symbols and lower-case names are allowed
|
|
96
|
+
name = command.delete_at(0).to_s.upcase
|
|
97
|
+
|
|
98
|
+
allowed = KNOWN_ARGUMENTS[name] || []
|
|
99
|
+
args = case allowed
|
|
100
|
+
when '*' # All arguments considered safe
|
|
101
|
+
command
|
|
102
|
+
when Array # A list of allowed argument indices
|
|
103
|
+
command.each_with_index.map do |arg, index|
|
|
104
|
+
allowed.include?(index) ? arg : '?'
|
|
105
|
+
end
|
|
106
|
+
else # Unknown command - assume nothing is safe
|
|
107
|
+
Array.new(command.length, '?')
|
|
108
|
+
end.join(' ')
|
|
109
|
+
|
|
110
|
+
[name, args]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def extract_command_names(commands)
|
|
114
|
+
commands.map do |c|
|
|
115
|
+
# Depending on how the methods on the Redis gem are called,
|
|
116
|
+
# there may be an additional level of nesting.
|
|
117
|
+
c = c[0] if c[0].is_a?(Array)
|
|
118
|
+
|
|
119
|
+
# For some commands, we also extract *some* of the arguments.
|
|
120
|
+
name, args = parse_name_and_args(c)
|
|
121
|
+
|
|
122
|
+
"#{name} #{args}".strip
|
|
123
|
+
end.join("\n")
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
data/lib/mnemosyne/version.rb
CHANGED
data/lib/mnemosyne.rb
CHANGED
|
@@ -43,6 +43,7 @@ module Mnemosyne
|
|
|
43
43
|
require 'mnemosyne/probes/msgr/client'
|
|
44
44
|
require 'mnemosyne/probes/msgr/consumer'
|
|
45
45
|
require 'mnemosyne/probes/redis/command'
|
|
46
|
+
require 'mnemosyne/probes/redis-client/command'
|
|
46
47
|
require 'mnemosyne/probes/responder/respond'
|
|
47
48
|
require 'mnemosyne/probes/restify/base'
|
|
48
49
|
require 'mnemosyne/probes/sidekiq/client'
|
|
@@ -54,5 +55,9 @@ module Mnemosyne
|
|
|
54
55
|
require 'mnemosyne/middleware/rack'
|
|
55
56
|
end
|
|
56
57
|
|
|
58
|
+
module Support
|
|
59
|
+
require 'mnemosyne/support/redis'
|
|
60
|
+
end
|
|
61
|
+
|
|
57
62
|
require 'mnemosyne/railtie' if defined?(Rails)
|
|
58
63
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mnemosyne-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.17.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jan Graichen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-11-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -46,7 +46,6 @@ extensions: []
|
|
|
46
46
|
extra_rdoc_files: []
|
|
47
47
|
files:
|
|
48
48
|
- ".editorconfig"
|
|
49
|
-
- ".github/workflows/lint.yml"
|
|
50
49
|
- ".github/workflows/test.yml"
|
|
51
50
|
- ".gitignore"
|
|
52
51
|
- ".markdownlint.yml"
|
|
@@ -66,10 +65,12 @@ files:
|
|
|
66
65
|
- gemfiles/rails_60.gemfile
|
|
67
66
|
- gemfiles/rails_61.gemfile
|
|
68
67
|
- gemfiles/rails_70.gemfile
|
|
68
|
+
- gemfiles/rails_71.gemfile
|
|
69
69
|
- gemfiles/redis_40.gemfile
|
|
70
70
|
- gemfiles/redis_50.gemfile
|
|
71
71
|
- gemfiles/sidekiq_50.gemfile
|
|
72
72
|
- gemfiles/sidekiq_60.gemfile
|
|
73
|
+
- gemfiles/sidekiq_70.gemfile
|
|
73
74
|
- lib/mnemosyne-ruby.rb
|
|
74
75
|
- lib/mnemosyne.rb
|
|
75
76
|
- lib/mnemosyne/client.rb
|
|
@@ -100,6 +101,7 @@ files:
|
|
|
100
101
|
- lib/mnemosyne/probes/mnemosyne/tracer.rb
|
|
101
102
|
- lib/mnemosyne/probes/msgr/client.rb
|
|
102
103
|
- lib/mnemosyne/probes/msgr/consumer.rb
|
|
104
|
+
- lib/mnemosyne/probes/redis-client/command.rb
|
|
103
105
|
- lib/mnemosyne/probes/redis/command.rb
|
|
104
106
|
- lib/mnemosyne/probes/responder/respond.rb
|
|
105
107
|
- lib/mnemosyne/probes/restify/base.rb
|
|
@@ -109,6 +111,7 @@ files:
|
|
|
109
111
|
- lib/mnemosyne/railtie.rb
|
|
110
112
|
- lib/mnemosyne/registry.rb
|
|
111
113
|
- lib/mnemosyne/span.rb
|
|
114
|
+
- lib/mnemosyne/support/redis.rb
|
|
112
115
|
- lib/mnemosyne/trace.rb
|
|
113
116
|
- lib/mnemosyne/version.rb
|
|
114
117
|
- mnemosyne-ruby.gemspec
|
|
@@ -135,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
135
138
|
- !ruby/object:Gem::Version
|
|
136
139
|
version: '0'
|
|
137
140
|
requirements: []
|
|
138
|
-
rubygems_version: 3.4.
|
|
141
|
+
rubygems_version: 3.4.22
|
|
139
142
|
signing_key:
|
|
140
143
|
specification_version: 4
|
|
141
144
|
summary: Ruby/Rails client for Mnemosyne APM
|
data/.github/workflows/lint.yml
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
name: Lint
|
|
2
|
-
on:
|
|
3
|
-
- pull_request
|
|
4
|
-
- push
|
|
5
|
-
|
|
6
|
-
jobs:
|
|
7
|
-
rubocop:
|
|
8
|
-
name: rubocop
|
|
9
|
-
runs-on: ubuntu-22.04
|
|
10
|
-
|
|
11
|
-
env:
|
|
12
|
-
BUNDLE_WITHOUT: development test
|
|
13
|
-
|
|
14
|
-
steps:
|
|
15
|
-
- uses: actions/checkout@master
|
|
16
|
-
- uses: ruby/setup-ruby@v1
|
|
17
|
-
env:
|
|
18
|
-
BUNDLE_JOBS: 4
|
|
19
|
-
BUNDLE_RETRY: 3
|
|
20
|
-
with:
|
|
21
|
-
ruby-version: 3.1
|
|
22
|
-
bundler-cache: true
|
|
23
|
-
|
|
24
|
-
- name: Run rubocop
|
|
25
|
-
run: bundle exec rubocop --parallel --color
|