sql_tracer 0.1.5 → 0.1.6
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/app/assets/stylesheets/sql_tracer/style.css +42 -0
- data/app/views/sql_tracer/sql_tracer/index.html.erb +75 -5
- data/lib/sql_tracer/adapters/mysql2.rb +9 -11
- data/lib/sql_tracer/config.rb +2 -2
- data/lib/sql_tracer/helper.rb +6 -6
- data/lib/sql_tracer/sql_logger.rb +20 -1
- data/lib/sql_tracer/version.rb +1 -1
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f21d52b8fc4e11295690f44a4a268c2e36a94cdb
|
4
|
+
data.tar.gz: a27c5ca3325849dad50e8eb1fb319927dc11de86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b7b8af5ef58e291457a4ad1d83526bbaf89a3bfe52fc68553f5ecd7a544f3b266d8edebc2351be7a5122efd6a829fd126d160c895177f1c95dc066c9f0e15b7
|
7
|
+
data.tar.gz: e83a0e5c7617ef3a4cba63b73146b7e65e7f6d3bfeac4f763d9a06795f11819d032a23f34896b291a5422d8756f8cef3893b4c73bdedba49d32bd40a2a97ca9b
|
@@ -155,6 +155,10 @@ a:active {
|
|
155
155
|
word-break: break-all;
|
156
156
|
}
|
157
157
|
|
158
|
+
.filter_template {
|
159
|
+
padding-left: 20px;
|
160
|
+
}
|
161
|
+
|
158
162
|
.stack_info {
|
159
163
|
word-break: break-all;
|
160
164
|
/*padding-left: 40px;*/
|
@@ -168,6 +172,7 @@ a:active {
|
|
168
172
|
#url_template,
|
169
173
|
#sqls_template,
|
170
174
|
#sql_template,
|
175
|
+
#filter_template,
|
171
176
|
#stack_info {
|
172
177
|
display: none;
|
173
178
|
}
|
@@ -190,3 +195,40 @@ a:active {
|
|
190
195
|
from { transform: scale(1) rotate(0deg);}
|
191
196
|
to { transform: scale(1) rotate(360deg);}
|
192
197
|
}
|
198
|
+
|
199
|
+
.filter_template input {
|
200
|
+
color: #373737;
|
201
|
+
}
|
202
|
+
|
203
|
+
/*for input */
|
204
|
+
input[type=text], select {
|
205
|
+
width: 15%;
|
206
|
+
/*padding: 12px 20px;*/
|
207
|
+
/*margin: 8px 0;*/
|
208
|
+
/*display: inline-block;*/
|
209
|
+
/*border: 1px solid #ccc;*/
|
210
|
+
/*border-radius: 4px;*/
|
211
|
+
/*box-sizing: border-box;*/
|
212
|
+
}
|
213
|
+
|
214
|
+
input[type=submit]:hover {
|
215
|
+
background-color: #45a049;
|
216
|
+
}
|
217
|
+
|
218
|
+
input{
|
219
|
+
border: 1px solid #ccc;
|
220
|
+
/*padding: 7px 0px;*/
|
221
|
+
border-radius: 3px;
|
222
|
+
/*padding-left:5px;*/
|
223
|
+
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
|
224
|
+
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
|
225
|
+
-webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
|
226
|
+
-o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
|
227
|
+
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s
|
228
|
+
}
|
229
|
+
input:focus{
|
230
|
+
border-color: #66afe9;
|
231
|
+
outline: 0;
|
232
|
+
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);
|
233
|
+
box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)
|
234
|
+
}
|
@@ -23,13 +23,13 @@
|
|
23
23
|
</h1>
|
24
24
|
<p>
|
25
25
|
It helps you figure out what sqls are executed and trace method call stack, you can take a look at
|
26
|
-
<a class="btn btn-primary btn-xs" target="_blank" href="https://
|
26
|
+
<a class="btn btn-primary btn-xs" target="_blank" href="https://git.dev.fwmrm.net/qzhang/sql_tracer">
|
27
27
|
Read Me</a>
|
28
28
|
to acquire more information.
|
29
29
|
</p>
|
30
30
|
<p>
|
31
31
|
If you have any questions or improvement, please open a issue.
|
32
|
-
<a class="btn btn-primary btn-xs" target="_blank" href="https://
|
32
|
+
<a class="btn btn-primary btn-xs" target="_blank" href="https://git.dev.fwmrm.net/qzhang/sql_tracer/issues/new">
|
33
33
|
New Issue
|
34
34
|
</a>
|
35
35
|
<p>
|
@@ -55,6 +55,19 @@
|
|
55
55
|
</h4>
|
56
56
|
</div>
|
57
57
|
</div>
|
58
|
+
|
59
|
+
<div id="filter_template" class="panel-heading filter_template">
|
60
|
+
<h4 class="panel-title">
|
61
|
+
<label class="sql-filter-label" for="input-2">SQL:</label>
|
62
|
+
<input class="sql-filter-class" type="text">
|
63
|
+
<label class="path-filter-label" for="input-2">PATH:</label>
|
64
|
+
<input class="path-filter-class" type="text">
|
65
|
+
<input type="checkbox" class="sort_by_checkbox" value='db'> Sort by DB
|
66
|
+
<input type="checkbox" class="sort_by_checkbox" value='operator'> Sort by Operator
|
67
|
+
</a>
|
68
|
+
</h4>
|
69
|
+
</div>
|
70
|
+
|
58
71
|
<div id="sql_template" class="panel-heading sql_template">
|
59
72
|
<h4 class="panel-title">
|
60
73
|
<a data-toggle="collapse" data-parent="#" href="#one-2" class="sql">
|
@@ -88,7 +101,7 @@
|
|
88
101
|
}
|
89
102
|
},
|
90
103
|
complete: function() {
|
91
|
-
setTimeout("refresh()",
|
104
|
+
setTimeout("refresh()", 4000)
|
92
105
|
}
|
93
106
|
});
|
94
107
|
}
|
@@ -107,6 +120,61 @@
|
|
107
120
|
$sqls_template.attr("id", "");
|
108
121
|
|
109
122
|
if (sqls && sqls.length > 0) {
|
123
|
+
var $filter_template = $("#filter_template").clone();
|
124
|
+
$filter_template.css("display", "block");
|
125
|
+
|
126
|
+
|
127
|
+
// Add Sort Action to Sort Checkboxes
|
128
|
+
let sortArray = [];
|
129
|
+
$filter_template.find(".sort_by_checkbox").on('click', function(e) {
|
130
|
+
if (e.target.checked) {
|
131
|
+
sortArray.push(e.target.value);
|
132
|
+
} else {
|
133
|
+
sortArray.splice(sortArray.indexOf(e.target.value), 1);
|
134
|
+
}
|
135
|
+
|
136
|
+
const compareArray = sortArray.concat('time');
|
137
|
+
var templates = $sqls_template.find(".sql_template");
|
138
|
+
templates.sort(function(a, b) {
|
139
|
+
var aSQL = $(a).find("a");
|
140
|
+
var bSQL = $(b).find("a");
|
141
|
+
|
142
|
+
for (var i = 0; i < compareArray.length; i++) {
|
143
|
+
if (String(aSQL.attr(compareArray[i])).toLowerCase() > String(bSQL.attr(compareArray[i])).toLowerCase()) {
|
144
|
+
return 1;
|
145
|
+
} else if (String(aSQL.attr(compareArray[i])).toLowerCase() < String(bSQL.attr(compareArray[i])).toLowerCase()) {
|
146
|
+
return -1;
|
147
|
+
}
|
148
|
+
}
|
149
|
+
return 0;
|
150
|
+
});
|
151
|
+
|
152
|
+
templates.each(function() {
|
153
|
+
$sqls_template.append(this);
|
154
|
+
});
|
155
|
+
});
|
156
|
+
|
157
|
+
// Add Filter Action to Filters
|
158
|
+
$filter_template.find("input").on('input', function(e) {
|
159
|
+
var sqlFilter = $filter_template.find(".sql-filter-class").val();
|
160
|
+
var pathFilter = $filter_template.find(".path-filter-class").val();
|
161
|
+
|
162
|
+
$.each($sqls_template.find(".sql_template"), function(index, template) {
|
163
|
+
if (!$(template).find("a").text().match(new RegExp(sqlFilter, "i")) || !$(template).next().find(".panel-body").text().match(new RegExp(pathFilter, "i"))
|
164
|
+
) {
|
165
|
+
$(template).hide();
|
166
|
+
$(template).next().hide();
|
167
|
+
} else {
|
168
|
+
$(template).show();
|
169
|
+
}
|
170
|
+
});
|
171
|
+
$url_template.find("span").html($sqls_template.find(".sql_template:visible").size());
|
172
|
+
});
|
173
|
+
|
174
|
+
|
175
|
+
$sqls_template.append($filter_template);
|
176
|
+
|
177
|
+
// Build Dom from sqls
|
110
178
|
$.each(sqls, function(index, sql_info) {
|
111
179
|
var $stack_info = $("#stack_info").clone();
|
112
180
|
$stack_info.attr("id", "");
|
@@ -114,8 +182,10 @@
|
|
114
182
|
|
115
183
|
var $sql_template = $("#sql_template").clone();
|
116
184
|
$sql_template.attr("id", "");
|
117
|
-
$sql_template.find("a").attr("
|
118
|
-
$sql_template.find("a").
|
185
|
+
$sql_template.find("a").attr("db", sql_info.sql.db);
|
186
|
+
$sql_template.find("a").attr("operator", sql_info.sql.operator);
|
187
|
+
$sql_template.find("a").attr("time", sql_info.sql.time);
|
188
|
+
$sql_template.find("a").html(sql_info.sql.sql);
|
119
189
|
$sql_template.find("a").click(function() {
|
120
190
|
if ($stack_info.is(":visible")) {
|
121
191
|
$sql_template.removeClass('active');
|
@@ -1,18 +1,16 @@
|
|
1
1
|
require 'active_record/connection_adapters/mysql2_adapter'
|
2
2
|
|
3
|
-
module
|
3
|
+
module ActiveRecord::ConnectionAdapters
|
4
4
|
module Mysql2SqlLogger
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def execute(*args)
|
10
|
-
SqlTracer::SqlLogger.log_sql(args.first)
|
11
|
-
execute_without_sql_tracer(*args)
|
12
|
-
end
|
5
|
+
def execute(*args)
|
6
|
+
SqlTracer::SqlLogger.log_sql(args.first)
|
7
|
+
super(*args)
|
13
8
|
end
|
14
9
|
end
|
15
|
-
end
|
16
10
|
|
17
|
-
|
11
|
+
class Mysql2Adapter
|
12
|
+
prepend Mysql2SqlLogger
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
18
16
|
|
data/lib/sql_tracer/config.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module SqlTracer
|
2
2
|
module Config
|
3
3
|
DEFAULTS = {
|
4
|
-
SQL_TRACER_SKIP_LIB_PATH:
|
5
|
-
SQL_TRACER_CONSOLE_OUTPUT_DISABLED: true, # sqls won't be output in back-end console if set to true
|
4
|
+
SQL_TRACER_SKIP_LIB_PATH: false, # method call paths in /.rvm directory won't be output, default true
|
5
|
+
SQL_TRACER_CONSOLE_OUTPUT_DISABLED: true, # sqls won't be output in back-end console if set to true, default false
|
6
6
|
SQL_TRACER_OUTPUT_SELECT_SQL_ENABLED: false, # output select type sql. By default, only (insert|update|delete) sql will be output
|
7
7
|
# sql which contains any element of this array won't be output
|
8
8
|
SQL_TRACER_SQL_FILTER: [],
|
data/lib/sql_tracer/helper.rb
CHANGED
@@ -3,8 +3,8 @@ module SqlTracer
|
|
3
3
|
class Helper
|
4
4
|
|
5
5
|
class << self
|
6
|
-
def
|
7
|
-
@output_select_sql_enabled ||= config.get(:
|
6
|
+
def output_select_sql_disabled?
|
7
|
+
@output_select_sql_enabled ||= config.get(:SQL_TRACER_OUTPUT_SELECT_SQL_DISABLED)
|
8
8
|
end
|
9
9
|
|
10
10
|
def should_skip_lib?
|
@@ -13,17 +13,17 @@ module SqlTracer
|
|
13
13
|
|
14
14
|
def should_skip_sql_by_keywords?(sql)
|
15
15
|
@sql_keywords ||= config.get(:SQL_TRACER_SQL_FILTER)
|
16
|
-
@sql_keywords.any? { |keyword| sql.include?(keyword) }
|
16
|
+
@sql_keywords.present? && @sql_keywords.any? { |keyword| sql.include?(keyword) }
|
17
17
|
end
|
18
18
|
|
19
19
|
def should_skip_url_by_keywords?(url)
|
20
20
|
@url_keywords ||= config.get(:SQL_TRACER_URL_FILTER)
|
21
|
-
@url_keywords.any? { |keyword| url.include?(keyword) }
|
21
|
+
@url_keywords.present? && @url_keywords.any? { |keyword| url.include?(keyword) }
|
22
22
|
end
|
23
23
|
|
24
24
|
def shoule_skip_path_by_keywords?(path)
|
25
25
|
@path_keywords ||= build_path_filter
|
26
|
-
@path_keywords.any? { |keyword| path.include?(keyword) }
|
26
|
+
@path_keywords.present? && @path_keywords.any? { |keyword| path.include?(keyword) }
|
27
27
|
end
|
28
28
|
|
29
29
|
def disable_console_output?
|
@@ -32,7 +32,7 @@ module SqlTracer
|
|
32
32
|
|
33
33
|
def should_output_sql?(sql)
|
34
34
|
reg = 'insert|update|delete'
|
35
|
-
reg << '|select'
|
35
|
+
reg << '|select' unless Helper.output_select_sql_disabled?
|
36
36
|
return sql =~ /^\s*(#{reg})\s/i && !Helper.should_skip_sql_by_keywords?(sql)
|
37
37
|
end
|
38
38
|
|
@@ -6,12 +6,31 @@ module SqlTracer
|
|
6
6
|
backtrace = Thread.current.backtrace
|
7
7
|
backtrace = Formatter.remove_filtered_path(backtrace)
|
8
8
|
Formatter.print_all(sql, backtrace) unless Helper.disable_console_output?
|
9
|
-
|
9
|
+
|
10
|
+
SqlTracer::SqlStack.sql_stack << { :sql => build_sql_struct(sql), :stack => backtrace }
|
10
11
|
end
|
11
12
|
rescue => e
|
12
13
|
Rails.logger.error "Failed to log sql in SqlTracer. Error: #{e.message}"
|
13
14
|
Rails.logger.error e.backtrace.join("\n")
|
14
15
|
end
|
15
16
|
end
|
17
|
+
|
18
|
+
def self.build_sql_struct(sql)
|
19
|
+
sql_struct = {
|
20
|
+
:sql => sql,
|
21
|
+
:operator => 'unknown',
|
22
|
+
:db => 'unknown',
|
23
|
+
:time => Time.now.to_f
|
24
|
+
}
|
25
|
+
puts
|
26
|
+
re = /^(insert into|update|delete|select)\s+(\S+)/i
|
27
|
+
begin
|
28
|
+
result = sql.scan(re)
|
29
|
+
sql_struct[:operator] = result[0][0]
|
30
|
+
sql_struct[:db] = result[0][1]
|
31
|
+
rescue
|
32
|
+
end
|
33
|
+
sql_struct
|
34
|
+
end
|
16
35
|
end
|
17
36
|
end
|
data/lib/sql_tracer/version.rb
CHANGED
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sql_tracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- qzhang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: It helps you figure out what sqls are executed and trace method call
|
14
14
|
stack
|
15
15
|
email:
|
16
|
-
-
|
16
|
+
- qzhang@freewheel.tv
|
17
17
|
executables: []
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
@@ -35,7 +35,7 @@ files:
|
|
35
35
|
- lib/sql_tracer/sql_logger.rb
|
36
36
|
- lib/sql_tracer/sql_stack.rb
|
37
37
|
- lib/sql_tracer/version.rb
|
38
|
-
homepage: https://
|
38
|
+
homepage: https://git.dev.fwmrm.net/qzhang/sql_tracer
|
39
39
|
licenses: []
|
40
40
|
metadata: {}
|
41
41
|
post_install_message:
|
@@ -59,4 +59,3 @@ signing_key:
|
|
59
59
|
specification_version: 4
|
60
60
|
summary: log backtrace when sql is executed
|
61
61
|
test_files: []
|
62
|
-
has_rdoc:
|