fluent-plugin-kv-parser 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +2 -3
- data/README.md +15 -6
- data/fluent-plugin-kv-parser.gemspec +2 -2
- data/lib/fluent/plugin/parser_kv.rb +15 -32
- data/test/test_kv_parser.rb +40 -46
- metadata +12 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f4b7b45b73282ce3360af992bf3f56eab1b6a043ed25d8ee37ffad639079a61f
|
4
|
+
data.tar.gz: 63d383d9edc7cf3d46f7d9176e3b7742ca3e26cae50854c27693528d8243a44e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52ae18e5a422586ca55fb78eb3598d9f880a111e22ced3a56e743a55e1a8584ee37d3c374cc8beef631b619f846e0ee23b75f99ba614742c7054d46a9d8565f4
|
7
|
+
data.tar.gz: 8b73739ebc3ece980df58d9836e15730c8fd1a0ebdfd52f3174ce7a1d404855d222483684a5b906ae45aa852a94cfc30848f465896087c2e235adaf2b660e765
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Key-Value Pairs Parser Plugin for [Fluentd](https://github.com/fluent/fluentd)
|
2
2
|
|
3
|
-
|
3
|
+
[![Build Status](https://travis-ci.org/fluent-plugins-nursery/fluent-plugin-kv-parser.svg?branch=master)](https://travis-ci.org/fluent-plugins-nursery/fluent-plugin-kv-parser)
|
4
4
|
|
5
5
|
## Overview
|
6
6
|
|
@@ -20,6 +20,13 @@ It is parsed as
|
|
20
20
|
|
21
21
|
with the event's time being `2013-01-01T12:34:00`
|
22
22
|
|
23
|
+
## Requirements
|
24
|
+
|
25
|
+
| fluent-plugin-kv-parser | fluentd | ruby |
|
26
|
+
|-------------------------|------------|--------|
|
27
|
+
| >= 1.0.0 | >= v0.14.0 | >= 2.1 |
|
28
|
+
| < 1.0.0 | >= v0.12.0 | >= 1.9 |
|
29
|
+
|
23
30
|
## How to Install and Use
|
24
31
|
|
25
32
|
For Fluentd,
|
@@ -40,15 +47,17 @@ For example, using `in_tcp` with the following configuration:
|
|
40
47
|
|
41
48
|
```aconf
|
42
49
|
<source>
|
43
|
-
type tcp
|
50
|
+
@type tcp
|
44
51
|
port 24225
|
45
52
|
tag kv_log
|
46
|
-
|
47
|
-
|
48
|
-
|
53
|
+
<parse>
|
54
|
+
@type kv
|
55
|
+
time_key my_time
|
56
|
+
types k1:integer,my_time:time
|
57
|
+
</parse>
|
49
58
|
</source>
|
50
59
|
<match kv_log>
|
51
|
-
type stdout
|
60
|
+
@type stdout
|
52
61
|
</match>
|
53
62
|
```
|
54
63
|
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "fluent-plugin-kv-parser"
|
7
|
-
spec.version = "
|
7
|
+
spec.version = "1.0.0"
|
8
8
|
spec.description = 'Fluentd parser plugin to parse key value pairs'
|
9
9
|
spec.authors = ["kiyoto"]
|
10
10
|
spec.email = ["kiyoto@treasure-data.com"]
|
@@ -19,5 +19,5 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_development_dependency "rake"
|
21
21
|
spec.add_development_dependency "test-unit", "> 3.0"
|
22
|
-
spec.add_runtime_dependency "fluentd", '
|
22
|
+
spec.add_runtime_dependency "fluentd", '> 0.14.0', '< 2'
|
23
23
|
end
|
@@ -1,14 +1,16 @@
|
|
1
|
+
require "fluent/plugin/parser"
|
2
|
+
|
1
3
|
module Fluent
|
2
|
-
|
3
|
-
class KVParser < Parser
|
4
|
-
|
5
|
-
|
4
|
+
module Plugin
|
5
|
+
class KVParser < Fluent::Plugin::Parser
|
6
|
+
Fluent::Plugin.register_parser("kv", self)
|
7
|
+
|
8
|
+
config_param :kv_delimiter, :string, default: '/\s+/'
|
9
|
+
config_param :kv_char, :string, default: '='
|
6
10
|
|
7
|
-
|
8
|
-
config_param :kv_char, :string, :default => '='
|
9
|
-
config_param :time_key, :string, :default => 'time'
|
11
|
+
config_set_default :time_key, "time"
|
10
12
|
|
11
|
-
def configure(conf
|
13
|
+
def configure(conf)
|
12
14
|
super
|
13
15
|
if @kv_delimiter[0] == '/' and @kv_delimiter[-1] == '/'
|
14
16
|
@kv_delimiter = Regexp.new(@kv_delimiter[1..-2])
|
@@ -18,34 +20,15 @@ module Fluent
|
|
18
20
|
def parse(text)
|
19
21
|
record = {}
|
20
22
|
text.split(@kv_delimiter).each do |kv|
|
21
|
-
|
22
|
-
record[
|
23
|
+
key, value = kv.split(@kv_char, 2)
|
24
|
+
record[key] = value
|
23
25
|
end
|
24
26
|
|
25
|
-
|
26
|
-
time = record
|
27
|
-
if time.nil?
|
28
|
-
time = Engine.now
|
29
|
-
elsif time.respond_to?(:to_i)
|
30
|
-
time = time.to_i
|
31
|
-
else
|
32
|
-
raise RuntimeError, "The #{@time_key}=#{time} is a bad time field"
|
33
|
-
end
|
27
|
+
time = parse_time(record)
|
28
|
+
time, record = convert_values(time, record)
|
34
29
|
|
35
30
|
yield time, record
|
36
31
|
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def convert_field_type!(record)
|
41
|
-
@type_converters.each_key { |key|
|
42
|
-
if value = record[key]
|
43
|
-
record[key] = convert_type(key, value)
|
44
|
-
end
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
32
|
end
|
49
|
-
register_template('kv', Proc.new { KVParser.new })
|
50
33
|
end
|
51
|
-
end
|
34
|
+
end
|
data/test/test_kv_parser.rb
CHANGED
@@ -1,73 +1,67 @@
|
|
1
1
|
require 'fluent/test'
|
2
|
-
require 'fluent/parser'
|
2
|
+
require 'fluent/test/driver/parser'
|
3
|
+
require 'fluent/test/helpers'
|
3
4
|
require 'fluent/plugin/parser_kv'
|
4
5
|
|
5
6
|
class KVParserTest < ::Test::Unit::TestCase
|
6
|
-
|
7
|
-
def create_driver(conf = {})
|
8
|
-
Fluent::Test::ParserTestDriver.new(Fluent::TextParser::KVParser).configure(conf)
|
9
|
-
end
|
7
|
+
include Fluent::Test::Helpers
|
10
8
|
|
11
9
|
def setup
|
12
|
-
|
13
|
-
ENV["TZ"] = "UTC"
|
10
|
+
Fluent::Test.setup
|
14
11
|
end
|
15
12
|
|
16
|
-
def
|
17
|
-
|
13
|
+
def create_driver(conf={})
|
14
|
+
Fluent::Test::Driver::Parser.new(Fluent::Plugin::KVParser).configure(conf)
|
18
15
|
end
|
19
16
|
|
20
|
-
|
17
|
+
data("single space" => ["k1=v1 k2=v2", { "k1" => "v1", "k2" => "v2" }],
|
18
|
+
"multiple space" => ["k1=v1 k2=v2", { "k1" => "v1", "k2" => "v2" }],
|
19
|
+
"reverse" => ["k2=v2 k1=v1", { "k1" => "v1", "k2" => "v2" }],
|
20
|
+
"tab" => ["k2=v2\tk1=v1", { "k1" => "v1", "k2" => "v2" }],
|
21
|
+
"tab and space" => ["k2=v2\t k1=v1", { "k1" => "v1", "k2" => "v2" }])
|
22
|
+
test "parse" do |(text, expected)|
|
21
23
|
d = create_driver
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
parser.parse("k2=v2 k1=v1") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
26
|
-
parser.parse("k2=v2\tk1=v1") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
27
|
-
parser.parse("k2=v2\t k1=v1") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
24
|
+
d.instance.parse(text) do |_time, record|
|
25
|
+
assert_equal(expected, record)
|
26
|
+
end
|
28
27
|
end
|
29
28
|
|
30
|
-
|
29
|
+
test "parse with types" do
|
31
30
|
d = create_driver("types" => "k1:integer")
|
32
|
-
|
33
|
-
|
31
|
+
d.instance.parse("k1=100") do |_time, record|
|
32
|
+
assert_equal({ "k1" => 100 }, record)
|
33
|
+
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
test "parse with time" do
|
37
37
|
d = create_driver("types" => "time:time")
|
38
|
-
|
39
|
-
|
40
|
-
assert_equal(
|
41
|
-
|
42
|
-
}
|
38
|
+
d.instance.parse("k1=foo time=1970-01-01T01:00:00") do |time, record|
|
39
|
+
assert_equal(event_time("1970-01-01T01:00:0"), time)
|
40
|
+
assert_equal({ "k1" => "foo" }, record)
|
41
|
+
end
|
43
42
|
end
|
44
43
|
|
45
|
-
|
44
|
+
test "parse with custom time_key" do
|
46
45
|
d = create_driver("time_key" => "my_time", "types" => "my_time:time")
|
47
|
-
|
48
|
-
|
49
|
-
assert_equal(
|
50
|
-
|
51
|
-
}
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_custom_delimiter
|
55
|
-
d = create_driver("kv_delimiter" => "|")
|
56
|
-
parser = d.instance
|
57
|
-
parser.parse("k1=v1|k2=v2") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
46
|
+
d.instance.parse("k1=foo my_time=1970-01-01T01:00:00") do |time, record|
|
47
|
+
assert_equal(event_time("1970-01-01T01:00:0"), time)
|
48
|
+
assert_equal({ "k1" => "foo" }, record)
|
49
|
+
end
|
58
50
|
end
|
59
51
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
52
|
+
data("pipe" => ["|", "k1=v1|k2=v2", {"k1" => "v1", "k2" => "v2" }],
|
53
|
+
"regexp" => ["/[@ ]/", "k1=v1@k2=v2 k3=v3", { "k1" => "v1", "k2" => "v2", "k3" => "v3" }])
|
54
|
+
test "parse with custom kv_delimiter" do |(delimiter, text, expected)|
|
55
|
+
d = create_driver("kv_delimiter" => delimiter)
|
56
|
+
d.instance.parse(text) do |_time, record|
|
57
|
+
assert_equal(expected, record)
|
58
|
+
end
|
66
59
|
end
|
67
60
|
|
68
|
-
|
61
|
+
test "parse with custom kv_char" do
|
69
62
|
d = create_driver("kv_char" => "#")
|
70
|
-
|
71
|
-
|
63
|
+
d.instance.parse("k1#v1 k2#v2") do |_time, record|
|
64
|
+
assert_equal({ "k1" => "v1", "k2" => "v2" }, record)
|
65
|
+
end
|
72
66
|
end
|
73
67
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-kv-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kiyoto
|
@@ -42,16 +42,22 @@ dependencies:
|
|
42
42
|
name: fluentd
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.14.0
|
48
|
+
- - "<"
|
46
49
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
50
|
+
version: '2'
|
48
51
|
type: :runtime
|
49
52
|
prerelease: false
|
50
53
|
version_requirements: !ruby/object:Gem::Requirement
|
51
54
|
requirements:
|
52
|
-
- - "
|
55
|
+
- - ">"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.14.0
|
58
|
+
- - "<"
|
53
59
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
60
|
+
version: '2'
|
55
61
|
description: Fluentd parser plugin to parse key value pairs
|
56
62
|
email:
|
57
63
|
- kiyoto@treasure-data.com
|
@@ -86,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
92
|
version: '0'
|
87
93
|
requirements: []
|
88
94
|
rubyforge_project:
|
89
|
-
rubygems_version: 2.
|
95
|
+
rubygems_version: 2.7.3
|
90
96
|
signing_key:
|
91
97
|
specification_version: 4
|
92
98
|
summary: Fluentd parser plugin to parse key value pairs
|