fluent-plugin-kv-parser 0.0.1
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 +7 -0
- data/Gemfile +3 -0
- data/README.md +78 -0
- data/Rakefile +10 -0
- data/fluent-plugin-docker-metrics.gemspec +23 -0
- data/lib/fluent/plugin/parser_kv.rb +51 -0
- data/test/test_kv_parser.rb +57 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 787237ea7e0cdfbefdef04d5190387575c51ebd9
|
4
|
+
data.tar.gz: f20c58f82c89bbcd528757dbd82806610182df83
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 40a7a05d055b54ef13fe08ad99bcf22bedc74970b65316659a39c8d677c5629f1985c514f39dcf1285d696ef1f0b38a916d4165ed53cd3d87cca12255d00adf0
|
7
|
+
data.tar.gz: 56f423018fb7e35d05ec54acd524d5f33fccb25ef5f09a5f58c00f83189992eb30cfc3b3167349eaa23fb52f9e79152c025f75e24b473ca64f5187e1a450dd57
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Key-Value Pairs Parser Plugin for [Fluentd](https://github.com/fluent/fluentd)
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
This is a parser plugin for Fluentd. Learn more about parser plugins [here](https://docs.fluentd.org/articles/parser-plugin-overview).
|
6
|
+
|
7
|
+
This plugin allows you to parse inputs that look like key-value pairs. For example, if your text logs look like
|
8
|
+
|
9
|
+
```
|
10
|
+
"this_field=10000 that_field=hello time=2013-01-01T12:34:00"
|
11
|
+
```
|
12
|
+
|
13
|
+
It is parsed as
|
14
|
+
|
15
|
+
```json
|
16
|
+
{"this_field":10000, "that_field":"hello"}
|
17
|
+
```
|
18
|
+
|
19
|
+
with the event's time being `2013-01-01T12:34:00`
|
20
|
+
|
21
|
+
## How to Install and Use
|
22
|
+
|
23
|
+
For Fluentd,
|
24
|
+
|
25
|
+
```
|
26
|
+
gem install fluent-plugin-kv-parser
|
27
|
+
```
|
28
|
+
|
29
|
+
For [Treasure Agent](https://docs.treasuredata.com/articles/td-agent),
|
30
|
+
|
31
|
+
```
|
32
|
+
/usr/sbin/td-agent-gem install fluent-plugin-kv-parser
|
33
|
+
```
|
34
|
+
|
35
|
+
Then, for parser-plugin enabled input plugins (including [in_tail](https://docs.fluentd.org/articles/in_tail), [in_tcp](https://docs.fluentd.org/articles/in_tcp), [in_udp](https://docs.fluentd.org/articles/in_udp) and [in_syslog](https://docs.fluentd.org/articles/syslog)), you can just write `format kv`
|
36
|
+
|
37
|
+
For example, using `in_tcp` with the following configuration:
|
38
|
+
|
39
|
+
```aconf
|
40
|
+
<source>
|
41
|
+
type tcp
|
42
|
+
port 24225
|
43
|
+
tag kv_log
|
44
|
+
format kv
|
45
|
+
time_key my_time
|
46
|
+
types k1:integer,my_time:time
|
47
|
+
</source>
|
48
|
+
<match kv_log>
|
49
|
+
type stdout
|
50
|
+
</match>
|
51
|
+
```
|
52
|
+
|
53
|
+
Running
|
54
|
+
|
55
|
+
```shell
|
56
|
+
echo 'my_time=2014-12-31T00:00:00 k1=1234 k2=hello' | nc localhost 24224
|
57
|
+
```
|
58
|
+
|
59
|
+
gives
|
60
|
+
|
61
|
+
```shell
|
62
|
+
2014-12-31 00:00:00 +0000 kv_log: {"k1":1234,"k2":"hello"}
|
63
|
+
```
|
64
|
+
|
65
|
+
## Parameters
|
66
|
+
|
67
|
+
* **kv_delimiter**: The delimiter for key-value pairs. By default, it is the regexp `/\t\s/+` (one or more whitespace/tabs). If the value starts and ends with the character `'/'`, the separator is interpreted to be a regexp. Else, it is interpreted to be a string. Hence,
|
68
|
+
|
69
|
+
- `kv_delimiter /a+/` splits on one or more "a"s
|
70
|
+
- `kv_delimiter a` splits on a single "a"
|
71
|
+
|
72
|
+
* **kv_char**: The string to split the key from the value. By default, it is "=".
|
73
|
+
* **time_key**: The time key field among the key-value pairs to be used as the time for the event. If missing or unparsable, the current time is used.
|
74
|
+
* **types**: The parameter to convert the values of key-value pairs. The syntax is `<key_name>:<type_name>`. For example, to convert the key "k1" into integer, write `types k1:integer`. For the `time` type, one can write `<key_name>:time:<time_format>` to convert the string into a time object. For example, to convert the string "my_time=12/31/2014 12:00:00", use `my_time:time:%m/%d/%Y %H:%M:%S`. This parameter is same as the one used for [in_tail](https://docs.fluentd.org/articles/in_tail) and others (see under the "types" section over there).
|
75
|
+
|
76
|
+
## License
|
77
|
+
|
78
|
+
Apache 2.0. Copyright Kiyoto Tamura
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "fluent-plugin-kv-parser"
|
7
|
+
spec.version = "0.0.1"
|
8
|
+
spec.description = 'Fluentd parser plugin to parse key value pairs'
|
9
|
+
spec.authors = ["kiyoto"]
|
10
|
+
spec.email = ["kiyoto@treasure-data.com"]
|
11
|
+
spec.summary = %q{Fluentd parser plugin to parse key value pairs}
|
12
|
+
spec.homepage = "https://github.com/kiyoto/fluent-plugin-kv-parser"
|
13
|
+
spec.license = "Apache License, Version 2.0"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", '~> 1.7'
|
21
|
+
spec.add_development_dependency "rake", '~> 10.1'
|
22
|
+
spec.add_runtime_dependency "fluentd", '~> 0.10'
|
23
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Fluent
|
2
|
+
class TextParser
|
3
|
+
class KVParser < Parser
|
4
|
+
include Configurable
|
5
|
+
include TypeConverter
|
6
|
+
|
7
|
+
config_param :kv_delimiter, :string, :default => '/[\t\s]+/'
|
8
|
+
config_param :kv_char, :string, :default => '='
|
9
|
+
config_param :time_key, :string, :default => 'time'
|
10
|
+
|
11
|
+
def configure(conf={})
|
12
|
+
super
|
13
|
+
if @kv_delimiter[0] == '/' and @kv_delimiter[-1] == '/'
|
14
|
+
@kv_delimiter = Regexp.new(@kv_delimiter[1..-2])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse(text)
|
19
|
+
record = {}
|
20
|
+
text.split(@kv_delimiter).each do |kv|
|
21
|
+
k, v = kv.split(@kv_char, 2)
|
22
|
+
record[k] = v
|
23
|
+
end
|
24
|
+
|
25
|
+
convert_field_type!(record) if @type_converters
|
26
|
+
time = record.delete(@time_key)
|
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
|
34
|
+
|
35
|
+
yield time, record
|
36
|
+
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
|
+
end
|
49
|
+
register_template('kv', Proc.new { KVParser.new })
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'fluent/test'
|
2
|
+
require 'fluent/parser'
|
3
|
+
require 'fluent/plugin/parser_kv'
|
4
|
+
|
5
|
+
module ParserTest
|
6
|
+
include Fluent
|
7
|
+
|
8
|
+
class KVParserTest < ::Test::Unit::TestCase
|
9
|
+
include ParserTest
|
10
|
+
|
11
|
+
def test_basic
|
12
|
+
parser = Fluent::TextParser::KVParser.new
|
13
|
+
parser.configure
|
14
|
+
parser.parse("k1=v1 k2=v2") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
15
|
+
parser.parse("k1=v1 k2=v2") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
16
|
+
parser.parse("k2=v2 k1=v1") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
17
|
+
parser.parse("k2=v2\tk1=v1") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
18
|
+
parser.parse("k2=v2\t k1=v1") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_with_types
|
22
|
+
parser = Fluent::TextParser::KVParser.new
|
23
|
+
parser.configure("types" => "k1:integer")
|
24
|
+
parser.parse("k1=100") {|_, v| assert_equal(100, v["k1"])}
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_with_time
|
28
|
+
parser = Fluent::TextParser::KVParser.new
|
29
|
+
parser.configure("types" => "time:time:%Y-%m-%dT%H:%M:%S")
|
30
|
+
parser.parse("k1=foo time=1970-01-01T01:00:00") {|time, v|
|
31
|
+
assert_equal(3600, time)
|
32
|
+
assert_equal("foo", v["k1"])
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_custom_delimiter
|
37
|
+
parser = Fluent::TextParser::KVParser.new
|
38
|
+
parser.configure("kv_delimiter" => "|")
|
39
|
+
parser.parse("k1=v1|k2=v2") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
40
|
+
parser.configure("kv_delimiter" => "/[@ ]/")
|
41
|
+
parser.parse("k1=v1@k2=v2 k3=v3") {|_, v|
|
42
|
+
assert_equal({"k1"=>"v1", "k2"=>"v2", "k3"=>"v3"}, v)
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_custom_kv_char
|
47
|
+
parser = Fluent::TextParser::KVParser.new
|
48
|
+
parser.configure("kv_char" => "#")
|
49
|
+
parser.parse("k1#v1 k2#v2") {|_, v| assert_equal({"k1"=>"v1", "k2"=>"v2"}, v)}
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_types_param
|
53
|
+
parser = Fluent::TextParser::KVParser.new
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-kv-parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- kiyoto
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: fluentd
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.10'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.10'
|
55
|
+
description: Fluentd parser plugin to parse key value pairs
|
56
|
+
email:
|
57
|
+
- kiyoto@treasure-data.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- Gemfile
|
63
|
+
- README.md
|
64
|
+
- Rakefile
|
65
|
+
- fluent-plugin-docker-metrics.gemspec
|
66
|
+
- lib/fluent/plugin/parser_kv.rb
|
67
|
+
- test/test_kv_parser.rb
|
68
|
+
homepage: https://github.com/kiyoto/fluent-plugin-kv-parser
|
69
|
+
licenses:
|
70
|
+
- Apache License, Version 2.0
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.2.2
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: Fluentd parser plugin to parse key value pairs
|
92
|
+
test_files:
|
93
|
+
- test/test_kv_parser.rb
|