fluent-plugin-record-modifier 0.3.0 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 344506e1d7deb2d3211df17f02386283fa8a30ab
4
- data.tar.gz: 44e6d422823ddf0c686abe066b7da36fc96e4e19
3
+ metadata.gz: 3ff1d6de463980c890752f4eb32719f3f160c026
4
+ data.tar.gz: 4ed772c23ab2316e1bf064a9fd3c1ed498c1aae8
5
5
  SHA512:
6
- metadata.gz: 45f15173d92fa1d91e20c62337ffe757852bf42bd006c7847459ca61521cd21cc63b604715489cfec05555f8ce95ba91d182816e470c64771bb3e81cecacad17
7
- data.tar.gz: 7c63568717b13b17bdec90bf43c6edf30884639dd9d586efe85bd90f02787d99a7cbbd26484f6ab2676bdddb2facae032148307b0a35aec6c36428f0e602f3ca
6
+ metadata.gz: 2477196fe7d51f5d26546107d4b9a01907e97e3dc38a0d5a2a1a4cc8182f298d24abb996b197e3609cae7e0a534781b93f0d5bd802d7afc31c0297f2f5e31924
7
+ data.tar.gz: e0826bc7e9203ea5a6bf24f715b5b63d2b13a95c407a4d298cfd8b9f2f7c781afed10c69248774e8930b7a0f86cc1f569c75a9c2e3c00e689e3dffc4fe2f6e5d
@@ -1,9 +1,10 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 1.9.3
5
4
  - 2.0.0
6
- - 2.1.1
5
+ - 2.1
6
+ - 2.2.3
7
+ - 2.3.0
7
8
  - ruby-head
8
9
  - rbx
9
10
 
@@ -11,9 +12,13 @@ branches:
11
12
  only:
12
13
  - master
13
14
 
15
+ gemfile:
16
+ - Gemfile
17
+
14
18
  matrix:
15
19
  allow_failures:
16
20
  - rvm: ruby-head
17
21
  - rvm: rbx
18
22
 
23
+ before_install: gem update bundler
19
24
  script: bundle exec rake test
data/ChangeLog CHANGED
@@ -1,3 +1,10 @@
1
+ Release 0.4.0 - 2016/01/08
2
+
3
+ * Introduce <record> directive
4
+ * Support ${xxx} placeholders
5
+ https://github.com/repeatedly/fluent-plugin-record-modifier/pull/6
6
+
7
+
1
8
  Release 0.3.0 - 2015/06/09
2
9
 
