groonga-query-log 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/doc/text/news.md +13 -0
  3. data/groonga-query-log.gemspec +2 -1
  4. data/lib/groonga-query-log/command/analyzer/reporter/console.rb +15 -5
  5. data/lib/groonga-query-log/command/analyzer/reporter/csv.rb +2 -2
  6. data/lib/groonga-query-log/command/analyzer/reporter/html.rb +105 -10
  7. data/lib/groonga-query-log/command/analyzer/sized-statistics.rb +20 -7
  8. data/lib/groonga-query-log/command/analyzer/worker-statistic.rb +64 -0
  9. data/lib/groonga-query-log/command/check-crash.rb +18 -18
  10. data/lib/groonga-query-log/command/check-performance-regression.rb +0 -4
  11. data/lib/groonga-query-log/command/extract.rb +1 -1
  12. data/lib/groonga-query-log/command/run-regression-test.rb +14 -0
  13. data/lib/groonga-query-log/command/verify-server.rb +7 -1
  14. data/lib/groonga-query-log/performance-verifier.rb +73 -0
  15. data/lib/groonga-query-log/server-verifier.rb +39 -0
  16. data/lib/groonga-query-log/statistic.rb +7 -2
  17. data/lib/groonga-query-log/version.rb +1 -1
  18. data/test/command/test-analyzer.rb +2 -2
  19. data/test/fixtures/multi.expected +25 -3
  20. data/test/fixtures/n_entries.expected +18 -3
  21. data/test/fixtures/order/-elapsed.expected +18 -3
  22. data/test/fixtures/order/-start-time.expected +18 -3
  23. data/test/fixtures/order/elapsed.expected +18 -3
  24. data/test/fixtures/order/start-time.expected +18 -3
  25. data/test/fixtures/reporter/console.expected +18 -3
  26. data/test/fixtures/reporter/html.expected +44 -7
  27. data/test/fixtures/reporter/json-stream.expected +2 -2
  28. data/test/fixtures/reporter/json.expected +2 -2
  29. data/test/fixtures/run-regression-test/db.new/db +0 -0
  30. data/test/fixtures/run-regression-test/db.new/db.0000000 +0 -0
  31. data/test/fixtures/run-regression-test/db.new/db.0000100 +0 -0
  32. data/test/fixtures/run-regression-test/db.new/db.0000101 +0 -0
  33. data/test/fixtures/run-regression-test/db.new/db.0000102 +0 -0
  34. data/test/fixtures/run-regression-test/db.new/db.0000103 +0 -0
  35. data/test/fixtures/run-regression-test/db.new/db.0000103.c +0 -0
  36. data/test/fixtures/run-regression-test/db.new/db.001 +0 -0
  37. data/test/fixtures/run-regression-test/db.new/db.conf +0 -0
  38. data/test/fixtures/run-regression-test/db.new/groonga.log +165 -0
  39. data/test/fixtures/run-regression-test/db.old/db +0 -0
  40. data/test/fixtures/run-regression-test/db.old/db.0000000 +0 -0
  41. data/test/fixtures/run-regression-test/db.old/db.0000100 +0 -0
  42. data/test/fixtures/run-regression-test/db.old/db.0000101 +0 -0
  43. data/test/fixtures/run-regression-test/db.old/db.0000102 +0 -0
  44. data/test/fixtures/run-regression-test/db.old/db.0000103 +0 -0
  45. data/test/fixtures/run-regression-test/db.old/db.0000103.c +0 -0
  46. data/test/fixtures/run-regression-test/db.old/db.001 +0 -0
  47. data/test/fixtures/run-regression-test/db.old/db.conf +0 -0
  48. data/test/fixtures/run-regression-test/db.old/groonga.log +79 -0
  49. data/test/fixtures/run-regression-test/results/query.log +0 -0
  50. data/test/fixtures/target-commands.expected +11 -3
  51. data/test/fixtures/target-tables.expected +11 -3
  52. metadata +102 -45
  53. data/test/#test-response-comparer.rb# +0 -14750
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c4745d088436d712bbc9d1b010c0219008baac00d05f5c5ebb59423912353ab
4
- data.tar.gz: 3d663956a09c081278a1f6a06534dfcd08e7a46c5ee270d06469be274817f8d7
3
+ metadata.gz: 5f9718a90b49d69a599b168a7ab18cece39ef1849355ef0c9c511a34c54ef636
4
+ data.tar.gz: bf2c8374333e8d70455d64aa71eb743d2e900410e38c9b04a4acf7ec96380763
5
5
  SHA512:
6
- metadata.gz: 705cfcf529854898bd27884a714ac123776f8e560e088ebacc5860049061de29c3454bcfafd45ab3655d812492659ced950d9fa66727d831fb4d7b3961cf779c
7
- data.tar.gz: eccf8a59cb0f6faba614bf9e4beae35228c4b3634a04e3d2a1af0fa50d7da60750e53a6ef891a3295c301bb47301c38685ece802b001b5a2e12ef4df1c384916
6
+ metadata.gz: e3ab37905b01d41b982c75e74a0e585b46f81d101b690c22b92ccc4fd8098deb889c45e1cc31998ece5c7a69b587f8852e226c84a8c0ffc822e5ae09c503f636
7
+ data.tar.gz: e85db7c29f331f0b2673beebbfda49a5aae5096630b1524140e7751256140b3293faa6cc630fb8e6c0acc2fe6c50a81eb2aea664be5985e533523692dd9f84a6
@@ -1,5 +1,18 @@
1
1
  # News
2
2
 
3
+ ## 1.5.3: 2019-10-21
4
+
5
+ ### Improvements
6
+
7
+ * `GroongaQueryLog::Statistic#end_time`: Renamed from
8
+ `#last_time`. `#last_time` is deprecated.
9
+
10
+ * `analyzer`: Added support for reporting worker idle time.
11
+
12
+ * `analyzer`: Added support for reporting the number of processed
13
+ requests per worker.
14
+
15
+ * `run-regression-test`: Added `--verify-performance` option.
3
16
 
4
17
  ## 1.5.2: 2019-09-26
5
18
 
@@ -1,6 +1,6 @@
1
1
  # -*- ruby -*-
2
2
  #
3
- # Copyright (C) 2012-2018 Kouhei Sutou <kou@clear-code.com>
3
+ # Copyright (C) 2012-2019 Sutou Kouhei <kou@clear-code.com>
4
4
  #
5
5
  # This library is free software; you can redistribute it and/or
6
6
  # modify it under the terms of the GNU Lesser General Public
@@ -52,6 +52,7 @@ Gem::Specification.new do |spec|
52
52
  spec.licenses = ["LGPLv2.1+"]
53
53
  spec.require_paths = ["lib"]
54
54
 
55
+ spec.add_runtime_dependency("charty")
55
56
  spec.add_runtime_dependency("diff-lcs")
56
57
  spec.add_runtime_dependency("groonga-client", ">= 0.6.2")
57
58
  spec.add_runtime_dependency("groonga-log", ">= 0.1.2")
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2011-2019 Sutou Kouhei <kou@clear-code.com>
2
2
  # Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
3
3
  #
4
4
  # This library is free software; you can redistribute it and/or
@@ -177,11 +177,21 @@ module GroongaQueryLog
177
177
  write(" # of slow responses : #{@statistics.n_slow_responses}\n")
178
178
  write(" responses/sec : #{@statistics.responses_per_second}\n")
179
179
  write(" start time : #{format_time(@statistics.start_time)}\n")
180
- write(" last time : #{format_time(@statistics.last_time)}\n")
181
- write(" period(sec) : #{@statistics.period}\n")
180
+ write(" end time : #{format_time(@statistics.end_time)}\n")
181
+ write(" period(sec) : %.3f\n" % @statistics.period)
182
182
  slow_response_ratio = @statistics.slow_response_ratio
183
183
  write(" slow response ratio : %5.3f%%\n" % slow_response_ratio)
184
- write(" total response time : #{@statistics.total_elapsed}\n")
184
+ write(" total response time : %.3f\n" % @statistics.total_elapsed)
185
+ write(" Workers:\n")
186
+ @statistics.each_worker do |worker|
187
+ write(" #{worker.id}:\n")
188
+ write(" # of processed requests: #{worker.n_statistics}\n")
189
+ write(" idle time(sec):\n")
190
+ write(" total : %.3f\n" % worker.idle_time_total)
191
+ write(" mean : %.3f\n" % worker.idle_time_mean)
192
+ write(" min : %.3f\n" % worker.idle_time_min)
193
+ write(" max : %.3f\n" % worker.idle_time_max)
194
+ end
185
195
  report_slow_operations
