fluent-plugin-file-alternative 0.1.2 → 0.1.3
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/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
File output plugin alternative implementation, **is 100% compatible with fluentd built-in 'out_file'**, and added many options to format output as you want.
|
4
4
|
|
5
|
-
FileAlternativeOutput slices data by time (for specified units), and store these data as plain text on
|
5
|
+
FileAlternativeOutput slices data by time (for specified units), and store these data as plain text on local file. You can specify to:
|
6
6
|
|
7
7
|
* format whole data as serialized JSON, single attribute or separated multi attributes
|
8
8
|
* include time as line header, or not
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
4
|
gem.name = "fluent-plugin-file-alternative"
|
5
|
-
gem.version = "0.1.
|
5
|
+
gem.version = "0.1.3"
|
6
6
|
|
7
7
|
gem.authors = ["TAGOMORI Satoshi"]
|
8
8
|
gem.email = ["tagomoris@gmail.com"]
|
@@ -16,5 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
|
18
18
|
gem.add_development_dependency "fluentd"
|
19
|
+
gem.add_development_dependency "fluent-mixin-plaintextformatter"
|
19
20
|
gem.add_runtime_dependency "fluentd"
|
21
|
+
gem.add_runtime_dependency "fluent-mixin-plaintextformatter"
|
20
22
|
end
|
@@ -1,207 +1,4 @@
|
|
1
|
-
|
2
|
-
module FluentExt::PlainTextFormatterMixin
|
3
|
-
# config_param :output_data_type, :string, :default => 'json' # or 'attr:field' or 'attr:field1,field2,field3(...)'
|
4
|
-
|
5
|
-
attr_accessor :output_include_time, :output_include_tag, :output_data_type
|
6
|
-
attr_accessor :add_newline, :field_separator
|
7
|
-
attr_accessor :remove_prefix, :default_tag
|
8
|
-
|
9
|
-
attr_accessor :f_separator
|
10
|
-
|
11
|
-
def configure(conf)
|
12
|
-
super
|
13
|
-
|
14
|
-
@output_include_time = Fluent::Config.bool_value(conf['output_include_time'])
|
15
|
-
@output_include_time = true if @output_include_time.nil?
|
16
|
-
|
17
|
-
@output_include_tag = Fluent::Config.bool_value(conf['output_include_tag'])
|
18
|
-
@output_include_tag = true if @output_include_tag.nil?
|
19
|
-
|
20
|
-
@output_data_type = conf['output_data_type']
|
21
|
-
@output_data_type = 'json' if @output_data_type.nil?
|
22
|
-
|
23
|
-
@f_separator = case conf['field_separator']
|
24
|
-
when 'SPACE' then ' '
|
25
|
-
when 'COMMA' then ','
|
26
|
-
else "\t"
|
27
|
-
end
|
28
|
-
@add_newline = Fluent::Config.bool_value(conf['add_newline'])
|
29
|
-
if @add_newline.nil?
|
30
|
-
@add_newline = true
|
31
|
-
end
|
32
|
-
|
33
|
-
@remove_prefix = conf['remove_prefix']
|
34
|
-
if @remove_prefix
|
35
|
-
@removed_prefix_string = @remove_prefix + '.'
|
36
|
-
@removed_length = @removed_prefix_string.length
|
37
|
-
end
|
38
|
-
if @output_include_tag and @remove_prefix and @remove_prefix.length > 0
|
39
|
-
@default_tag = conf['default_tag']
|
40
|
-
if @default_tag.nil? or @default_tag.length < 1
|
41
|
-
raise Fluent::ConfigError, "Missing 'default_tag' with output_include_tag and remove_prefix."
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# default timezone: utc
|
46
|
-
if conf['localtime'].nil? and conf['utc'].nil?
|
47
|
-
@utc = true
|
48
|
-
@localtime = false
|
49
|
-
elsif not @localtime and not @utc
|
50
|
-
@utc = true
|
51
|
-
@localtime = false
|
52
|
-
end
|
53
|
-
# mix-in default time formatter (or you can overwrite @timef on your own configure)
|
54
|
-
@timef = @output_include_time ? Fluent::TimeFormatter.new(@time_format, @localtime) : nil
|
55
|
-
|
56
|
-
@custom_attributes = []
|
57
|
-
if @output_data_type == 'json'
|
58
|
-
self.instance_eval {
|
59
|
-
def stringify_record(record)
|
60
|
-
record.to_json
|
61
|
-
end
|
62
|
-
}
|
63
|
-
elsif @output_data_type =~ /^attr:(.*)$/
|
64
|
-
@custom_attributes = $1.split(',')
|
65
|
-
if @custom_attributes.size > 1
|
66
|
-
self.instance_eval {
|
67
|
-
def stringify_record(record)
|
68
|
-
@custom_attributes.map{|attr| (record[attr] || 'NULL').to_s}.join(@f_separator)
|
69
|
-
end
|
70
|
-
}
|
71
|
-
elsif @custom_attributes.size == 1
|
72
|
-
self.instance_eval {
|
73
|
-
def stringify_record(record)
|
74
|
-
(record[@custom_attributes[0]] || 'NULL').to_s
|
75
|
-
end
|
76
|
-
}
|
77
|
-
else
|
78
|
-
raise Fluent::ConfigError, "Invalid attributes specification: '#{@output_data_type}', needs one or more attributes."
|
79
|
-
end
|
80
|
-
else
|
81
|
-
raise Fluent::ConfigError, "Invalid output_data_type: '#{@output_data_type}'. specify 'json' or 'attr:ATTRIBUTE_NAME' or 'attr:ATTR1,ATTR2,...'"
|
82
|
-
end
|
83
|
-
|
84
|
-
if @output_include_time and @output_include_tag
|
85
|
-
if @add_newline and @remove_prefix
|
86
|
-
self.instance_eval {
|
87
|
-
def format(tag,time,record)
|
88
|
-
if (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or
|
89
|
-
tag == @remove_prefix
|
90
|
-
tag = tag[@removed_length..-1] || @default_tag
|
91
|
-
end
|
92
|
-
@timef.format(time) + @f_separator + tag + @f_separator + stringify_record(record) + "\n"
|
93
|
-
end
|
94
|
-
}
|
95
|
-
elsif @add_newline
|
96
|
-
self.instance_eval {
|
97
|
-
def format(tag,time,record)
|
98
|
-
@timef.format(time) + @f_separator + tag + @f_separator + stringify_record(record) + "\n"
|
99
|
-
end
|
100
|
-
}
|
101
|
-
elsif @remove_prefix
|
102
|
-
self.instance_eval {
|
103
|
-
def format(tag,time,record)
|
104
|
-
if (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or
|
105
|
-
tag == @remove_prefix
|
106
|
-
tag = tag[@removed_length..-1] || @default_tag
|
107
|
-
end
|
108
|
-
@timef.format(time) + @f_separator + tag + @f_separator + stringify_record(record)
|
109
|
-
end
|
110
|
-
}
|
111
|
-
else
|
112
|
-
self.instance_eval {
|
113
|
-
def format(tag,time,record)
|
114
|
-
@timef.format(time) + @f_separator + tag + @f_separator + stringify_record(record)
|
115
|
-
end
|
116
|
-
}
|
117
|
-
end
|
118
|
-
elsif @output_include_time
|
119
|
-
if @add_newline
|
120
|
-
self.instance_eval {
|
121
|
-
def format(tag,time,record);
|
122
|
-
@timef.format(time) + @f_separator + stringify_record(record) + "\n"
|
123
|
-
end
|
124
|
-
}
|
125
|
-
else
|
126
|
-
self.instance_eval {
|
127
|
-
def format(tag,time,record);
|
128
|
-
@timef.format(time) + @f_separator + stringify_record(record)
|
129
|
-
end
|
130
|
-
}
|
131
|
-
end
|
132
|
-
elsif @output_include_tag
|
133
|
-
if @add_newline and @remove_prefix
|
134
|
-
self.instance_eval {
|
135
|
-
def format(tag,time,record)
|
136
|
-
if (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or
|
137
|
-
tag == @remove_prefix
|
138
|
-
tag = tag[@removed_length..-1] || @default_tag
|
139
|
-
end
|
140
|
-
tag + @f_separator + stringify_record(record) + "\n"
|
141
|
-
end
|
142
|
-
}
|
143
|
-
elsif @add_newline
|
144
|
-
self.instance_eval {
|
145
|
-
def format(tag,time,record)
|
146
|
-
tag + @f_separator + stringify_record(record) + "\n"
|
147
|
-
end
|
148
|
-
}
|
149
|
-
elsif @remove_prefix
|
150
|
-
self.instance_eval {
|
151
|
-
def format(tag,time,record)
|
152
|
-
if (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or
|
153
|
-
tag == @remove_prefix
|
154
|
-
tag = tag[@removed_length..-1] || @default_tag
|
155
|
-
end
|
156
|
-
tag + @f_separator + stringify_record(record)
|
157
|
-
end
|
158
|
-
}
|
159
|
-
else
|
160
|
-
self.instance_eval {
|
161
|
-
def format(tag,time,record)
|
162
|
-
tag + @f_separator + stringify_record(record)
|
163
|
-
end
|
164
|
-
}
|
165
|
-
end
|
166
|
-
else # without time, tag
|
167
|
-
if @add_newline
|
168
|
-
self.instance_eval {
|
169
|
-
def format(tag,time,record);
|
170
|
-
stringify_record(record) + "\n"
|
171
|
-
end
|
172
|
-
}
|
173
|
-
else
|
174
|
-
self.instance_eval {
|
175
|
-
def format(tag,time,record);
|
176
|
-
stringify_record(record)
|
177
|
-
end
|
178
|
-
}
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def stringify_record(record)
|
184
|
-
record.to_json
|
185
|
-
end
|
186
|
-
|
187
|
-
def format(tag, time, record)
|
188
|
-
if tag == @remove_prefix or (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length)
|
189
|
-
tag = tag[@removed_length..-1] || @default_tag
|
190
|
-
end
|
191
|
-
time_str = if @output_include_time
|
192
|
-
@timef.format(time) + @f_separator
|
193
|
-
else
|
194
|
-
''
|
195
|
-
end
|
196
|
-
tag_str = if @output_include_tag
|
197
|
-
tag + @f_separator
|
198
|
-
else
|
199
|
-
''
|
200
|
-
end
|
201
|
-
time_str + tag_str + stringify_record(record) + "\n"
|
202
|
-
end
|
203
|
-
|
204
|
-
end
|
1
|
+
require 'fluent/mixin/plaintextformatter'
|
205
2
|
|
206
3
|
class Fluent::FileAlternativeOutput < Fluent::TimeSlicedOutput
|
207
4
|
Fluent::Plugin.register_output('file_alternative', self)
|
@@ -215,8 +12,6 @@ class Fluent::FileAlternativeOutput < Fluent::TimeSlicedOutput
|
|
215
12
|
|
216
13
|
config_param :path, :string # /path/pattern/to/hdfs/file can use %Y %m %d %H %M %S
|
217
14
|
|
218
|
-
config_param :time_format, :string, :default => nil
|
219
|
-
|
220
15
|
config_param :compress, :default => nil do |val|
|
221
16
|
c = SUPPORTED_COMPRESS[val.to_sym]
|
222
17
|
unless c
|
@@ -225,14 +20,7 @@ class Fluent::FileAlternativeOutput < Fluent::TimeSlicedOutput
|
|
225
20
|
c
|
226
21
|
end
|
227
22
|
|
228
|
-
include
|
229
|
-
|
230
|
-
config_set_default :output_include_time, true
|
231
|
-
config_set_default :output_include_tag, true
|
232
|
-
config_set_default :output_data_type, 'json'
|
233
|
-
config_set_default :field_separator, "\t"
|
234
|
-
config_set_default :add_newline, true
|
235
|
-
config_set_default :remove_prefix, nil
|
23
|
+
include Fluent::Mixin::PlainTextFormatter
|
236
24
|
|
237
25
|
def initialize
|
238
26
|
super
|
@@ -272,8 +60,6 @@ class Fluent::FileAlternativeOutput < Fluent::TimeSlicedOutput
|
|
272
60
|
unless @path.index('/') == 0
|
273
61
|
raise Fluent::ConfigError, "Path on filesystem MUST starts with '/', but '#{@path}'"
|
274
62
|
end
|
275
|
-
|
276
|
-
@timef = Fluent::TimeFormatter.new(@time_format, @localtime)
|
277
63
|
end
|
278
64
|
|
279
65
|
def start
|
@@ -290,10 +76,8 @@ class Fluent::FileAlternativeOutput < Fluent::TimeSlicedOutput
|
|
290
76
|
record.to_json
|
291
77
|
end
|
292
78
|
|
293
|
-
def format(tag, time, record)
|
294
|
-
|
295
|
-
time_str + @f_separator + tag + @f_separator + record_to_string(record) + @line_end
|
296
|
-
end
|
79
|
+
# def format(tag, time, record)
|
80
|
+
# end
|
297
81
|
|
298
82
|
def path_format(chunk_key)
|
299
83
|
suffix = case @compress
|
@@ -36,7 +36,7 @@ class FileAlternativeOutputTest < Test::Unit::TestCase
|
|
36
36
|
assert_equal true, d.instance.output_include_tag
|
37
37
|
assert_equal 'json', d.instance.output_data_type
|
38
38
|
assert_equal true, d.instance.add_newline
|
39
|
-
assert_equal "
|
39
|
+
assert_equal "TAB", d.instance.field_separator
|
40
40
|
assert_nil d.instance.remove_prefix
|
41
41
|
end
|
42
42
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-file-alternative
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: fluent-mixin-plaintextformatter
|
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'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: fluentd
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,6 +59,22 @@ dependencies:
|
|
43
59
|
- - ! '>='
|
44
60
|
- !ruby/object:Gem::Version
|
45
61
|
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: fluent-mixin-plaintextformatter
|
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'
|
46
78
|
description: alternative implementation of out_file, with various configurations
|
47
79
|
email:
|
48
80
|
- tagomoris@gmail.com
|