[Groonga-commit] groonga/groonga [master] [query-log][analyzer] support JSON report. refs #939

Back to archive index

null+****@clear***** null+****@clear*****
2011年 6月 2日 (木) 14:19:15 JST


Kouhei Sutou	2011-06-02 05:19:15 +0000 (Thu, 02 Jun 2011)

  New Revision: d730211962add109fe2df1aba4c18272dbbbfffd

  Log:
    [query-log][analyzer] support JSON report. refs #939

  Modified files:
    tools/groonga-query-log-analyzer.rb

  Modified: tools/groonga-query-log-analyzer.rb (+83 -14)
===================================================================
--- tools/groonga-query-log-analyzer.rb    2011-06-01 09:58:20 +0000 (a482271)
+++ tools/groonga-query-log-analyzer.rb    2011-06-02 05:19:15 +0000 (607210c)
@@ -26,7 +26,7 @@ class GroongaQueryLogAnaylzer
       thread.join
     end
 
-    reporter = ConsoleQueryLogReporter.new(parser.statistics)
+    reporter = create_reporter(parser.statistics)
     reporter.apply_options(@options)
     reporter.report
   end
@@ -39,6 +39,7 @@ class GroongaQueryLogAnaylzer
     @options[:color] = :auto
     @options[:output] = "-"
     @options[:slow_threshold] = 0.05
+    @options[:reporter] = "console"
 
     @option_parser = OptionParser.new do |parser|
       parser.banner += " LOG1 ..."
@@ -92,6 +93,25 @@ class GroongaQueryLogAnaylzer
                 "(#{@options[:slow_threshold]})") do |threshold|
         @options[:slow_threshold] = threshold
       end
+
+      available_reporters = ["console", "json"]
+      parser.on("--reporter=REPORTER",
+                available_reporters,
+                "Reports statistics by REPORTER.",
+                "available values: [#{available_reporters.join(', ')}]",
+                "(#{@options[:reporter]})") do |reporter|
+        @options[:reporter] = reporter
+      end
+    end
+
+    def create_reporter(statistics)
+      case @options[:reporter]
+      when "json"
+        require 'json'
+        JSONQueryLogReporter.new(statistics)
+      else
+        ConsoleQueryLogReporter.new(statistics)
+      end
     end
   end
 
@@ -304,12 +324,14 @@ class GroongaQueryLogAnaylzer
   class QueryLogReporter
     include Enumerable
 
+    attr_reader :output
     attr_accessor :n_entries, :slow_threshold
     def initialize(statistics)
       @statistics = statistics
       @order = "-elapsed"
       @n_entries = 10
       @slow_threshold = 0.05
+      @output = $stdout
       @sorted_statistics = nil
     end
 
@@ -317,6 +339,7 @@ class GroongaQueryLogAnaylzer
       self.order = options[:order] || @order
       self.n_entries = options[:n_entries] || @n_entries
       self.slow_threshold = options[:slow_threshold] || @slow_threshold
+      self.output = options[:output] || @output
     end
 
     def order=(order)
@@ -325,6 +348,11 @@ class GroongaQueryLogAnaylzer
       @sorted_statistics = nil
     end
 
+    def output=(output)
+      @output = output
+      @output = $stdout if @output == "-"
+    end
+
     def sorted_statistics
       @sorted_statistics ||=****@stati*****_by(&sorter)
     end
@@ -361,6 +389,16 @@ class GroongaQueryLogAnaylzer
     def slow?(elapsed)
       elapsed >= @slow_threshold
     end
+
+    def setup_output
+      if****@outpu*****_a?(String)
+        File.open(@output, "w") do |output|
+          yield(output)
+        end
+      else
+        yield(@output)
+      end
+    end
   end
 
   class ConsoleQueryLogReporter < QueryLogReporter
@@ -460,7 +498,6 @@ class GroongaQueryLogAnaylzer
     def initialize(statistics)
       super
       @color = :auto
-      @output = $stdout
       @reset_color = Color.new("reset")
       @color_schema = {
         :elapsed => {:foreground => :white, :background => :green},
@@ -472,8 +509,6 @@ class GroongaQueryLogAnaylzer
     def apply_options(options)
       super
       @color = options[:color] || @color
-      @output = options[:output] || @output
-      @output = $stdout if @output == "-"
     end
 
     def report
@@ -532,16 +567,6 @@ class GroongaQueryLogAnaylzer
       end
     end
 
-    def setup_output
-      if****@outpu*****_a?(String)
-        File.open(@output, "w") do |output|
-          yield(output)
-        end
-      else
-        yield(@output)
-      end
-    end
-
     def setup_color(output)
       color = @color
       @color = guess_color_availability(output) if @color == :auto
@@ -577,6 +602,50 @@ class GroongaQueryLogAnaylzer
       "%s%s%s" % [color.escape_sequence, text, @reset_color.escape_sequence]
     end
   end
+
+  class JSONQueryLogReporter < QueryLogReporter
+    def report
+      setup_output do |output|
+        output.print("[")
+        each_with_index do |statistic, i|
+          output.print(",") if i > 0
+          output.print("\n")
+          output.print(format_statistic(statistic))
+        end
+        output.puts
+        output.puts("]")
+      end
+    end
+
+    private
+    def format_statistic(statistic)
+      data = {
+        "start_time" => statistic.start_time.to_i,
+        "end_time" => statistic.end_time.to_i,
+        "elapsed" => statistic.elapsed_in_seconds,
+        "return_code" => statistic.return_code,
+        "raw_command" => statistic.raw_command,
+      }
+      command = statistic.command
+      parameters = command.parameters.collect do |key, value|
+        {"key" => key, "value" => value}
+      end
+      data["command"] = {
+        "name" => command.name,
+        "parameters" => parameters,
+      }
+      steps = []
+      statistic.each_trace_info do |info|
+        step = {}
+        step["name"] = info[:label]
+        step["relative_elapsed"] = info[:relative_elapsed_in_seconds]
+        step["context"] = info[:context]
+        steps << step
+      end
+      data["steps"] = steps
+      JSON.generate(data)
+    end
+  end
 end
 
 if __FILE__ == $0




Groonga-commit メーリングリストの案内
Back to archive index