spring_onion 0.2.1 → 1.0.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/.rspec +0 -1
- data/.rubocop.yml +4 -0
- data/.travis.yml +17 -1
- data/Appraisals +9 -0
- data/Dockerfile +14 -0
- data/Gemfile.lock +2 -2
- data/README.md +10 -0
- data/Rakefile +6 -1
- data/docker-compose.yml +15 -0
- data/gemfiles/ar52.gemfile +9 -0
- data/gemfiles/ar60.gemfile +9 -0
- data/lib/spring_onion.rb +1 -0
- data/lib/spring_onion/config.rb +2 -2
- data/lib/spring_onion/explainer.rb +17 -22
- data/lib/spring_onion/json_logger.rb +25 -0
- data/lib/spring_onion/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3d2f2a889573516f94fa1f5fb4a3276a26c31de830a9dabc56785e35c715c57
|
4
|
+
data.tar.gz: de4ca5c79ffdf0455552f54fb95d0316cf5eb075bb281c975e1db3bd0d6a3655
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 247a3d06f4f82854f0fa3a395a5f5ba224362772c3f3c40273029009db5f10babaf5a70de589d1ce08b2c242ec4d1072ab038d0dfb92196262c2527094f879ea
|
7
|
+
data.tar.gz: 6754099ea2ffb1d6ce713d665954dfb7ebce6f74a51141f85006ff06e4b0bc32083ea155e2c116d22a59552a97d69efa62655935f79337d5736e1883fb448c8d
|
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
@@ -4,6 +4,8 @@ AllCops:
|
|
4
4
|
TargetRubyVersion: 2.5
|
5
5
|
Style/Documentation:
|
6
6
|
Enabled: false
|
7
|
+
Style/TrailingCommaInArrayLiteral:
|
8
|
+
EnforcedStyleForMultiline: consistent_comma
|
7
9
|
Style/TrailingCommaInHashLiteral:
|
8
10
|
EnforcedStyleForMultiline: consistent_comma
|
9
11
|
Metrics/AbcSize:
|
@@ -12,6 +14,8 @@ Metrics/CyclomaticComplexity:
|
|
12
14
|
Enabled: false
|
13
15
|
Metrics/MethodLength:
|
14
16
|
Enabled: false
|
17
|
+
Metrics/BlockLength:
|
18
|
+
Enabled: false
|
15
19
|
Layout/LineLength:
|
16
20
|
Enabled: false
|
17
21
|
|
data/.travis.yml
CHANGED
@@ -2,5 +2,21 @@
|
|
2
2
|
language: ruby
|
3
3
|
cache: bundler
|
4
4
|
rvm:
|
5
|
+
- 2.5.8
|
5
6
|
- 2.6.6
|
6
|
-
|
7
|
+
- 2.7.1
|
8
|
+
gemfile:
|
9
|
+
- gemfiles/ar52.gemfile
|
10
|
+
- gemfiles/ar60.gemfile
|
11
|
+
services:
|
12
|
+
- mysql
|
13
|
+
env:
|
14
|
+
- DATABASE_URL=mysql2://travis@localhost/sakila
|
15
|
+
before_install:
|
16
|
+
- gem install bundler -v 2.1.2
|
17
|
+
- curl -sSfL https://downloads.mysql.com/docs/sakila-db.tar.gz -o - | tar zxf -
|
18
|
+
- cd sakila-db
|
19
|
+
- mysql < sakila-schema.sql
|
20
|
+
- mysql < sakila-data.sql
|
21
|
+
script:
|
22
|
+
- bundle exec rake
|
data/Appraisals
ADDED
data/Dockerfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
FROM rubylang/ruby:2.5-bionic
|
2
|
+
|
3
|
+
RUN apt-get update && \
|
4
|
+
apt-get install -y \
|
5
|
+
mysql-client \
|
6
|
+
libmysqlclient-dev \
|
7
|
+
rubygems \
|
8
|
+
curl
|
9
|
+
|
10
|
+
COPY ./ /mnt/
|
11
|
+
WORKDIR /mnt
|
12
|
+
RUN gem update bundler -f && \
|
13
|
+
bundle install && \
|
14
|
+
bundle exec appraisal install
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# SpringOnion
|
2
2
|
|
3
3
|
Log MySQL queries with EXPLAIN that may be slow.
|
4
|
+
|
4
5
|
Inspired by [MySQLCasualLog.pm](https://gist.github.com/kamipo/839e8a5b6d12bddba539).
|
5
6
|
|
7
|
+
[](https://travis-ci.org/winebarrel/spring_onion)
|
8
|
+
|
6
9
|
## Installation
|
7
10
|
|
8
11
|
Add this line to your application's Gemfile:
|
@@ -75,3 +78,10 @@ p Employee.all.to_a.count
|
|
75
78
|
]
|
76
79
|
}
|
77
80
|
```
|
81
|
+
|
82
|
+
## Test
|
83
|
+
|
84
|
+
```sh
|
85
|
+
docker-compose build
|
86
|
+
docker-compose run client bundle exec appraisal ar60 rake
|
87
|
+
```
|
data/Rakefile
CHANGED
@@ -2,7 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'bundler/gem_tasks'
|
4
4
|
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
5
6
|
|
6
7
|
RSpec::Core::RakeTask.new(:spec)
|
7
8
|
|
8
|
-
|
9
|
+
RuboCop::RakeTask.new do |task|
|
10
|
+
task.options = %w[-c .rubocop.yml]
|
11
|
+
end
|
12
|
+
|
13
|
+
task default: %i[rubocop spec]
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
version: "3.8"
|
2
|
+
services:
|
3
|
+
client:
|
4
|
+
build: .
|
5
|
+
environment:
|
6
|
+
MYSQL_PING_ATTEMPTS: "10"
|
7
|
+
DATABASE_URL: mysql2://root@db/sakila
|
8
|
+
volumes:
|
9
|
+
- ./:/mnt
|
10
|
+
depends_on:
|
11
|
+
- db
|
12
|
+
db:
|
13
|
+
image: budougumi0617/mysql-sakila:5.7
|
14
|
+
environment:
|
15
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: "1"
|
data/lib/spring_onion.rb
CHANGED
data/lib/spring_onion/config.rb
CHANGED
@@ -60,9 +60,9 @@ module SpringOnion
|
|
60
60
|
end
|
61
61
|
|
62
62
|
@logger = Logger.new($stdout).tap do |logger|
|
63
|
-
logger.formatter = lambda
|
63
|
+
logger.formatter = lambda do |severity, datetime, _progname, msg|
|
64
64
|
"\n#{self}\t#{severity}\t#{datetime}\t#{msg}\n"
|
65
|
-
|
65
|
+
end
|
66
66
|
end
|
67
67
|
|
68
68
|
@trace_len = 3
|
@@ -3,14 +3,16 @@
|
|
3
3
|
module SpringOnion
|
4
4
|
module Explainer
|
5
5
|
def execute(*args)
|
6
|
-
_with_explain(args.first) do
|
6
|
+
_with_explain(sql: args.first) do
|
7
7
|
super
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
private
|
12
|
+
|
13
|
+
def _with_explain(sql:)
|
12
14
|
begin
|
13
|
-
if SpringOnion.enabled && sql =~
|
15
|
+
if SpringOnion.enabled && sql =~ /\A\s*SELECT\b/i && SpringOnion.sql_filter.call(sql)
|
14
16
|
trace = SpringOnion.source_filter.call(caller)
|
15
17
|
|
16
18
|
unless trace.length.zero?
|
@@ -19,9 +21,11 @@ module SpringOnion
|
|
19
21
|
|
20
22
|
exp = conn.query("EXPLAIN #{sql}", as: :hash).to_a
|
21
23
|
exp.each { |r| r.delete('id') }
|
22
|
-
|
24
|
+
_validate_explain(sql: sql, exp: exp, trace: trace)
|
23
25
|
end
|
24
26
|
end
|
27
|
+
rescue SpringOnion::Error
|
28
|
+
raise
|
25
29
|
rescue StandardError => e
|
26
30
|
SpringOnion.logger.error(e)
|
27
31
|
end
|
@@ -29,35 +33,26 @@ module SpringOnion
|
|
29
33
|
yield
|
30
34
|
end
|
31
35
|
|
32
|
-
def
|
36
|
+
def _validate_explain(sql:, exp:, trace:)
|
33
37
|
warnings = SpringOnion.warnings
|
34
|
-
|
38
|
+
warning_names_by_index = {}
|
35
39
|
|
36
40
|
exp.each_with_index do |row, i|
|
37
41
|
warning_names = warnings.select do |_name, validator|
|
38
42
|
validator.call(row)
|
39
43
|
end.keys
|
40
44
|
|
41
|
-
|
45
|
+
warning_names_by_index[i] = warning_names unless warning_names.empty?
|
42
46
|
end
|
43
47
|
|
44
|
-
return if
|
48
|
+
return if warning_names_by_index.empty?
|
45
49
|
|
46
|
-
|
50
|
+
SpringOnion::JsonLogger.log(
|
47
51
|
sql: sql,
|
48
|
-
explain: exp
|
49
|
-
warnings:
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
line = if SpringOnion.json_pretty
|
54
|
-
JSON.pretty_generate(h)
|
55
|
-
else
|
56
|
-
JSON.dump(h)
|
57
|
-
end
|
58
|
-
|
59
|
-
line = CodeRay.scan(line, :json).terminal if SpringOnion.color
|
60
|
-
SpringOnion.logger.info(line)
|
52
|
+
explain: exp,
|
53
|
+
warnings: warning_names_by_index,
|
54
|
+
trace: trace
|
55
|
+
)
|
61
56
|
end
|
62
57
|
end
|
63
58
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SpringOnion
|
4
|
+
module JsonLogger
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def log(sql:, explain:, warnings:, trace:)
|
8
|
+
h = {
|
9
|
+
sql: sql,
|
10
|
+
explain: explain.each_with_index.map { |r, i| { line: i + 1 }.merge(r) },
|
11
|
+
warnings: warnings.transform_keys { |i| "line #{i + 1}" },
|
12
|
+
backtrace: trace.slice(0, SpringOnion.trace_len),
|
13
|
+
}
|
14
|
+
|
15
|
+
line = if SpringOnion.json_pretty
|
16
|
+
JSON.pretty_generate(h)
|
17
|
+
else
|
18
|
+
JSON.dump(h)
|
19
|
+
end
|
20
|
+
|
21
|
+
line = CodeRay.scan(line, :json).terminal if SpringOnion.color
|
22
|
+
SpringOnion.logger.info(line)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/spring_onion/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spring_onion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- winebarrel
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -133,15 +133,21 @@ files:
|
|
133
133
|
- ".rspec"
|
134
134
|
- ".rubocop.yml"
|
135
135
|
- ".travis.yml"
|
136
|
+
- Appraisals
|
137
|
+
- Dockerfile
|
136
138
|
- Gemfile
|
137
139
|
- Gemfile.lock
|
138
140
|
- LICENSE.txt
|
139
141
|
- README.md
|
140
142
|
- Rakefile
|
143
|
+
- docker-compose.yml
|
144
|
+
- gemfiles/ar52.gemfile
|
145
|
+
- gemfiles/ar60.gemfile
|
141
146
|
- lib/spring_onion.rb
|
142
147
|
- lib/spring_onion/config.rb
|
143
148
|
- lib/spring_onion/error.rb
|
144
149
|
- lib/spring_onion/explainer.rb
|
150
|
+
- lib/spring_onion/json_logger.rb
|
145
151
|
- lib/spring_onion/version.rb
|
146
152
|
- spring_onion.gemspec
|
147
153
|
homepage: https://github.com/winebarrel/spring_onion
|