fluent-plugin-remove-empty 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c27b47de51f0e72ef214b0d5c1951bd9922168d5
4
+ data.tar.gz: 2601881938c556aa5b6478ab1363afb12d1abfa8
5
+ SHA512:
6
+ metadata.gz: 1dc1429b3686c5f6c498f202a57dc9b09fc15f443880b0623602aac247e0eee5ee3dddccbd2976dddc2b3db79a38415fb73dc494ca348e465d9207a2e825afb7
7
+ data.tar.gz: ef9cb7638d5c22438bae04da151efc50183d438357b10417ca7ee2de77ee981eae879ad1c96dd01fd4958a2a872fe4f5e99ddfc14f30a90b757cabda1bee0380
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,9 @@
1
+ # fluent-plugin-remove-empty
2
+
3
+ Fluentd plugin to remove empty fields of a event record
4
+
5
+ ## Installation
6
+
7
+ Use RubyGems:
8
+
9
+ gem install fluent-plugin-remove-empty
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "fluent-plugin-remove-empty"
6
+ gem.version = "0.0.1"
7
+ gem.authors = ["Chadin Anuwattanaporn"]
8
+ gem.email = "chadin@sogamo.com"
9
+ gem.homepage = "https://github.com/newcmd001/fluent-plugin-remove-empty"
10
+ gem.description = "Fluentd plugin to remove empty fields of a event record"
11
+ gem.summary = gem.description
12
+ gem.licenses = ["MIT"]
13
+ gem.has_rdoc = false
14
+
15
+ gem.files = `git ls-files`.split("\n")
16
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency "fluentd", "~> 0.10.17"
21
+ gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "rspec"
23
+ gem.add_development_dependency "pry"
24
+ gem.add_development_dependency "pry-nav"
25
+ end
@@ -0,0 +1,176 @@
1
+ require 'socket'
2
+ require 'ostruct'
3
+
4
+ module Fluent
5
+ class RemoveEmptyOutput < Output
6
+ Fluent::Plugin.register_output('remove_empty', self)
7
+
8
+ def initialize
9
+ super
10
+ end
11
+
12
+ config_param :tag, :string, :default => nil
13
+
14
+ BUILTIN_CONFIGURATIONS = %W(type tag)
15
+
16
+ # To support log_level option implemented by Fluentd v0.10.43
17
+ unless method_defined?(:log)
18
+ define_method("log") { $log }
19
+ end
20
+
21
+ def configure(conf)
22
+ super
23
+
24
+ @map = {}
25
+ conf.each_pair { |k, v|
26
+ next if BUILTIN_CONFIGURATIONS.include?(k)
27
+ conf.has_key?(k) # to suppress unread configuration warning
28
+ @map[k] = v
29
+ }
30
+
31
+ if @tag.nil?
32
+ raise Fluent::ConfigError, "out_remove_empty: `tag` must be specified"
33
+ end
34
+
35
+ @placeholder_expander =
36
+ if @enable_ruby
37
+ # require utilities which would be used in ruby placeholders
38
+ require 'pathname'
39
+ require 'uri'
40
+ require 'cgi'
41
+ RubyPlaceholderExpander.new(log)
42
+ else
43
+ PlaceholderExpander.new(log)
44
+ end
45
+
46
+ @hostname = Socket.gethostname
47
+ end
48
+
49
+ def emit(tag, es, chain)
50
+ tag_parts = tag.split('.')
51
+ tag_prefix = tag_prefix(tag_parts)
52
+ tag_suffix = tag_suffix(tag_parts)
53
+ placeholders = {
54
+ 'tag' => tag,
55
+ 'tags' => tag_parts,
56
+ 'tag_parts' => tag_parts,
57
+ 'tag_prefix' => tag_prefix,
58
+ 'tag_suffix' => tag_suffix,
59
+ 'hostname' => @hostname,
60
+ }
61
+ last_record = nil
62
+ es.each {|time, record|
63
+ last_record = record # for debug log
64
+ new_tag, new_record = reform(@tag, time, record, placeholders)
65
+ Engine.emit(new_tag, time, new_record)
66
+ }
67
+ chain.next
68
+ rescue => e
69
+ log.warn "remove_empty: #{e.class} #{e.message} #{e.backtrace.first}"
70
+ log.debug "remove_empty: tag:#{@tag} map:#{@map} record:#{last_record} placeholders:#{placeholders}"
71
+ end
72
+
73
+ private
74
+
75
+ def reform(tag, time, record, opts)
76
+ @placeholder_expander.prepare_placeholders(time, record, opts)
77
+ new_tag = @placeholder_expander.expand(tag)
78
+
79
+ new_record = record.dup
80
+ new_record.each_key do |k|
81
+ if new_record[k] == ""
82
+ new_record.delete(k)
83
+ end
84
+ end
85
+
86
+ [new_tag, new_record]
87
+ end
88
+
89
+ def tag_prefix(tag_parts)
90
+ return [] if tag_parts.empty?
91
+ tag_prefix = [tag_parts.first]
92
+ 1.upto(tag_parts.size-1).each do |i|
93
+ tag_prefix[i] = "#{tag_prefix[i-1]}.#{tag_parts[i]}"
94
+ end
95
+ tag_prefix
96
+ end
97
+
98
+ def tag_suffix(tag_parts)
99
+ return [] if tag_parts.empty?
100
+ rev_tag_parts = tag_parts.reverse
101
+ rev_tag_suffix = [rev_tag_parts.first]
102
+ 1.upto(tag_parts.size-1).each do |i|
103
+ rev_tag_suffix[i] = "#{rev_tag_parts[i]}.#{rev_tag_suffix[i-1]}"
104
+ end
105
+ rev_tag_suffix.reverse
106
+ end
107
+
108
+ class PlaceholderExpander
109
+ attr_reader :placeholders, :log
110
+
111
+ def initialize(log)
112
+ @log = log
113
+ end
114
+
115
+ def prepare_placeholders(time, record, opts)
116
+ placeholders = { '${time}' => Time.at(time).to_s }
117
+ record.each {|key, value| placeholders.store("${#{key}}", value) }
118
+
119
+ opts.each do |key, value|
120
+ if value.kind_of?(Array) # tag_parts, etc
121
+ size = value.size
122
+ value.each_with_index { |v, idx|
123
+ placeholders.store("${#{key}[#{idx}]}", v)
124
+ placeholders.store("${#{key}[#{idx-size}]}", v) # support [-1]
125
+ }
126
+ else # string, interger, float, and others?
127
+ placeholders.store("${#{key}}", value)
128
+ end
129
+ end
130
+
131
+ @placeholders = placeholders
132
+ end
133
+
134
+ def expand(str)
135
+ str.gsub(/(\${[a-z_]+(\[-?[0-9]+\])?}|__[A-Z_]+__)/) {
136
+ log.warn "remove_empty: unknown placeholder `#{$1}` found" unless @placeholders.include?($1)
137
+ @placeholders[$1]
138
+ }
139
+ end
140
+ end
141
+
142
+ class RubyPlaceholderExpander
143
+ attr_reader :placeholders, :log
144
+
145
+ def initialize(log)
146
+ @log = log
147
+ end
148
+
149
+ # Get placeholders as a struct
150
+ #
151
+ # @param [Time] time the time
152
+ # @param [Hash] record the record
153
+ # @param [Hash] opts others
154
+ def prepare_placeholders(time, record, opts)
155
+ struct = UndefOpenStruct.new(record)
156
+ struct.time = Time.at(time)
157
+ opts.each {|key, value| struct.__send__("#{key}=", value) }
158
+ @placeholders = struct
159
+ end
160
+
161
+ # Replace placeholders in a string
162
+ #
163
+ # @param [String] str the string to be replaced
164
+ def expand(str)
165
+ str = str.gsub(/\$\{([^}]+)\}/, '#{\1}') # ${..} => #{..}
166
+ eval "\"#{str}\"", @placeholders.instance_eval { binding }
167
+ end
168
+
169
+ class UndefOpenStruct < OpenStruct
170
+ (Object.instance_methods).each do |m|
171
+ undef_method m unless m.to_s =~ /^__|respond_to_missing\?|object_id|public_methods|instance_eval|method_missing|define_singleton_method|respond_to\?|new_ostruct_member/
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-remove-empty
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chadin Anuwattanaporn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.17
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.17
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-nav
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Fluentd plugin to remove empty fields of a event record
84
+ email: chadin@sogamo.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - Gemfile
90
+ - README.md
91
+ - fluent-plugin-remove-empty.gemspec
92
+ - lib/fluent/plugin/out_remove_empty.rb
93
+ homepage: https://github.com/newcmd001/fluent-plugin-remove-empty
94
+ licenses:
95
+ - MIT
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.0.14
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Fluentd plugin to remove empty fields of a event record
117
+ test_files: []