3
10
  * Add record_modifier filter
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Output filter plugin for modifying each event record for [Fluentd](http://fluentd.org)
1
+ # Filter plugin for modifying each event record for [Fluentd](http://fluentd.org)
2
2
 
3
3
  Adding arbitary field to event record without custmizing existence plugin.
4
4
 
@@ -13,13 +13,16 @@ Use RubyGems:
13
13
 
14
14
  ## Configuration
15
15
 
16
- <match pattern>
17
- type record_modifier
18
- tag foo.filtered
16
+ Use `record_modifier` filter.
19
17
 
20
- gen_host ${hostname}
21
- foo bar
22
- </match>
18
+ <filter pattern>
19
+ @type record_modifier
20
+
21
+ <record>
22
+ gen_host ${hostname}
23
+ foo bar
24
+ </record>
25
+ </filter>
23
26
 
24
27
  If following record is passed:
25
28
 
@@ -33,6 +36,37 @@ then you got new record like below:
33
36
  {"message":"hello world!", "gen_host":"oreore-mac.local", "foo":"bar"}
34
37
  ```
35
38
 
39
+ You can also use `record_transformer` like `${xxx}` placeholders and access `tag`, `time`, `record` and `tag_parts` values by Ruby code.
40
+
41
+ <filter pattern>
42
+ @type record_modifier
43
+
44
+ <record>
45
+ tag ${tag}
46
+ tag_extract ${tag_parts[0]}-${tag_pars[1]}-foo
47
+ formatted_time ${Time.at(time).to_s}
48
+ new_field foo:${record['key1'] + record['dict']['key']}
49
+ </record>
50
+ </filter>
51
+
52
+ `record_modifier` is faster than `record_transformer`. See [this comment](https://github.com/repeatedly/fluent-plugin-record-modifier/pull/7#issuecomment-169843012).
53
+ But unlike `record_transformer`, `record_modifier` doesn't support following features for now.
54
+
55
+ - tag_suffix and tag_prefix
56
+ - dynamic key placeholder
57
+
58
+ ### record_modifier output
59
+
60
+ In v0.10, you can use `record_modifier` output to emulate filter. `record_modifier` output doesn't support `<record>` way.
61
+
62
+ <match pattern>
63
+ type record_modifier
64
+ tag foo.filtered
65
+
66
+ gen_host ${hostname}
67
+ foo bar
68
+ </match>
69
+
36
70
  ### char_encoding
37
71
 
38
72
  Fluentd including some plugins treats the logs as a BINARY by default to forward.
@@ -41,7 +75,7 @@ But an user sometimes processes the logs depends on their requirements, e.g. han
41
75
  `char_encoding` parameter is useful for this case.
42
76
 
43
77
  ```conf
44
- <match pattern>
78
+ <filter pattern>
45
79
  type record_modifier
46
80
 
47
81
  # set UTF-8 encoding information to string.
@@ -49,7 +83,7 @@ But an user sometimes processes the logs depends on their requirements, e.g. han
49
83
 
50
84
  # change char encoding from 'UTF-8' to 'EUC-JP'
51
85
  char_encoding utf-8:euc-jp
52
- </match>
86
+ </filter>
53
87
  ```
54
88
 
55
89
  ### remove_keys
@@ -58,12 +92,12 @@ The logs include needless record keys in some cases.
58
92
  You can remove it by using `remove_keys` parameter.
59
93
 
60
94
  ```conf
61
- <match pattern>
95
+ <filter pattern>
62
96
  type record_modifier
63
97
 
64
98
  # remove key1 and key2 keys from record
65
99
  remove_keys key1,key2
66
- </match>
100
+ </filter>
67
101
  ```
68
102
 
69
103
  If following record is passed:
@@ -80,7 +114,6 @@ then you got new record like below:
80
114
 
81
115
  ### Mixins
82
116
 
83
- * [SetTagKeyMixin](https://github.com/fluent/fluentd/blob/master/lib/fluent/mixin.rb#L181)
84
117
  * [fluent-mixin-config-placeholders](https://github.com/tagomoris/fluent-mixin-config-placeholders)
85
118
 
86
119
  ## TODO
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -20,4 +20,5 @@ Gem::Specification.new do |gem|
20
20
  gem.add_dependency "fluentd", [">= 0.10.58", "< 2"]
21
21
  gem.add_dependency "fluent-mixin-config-placeholders", ">= 0.3.0"
22
22
  gem.add_development_dependency "rake", ">= 0.9.2"
23
+ gem.add_development_dependency("test-unit", ["~> 3.1.4"])
23
24
  end
@@ -7,19 +7,23 @@ module Fluent
7
7
  config_param :char_encoding, :string, :default => nil
8
8
  config_param :remove_keys, :string, :default => nil
9
9
 
10
- include SetTagKeyMixin
11
10
  include Fluent::Mixin::ConfigPlaceholders
12
11
 
13
- BUILTIN_CONFIGURATIONS = %W(type @type log_level @log_level id @id include_tag_key tag_key char_encoding remove_keys)
12
+ BUILTIN_CONFIGURATIONS = %W(type @type log_level @log_level id @id char_encoding remove_keys)
14
13
 
15
14
  def configure(conf)
16
15
  super
17
16
 
17
+ if conf.has_key?('include_tag_key')
18
+ raise ConfigError, "include_tag_key and tag_key parameters are removed. Use 'tag ${tag}' in <record> section"
19
+ end
20
+
18
21
  @map = {}
19
22
  conf.each_pair { |k, v|
20
23
  unless BUILTIN_CONFIGURATIONS.include?(k)
21
24
  conf.has_key?(k)
22
- @map[k] = v
25
+ $log.warn "top level definition is deprecated. Please put parameters inside <record>: '#{k} #{v}'"
26
+ @map[k] = DynamicExpander.new(k, v)
23
27
  end
24
28
  }
25
29
 
@@ -39,33 +43,46 @@ module Fluent
39
43
  end
40
44
  end
41
45
 
46
+ @has_tag_parts = false
47
+ conf.elements.select { |element| element.name == 'record' }.each do |element|
48
+ element.each_pair do |k, v|
49
+ element.has_key?(k) # to suppress unread configuration warning
50
+ @has_tag_parts = true if v.include?('tag_parts')
51
+ @map[k] = DynamicExpander.new(k, v)
52
+ end
53
+ end
54
+
42
55
  if @remove_keys
43
- @remove_keys = @remove_keys.split(',').map {|e| e.strip }
56
+ @remove_keys = @remove_keys.split(',').map { |e| e.strip }
44
57
  end
45
- end
46
58
 
47
- def filter(tag, time, record)
48
- filter_record(tag, time, record)
49
- modify_record(record)
59
+ # Collect DynamicExpander related garbage instructions
60
+ GC.start
50
61
  end
51
62
 
52
- private
53
-
54
- def modify_record(record)
55
- @map.each_pair { |k, v|
56
- record[k] = v
57
- }
63
+ def filter_stream(tag, es)
64
+ new_es = MultiEventStream.new
65
+ tag_parts = @has_tag_parts ? tag.split('.') : nil
58
66
 
59
- if @remove_keys
60
- @remove_keys.each { |v|
61
- record.delete(v)
67
+ es.each { |time, record|
68
+ @map.each_pair { |k, v|
69
+ record[k] = v.expand(tag, time, record, tag_parts)
62
70
  }
63
- end
64
71
 
65
- record = change_encoding(record) if @char_encoding
66
- record
72
+ if @remove_keys
73
+ @remove_keys.each { |v|
74
+ record.delete(v)
75
+ }
76
+ end
77
+
78
+ record = change_encoding(record) if @char_encoding
79
+ new_es.add(time, record)
80
+ }
81
+ new_es
67
82
  end
68
83
 
84
+ private
85
+
69
86
  def set_encoding(record)
70
87
  record.each_pair { |k, v|
71
88
  if v.is_a?(String)
@@ -82,5 +99,53 @@ module Fluent
82
99
  end
83
100
  }
84
101
  end
102
+
103
+ class DynamicExpander
104
+ def initialize(param_key, param_value)
105
+ if param_value.include?('${')
106
+ __str_eval_code__ = parse_parameter(param_value)
107
+
108
+ # Use class_eval with string instead of define_method for performance.
109
+ # It can't share instructions but this is 2x+ faster than define_method in filter case.
110
+ # Refer: http://tenderlovemaking.com/2013/03/03/dynamic_method_definitions.html
111
+ (class << self; self; end).class_eval <<-EORUBY, __FILE__, __LINE__ + 1
112
+ def expand(tag, time, record, tag_parts)
113
+ #{__str_eval_code__}
114
+ end
115
+ EORUBY
116
+ else
117
+ @param_value = param_value
118
+ end
119
+
120
+ begin
121
+ # check eval genarates wrong code or not
122
+ expand(nil, nil, nil, nil)
123
+ rescue SyntaxError
124
+ raise ConfigError, "Pass invalid syntax parameter : key = #{param_key}, value = #{param_value}"
125
+ rescue
126
+ # Ignore other runtime errors
127
+ end
128
+ end
129
+
130
+ # Default implementation for fixed value. This is overwritten when parameter contains '${xxx}' placeholder
131
+ def expand(tag, time, record, tag_parts)
132
+ @param_value
133
+ end
134
+
135
+ private
136
+
137
+ def parse_parameter(value)
138
+ num_placeholders = value.scan('${').size
139
+ if num_placeholders == 1
140
+ if value.start_with?('${') && value.end_with?('}')
141
+ return value[2..-2]
142
+ else
143
+ "\"#{value.gsub('${', '#{')}\""
144
+ end
145
+ else
146
+ "\"#{value.gsub('${', '#{')}\""
147
+ end
148
+ end
149
+ end
85
150
  end if defined?(Filter)
86
151
  end
@@ -12,12 +12,14 @@ class RecordModifierFilterTest < Test::Unit::TestCase
12
12
 
13
13
  CONFIG = %[
14
14
  type record_modifier
15
-
16
- gen_host ${hostname}
17
- foo bar
18
- include_tag_key
19
- tag_key included_tag
20
15
  remove_keys hoge
16
+
17
+ <record>
18
+ gen_host ${hostname}
19
+ foo bar
20
+ included_tag ${tag}
21
+ tag_wrap -${tag_parts[0]}-${tag_parts[1]}-
22
+ </record>
21
23
  ]
22
24
 
23
25
  def create_driver(conf = CONFIG)
@@ -33,8 +35,9 @@ class RecordModifierFilterTest < Test::Unit::TestCase
33
35
  d = create_driver
34
36
  map = d.instance.instance_variable_get(:@map)
35
37
 
36
- assert_equal get_hostname, map['gen_host']
37
- assert_equal 'bar', map['foo']
38
+ map.each_pair { |k, v|
39
+ assert v.is_a?(Fluent::RecordModifierFilter::DynamicExpander)
40
+ }
38
41
  end
39
42
 
40
43
  def test_format
@@ -45,7 +48,7 @@ class RecordModifierFilterTest < Test::Unit::TestCase
45
48
  d.emit("a" => 2)
46
49
  end
47
50
 
48
- mapped = {'gen_host' => get_hostname, 'foo' => 'bar', 'included_tag' => @tag}
51
+ mapped = {'gen_host' => get_hostname, 'foo' => 'bar', 'included_tag' => @tag, 'tag_wrap' => "-#{@tag.split('.')[0]}-#{@tag.split('.')[1]}-"}
49
52
  assert_equal [
50
53
  {"a" => 1}.merge(mapped),
51
54
  {"a" => 2}.merge(mapped),
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-record-modifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Nakagawa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-09 00:00:00.000000000 Z
11
+ date: 2016-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -58,6 +58,20 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: 0.9.2
61
+ - !ruby/object:Gem::Dependency
62
+ name: test-unit
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 3.1.4
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 3.1.4
61
75
  description: Output filter plugin for modifying each event record
62
76
  email: repeatedly@gmail.com
63
77
  executables: []