186
196
  end
187
197
 
@@ -266,7 +276,7 @@ module GroongaQueryLog
266
276
  :elapsed)
267
277
  data = [
268
278
  format_time(statistic.start_time),
269
- format_time(statistic.last_time),
279
+ format_time(statistic.end_time),
270
280
  formatted_elapsed,
271
281
  statistic.return_code,
272
282
  ]
@@ -33,7 +33,7 @@ module GroongaQueryLog
33
33
  @csv = CSV.new(@output)
34
34
  header = [
35
35
  "start_time",
36
- "last_time",
36
+ "end_time",
37
37
  "elapsed",
38
38
  "return_code",
39
39
  "slow",
@@ -46,7 +46,7 @@ module GroongaQueryLog
46
46
  def report_statistic(statistic)
47
47
  record = [
48
48
  format_time(statistic.start_time),
49
- format_time(statistic.last_time),
49
+ format_time(statistic.end_time),
50
50
  statistic.elapsed_in_seconds,
51
51
  statistic.return_code,
52
52
  statistic.slow?,
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2011-2018 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2011-2019 Sutou Kouhei <kou@clear-code.com>
2
2
  # Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
3
3
  #
4
4
  # This library is free software; you can redistribute it and/or
@@ -16,6 +16,9 @@
16
16
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
  require "erb"
19
+
20
+ require "charty"
21
+
19
22
  require "groonga-query-log/command/analyzer/reporter"
20
23
 
21
24
  module GroongaQueryLog
@@ -24,6 +27,34 @@ module GroongaQueryLog
24
27
  class HTMLReporter < Reporter
25
28
  include ERB::Util
26
29
 
30
+ private
31
+ def setup_output
32
+ @directory_output_mode = false
33
+ return super unless directory_output?
34
+
35
+ @directory_output_mode = true
36
+ original_output = @output
37
+ begin
38
+ FileUtils.mkdir_p(@output)
39
+ File.open(File.join(@output, "index.html"), "w") do |output|
40
+ @output = output
41
+ yield(@output)
42
+ end
43
+ ensure
44
+ @output = original_output
45
+ end
46
+ end
47
+
48
+ def directory_output?
49
+ return false unless @output.is_a?(String)
50
+
51
+ return true if File.directory?(@output)
52
+ return true if File.extname(@output).empty?
53
+ return true if @output.end_with?("/")
54
+
55
+ false
56
+ end
57
+
27
58
  def start
28
59
  write(header)
29
60
  end
@@ -38,6 +69,7 @@ module GroongaQueryLog
38
69
  <div class="summary">
39
70
  <%= analyze_parameters %>
40
71
  <%= metrics %>
72
+ <%= workers %>
41
73
  <%= slow_operations %>
42
74
  </div>
43
75
  EOH
@@ -56,10 +88,10 @@ module GroongaQueryLog
56
88
  statistic_html = erb(<<-EOH, __LINE__ + 1, binding)
57
89
  <div class="statistic-heading">
58
90
  <h3>Command</h3>
59
- <div class="metrics">
91
+ <div class="statistic-metrics">
60
92
  [<%= format_time(statistic.start_time) %>
61
93
  -
62
- <%= format_time(statistic.last_time) %>
94
+ <%= format_time(statistic.end_time) %>
63
95
  (<%= format_elapsed(statistic.elapsed_in_seconds,
64
96
  :slow? => statistic.slow?) %>)]
65
97
  (<%= span({:class => "return-code"}, h(statistic.return_code)) %>)
@@ -111,7 +143,6 @@ module GroongaQueryLog
111
143
  write(statistic_html)
112
144
  end
113
145
 
114
- private
115
146
  def erb(content, line, _binding=nil)
116
147
  _erb = ERB.new(content, nil, "<>")
117
148
  eval(_erb.src, _binding || binding, __FILE__, line)
@@ -119,8 +150,10 @@ module GroongaQueryLog
119
150
 
120
151
  def header
121
152
  erb(<<-EOH, __LINE__ + 1)
153
+ <!DOCTYPE html>
122
154
  <html>
123
155
  <head>
156
+ <meta charset="utf-8">
124
157
  <title>groonga query analyzer</title>
125
158
  <style>
126
159
  table,
@@ -136,18 +169,24 @@ span.slow
136
169
  color: red;
137
170
  }
138
171
 
139
- div.parameters
172
+ div.parameters,
173
+ div.metrics,
174
+ div.workers
140
175
  {
141
176
  float: left;
142
177
  padding: 2em;
143
178
  }
144
179
 
145
- div.parameters h3
180
+ div.parameters h3,
181
+ div.metrics h3,
182
+ div.workers h3
146
183
  {
147
184
  text-align: center;
148
185
  }
149
186
 
150
- div.parameters table
187
+ div.parameters table,
188
+ div.metrics table,
189
+ div.workers table
151
190
  {
152
191
  margin-right: auto;
153
192
  margin-left: auto;
@@ -218,7 +257,7 @@ td.name
218
257
 
219
258
  def metrics
220
259
  erb(<<-EOH, __LINE__ + 1)
221
- <div class="parameters">
260
+ <div class="metrics">
222
261
  <h3>Metrics</h3>
223
262
  <table>
224
263
  <tr><th>Name</th><th>Value</th></tr>
@@ -239,8 +278,8 @@ td.name
239
278
  <td><%= format_time(@statistics.start_time) %></td>
240
279
  </tr>
241
280
  <tr>
242
- <th>last time</th>
243
- <td><%= format_time(@statistics.last_time) %></td>
281
+ <th>end time</th>
282
+ <td><%= format_time(@statistics.end_time) %></td>
244
283
  </tr>
245
284
  <tr>
246
285
  <th>period</th>
@@ -259,6 +298,62 @@ td.name
259
298
  EOH
260
299
  end
261
300
 
301
+ def workers
302
+ html = ""
303
+ html << erb(<<-WORKERS, __LINE__ + 1)
304
+ <div class="workers">
305
+ <h3>Workers</h3>
306
+ <table>
307
+ <tr>
308
+ <th>ID</th>
309
+ <th># of processed requests</th>
310
+ <th>idle time total</th>
311
+ <th>idle time mean</th>
312
+ <th>idle time min</th>
313
+ <th>idle time max</th>
314
+ </tr>
315
+ <% @statistics.each_worker do |worker| %>
316
+ <tr>
317
+ <td><%= h(worker.id) %></td>
318
+ <td><%= h(worker.n_statistics) %></td>
319
+ <td><%= h("%.3f" % worker.idle_time_total) %></td>
320
+ <td><%= h("%.3f" % worker.idle_time_mean) %></td>
321
+ <td><%= h("%.3f" % worker.idle_time_min) %></td>
322
+ <td><%= h("%.3f" % worker.idle_time_max) %></td>
323
+ </tr>
324
+ <% end %>
325
+ </table>
326
+ WORKERS
327
+ use_charty = false # TODO
328
+ if use_charty
329
+ plotter = Charty::Plotter.new(:google_charts)
330
+ @statistics.each_worker do |worker|
331
+ figure = plotter.curve do
332
+ metrics = worker.metrics
333
+ series(metrics[:timestamp],
334
+ metrics[:idle_time],
335
+ label: worker.id)
336
+ xlabel("timestamp")
337
+ ylabel("idle time")
338
+ end
339
+ html << figure.render
340
+ figure = plotter.curve do
341
+ metrics = worker.metrics
342
+ series(metrics[:timestamp],
343
+ metrics[:elapsed],
344
+ label: worker.id)
345
+ xlabel("timestamp")
346
+ ylabel("elapsed")
347
+ end
348
+ html << figure.render
349
+ end
350
+ end
351
+ html << erb(<<-WORKERS, __LINE__ + 1)
352
+ </div>
353
+ WORKERS
354
+ html
355
+ end
356
+
262
357
  def slow_operations
263
358
  erb(<<-EOH, __LINE__ + 1)
264
359
  <div class="statistics">
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2011-2017 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2011-2019 Sutou Kouhei <kou@clear-code.com>
2
2
  # Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
3
3
  #
4
4
  # This library is free software; you can redistribute it and/or
@@ -16,6 +16,7 @@
16
16
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
  require "groonga-query-log/command/analyzer/sized-grouped-operations"
19
+ require "groonga-query-log/command/analyzer/worker-statistic"
19
20
 
20
21
  module GroongaQueryLog
21
22
  module Command
@@ -23,18 +24,19 @@ module GroongaQueryLog
23
24
  class SizedStatistics < Array
24
25
  attr_reader :n_responses, :n_slow_responses, :n_slow_operations
25
26
  attr_reader :slow_operations, :total_elapsed
26
- attr_reader :start_time, :last_time
27
+ attr_reader :start_time, :end_time
27
28
  def initialize
28
29
  @max_size = 10
29
30
  self.order = "-elapsed"
30
31
  @start_time = nil
31
- @last_time = nil
32
+ @end_time = nil
32
33
  @n_responses = 0
33
34
  @n_slow_responses = 0
34
35
  @n_slow_operations = 0
35
36
  @slow_operations = SizedGroupedOperations.new
36
37
  @total_elapsed = 0
37
38
  @collect_slow_statistics = true
39
+ @workers = {}
38
40
  end
39
41
 
40
42
  def order=(new_order)
@@ -92,8 +94,8 @@ module GroongaQueryLog
92
94
  end
93
95
 
94
96
  def period
95
- if @start_time and @last_time
96
- @last_time - @start_time
97
+ if @start_time and @end_time
98
+ @end_time - @start_time
97
99
  else
98
100
  0
99
101
  end
@@ -111,6 +113,10 @@ module GroongaQueryLog
111
113
  end
112
114
  end
113
115
 
116
+ def each_worker(&block)
117
+ @workers.each_value(&block)
118
+ end
119
+
114
120
  private
115
121
  def create_sorter
116
122
  case @order
@@ -134,10 +140,11 @@ module GroongaQueryLog
134
140
  end
135
141
 
136
142
  def update_statistic(statistic)
143
+ update_worker_statistic(statistic)
137
144
  @start_time ||= statistic.start_time
138
145
  @start_time = [@start_time, statistic.start_time].min
139
- @last_time ||= statistic.last_time
140
- @last_time = [@last_time, statistic.last_time].max
146
+ @end_time ||= statistic.end_time
147
+ @end_time = [@end_time, statistic.end_time].max
141
148
  @n_responses += 1
142
149
  @total_elapsed += statistic.elapsed_in_seconds
143
150
  return unless @collect_slow_statistics
@@ -152,6 +159,12 @@ module GroongaQueryLog
152
159
  end
153
160
  end
154
161
  end
162
+
163
+ def update_worker_statistic(statistic)
164
+ id = statistic.context_id
165
+ @workers[id] ||= WorkerStatistic.new(id)
166
+ @workers[id] << statistic
167
+ end
155
168
  end
156
169
  end
157
170
  end
@@ -0,0 +1,64 @@
1
+ # Copyright (C) 2019 Sutou Kouhei <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ module GroongaQueryLog
18
+ module Command
19
+ class Analyzer
20
+ class WorkerStatistic
21
+ attr_reader :id
22
+ attr_reader :idle_time_total
23
+ attr_reader :idle_time_mean
24
+ attr_reader :idle_time_min
25
+ attr_reader :idle_time_max
26
+ attr_reader :n_statistics
27
+ attr_reader :metrics
28
+ def initialize(id)
29
+ @id = id
30
+ @idle_time_total = 0.0
31
+ @idle_time_mean = 0.0
32
+ @idle_time_min = 0.0
33
+ @idle_time_max = 0.0
34
+ @n_statistics = 0
35
+ @metrics = {
36
+ timestamp: [],
37
+ idle_time: [],
38
+ elapsed: [],
39
+ }
40
+ @previous_statistic = nil
41
+ end
42
+
43
+ def <<(statistic)
44
+ @n_statistics += 1
45
+ if @previous_statistic
46
+ idle_time = statistic.start_time - @previous_statistic.end_time
47
+ @idle_time_total += idle_time
48
+ @idle_time_mean += ((idle_time - @idle_time_mean) / @n_statistics)
49
+ if @idle_time_min.zero?
50
+ @idle_time_min = idle_time
51
+ else
52
+ @idle_time_min = [@idle_time_min, idle_time].min
53
+ end
54
+ @idle_time_max = [@idle_time_max, idle_time].max
55
+ @metrics[:timestamp] << statistic.start_time
56
+ @metrics[:idle_time] << idle_time
57
+ @metrics[:elapsed] << statistic.elapsed_in_seconds
58
+ end
59
+ @previous_statistic = statistic
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end