fluent-plugin-groonga 1.0.8 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5c57a846ebfc9321fd1ab1b79ce794e6aefbfff
4
- data.tar.gz: fd6dbc5627188c8cc20d221b27ca802d755dd2ea
3
+ metadata.gz: bf6b4e7487748c2f6c1afd542bcc01b28cae47d5
4
+ data.tar.gz: 7a84873889cb7b1fa6a48d6e7335f314c4f8756f
5
5
  SHA512:
6
- metadata.gz: d9699527fea08ac73e293215282f327f51cafa880eae410ff0ffada7568144032480481e55405ae4217654e7cd503301fc29ade309e9cc76619e5dd322e74d8d
7
- data.tar.gz: a9acb39dd64613ff97eb4336e21b7b34e28e9d8876285bb69b6e8fc9e3effbb9d5470aeab16478b5ae09bfeb97807de598d0f6a7c6e9fab081800c208f19cb71
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.8"
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
- @table = nil
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 @table
314
+ return if @target_table
309
315
 
310
- table_list = @client.execute("table_list")
311
- target_table = table_list.find do |table|
312
- table.name == @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
- if target_table
315
- @table = Table.new(@table_name, target_table.domain)
316
- else
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
- @table = Table.new(@table_name, nil)
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[column.name] = Column.new(column.name,
332
- column.range,
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
- if mapping
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
- def initialize(name, key_type)
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
- @key_type = key_type
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 = @client.execute(command)
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,
@@ -169,7 +169,6 @@
169
169
  <index>
170
170
  table Terms
171
171
  name logs_message_index
172
- flags WITH_POSITION
173
172
  </index>
174
173
  </mapping>
175
174
 
@@ -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.8
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-05 00:00:00.000000000 Z
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: