fluent-plugin-groonga 1.0.8 → 1.0.9
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/doc/text/news.md +15 -0
- data/fluent-plugin-groonga.gemspec +1 -1
- data/lib/fluent/plugin/out_groonga.rb +95 -45
- data/sample/store-apache.conf +0 -1
- data/sample/store-syslog.conf +92 -0
- data/test/output/test_table_index_definition.rb +95 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf6b4e7487748c2f6c1afd542bcc01b28cae47d5
|
4
|
+
data.tar.gz: 7a84873889cb7b1fa6a48d6e7335f314c4f8756f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c6d1479f6d93ac5eab837923878e3ae973c77700d461b787bb44e0f86048bf93b7900c7651302f830e6fb497afcfa7c28c0af95813bd4f0eb1cf553514e8e15
|
7
|
+
data.tar.gz: 0615408e6acc183ae5d7de3cd2e2ea51e445b2988c83766985230951dcff6a37350733bfd8d12bcc61e2227b41c45ec1b6eb234225cc957bbe45f1f3cb9169d4
|
data/doc/text/news.md
CHANGED
@@ -2,6 +2,21 @@
|
|
2
2
|
|
3
3
|
# News
|
4
4
|
|
5
|
+
## 1.0.9: 2014-11-20
|
6
|
+
|
7
|
+
### Improves
|
8
|
+
|
9
|
+
* out: Added log message with host, port and command name on Groonga
|
10
|
+
command execution error.
|
11
|
+
* out: Added `WITH_POSITION` index flag automatically when it is
|
12
|
+
needed.
|
13
|
+
* out: Supported creating index for existing column.
|
14
|
+
|
15
|
+
### Fixes
|
16
|
+
|
17
|
+
* out: Fixed a bug that needless `WITH_SECTION` flags is used.
|
18
|
+
* out: Fixed a bug that wrong index name is used.
|
19
|
+
|
5
20
|
## 1.0.8: 2014-11-05
|
6
21
|
|
7
22
|
### Fixes
|
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
Gem::Specification.new do |spec|
|
19
19
|
spec.name = "fluent-plugin-groonga"
|
20
|
-
spec.version = "1.0.
|
20
|
+
spec.version = "1.0.9"
|
21
21
|
spec.authors = ["Kouhei Sutou"]
|
22
22
|
spec.email = ["kou@clear-code.com"]
|
23
23
|
spec.summary = "Fluentd plugin to store data into Groonga and implement Groonga replication system."
|
@@ -122,7 +122,28 @@ module Fluent
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
+
module DefinitionParseMethods
|
126
|
+
private
|
127
|
+
def parse_flags(flags)
|
128
|
+
if flags.is_a?(Array)
|
129
|
+
flags
|
130
|
+
else
|
131
|
+
flags.strip.split(/\s*\|\s*/)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def parse_items(items)
|
136
|
+
if items.is_a?(Array)
|
137
|
+
items
|
138
|
+
else
|
139
|
+
items.strip.split(/\s*,\s*/)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
125
144
|
class TableDefinition
|
145
|
+
include DefinitionParseMethods
|
146
|
+
|
126
147
|
def initialize(raw)
|
127
148
|
@raw = raw
|
128
149
|
end
|
@@ -192,24 +213,9 @@ module Fluent
|
|
192
213
|
arguments
|
193
214
|
end
|
194
215
|
|
195
|
-
private
|
196
|
-
def parse_flags(flags)
|
197
|
-
if flags.is_a?(Array)
|
198
|
-
flags
|
199
|
-
else
|
200
|
-
flags.strip.split(/\s*\|\s*/)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
def parse_items(items)
|
205
|
-
if items.is_a?(Array)
|
206
|
-
items
|
207
|
-
else
|
208
|
-
items.strip.split(/\s*,\s*/)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
216
|
class IndexDefinition
|
217
|
+
include DefinitionParseMethods
|
218
|
+
|
213
219
|
def initialize(table, raw)
|
214
220
|
@table = table
|
215
221
|
@raw = raw
|
@@ -224,7 +230,7 @@ module Fluent
|
|
224
230
|
end
|
225
231
|
|
226
232
|
def source_columns
|
227
|
-
@raw[:source_columns]
|
233
|
+
parse_items(@raw[:source_columns])
|
228
234
|
end
|
229
235
|
|
230
236
|
def flags
|
@@ -240,7 +246,7 @@ module Fluent
|
|
240
246
|
"name" => name,
|
241
247
|
"flags" => flags.join("|"),
|
242
248
|
"type" => source_table,
|
243
|
-
"source" => source_columns,
|
249
|
+
"source" => source_columns.join(","),
|
244
250
|
}
|
245
251
|
end
|
246
252
|
end
|
@@ -279,7 +285,7 @@ module Fluent
|
|
279
285
|
@client = client
|
280
286
|
@table_name = table_name
|
281
287
|
@mappings = mappings
|
282
|
-
@
|
288
|
+
@taget_table = nil
|
283
289
|
@columns = nil
|
284
290
|
end
|
285
291
|
|
@@ -305,19 +311,24 @@ module Fluent
|
|
305
311
|
|
306
312
|
private
|
307
313
|
def ensure_table
|
308
|
-
return if @
|
314
|
+
return if @target_table
|
309
315
|
|
310
|
-
|
311
|
-
|
312
|
-
table.name
|
316
|
+
@tables = {}
|
317
|
+
@client.execute("table_list").collect do |table|
|
318
|
+
name = table.name
|
319
|
+
options = {
|
320
|
+
:default_tokenizer => table.default_tokenizer,
|
321
|
+
}
|
322
|
+
@tables[name] = Table.new(table.name, options)
|
313
323
|
end
|
314
|
-
|
315
|
-
|
316
|
-
|
324
|
+
|
325
|
+
@target_table = @tables[@table_name]
|
326
|
+
unless @target_table
|
317
327
|
@client.execute("table_create",
|
318
328
|
"name" => @table_name,
|
319
329
|
"flags" => "TABLE_NO_KEY")
|
320
|
-
@
|
330
|
+
@target_table = Table.new(@table_name)
|
331
|
+
@tables[@table_name] = @target_table
|
321
332
|
end
|
322
333
|
end
|
323
334
|
|
@@ -327,10 +338,10 @@ module Fluent
|
|
327
338
|
column_list = @client.execute("column_list", "table" => @table_name)
|
328
339
|
@columns = {}
|
329
340
|
column_list.each do |column|
|
341
|
+
name = column.name
|
330
342
|
vector_p = column.flags.split("|").include?("COLUMN_VECTOR")
|
331
|
-
@columns[
|
332
|
-
|
333
|
-
vector_p)
|
343
|
+
@columns[name] = Column.new(name, column.range, vector_p)
|
344
|
+
ensure_column_indexes(name)
|
334
345
|
end
|
335
346
|
end
|
336
347
|
|
@@ -354,21 +365,38 @@ module Fluent
|
|
354
365
|
"name" => name,
|
355
366
|
"flags" => flags,
|
356
367
|
"type" => value_type)
|
357
|
-
|
358
|
-
mapping.indexes.each do |index|
|
359
|
-
index_flags = ["COLUMN_INDEX", index[:flags]].compact
|
360
|
-
@client.execute("column_create",
|
361
|
-
"table" => index[:table],
|
362
|
-
"name" => index[:table],
|
363
|
-
"flags" => index_flags.join("|"),
|
364
|
-
"type" => @table_name,
|
365
|
-
"source" => name)
|
366
|
-
end
|
367
|
-
end
|
368
|
+
ensure_column_indexes(name)
|
368
369
|
|
369
370
|
Column.new(name, value_type, vector_p)
|
370
371
|
end
|
371
372
|
|
373
|
+
def ensure_column_indexes(name)
|
374
|
+
mapping = @mappings.find do |_mapping|
|
375
|
+
_mapping.name == name
|
376
|
+
end
|
377
|
+
return if mapping.nil?
|
378
|
+
|
379
|
+
mapping.indexes.each do |index|
|
380
|
+
table = @tables[index[:table]]
|
381
|
+
if table
|
382
|
+
column_list = @client.execute("column_list", "table" => table.name)
|
383
|
+
exist = column_list.any? {|column| column.name == index[:name]}
|
384
|
+
next if exist
|
385
|
+
end
|
386
|
+
|
387
|
+
index_flags = ["COLUMN_INDEX"]
|
388
|
+
index_flags << "WITH_POSITION" if table and table.default_tokenizer
|
389
|
+
index_flags << index[:flags] if index[:flags]
|
390
|
+
|
391
|
+
@client.execute("column_create",
|
392
|
+
"table" => index[:table],
|
393
|
+
"name" => index[:name],
|
394
|
+
"flags" => index_flags.join("|"),
|
395
|
+
"type" => @table_name,
|
396
|
+
"source" => name)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
372
400
|
class TypeGuesser
|
373
401
|
def initialize(sample_values)
|
374
402
|
@sample_values = sample_values
|
@@ -485,9 +513,21 @@ module Fluent
|
|
485
513
|
end
|
486
514
|
|
487
515
|
class Table
|
488
|
-
|
516
|
+
attr_reader :name
|
517
|
+
attr_reader :flags
|
518
|
+
attr_reader :domain
|
519
|
+
attr_reader :range
|
520
|
+
attr_reader :default_tokenizer
|
521
|
+
attr_reader :normalizer
|
522
|
+
attr_reader :token_filters
|
523
|
+
def initialize(name, options={})
|
489
524
|
@name = name
|
490
|
-
@
|
525
|
+
@flags = options[:flags]
|
526
|
+
@domain = options[:domain]
|
527
|
+
@range = options[:range]
|
528
|
+
@default_tokenizer = options[:default_tokenizer]
|
529
|
+
@normalizer = options[:normalizer]
|
530
|
+
@token_filters = options[:token_filters]
|
491
531
|
end
|
492
532
|
end
|
493
533
|
|
@@ -579,7 +619,17 @@ module Fluent
|
|
579
619
|
:host => @host,
|
580
620
|
:port => @port,
|
581
621
|
:backend => :synchronous)
|
582
|
-
response =
|
622
|
+
response = nil
|
623
|
+
begin
|
624
|
+
response = @client.execute(command)
|
625
|
+
rescue Groonga::Client::Error
|
626
|
+
$log.error("[output][groonga][error]",
|
627
|
+
:protocol => @protocol,
|
628
|
+
:host => @host,
|
629
|
+
:port => @port,
|
630
|
+
:command_name => name)
|
631
|
+
raise
|
632
|
+
end
|
583
633
|
unless response.success?
|
584
634
|
$log.error("[output][groonga][error]",
|
585
635
|
:status_code => response.status_code,
|
data/sample/store-apache.conf
CHANGED
@@ -0,0 +1,92 @@
|
|
1
|
+
# Required plugins:
|
2
|
+
# * fluent-plugin-config-expander
|
3
|
+
# * fluent-plugin-forest
|
4
|
+
# * fluent-plugin-parser
|
5
|
+
# * fluent-plugin-record-reformer
|
6
|
+
# * fluent-plugin-groonga
|
7
|
+
|
8
|
+
<source>
|
9
|
+
type forward
|
10
|
+
</source>
|
11
|
+
|
12
|
+
<source>
|
13
|
+
type config_expander
|
14
|
+
<config>
|
15
|
+
type tail
|
16
|
+
path /var/log/messages
|
17
|
+
pos_file /var/log/td-agent/messages.pos
|
18
|
+
tag raw.messages.log.${hostname}
|
19
|
+
format none
|
20
|
+
</config>
|
21
|
+
</source>
|
22
|
+
|
23
|
+
<match raw.*.log.**>
|
24
|
+
type forest
|
25
|
+
subtype parser
|
26
|
+
|
27
|
+
<template>
|
28
|
+
key_name message
|
29
|
+
</template>
|
30
|
+
|
31
|
+
<case raw.messages.log.**>
|
32
|
+
remove_prefix raw
|
33
|
+
format syslog
|
34
|
+
</case>
|
35
|
+
</match>
|
36
|
+
|
37
|
+
<match *.log.*.**>
|
38
|
+
type record_reformer
|
39
|
+
enable_ruby false
|
40
|
+
|
41
|
+
tag ${tag_parts[1]}
|
42
|
+
|
43
|
+
<record>
|
44
|
+
host ${tag_suffix[2]}
|
45
|
+
type ${tag_parts[0]}
|
46
|
+
timestamp ${time}
|
47
|
+
</record>
|
48
|
+
</match>
|
49
|
+
|
50
|
+
<match log>
|
51
|
+
type groonga
|
52
|
+
store_table Logs
|
53
|
+
|
54
|
+
protocol http
|
55
|
+
host 127.0.0.1
|
56
|
+
|
57
|
+
buffer_type file
|
58
|
+
buffer_path /var/spool/td-agent/buffer/groonga
|
59
|
+
flush_interval 1
|
60
|
+
|
61
|
+
<table>
|
62
|
+
name Terms
|
63
|
+
flags TABLE_PAT_KEY
|
64
|
+
key_type ShortText
|
65
|
+
default_tokenizer TokenBigram
|
66
|
+
normalizer NormalizerAuto
|
67
|
+
</table>
|
68
|
+
|
69
|
+
<table>
|
70
|
+
name Timestamps
|
71
|
+
flags TABLE_PAT_KEY
|
72
|
+
key_type Time
|
73
|
+
</table>
|
74
|
+
|
75
|
+
<mapping>
|
76
|
+
name timestamp
|
77
|
+
type Time
|
78
|
+
<index>
|
79
|
+
table Timestamps
|
80
|
+
name logs_index
|
81
|
+
</index>
|
82
|
+
</mapping>
|
83
|
+
|
84
|
+
<mapping>
|
85
|
+
name message
|
86
|
+
type Text
|
87
|
+
<index>
|
88
|
+
table Terms
|
89
|
+
name logs_message_index
|
90
|
+
</index>
|
91
|
+
</mapping>
|
92
|
+
</match>
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Copyright (C) 2014 Kouhei Sutou <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 version 2.1 as published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This library is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
10
|
+
# Lesser General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU Lesser General Public
|
13
|
+
# License along with this library; if not, write to the Free Software
|
14
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
15
|
+
|
16
|
+
require "fluent/plugin/out_groonga"
|
17
|
+
|
18
|
+
class OutputTypeTableIndexDefinitionTest < Test::Unit::TestCase
|
19
|
+
def table_definition
|
20
|
+
raw = {
|
21
|
+
:name => "Terms",
|
22
|
+
:default_tokenizer => "TokenBigram",
|
23
|
+
}
|
24
|
+
Fluent::GroongaOutput::TableDefinition.new(raw)
|
25
|
+
end
|
26
|
+
|
27
|
+
def definition(raw={})
|
28
|
+
default_raw = {
|
29
|
+
:source_columns => "title",
|
30
|
+
}
|
31
|
+
raw = default_raw.merge(raw)
|
32
|
+
Fluent::GroongaOutput::TableDefinition::IndexDefinition.new(table_definition,
|
33
|
+
raw)
|
34
|
+
end
|
35
|
+
|
36
|
+
sub_test_case "readers" do
|
37
|
+
sub_test_case "\#name" do
|
38
|
+
test "specified" do
|
39
|
+
assert_equal("logs_index", definition(:name => "logs_index").name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
sub_test_case "\#flags" do
|
44
|
+
test "default" do
|
45
|
+
assert_equal(["COLUMN_INDEX", "WITH_POSITION"],
|
46
|
+
definition.flags)
|
47
|
+
end
|
48
|
+
|
49
|
+
test "multiple source columns" do
|
50
|
+
assert_equal(["COLUMN_INDEX", "WITH_POSITION", "WITH_SECTION"],
|
51
|
+
definition(:source_columns => "title,content").flags)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
sub_test_case "\#source_table" do
|
56
|
+
test "specified" do
|
57
|
+
assert_equal("Logs",
|
58
|
+
definition(:source_table => "Logs").source_table)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
sub_test_case "\#source_columns" do
|
63
|
+
test "one" do
|
64
|
+
assert_equal(["title"],
|
65
|
+
definition(:source_columns => "title").source_columns)
|
66
|
+
end
|
67
|
+
|
68
|
+
test "multiple" do
|
69
|
+
raw = {
|
70
|
+
:source_columns => "title,content",
|
71
|
+
}
|
72
|
+
assert_equal(["title", "content"],
|
73
|
+
definition(raw).source_columns)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
sub_test_case "\#to_create_arguments" do
|
79
|
+
test "full" do
|
80
|
+
raw = {
|
81
|
+
:name => "logs_index",
|
82
|
+
:source_table => "Logs",
|
83
|
+
:source_columns => "title, content",
|
84
|
+
}
|
85
|
+
assert_equal({
|
86
|
+
"table" => "Terms",
|
87
|
+
"name" => "logs_index",
|
88
|
+
"flags" => "COLUMN_INDEX|WITH_POSITION|WITH_SECTION",
|
89
|
+
"type" => "Logs",
|
90
|
+
"source" => "title,content",
|
91
|
+
},
|
92
|
+
definition(raw).to_create_arguments)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-groonga
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kouhei Sutou
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -158,8 +158,10 @@ files:
|
|
158
158
|
- sample/gqtp.conf
|
159
159
|
- sample/http.conf
|
160
160
|
- sample/store-apache.conf
|
161
|
+
- sample/store-syslog.conf
|
161
162
|
- sample/store.conf
|
162
163
|
- test/output/test_table_definition.rb
|
164
|
+
- test/output/test_table_index_definition.rb
|
163
165
|
- test/output/test_type_guesser.rb
|
164
166
|
- test/run-test.rb
|
165
167
|
- test/test_input.rb
|
@@ -193,6 +195,7 @@ test_files:
|
|
193
195
|
- test/test_output.rb
|
194
196
|
- test/test_input.rb
|
195
197
|
- test/run-test.rb
|
198
|
+
- test/output/test_table_index_definition.rb
|
196
199
|
- test/output/test_type_guesser.rb
|
197
200
|
- test/output/test_table_definition.rb
|
198
201
|
has_rdoc:
|