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 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
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
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,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << "test" << "lib"
6
+ test.pattern = 'test/test_*.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task :default => :test
@@ -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