groonga-query-log 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +3 -1
- data/bin/{groonga-query-log-analyzer → groonga-query-log-analyze} +0 -0
- data/bin/groonga-query-log-extract +28 -0
- data/doc/text/news.md +16 -0
- data/lib/groonga/query-log.rb +1 -0
- data/lib/groonga/query-log/analyzer.rb +32 -7
- data/lib/groonga/query-log/commandline-utils.rb +34 -0
- data/lib/groonga/query-log/extractor.rb +188 -0
- data/lib/groonga/query-log/parser.rb +9 -0
- data/lib/groonga/query-log/version.rb +1 -1
- data/test/fixtures/multi.expected +41 -0
- data/test/fixtures/other-query.log +5 -0
- data/test/test-analyzer.rb +23 -3
- data/test/test-extractor.rb +191 -0
- metadata +16 -6
data/Rakefile
CHANGED
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
|
5
|
+
# Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
|
6
|
+
#
|
7
|
+
# This library is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU Lesser General Public
|
9
|
+
# License version 2.1 as published by the Free Software Foundation.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
|
20
|
+
require "groonga/query-log/extractor"
|
21
|
+
|
22
|
+
extracter = Groonga::QueryLog::Extractor.new
|
23
|
+
begin
|
24
|
+
extracter.run(*ARGV)
|
25
|
+
rescue Groonga::QueryLog::Extractor::Error
|
26
|
+
$stderr.puts($!.message)
|
27
|
+
exit(false)
|
28
|
+
end
|
data/doc/text/news.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# News
|
2
2
|
|
3
|
+
## 1.0.1: 2012-12-21
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* Added "groonga-query-log-extract" command and classes implementing it.
|
8
|
+
"groonga-query-log-extract" is the command to extract commands
|
9
|
+
(table_create ..., load..., select... and so on) from query
|
10
|
+
logs. "groonga-query-log-extract --help" shows its usage.
|
11
|
+
|
12
|
+
### Changes
|
13
|
+
|
14
|
+
* Rename groonga-query-log-analyzer to groonga-query-log-analyze
|
15
|
+
(removed trailing "r").
|
16
|
+
* Raised error and exited of each running command for no specified
|
17
|
+
input files, redirects, and pipe via standard input.
|
18
|
+
|
3
19
|
## 1.0.0: 2012-12-14
|
4
20
|
|
5
21
|
The first release!!!
|
data/lib/groonga/query-log.rb
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
|
20
20
|
require "optparse"
|
21
21
|
require "json"
|
22
|
+
require "groonga/query-log/commandline-utils"
|
22
23
|
require "groonga/query-log/parser"
|
23
24
|
require "groonga/query-log/analyzer/streamer"
|
24
25
|
require "groonga/query-log/analyzer/sized-statistics"
|
@@ -26,9 +27,14 @@ require "groonga/query-log/analyzer/sized-statistics"
|
|
26
27
|
module Groonga
|
27
28
|
module QueryLog
|
28
29
|
class Analyzer
|
30
|
+
include CommandLineUtils
|
31
|
+
|
29
32
|
class Error < StandardError
|
30
33
|
end
|
31
34
|
|
35
|
+
class NoInputError < Error
|
36
|
+
end
|
37
|
+
|
32
38
|
class UnsupportedReporter < Error
|
33
39
|
end
|
34
40
|
|
@@ -36,8 +42,23 @@ module Groonga
|
|
36
42
|
setup_options
|
37
43
|
end
|
38
44
|
|
39
|
-
|
40
|
-
|
45
|
+
# Executes analyzer for groonga's query logs.
|
46
|
+
# "groonga-query-log-analyze" command run this method.
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# analyzer = Groonga::QueryLog::Analyzer.new
|
50
|
+
# analyzer.run("--output", "statistics.html",
|
51
|
+
# "--reporter", "html",
|
52
|
+
# "query.log")
|
53
|
+
#
|
54
|
+
# If only paths of query log files are specified,
|
55
|
+
# this method prints a result of them to console with coloring.
|
56
|
+
#
|
57
|
+
# @param [Array<String>] arguments arguments for
|
58
|
+
# groonga-query-log-analyze. Please execute
|
59
|
+
# "groonga-query-log-analyze --help" or see #setup_options.
|
60
|
+
def run(*arguments)
|
61
|
+
log_paths = @option_parser.parse!(arguments)
|
41
62
|
|
42
63
|
stream = @options[:stream]
|
43
64
|
dynamic_sort = @options[:dynamic_sort]
|
@@ -60,13 +81,17 @@ module Groonga
|
|
60
81
|
full_statistics << statistic
|
61
82
|
end
|
62
83
|
end
|
84
|
+
|
63
85
|
if log_paths.empty?
|
86
|
+
unless log_via_stdin?
|
87
|
+
raise(NoInputError, "Error: Please specify input log files.")
|
88
|
+
end
|
64
89
|
parser.parse(ARGF, &process_statistic)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
90
|
+
end
|
91
|
+
|
92
|
+
log_paths.each do |log_path|
|
93
|
+
File.open(log_path) do |log|
|
94
|
+
parser.parse(log, &process_statistic)
|
70
95
|
end
|
71
96
|
end
|
72
97
|
if stream
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
7
|
+
# License version 2.1 as published by the Free Software Foundation.
|
8
|
+
#
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12
|
+
# Lesser General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
15
|
+
# License along with this library; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
17
|
+
|
18
|
+
module Groonga
|
19
|
+
module QueryLog
|
20
|
+
module CommandLineUtils
|
21
|
+
def log_via_stdin?
|
22
|
+
stdin_with_pipe? or stdin_with_redirect?
|
23
|
+
end
|
24
|
+
|
25
|
+
def stdin_with_pipe?
|
26
|
+
File.pipe?($stdin)
|
27
|
+
end
|
28
|
+
|
29
|
+
def stdin_with_redirect?
|
30
|
+
not File.select([$stdin], [], [], 0).nil?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
|
5
|
+
# Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
|
6
|
+
#
|
7
|
+
# This library is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU Lesser General Public
|
9
|
+
# License version 2.1 as published by the Free Software Foundation.
|
10
|
+
#
|
11
|
+
# This library is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
# Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with this library; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
|
20
|
+
require "ostruct"
|
21
|
+
require "optparse"
|
22
|
+
require "pathname"
|
23
|
+
require "groonga/query-log/commandline-utils"
|
24
|
+
require "groonga/query-log/parser"
|
25
|
+
|
26
|
+
module Groonga
|
27
|
+
module QueryLog
|
28
|
+
class Extractor
|
29
|
+
include CommandLineUtils
|
30
|
+
|
31
|
+
class Error < StandardError
|
32
|
+
end
|
33
|
+
|
34
|
+
class NoInputError < Error
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_accessor :options
|
38
|
+
attr_reader :option_parser
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@options = nil
|
42
|
+
@option_parser = nil
|
43
|
+
setup_options
|
44
|
+
end
|
45
|
+
|
46
|
+
# Executes extractor for groonga's query logs.
|
47
|
+
# "groonga-query-log-extract" command runs this method.
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# extractor = Groonga::QueryLog::Extractor.new
|
51
|
+
# extractor.run("--output", "commands.output",
|
52
|
+
# "--command", "select",
|
53
|
+
# "query.log")
|
54
|
+
#
|
55
|
+
# If only paths of query log files are specified,
|
56
|
+
# this method prints command(s) of them to console.
|
57
|
+
#
|
58
|
+
# @param [Array<String>] arguments arguments for
|
59
|
+
# groonga-query-log-extract. Please execute
|
60
|
+
# "groonga-query-log-extract --help" or see #setup_options.
|
61
|
+
def run(*arguments)
|
62
|
+
begin
|
63
|
+
log_paths = @option_parser.parse!(arguments)
|
64
|
+
rescue OptionParser::ParseError
|
65
|
+
raise(ArgumentError, $!.message)
|
66
|
+
end
|
67
|
+
|
68
|
+
if log_paths.empty?
|
69
|
+
unless log_via_stdin?
|
70
|
+
raise(NoInputError, "Error: Please specify input log files.")
|
71
|
+
end
|
72
|
+
log = ARGF
|
73
|
+
else
|
74
|
+
log = log_paths
|
75
|
+
end
|
76
|
+
|
77
|
+
if @options.output_path
|
78
|
+
File.open(@options.output_path, "w") do |output|
|
79
|
+
extract(log, output)
|
80
|
+
end
|
81
|
+
else
|
82
|
+
extract(log, $stdout)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
def setup_options
|
88
|
+
@options = OpenStruct.new
|
89
|
+
@options.unify_format = nil
|
90
|
+
@options.commands = []
|
91
|
+
@options.exclude_commands = []
|
92
|
+
@options.output_path = nil
|
93
|
+
@option_parser = OptionParser.new do |parser|
|
94
|
+
parser.banner += " QUERY_LOG1 ..."
|
95
|
+
|
96
|
+
available_formats = ["uri", "command"]
|
97
|
+
parser.on("--unify-format=FORMAT",
|
98
|
+
available_formats,
|
99
|
+
"Unify command format to FORMAT.",
|
100
|
+
"(#{available_formats.join(', ')})",
|
101
|
+
"[not unify]") do |format|
|
102
|
+
@options.unify_format = format
|
103
|
+
end
|
104
|
+
|
105
|
+
parser.on("--command=COMMAND",
|
106
|
+
"Extract only COMMAND.",
|
107
|
+
"To extract one or more commands,",
|
108
|
+
"specify this command a number of times.",
|
109
|
+
"Use /.../ as COMMAND to match command with regular expression.",
|
110
|
+
"[all commands]") do |command|
|
111
|
+
case command
|
112
|
+
when /\A\/(.*)\/(i)?\z/
|
113
|
+
@options.commands << Regexp.new($1, $2 == "i")
|
114
|
+
when
|
115
|
+
@options.commands << command
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
parser.on("--exclude-command=COMMAND",
|
120
|
+
"Don't extract COMMAND.",
|
121
|
+
"To ignore one or more commands,",
|
122
|
+
"specify this command a number of times.",
|
123
|
+
"Use /.../ as COMMAND to match command with regular expression.",
|
124
|
+
"[no commands]") do |command|
|
125
|
+
case command
|
126
|
+
when /\A\/(.*)\/(i)?\z/
|
127
|
+
@options.exclude_commands << Regexp.new($1, $2 == "i")
|
128
|
+
when
|
129
|
+
@options.exclude_commands << command
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
parser.on("--output=PATH",
|
134
|
+
"Output to PATH.",
|
135
|
+
"[standard output]") do |path|
|
136
|
+
@options.output_path = path
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def extract(log, output)
|
142
|
+
if log.instance_of?(Array)
|
143
|
+
log.each do |log_path|
|
144
|
+
File.open(log_path) do |log_file|
|
145
|
+
extract_command(log_file, output)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
else
|
149
|
+
extract_command(log, output)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def extract_command(log, output)
|
154
|
+
parser = Groonga::QueryLog::Parser.new
|
155
|
+
parser.parse(log) do |statistic|
|
156
|
+
command = statistic.command
|
157
|
+
next unless target?(command)
|
158
|
+
command_text = nil
|
159
|
+
case @options.unify_format
|
160
|
+
when "uri"
|
161
|
+
command_text = command.to_uri_format
|
162
|
+
when "command"
|
163
|
+
command_text = command.to_command_format
|
164
|
+
else
|
165
|
+
command_text = statistic.raw_command
|
166
|
+
end
|
167
|
+
output.puts(command_text)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def target?(command)
|
172
|
+
name = command.name
|
173
|
+
commands = @options.commands
|
174
|
+
exclude_commands = @options.exclude_commands
|
175
|
+
|
176
|
+
unless commands.empty?
|
177
|
+
return commands.any? {|command| command === name}
|
178
|
+
end
|
179
|
+
|
180
|
+
unless exclude_commands.empty?
|
181
|
+
return (not exclude_commands.any? {|command| command === name})
|
182
|
+
end
|
183
|
+
|
184
|
+
true
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -26,6 +26,15 @@ module Groonga
|
|
26
26
|
def initialize
|
27
27
|
end
|
28
28
|
|
29
|
+
# Parses query-log file as stream to
|
30
|
+
# {Groonga::QueryLog::Analyzer::Statistics} including some
|
31
|
+
# informations for each query.
|
32
|
+
#
|
33
|
+
# @param [IO] input IO for input query log file.
|
34
|
+
# @yield [statistics] if a block is specified, it is called
|
35
|
+
# every time a query is finished parsing.
|
36
|
+
# @yieldparam [Groonga::QueryLog::Analyzer::Statistic] statistic
|
37
|
+
# statistics of each query in log files.
|
29
38
|
def parse(input, &block)
|
30
39
|
current_statistics = {}
|
31
40
|
input.each_line do |line|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
Summary:
|
2
|
+
Threshold:
|
3
|
+
slow response : 0.2
|
4
|
+
slow operation : 0.1
|
5
|
+
# of responses : 4
|
6
|
+
# of slow responses : 0
|
7
|
+
responses/sec : 9.468517046370479e-06
|
8
|
+
start time : 2012-12-12 17:39:17.3
|
9
|
+
last time : 2012-12-17 15:00:10.1
|
10
|
+
period(sec) : 422452.637557779
|
11
|
+
slow response ratio : 0.000%
|
12
|
+
total response time : 0.10129859499999999
|
13
|
+
Slow Operations:
|
14
|
+
|
15
|
+
Slow Queries:
|
16
|
+
1) [2012-12-17 15:00:10.1-2012-12-17 15:00:10.1 (0.05231682)](0): table_create --name Comments --flags TABLE_HASH_KEY --key_type UInt32 name: <table_create>
|
17
|
+
parameters:
|
18
|
+
<name>: <Comments>
|
19
|
+
<flags>: <TABLE_HASH_KEY>
|
20
|
+
<key_type>: <UInt32>
|
21
|
+
|
22
|
+
2) [2012-12-17 15:00:10.1-2012-12-17 15:00:10.1 (0.04463578)](0): column_create --table Comments --name title --flags COLUMN_SCALAR --type ShortText name: <column_create>
|
23
|
+
parameters:
|
24
|
+
<table>: <Comments>
|
25
|
+
<name>: <title>
|
26
|
+
<flags>: <COLUMN_SCALAR>
|
27
|
+
<type>: <ShortText>
|
28
|
+
|
29
|
+
3) [2012-12-12 17:39:17.3-2012-12-12 17:39:17.3 (0.00312886)](0): load --table Video name: <load>
|
30
|
+
parameters:
|
31
|
+
<table>: <Video>
|
32
|
+
|
33
|
+
4) [2012-12-12 17:39:17.3-2012-12-12 17:39:17.3 (0.00121714)](0): select --table Users --query follower:@groonga --output_columns _key,name name: <select>
|
34
|
+
parameters:
|
35
|
+
<table>: <Users>
|
36
|
+
<query>: <follower:@groonga>
|
37
|
+
<output_columns>: <_key,name>
|
38
|
+
1) 0.00084295: filter( 2) query: follower:@groonga
|
39
|
+
2) 0.00002795: select( 2)
|
40
|
+
3) 0.00019585: output( 2) _key,name
|
41
|
+
|
@@ -0,0 +1,5 @@
|
|
1
|
+
2012-12-17 15:00:10.165344|0x7fff8f4c8ca0|>table_create --name Comments --flags TABLE_HASH_KEY --key_type UInt32
|
2
|
+
2012-12-17 15:00:10.217643|0x7fff8f4c8ca0|<000000052316820 rc=0
|
3
|
+
2012-12-17 15:00:10.217818|0x7fff8f4c8ca0|>column_create --table Comments --name title --flags COLUMN_SCALAR --type ShortText
|
4
|
+
2012-12-17 15:00:10.262427|0x7fff8f4c8ca0|<000000044635779 rc=0
|
5
|
+
2012-12-17 15:00:10.476747|0x60c8e0| query log will be closed: </tmp/query.log>
|
data/test/test-analyzer.rb
CHANGED
@@ -31,7 +31,25 @@ class AnalyzerTest < Test::Unit::TestCase
|
|
31
31
|
@analyzer = Groonga::QueryLog::Analyzer.new
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
class TestInputFile < self
|
35
|
+
def test_multi
|
36
|
+
other_query_log_path = File.join(@fixtures_path, "other-query.log")
|
37
|
+
actual_result = run_analyzer(@query_log_path, other_query_log_path)
|
38
|
+
expected_result_path = File.join(@fixtures_path, "multi.expected")
|
39
|
+
|
40
|
+
assert_equal(File.read(expected_result_path), actual_result)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_no_specified
|
44
|
+
assert_raise(Groonga::QueryLog::Analyzer::NoInputError) do
|
45
|
+
run_analyzer
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
data(:console => "console",
|
51
|
+
:html => "html",
|
52
|
+
:json => "json")
|
35
53
|
def test_reporter(reporter)
|
36
54
|
actual_result = run_analyzer("--reporter", reporter, @query_log_path)
|
37
55
|
actual_result = normalize_json(actual_result) if reporter == "json"
|
@@ -46,8 +64,10 @@ class AnalyzerTest < Test::Unit::TestCase
|
|
46
64
|
assert_equal(expected_result, actual_result)
|
47
65
|
end
|
48
66
|
|
49
|
-
data(:asc_elapsed
|
50
|
-
|
67
|
+
data(:asc_elapsed => "elapsed",
|
68
|
+
:asc_start_time => "start-time",
|
69
|
+
:desc_elapsed => "-elapsed",
|
70
|
+
:desc_start_time => "-start-time")
|
51
71
|
def test_order(order)
|
52
72
|
actual_result = run_analyzer("--order=#{order}", @query_log_path)
|
53
73
|
|
@@ -0,0 +1,191 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
#
|
4
|
+
# Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
|
5
|
+
#
|
6
|
+
# This library is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the GNU Lesser General Public
|
8
|
+
# License version 2.1 as published by the Free Software Foundation.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
|
+
|
19
|
+
require "stringio"
|
20
|
+
require "groonga/command"
|
21
|
+
require "groonga/query-log/extractor"
|
22
|
+
|
23
|
+
class TestExtractor < Test::Unit::TestCase
|
24
|
+
setup
|
25
|
+
def setup_fixtures
|
26
|
+
@fixtures_path = File.join(File.dirname(__FILE__), "fixtures")
|
27
|
+
@query_log_path = File.join(@fixtures_path, "query.log")
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup
|
31
|
+
@extractor = Groonga::QueryLog::Extractor.new
|
32
|
+
end
|
33
|
+
|
34
|
+
class TestInputFile < self
|
35
|
+
def test_multi
|
36
|
+
other_query_log_path = File.join(@fixtures_path, "other-query.log")
|
37
|
+
actual_commands = run_extractor(@query_log_path, other_query_log_path)
|
38
|
+
expected_commands = <<-EOC
|
39
|
+
load --table Video
|
40
|
+
select --table Users --query follower:@groonga --output_columns _key,name
|
41
|
+
table_create --name Comments --flags TABLE_HASH_KEY --key_type UInt32
|
42
|
+
column_create --table Comments --name title --flags COLUMN_SCALAR --type ShortText
|
43
|
+
EOC
|
44
|
+
assert_equal(expected_commands, actual_commands)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_no_specified
|
48
|
+
assert_raise(Groonga::QueryLog::Extractor::NoInputError) do
|
49
|
+
run_extractor
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class TestUnifyFormat < self
|
55
|
+
def test_commands
|
56
|
+
actual_commands = run_extractor(@query_log_path,
|
57
|
+
"--unify-format", "command")
|
58
|
+
|
59
|
+
expected_commands = <<-EOC
|
60
|
+
load --table "Video"
|
61
|
+
select --output_columns "_key,name" --query "follower:@groonga" --table "Users"
|
62
|
+
EOC
|
63
|
+
assert_equal(expected_commands, actual_commands)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_uri
|
67
|
+
actual_commands = run_extractor(@query_log_path,
|
68
|
+
"--unify-format", "uri")
|
69
|
+
expected_commands = <<-EOC
|
70
|
+
/d/load?table=Video
|
71
|
+
/d/select?output_columns=_key%2Cname&query=follower%3A%40groonga&table=Users
|
72
|
+
EOC
|
73
|
+
assert_equal(expected_commands, actual_commands)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_not_unify
|
77
|
+
actual_commands = run_extractor(@query_log_path)
|
78
|
+
expected_commands = <<-EOC
|
79
|
+
load --table Video
|
80
|
+
select --table Users --query follower:@groonga --output_columns _key,name
|
81
|
+
EOC
|
82
|
+
assert_equal(expected_commands, actual_commands)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_command
|
87
|
+
actual_command = run_extractor(@query_log_path, "--command", "load")
|
88
|
+
expected_command = "load --table Video\n"
|
89
|
+
|
90
|
+
assert_equal(expected_command, actual_command)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_exclude_command
|
94
|
+
actual_command = run_extractor(@query_log_path, "--exclude-command", "load")
|
95
|
+
expected_command = "select --table Users --query follower:@groonga" +
|
96
|
+
" --output_columns _key,name\n"
|
97
|
+
|
98
|
+
assert_equal(expected_command, actual_command)
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
def run_extractor(*arguments)
|
103
|
+
Tempfile.open("extract.actual") do |output|
|
104
|
+
arguments << "--output" << output.path
|
105
|
+
@extractor.run(*arguments)
|
106
|
+
File.read(output.path)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class TestExtract < self
|
111
|
+
def setup
|
112
|
+
super
|
113
|
+
@log = <<-EOL
|
114
|
+
2012-12-12 17:39:17.628846|0x7fff786aa2b0|>select --table Users --query follower:@groonga --output_columns _key,name
|
115
|
+
2012-12-12 17:39:17.629676|0x7fff786aa2b0|:000000000842953 filter(2)
|
116
|
+
2012-12-12 17:39:17.629709|0x7fff786aa2b0|:000000000870900 select(2)
|
117
|
+
2012-12-12 17:39:17.629901|0x7fff786aa2b0|:000000001066752 output(2)
|
118
|
+
2012-12-12 17:39:17.630052|0x7fff786aa2b0|<000000001217140 rc=0
|
119
|
+
EOL
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_command_format
|
123
|
+
@extractor.options.unify_format = "command"
|
124
|
+
expected_formatted_command = "select --output_columns \"_key,name\""+
|
125
|
+
" --query \"follower:@groonga\"" +
|
126
|
+
" --table \"Users\"\n"
|
127
|
+
assert_equal(expected_formatted_command, extract)
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_uri_format
|
131
|
+
@extractor.options.unify_format = "uri"
|
132
|
+
expected_formatted_command = "/d/select?output_columns=_key%2Cname" +
|
133
|
+
"&query=follower%3A%40groonga" +
|
134
|
+
"&table=Users\n"
|
135
|
+
assert_equal(expected_formatted_command, extract)
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_not_unify
|
139
|
+
@extractor.options.unify_format = nil
|
140
|
+
expected_formatted_command = "select --table Users" +
|
141
|
+
" --query follower:@groonga" +
|
142
|
+
" --output_columns _key,name\n"
|
143
|
+
assert_equal(expected_formatted_command, extract)
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
def extract
|
148
|
+
output = StringIO.new
|
149
|
+
@extractor.send(:extract, @log, output)
|
150
|
+
output.string
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class TestTarget < self
|
155
|
+
def test_include
|
156
|
+
@extractor.options.commands = ["register"]
|
157
|
+
assert_true(target?("register"))
|
158
|
+
assert_false(target?("dump"))
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_exclude
|
162
|
+
@extractor.options.exclude_commands = ["dump"]
|
163
|
+
assert_true(target?("register"))
|
164
|
+
assert_false(target?("dump"))
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_not_specified
|
168
|
+
assert_true(target?("register"))
|
169
|
+
assert_true(target?("dump"))
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_regular_expression_include
|
173
|
+
@extractor.options.commands = [/table/]
|
174
|
+
assert_true(target?("table_create"))
|
175
|
+
assert_false(target?("dump"))
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_regular_expression_exclude
|
179
|
+
@extractor.options.exclude_commands = [/table/]
|
180
|
+
assert_false(target?("table_create"))
|
181
|
+
assert_true(target?("dump"))
|
182
|
+
end
|
183
|
+
|
184
|
+
private
|
185
|
+
def target?(name)
|
186
|
+
command_class = Groonga::Command.find(name)
|
187
|
+
command = command_class.new(name, [])
|
188
|
+
@extractor.send(:target?, command)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groonga-query-log
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: groonga-command
|
@@ -143,7 +143,8 @@ description: ''
|
|
143
143
|
email:
|
144
144
|
- kou@clear-code.com
|
145
145
|
executables:
|
146
|
-
- groonga-query-log-
|
146
|
+
- groonga-query-log-extract
|
147
|
+
- groonga-query-log-analyze
|
147
148
|
extensions: []
|
148
149
|
extra_rdoc_files: []
|
149
150
|
files:
|
@@ -154,6 +155,7 @@ files:
|
|
154
155
|
- lib/groonga/query-log.rb
|
155
156
|
- lib/groonga/query-log/parser.rb
|
156
157
|
- lib/groonga/query-log/analyzer.rb
|
158
|
+
- lib/groonga/query-log/commandline-utils.rb
|
157
159
|
- lib/groonga/query-log/analyzer/streamer.rb
|
158
160
|
- lib/groonga/query-log/analyzer/statistic.rb
|
159
161
|
- lib/groonga/query-log/analyzer/reporter.rb
|
@@ -162,12 +164,15 @@ files:
|
|
162
164
|
- lib/groonga/query-log/analyzer/reporter/console.rb
|
163
165
|
- lib/groonga/query-log/analyzer/reporter/json.rb
|
164
166
|
- lib/groonga/query-log/analyzer/reporter/html.rb
|
167
|
+
- lib/groonga/query-log/extractor.rb
|
165
168
|
- lib/groonga/query-log/version.rb
|
166
169
|
- doc/text/news.md
|
167
170
|
- doc/text/lgpl-2.1.txt
|
168
171
|
- .yardopts
|
169
172
|
- test/run-test.rb
|
170
173
|
- test/command/test-select.rb
|
174
|
+
- test/test-extractor.rb
|
175
|
+
- test/fixtures/multi.expected
|
171
176
|
- test/fixtures/no-report-summary.expected
|
172
177
|
- test/fixtures/query.log
|
173
178
|
- test/fixtures/order/start-time.expected
|
@@ -175,13 +180,15 @@ files:
|
|
175
180
|
- test/fixtures/order/-start-time.expected
|
176
181
|
- test/fixtures/order/elapsed.expected
|
177
182
|
- test/fixtures/n_entries.expected
|
183
|
+
- test/fixtures/other-query.log
|
178
184
|
- test/fixtures/reporter/html.expected
|
179
185
|
- test/fixtures/reporter/json.expected
|
180
186
|
- test/fixtures/reporter/console.expected
|
181
187
|
- test/groonga-query-log-test-utils.rb
|
182
188
|
- test/test-parser.rb
|
183
189
|
- test/test-analyzer.rb
|
184
|
-
- bin/groonga-query-log-
|
190
|
+
- bin/groonga-query-log-extract
|
191
|
+
- bin/groonga-query-log-analyze
|
185
192
|
homepage: https://github.com/groonga/groonga-query-log
|
186
193
|
licenses:
|
187
194
|
- LGPLv2.1+
|
@@ -197,7 +204,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
197
204
|
version: '0'
|
198
205
|
segments:
|
199
206
|
- 0
|
200
|
-
hash:
|
207
|
+
hash: -2724892478049982090
|
201
208
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
202
209
|
none: false
|
203
210
|
requirements:
|
@@ -206,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
213
|
version: '0'
|
207
214
|
segments:
|
208
215
|
- 0
|
209
|
-
hash:
|
216
|
+
hash: -2724892478049982090
|
210
217
|
requirements: []
|
211
218
|
rubyforge_project:
|
212
219
|
rubygems_version: 1.8.23
|
@@ -219,6 +226,8 @@ summary: Groonga-query-log is a collection of libarary and tools to process [gro
|
|
219
226
|
test_files:
|
220
227
|
- test/run-test.rb
|
221
228
|
- test/command/test-select.rb
|
229
|
+
- test/test-extractor.rb
|
230
|
+
- test/fixtures/multi.expected
|
222
231
|
- test/fixtures/no-report-summary.expected
|
223
232
|
- test/fixtures/query.log
|
224
233
|
- test/fixtures/order/start-time.expected
|
@@ -226,6 +235,7 @@ test_files:
|
|
226
235
|
- test/fixtures/order/-start-time.expected
|
227
236
|
- test/fixtures/order/elapsed.expected
|
228
237
|
- test/fixtures/n_entries.expected
|
238
|
+
- test/fixtures/other-query.log
|
229
239
|
- test/fixtures/reporter/html.expected
|
230
240
|
- test/fixtures/reporter/json.expected
|
231
241
|
- test/fixtures/reporter/console.expected
|