fluent-mixin-type-converter 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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ vendor/*
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.1.0
5
+ - 2.0.0
6
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fluent-mixin-type-converter.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ Copyright (c) 2014- Kentaro Yoshida
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
14
+
data/README.md ADDED
@@ -0,0 +1,164 @@
1
+ ## Fluent::Mixin::TypeConverter [![Build Status](https://travis-ci.org/y-ken/fluent-mixin-type-converter.png?branch=master)](https://travis-ci.org/y-ken/fluent-mixin-type-converter)
2
+
3
+ ## Overview
4
+
5
+ Fluentd mixin plugin to provides type conversion function as like as in_tail plugin. It acts calling [Fluent::TextParser::TypeConverter](https://github.com/fluent/fluentd/blob/master/lib/fluent/parser.rb) as mixin. It will let you get easy to implement type conversion for your own plugins.
6
+
7
+ ## Function
8
+
9
+ It supportes these type conversion.
10
+
11
+ - string
12
+ - integer
13
+ - float
14
+ - bool
15
+ - time
16
+ - array
17
+
18
+ #### Option
19
+
20
+ * `types_delimiter`
21
+ [default] `,`
22
+
23
+ * `types_label_delimiter`
24
+ [default] `:`
25
+
26
+ ## Configuration
27
+
28
+ Adding this mixin plugin, it will enabled to use these type conversion in your plugins.
29
+
30
+ ```xml
31
+ # input plugin example
32
+ <source>
33
+ type foo_bar
34
+ tag test.message
35
+
36
+ # type conversion with this rule before emit.
37
+ types member_id:int,temperature:float
38
+ </source>
39
+ ```
40
+
41
+ ```xml
42
+ # output plugin example
43
+ <match test.foo>
44
+ type foo_bar
45
+ tag test.message
46
+
47
+ # type conversion with this rule before emit.
48
+ types member_id:int,temperature:float
49
+ </match>
50
+ ```
51
+
52
+ Another examples are written in [unit test](https://github.com/y-ken/fluent-mixin-type-converter/blob/master/test/mixin/test_type_converter).
53
+
54
+ ## Usage
55
+
56
+ #### 1. edit gemspec
57
+
58
+ add dependency for .gemspec file like below. For more detail, see [gemspec example](https://github.com/y-ken/fluent-plugin-watch-process/blob/master/fluent-plugin-watch-process.gemspec)
59
+
60
+ ```ruby
61
+ spec.add_runtime_dependency "fluent-mixin-type-converter"
62
+ ```
63
+
64
+ #### 2. activate fluent-mixin-type-converter for your plugin
65
+
66
+ It is the instruction in the case of adding `fluent-plugin-foobar`.
67
+
68
+ ```
69
+ $ cd fluent-plugin-foobar
70
+ $ vim fluent-plugin-foobar.gemspec # edit gemspec
71
+ $ bundle install --path vendor/bundle # or just type `bundle install`
72
+ ```
73
+
74
+ #### 3. edit your plugin to implement
75
+
76
+ It is a quick guide to enable your plugin to use TypeConverter Mixin.
77
+ The key points of basic implmentation is just like below.
78
+
79
+ * add `require 'fluent/mixin/type_converter'` at the top of source
80
+ * in the case of output plugin, add `include Fluent::HandleTagNameMixin` (recommend)
81
+ this is required if you will use kind of 'remove_tag_prefix' option together
82
+ * add `include Fluent::Mixin::TypeConverter` in intput/output class after HandleTagNameMixin
83
+ * add `emit_tag = tag.dup` and `filter_record(emit_tag, time, record)` before `Engine.emit`
84
+
85
+ ##### implement example for input plugin
86
+
87
+ ```ruby
88
+ require 'fluent/mixin/type_converter
89
+
90
+ module Fluent
91
+ class FooBarInput < Fluent::Input
92
+ Plugin.register_input('foo_bar', self)
93
+
94
+ # ...snip...
95
+
96
+ include Fluent::Mixin::TypeConverter
97
+ config_param :types, :string, :default => nil
98
+ config_param :types_delimiter, :string, :default => ','
99
+ config_param :types_label_delimiter, :string, :default => ':'
100
+
101
+ # ...snip...
102
+
103
+ def emit_message(tag, message)
104
+ emit_tag = tag.dup
105
+ filter_record(emit_tag, Engine.now, message)
106
+ Engine.emit(emit_tag, Engine.now, message)
107
+ end
108
+
109
+ # ...snip...
110
+
111
+ end
112
+ end
113
+ ```
114
+
115
+ ##### implement example for output plugin
116
+
117
+ ```ruby
118
+ require 'fluent/mixin/type_converter
119
+
120
+ class Fluent
121
+ class FooBarOutput < Fluent::Output
122
+ Fluent::Plugin.register_output('foo_bar', self)
123
+
124
+ # ...snip...
125
+
126
+ include Fluent::Mixin::TypeConverter
127
+ config_param :types, :string, :default => nil
128
+ config_param :types_delimiter, :string, :default => ','
129
+ config_param :types_label_delimiter, :string, :default => ':'
130
+
131
+ # ...snip...
132
+
133
+ def emit(tag, es, chain)
134
+ es.each do |time, record|
135
+ emit_tag = tag.dup
136
+ filter_record(emit_tag, time, record)
137
+ Fluent::Engine.emit(emit_tag, time, record)
138
+ end
139
+ chain.next
140
+ end
141
+
142
+ # ...snip...
143
+
144
+ end
145
+ end
146
+ ```
147
+
148
+ ## Case Study
149
+
150
+ These cool plugins are using this mixin!
151
+
152
+ * [fluent-plugin-watch-process](https://github.com/y-ken/fluent-plugin-watch-process/)
153
+
154
+ ## TODO
155
+
156
+ Pull requests are very welcome!!
157
+
158
+ ## Copyright
159
+
160
+ Copyright © 2014- Kentaro Yoshida ([@yoshi_ken](https://twitter.com/yoshi_ken))
161
+
162
+ ## License
163
+
164
+ Apache License, Version 2.0
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+ Rake::TestTask.new(:test) do |test|
4
+ test.libs << 'lib' << 'test'
5
+ test.pattern = 'test/**/test_*.rb'
6
+ test.verbose = true
7
+ end
8
+
9
+ 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-mixin-type-converter"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Kentaro Yoshida"]
9
+ spec.email = ["y.ken.studio@gmail.com"]
10
+ spec.summary = %q{Fluentd mixin plugin to provides type conversion function as like as in_tail plugin. It acts calling Fluent::TextParser::TypeConverter as mixin. It will let you get easy to implement type conversion for your own plugins.}
11
+ spec.homepage = "https://github.com/y-ken/fluent-mixin-type-converter"
12
+ spec.license = "Apache License, Version 2.0"
13
+
14
+ spec.files = `git ls-files`.split($/)
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler"
20
+ spec.add_development_dependency "rake"
21
+ spec.add_development_dependency "fluent-mixin-rewrite-tag-name"
22
+ spec.add_runtime_dependency "fluentd"
23
+ end
@@ -0,0 +1,31 @@
1
+ module Fluent
2
+ module Mixin
3
+ module TypeConverter
4
+ include Configurable
5
+ include RecordFilterMixin
6
+ include Fluent::TextParser::TypeConverter
7
+
8
+ attr_accessor :types, :types_delimiter, :types_label_delimiter
9
+
10
+ def configure(conf)
11
+ super
12
+
13
+ end
14
+
15
+ def filter_record(tag, time, record)
16
+ super
17
+ if @types
18
+ convert_field_type!(record)
19
+ end
20
+ end
21
+
22
+ def convert_field_type!(record)
23
+ record.each { |key, value|
24
+ record[key] = convert_type(key, value)
25
+ }
26
+ self
27
+ end
28
+
29
+ end
30
+ end
31
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+
15
+ require 'fluent/test'
16
+ unless ENV.has_key?('VERBOSE')
17
+ nulllogger = Object.new
18
+ nulllogger.instance_eval {|obj|
19
+ def method_missing(method, *args)
20
+ # pass
21
+ end
22
+ }
23
+ $log = nulllogger
24
+ end
25
+
26
+ require 'fluent/mixin/type_converter'
27
+ require_relative 'plugin'
28
+
29
+ class Test::Unit::TestCase
30
+ end
@@ -0,0 +1,93 @@
1
+ require 'helper'
2
+
3
+ class TypeConverterMixinTest < Test::Unit::TestCase
4
+ def setup
5
+ Fluent::Test.setup
6
+ end
7
+
8
+ CONFIG = %[
9
+ tag log.${tag}
10
+ remove_tag_prefix apache.
11
+ types code:integer,response_time:float
12
+ ]
13
+
14
+ def create_driver(conf=CONFIG,tag='test')
15
+ Fluent::Test::OutputTestDriver.new(Fluent::TypeConverterMixinOutput, tag).configure(conf)
16
+ end
17
+
18
+ def test_configure
19
+ assert_raise(Fluent::ConfigError) {
20
+ d = create_driver('')
21
+ }
22
+ assert_raise(Fluent::ConfigError) {
23
+ d = create_driver('unknown_keys')
24
+ }
25
+ d = create_driver(CONFIG)
26
+ puts d.instance.inspect
27
+ assert_equal 'code:integer,response_time:float', d.instance.config['types']
28
+ end
29
+
30
+ def test_emit
31
+ d1 = create_driver(CONFIG, 'apache.access')
32
+ d1.run do
33
+ d1.emit({
34
+ 'code' => '200',
35
+ 'response_time' => '0.03'
36
+ })
37
+ end
38
+ emits = d1.emits
39
+ assert_equal 1, emits.length
40
+ p emits[0]
41
+ assert_equal 'log.access', emits[0][0] # tag
42
+ assert_equal 200, emits[0][2]['code']
43
+ assert_equal 0.03, emits[0][2]['response_time']
44
+ end
45
+
46
+ def test_emit_with_custom_delimiter
47
+ d1 = create_driver(%[
48
+ tag test.message
49
+ types code:integer|response_time:float
50
+ types_delimiter |
51
+ types_label_delimiter :
52
+ ], 'apache.access')
53
+ d1.run do
54
+ d1.emit({
55
+ 'code' => '200',
56
+ 'response_time' => '0.03'
57
+ })
58
+ end
59
+ emits = d1.emits
60
+ assert_equal 1, emits.length
61
+ p emits[0]
62
+ assert_equal 'test.message', emits[0][0] # tag
63
+ assert_equal 200, emits[0][2]['code']
64
+ assert_equal 0.03, emits[0][2]['response_time']
65
+ end
66
+
67
+ def test_emit_all_types
68
+ d1 = create_driver(%[
69
+ tag test.message
70
+ types string:string,integer:integer,float:float,bool:bool,time:time,array:array
71
+ ], 'apache.access')
72
+ d1.run do
73
+ d1.emit({
74
+ 'string' => 'foo',
75
+ 'integer' => '500',
76
+ 'float' => '0.5',
77
+ 'bool' => 'true',
78
+ 'time' => '2014-01-21 12:29:44 +0900',
79
+ 'array' => 'foo,1,2.0,true'
80
+ })
81
+ end
82
+ emits = d1.emits
83
+ assert_equal 1, emits.length
84
+ p emits[0]
85
+ assert_equal 'test.message', emits[0][0] # tag
86
+ assert_equal 'foo', emits[0][2]['string']
87
+ assert_equal 500, emits[0][2]['integer']
88
+ assert_equal 0.5, emits[0][2]['float']
89
+ assert_equal true, emits[0][2]['bool']
90
+ assert_equal 1390274984, emits[0][2]['time']
91
+ assert_equal ["foo", "1", "2.0", "true"], emits[0][2]['array']
92
+ end
93
+ end
data/test/plugin.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'fluent/mixin/rewrite_tag_name'
2
+
3
+ class Fluent::TypeConverterMixinOutput < Fluent::Output
4
+ Fluent::Plugin.register_output('type_converter_mixin', self)
5
+
6
+ config_param :tag, :string, :default => nil
7
+ config_param :types, :string, :default => nil
8
+ config_param :types_delimiter, :string, :default => ','
9
+ config_param :types_label_delimiter, :string, :default => ':'
10
+
11
+ include Fluent::HandleTagNameMixin
12
+ include Fluent::Mixin::RewriteTagName
13
+ include Fluent::Mixin::TypeConverter
14
+
15
+ def configure(conf)
16
+ super
17
+
18
+ if ( !@tag && !@remove_tag_prefix && !@remove_tag_suffix && !@add_tag_prefix && !@add_tag_suffix )
19
+ raise Fluent::ConfigError, "RewriteTagNameMixin: missing remove_tag_prefix, remove_tag_suffix, add_tag_prefix or add_tag_suffix."
20
+ end
21
+ end
22
+
23
+ def emit(tag, es, chain)
24
+ es.each do |time, record|
25
+ emit_tag = tag.dup
26
+ filter_record(emit_tag, time, record)
27
+ Fluent::Engine.emit(emit_tag, time, record)
28
+ end
29
+ chain.next
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-mixin-type-converter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kentaro Yoshida
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: fluent-mixin-rewrite-tag-name
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: fluentd
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description:
79
+ email:
80
+ - y.ken.studio@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - .travis.yml
87
+ - Gemfile
88
+ - LICENSE
89
+ - README.md
90
+ - Rakefile
91
+ - fluent-mixin-type-converter.gemspec
92
+ - lib/fluent/mixin/type_converter.rb
93
+ - test/helper.rb
94
+ - test/mixin/test_type_converter.rb
95
+ - test/plugin.rb
96
+ homepage: https://github.com/y-ken/fluent-mixin-type-converter
97
+ licenses:
98
+ - Apache License, Version 2.0
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 1.8.23
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: Fluentd mixin plugin to provides type conversion function as like as in_tail
121
+ plugin. It acts calling Fluent::TextParser::TypeConverter as mixin. It will let
122
+ you get easy to implement type conversion for your own plugins.
123
+ test_files:
124
+ - test/helper.rb
125
+ - test/mixin/test_type_converter.rb
126
+ - test/plugin.rb