spring_onion 0.1.2 → 0.2.2

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: 1a365d84922c1478abeb1ece890c64670ccbc148262362247d76f6b0d14e4fbe
4
- data.tar.gz: 9a121f4fd4e29c0f197abf019de3b83c32823f7dbfed4501a29d8a4d80da5463
3
+ metadata.gz: 54ea2a17b7ab30f6e646ed61b125dcc22e82cf304c946d26c70222a6e5a78341
4
+ data.tar.gz: af308c44d05e7b58048e5c29bd8f708a14d7067111210338ec52296ae9e00f16
5
5
  SHA512:
6
- metadata.gz: 6ad8867bd4a3743844350ca26c6cf766283e5fb22ebe882b5fb807d016c18687339a26947408935bc582ea411307673da3c5fa3cb2ba9d28d7988e875fdabd2a
7
- data.tar.gz: 5a67f25e5e346f2b5f396ad366bade23dd03d695f487893daa21d167b52b66a89eabde482038aac80c4b612de0b32ac2a601f785da5ba75925038afa091cb5b9
6
+ metadata.gz: 1d5fcd164189c1a47126b009f0d058baffc306958cb2dcbd3bbf8e0f0bd4d54f49b9f862204b0d46bb4f68e44cd24257a2f62dced99f93b900d620f7871f2cc4
7
+ data.tar.gz: 0cae3be0dc5e774d092b3e2624bc943604dc8a0aac30dadf645a86f736f13f80978d0ec5a4a5bf595c7eff150f047f79a95769ab9d344bc15917d2ca4dd9b0c1
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spring_onion (0.1.2)
4
+ spring_onion (0.2.2)
5
5
  activerecord
6
+ coderay
6
7
  mysql2
7
8
 
8
9
  GEM
@@ -24,6 +25,7 @@ GEM
24
25
  rake
25
26
  thor (>= 0.14.0)
26
27
  ast (2.4.1)
28
+ coderay (1.1.3)
27
29
  concurrent-ruby (1.1.6)
28
30
  diff-lcs (1.4.4)
29
31
  i18n (1.8.3)
data/README.md CHANGED
@@ -39,8 +39,8 @@ SpringOnion.source_filter_re = //
39
39
 
40
40
  class Employee < ActiveRecord::Base; end
41
41
 
42
- Employee.all.to_a.count
43
- #=> SpringOnion INFO 2020-07-18 01:53:27 +0900 {"sql":"SELECT `employees`.* FROM `employees`","explain":[{"line":1,"select_type":"SIMPLE","table":"employees","partitions":null,"type":"ALL","possible_keys":null,"key":null,"key_len":null,"ref":null,"rows":298936,"filtered":100.0,"Extra":null}],"violations":{"line 1":["slow_type"]},"backtrace":["/foo/bar/zoo/baz.rb:18:in `\u003ctop (required)\u003e'"]}
42
+ p Employee.all.to_a.count
43
+ #=> SpringOnion INFO 2020-07-18 01:53:27 +0900 {"sql":"SELECT `employees`.* FROM `employees`","explain":[{"line":1,"select_type":"SIMPLE","table":"employees","partitions":null,"type":"ALL","possible_keys":null,"key":null,"key_len":null,"ref":null,"rows":298936,"filtered":100.0,"Extra":null}],"warnings":{"line 1":["slow_type"]},"backtrace":["/foo/bar/zoo/baz.rb:18:in `\u003ctop (required)\u003e'"]}
44
44
  #=> 300024
