groonga-query-log 1.5.2 → 1.5.3

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.
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