45
45
  ```
46
46
 
@@ -65,7 +65,7 @@ Employee.all.to_a.count
65
65
  "Extra": null
66
66
  }
67
67
  ],
68
- "violations": {
68
+ "warnings": {
69
69
  "line 1": [
70
70
  "slow_type"
71
71
  ]
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'logger'
4
+ require 'coderay'
4
5
  require 'active_support'
5
6
 
6
7
  require 'spring_onion/config'
7
8
  require 'spring_onion/error'
8
9
  require 'spring_onion/explainer'
10
+ require 'spring_onion/json_logger'
9
11
  require 'spring_onion/version'
10
12
 
11
13
  ActiveSupport.on_load :active_record do
@@ -17,7 +17,7 @@ module SpringOnion
17
17
  'Using temporary'
18
18
  )
19
19
 
20
- @violations = {
20
+ @warnings = {
21
21
  slow_select_type: ->(exp) { SLOW_SELECT_TYPE_RE =~ exp['select_type'] },
22
22
  slow_type: ->(exp) { SLOW_TYPE_RE =~ exp['type'] },
23
23
  slow_possible_keys: ->(exp) { SLOW_POSSIBLE_KEYS_RE =~ exp['possible_keys'] },
@@ -42,39 +42,42 @@ module SpringOnion
42
42
  @ignore_sql_filter_re !~ sql && @sql_filter_re =~ sql
43
43
  end
44
44
 
45
- @source_filter_re = Regexp.union(
46
- [%r{/app/}].tap do |ary|
47
- re = ENV['SPRING_ONION_SOURCE_FILTER_RE']
48
- ary << Regexp.new(re) if re
49
- end
50
- )
45
+ @source_filter_re = ENV['SPRING_ONION_SOURCE_FILTER_RE'].yield_self do |re|
46
+ re ? Regexp.new(re) : %r{/app/}
47
+ end
51
48
 
52
49
  @ignore_source_filter_re = Regexp.union(
53
- [RbConfig::TOPDIR, *Gem.path].tap do |ary|
50
+ [RbConfig::TOPDIR, *Gem.path, '/.rbenv/versions/'].tap do |ary|
54
51
  re = ENV['SPRING_ONION_IGNORE_SOURCE_FILTER_RE']
55
52
  ary << Regexp.new(re) if re
56
53
  end
57
54
  )
58
55
 
59
56
  @source_filter = lambda do |backtrace_lines|
60
- backtrace_lines.grep_v(@ignore_source_filter_re).grep(@source_filter_re)
57
+ backtrace_lines = backtrace_lines.grep_v(@ignore_source_filter_re)
58
+ idx = backtrace_lines.index { |l| @source_filter_re =~ l }
59
+ idx ? backtrace_lines.slice(idx..-1) : []
61
60
  end
62
61
 
63
62
  @logger = Logger.new($stdout).tap do |logger|
64
- logger.formatter = lambda { |severity, datetime, _progname, msg|
63
+ logger.formatter = lambda do |severity, datetime, _progname, msg|
65
64
  "\n#{self}\t#{severity}\t#{datetime}\t#{msg}\n"
66
- }
65
+ end
67
66
  end
68
67
 
69
68
  @trace_len = 3
69
+ @json_pretty = (/\A(1|true)\z/i =~ ENV['SPRING_ONION_JSON_PRETTY'])
70
+ @color = /\A(1|true)\z/i =~ ENV.fetch('SPRING_ONION_COLOR', $stdout.tty?.to_s)
70
71
 
71
72
  class << self
72
73
  attr_accessor :enabled,
73
74
  :connection,
74
- :violations,
75
+ :warnings,
75
76
  :sql_filter_re, :ignore_sql_filter_re, :sql_filter,
76
77
  :source_filter_re, :ignore_source_filter_re, :source_filter,
77
78
  :logger,
78
- :trace_len
79
+ :trace_len,
80
+ :json_pretty,
81
+ :color
79
82
  end
80
83
  end
@@ -19,7 +19,7 @@ module SpringOnion
19
19
 
20
20
  exp = conn.query("EXPLAIN #{sql}", as: :hash).to_a
21
21
  exp.each { |r| r.delete('id') }
22
- _validate(exp, sql, trace)
22
+ _validate_explain(exp, sql, trace)
23
23
  end
24
24
  end
25
25
  rescue StandardError => e
@@ -29,26 +29,26 @@ module SpringOnion
29
29
  yield
30
30
  end
31
31
 
32
- def _validate(exp, sql, trace)
33
- violations = SpringOnion.violations
34
- violation_names_by_line = {}
32
+ def _validate_explain(exp, sql, trace)
33
+ warnings = SpringOnion.warnings
34
+ warning_names_by_index = {}
35
35
 
36
36
  exp.each_with_index do |row, i|
37
- violation_names = violations.select do |_name, validator|
37
+ warning_names = warnings.select do |_name, validator|
38
38
  validator.call(row)
39
39
  end.keys
40
40
 
41
- violation_names_by_line["line #{i + 1}"] = violation_names unless violation_names.empty?
41
+ warning_names_by_index[i] = warning_names unless warning_names.empty?
42
42
  end
43
43
 
44
- return if violation_names_by_line.empty?
44
+ return if warning_names_by_index.empty?
45
45
 
46
- SpringOnion.logger.info({
46
+ SpringOnion::JsonLogger.log(
47
47
  sql: sql,
48
- explain: exp.each_with_index.map { |r, i| { line: i + 1 }.merge(r) },
49
- violations: violation_names_by_line,
50
- backtrace: trace.slice(0, SpringOnion.trace_len),
51
- }.to_json)
48
+ explain: exp,
49
+ warnings: warning_names_by_index,
50
+ trace: trace
51
+ )
52
52
  end
53
53
  end
54
54
  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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SpringOnion
4
- VERSION = '0.1.2'
4
+ VERSION = '0.2.2'
5
5
  end
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.require_paths = ['lib']
25
25
 
26
26
  spec.add_dependency 'activerecord'
27
+ spec.add_dependency 'coderay'
27
28
  spec.add_dependency 'mysql2'
28
29
  spec.add_development_dependency 'appraisal'
29
30
  spec.add_development_dependency 'bundler'
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.1.2
4
+ version: 0.2.2
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-17 00:00:00.000000000 Z
11
+ date: 2020-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: coderay
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: mysql2
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -128,6 +142,7 @@ files:
128
142
  - lib/spring_onion/config.rb
129
143
  - lib/spring_onion/error.rb
130
144
  - lib/spring_onion/explainer.rb
145
+ - lib/spring_onion/json_logger.rb
131
146
  - lib/spring_onion/version.rb
132
147
  - spring_onion.gemspec
133
148
  homepage: https://github.com/winebarrel/spring_onion