fluentd 0.10.62 → 0.12.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +1 -2
- data/.travis.yml +0 -4
- data/ChangeLog +0 -72
- data/Gemfile +0 -6
- data/Rakefile +12 -3
- data/example/in_http.conf +14 -0
- data/example/in_syslog.conf +15 -0
- data/example/in_tail.conf +14 -0
- data/example/in_tcp.conf +13 -0
- data/example/in_udp.conf +13 -0
- data/example/out_copy.conf +20 -0
- data/example/out_file.conf +13 -0
- data/example/out_forward.conf +30 -0
- data/fluent.conf +2 -12
- data/fluentd.gemspec +8 -11
- data/lib/fluent/agent.rb +180 -0
- data/lib/fluent/buffer.rb +6 -12
- data/lib/fluent/command/cat.rb +1 -3
- data/lib/fluent/command/debug.rb +1 -3
- data/lib/fluent/command/fluentd.rb +0 -10
- data/lib/fluent/config.rb +9 -3
- data/lib/fluent/config/basic_parser.rb +1 -6
- data/lib/fluent/config/configure_proxy.rb +25 -61
- data/lib/fluent/config/dsl.rb +16 -0
- data/lib/fluent/config/element.rb +21 -2
- data/lib/fluent/config/error.rb +16 -0
- data/lib/fluent/config/literal_parser.rb +9 -27
- data/lib/fluent/config/parser.rb +16 -0
- data/lib/fluent/config/section.rb +16 -2
- data/lib/fluent/config/types.rb +16 -1
- data/lib/fluent/config/v1_parser.rb +4 -12
- data/lib/fluent/configurable.rb +16 -0
- data/lib/fluent/engine.rb +43 -163
- data/lib/fluent/env.rb +16 -1
- data/lib/fluent/event.rb +20 -48
- data/lib/fluent/event_router.rb +187 -0
- data/lib/fluent/filter.rb +32 -0
- data/lib/fluent/formatter.rb +29 -101
- data/lib/fluent/input.rb +6 -4
- data/lib/fluent/label.rb +18 -0
- data/lib/fluent/load.rb +1 -3
- data/lib/fluent/log.rb +1 -3
- data/lib/fluent/match.rb +12 -19
- data/lib/fluent/mixin.rb +9 -25
- data/lib/fluent/output.rb +27 -45
- data/lib/fluent/parser.rb +93 -99
- data/lib/fluent/plugin.rb +22 -48
- data/lib/fluent/plugin/buf_file.rb +10 -7
- data/lib/fluent/plugin/buf_memory.rb +2 -3
- data/lib/fluent/plugin/buf_zfile.rb +75 -0
- data/lib/fluent/plugin/exec_util.rb +16 -0
- data/lib/fluent/plugin/in_debug_agent.rb +2 -3
- data/lib/fluent/plugin/in_exec.rb +2 -9
- data/lib/fluent/plugin/in_forward.rb +4 -22
- data/lib/fluent/plugin/in_gc_stat.rb +2 -3
- data/lib/fluent/plugin/in_http.rb +19 -59
- data/lib/fluent/plugin/in_monitor_agent.rb +21 -47
- data/lib/fluent/plugin/in_object_space.rb +2 -3
- data/lib/fluent/plugin/in_status.rb +2 -3
- data/lib/fluent/plugin/in_stream.rb +6 -16
- data/lib/fluent/plugin/in_syslog.rb +8 -17
- data/lib/fluent/plugin/in_tail.rb +17 -24
- data/lib/fluent/plugin/in_tcp.rb +16 -0
- data/lib/fluent/plugin/in_udp.rb +16 -0
- data/lib/fluent/plugin/out_copy.rb +3 -4
- data/lib/fluent/plugin/out_exec.rb +2 -4
- data/lib/fluent/plugin/out_exec_filter.rb +2 -13
- data/lib/fluent/plugin/out_file.rb +5 -6
- data/lib/fluent/plugin/out_forward.rb +4 -5
- data/lib/fluent/plugin/out_null.rb +2 -3
- data/lib/fluent/plugin/out_relabel.rb +26 -0
- data/lib/fluent/plugin/out_roundrobin.rb +3 -4
- data/lib/fluent/plugin/out_stdout.rb +2 -3
- data/lib/fluent/plugin/out_stream.rb +2 -3
- data/{test/scripts → lib}/fluent/plugin/out_test.rb +2 -3
- data/lib/fluent/plugin/socket_util.rb +19 -10
- data/lib/fluent/process.rb +4 -6
- data/lib/fluent/registry.rb +16 -0
- data/lib/fluent/root_agent.rb +212 -0
- data/lib/fluent/status.rb +2 -3
- data/lib/fluent/supervisor.rb +33 -54
- data/lib/fluent/test.rb +16 -0
- data/lib/fluent/test/base.rb +3 -17
- data/lib/fluent/test/input_test.rb +52 -7
- data/lib/fluent/test/output_test.rb +4 -20
- data/lib/fluent/version.rb +17 -1
- data/spec/config/config_parser_spec.rb +314 -0
- data/spec/config/configurable_spec.rb +524 -0
- data/spec/config/configure_proxy_spec.rb +96 -0
- data/spec/config/dsl_spec.rb +239 -0
- data/spec/config/helper.rb +49 -0
- data/spec/config/literal_parser_spec.rb +222 -0
- data/spec/config/section_spec.rb +97 -0
- data/spec/config/system_config_spec.rb +49 -0
- data/test/helper.rb +0 -25
- data/test/plugin/test_in_exec.rb +1 -1
- data/test/plugin/test_in_forward.rb +2 -1
- data/test/plugin/test_in_gc_stat.rb +1 -1
- data/test/plugin/test_in_http.rb +3 -78
- data/test/plugin/test_in_object_space.rb +1 -1
- data/test/plugin/test_in_status.rb +1 -1
- data/test/plugin/test_in_stream.rb +2 -1
- data/test/plugin/test_in_syslog.rb +2 -1
- data/test/plugin/test_in_tail.rb +6 -11
- data/test/plugin/test_in_tcp.rb +2 -1
- data/test/plugin/test_in_udp.rb +2 -1
- data/test/plugin/test_out_copy.rb +1 -12
- data/test/plugin/test_out_exec.rb +1 -1
- data/test/plugin/test_out_exec_filter.rb +1 -1
- data/test/plugin/test_out_file.rb +7 -96
- data/test/plugin/test_out_forward.rb +2 -1
- data/test/plugin/test_out_roundrobin.rb +1 -12
- data/test/plugin/test_out_stdout.rb +1 -1
- data/test/plugin/test_out_stream.rb +2 -1
- data/test/scripts/fluent/plugin/formatter_known.rb +1 -4
- data/test/scripts/fluent/plugin/parser_known.rb +1 -2
- data/test/test_config.rb +1 -1
- data/test/test_configdsl.rb +2 -1
- data/test/test_formatter.rb +3 -395
- data/test/test_match.rb +2 -1
- data/test/test_mixin.rb +3 -75
- data/test/test_output.rb +1 -112
- data/test/test_parser.rb +85 -152
- metadata +58 -167
- data/example/v1_literal_example.conf +0 -36
- data/lib/fluent/plugin/in_dummy.rb +0 -103
- data/lib/fluent/timezone.rb +0 -131
- data/test/config/assertions.rb +0 -42
- data/test/config/test_config_parser.rb +0 -389
- data/test/config/test_configurable.rb +0 -652
- data/test/config/test_configure_proxy.rb +0 -99
- data/test/config/test_dsl.rb +0 -237
- data/test/config/test_literal_parser.rb +0 -295
- data/test/config/test_section.rb +0 -112
- data/test/config/test_system_config.rb +0 -99
- data/test/config/test_types.rb +0 -63
- data/test/plugin/test_in_dummy.rb +0 -95
- data/test/test_event.rb +0 -168
- data/test/test_input.rb +0 -21
data/lib/fluent/event.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# Copyright (C) 2011 FURUHASHI Sadayuki
|
2
|
+
# Fluentd
|
5
3
|
#
|
6
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
5
|
# you may not use this file except in compliance with the License.
|
@@ -15,6 +13,7 @@
|
|
15
13
|
# See the License for the specific language governing permissions and
|
16
14
|
# limitations under the License.
|
17
15
|
#
|
16
|
+
|
18
17
|
module Fluent
|
19
18
|
class EventStream
|
20
19
|
include Enumerable
|
@@ -28,11 +27,11 @@ module Fluent
|
|
28
27
|
end
|
29
28
|
|
30
29
|
def to_msgpack_stream
|
31
|
-
out =
|
30
|
+
out = ''
|
32
31
|
each {|time,record|
|
33
32
|
[time,record].to_msgpack(out)
|
34
33
|
}
|
35
|
-
out
|
34
|
+
out
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
@@ -67,7 +66,7 @@ module Fluent
|
|
67
66
|
end
|
68
67
|
|
69
68
|
def dup
|
70
|
-
entries = @entries.map
|
69
|
+
entries = @entries.map(:dup)
|
71
70
|
ArrayEventStream.new(entries)
|
72
71
|
end
|
73
72
|
|
@@ -132,53 +131,26 @@ module Fluent
|
|
132
131
|
end
|
133
132
|
end
|
134
133
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
@data = data
|
140
|
-
end
|
141
|
-
|
142
|
-
def repeatable?
|
143
|
-
true
|
144
|
-
end
|
145
|
-
|
146
|
-
def each(&block)
|
147
|
-
# TODO format check
|
148
|
-
unpacker = MessagePack::Unpacker.new
|
149
|
-
unpacker.feed_each(@data, &block)
|
150
|
-
nil
|
151
|
-
end
|
152
|
-
|
153
|
-
def to_msgpack_stream
|
154
|
-
@data
|
155
|
-
end
|
134
|
+
class MessagePackEventStream < EventStream
|
135
|
+
# Keep cached_unpacker argument for existence plugins
|
136
|
+
def initialize(data, cached_unpacker = nil)
|
137
|
+
@data = data
|
156
138
|
end
|
157
139
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
def initialize(data, cached_unpacker=nil)
|
162
|
-
@data = data
|
163
|
-
@unpacker = cached_unpacker || MessagePack::Unpacker.new
|
164
|
-
end
|
165
|
-
|
166
|
-
def repeatable?
|
167
|
-
true
|
168
|
-
end
|
169
|
-
|
170
|
-
def each(&block)
|
171
|
-
@unpacker.reset
|
172
|
-
# TODO format check
|
173
|
-
@unpacker.feed_each(@data, &block)
|
174
|
-
nil
|
175
|
-
end
|
140
|
+
def repeatable?
|
141
|
+
true
|
142
|
+
end
|
176
143
|
|
177
|
-
|
178
|
-
|
179
|
-
|
144
|
+
def each(&block)
|
145
|
+
# TODO format check
|
146
|
+
unpacker = MessagePack::Unpacker.new
|
147
|
+
unpacker.feed_each(@data, &block)
|
148
|
+
nil
|
180
149
|
end
|
181
150
|
|
151
|
+
def to_msgpack_stream
|
152
|
+
@data
|
153
|
+
end
|
182
154
|
end
|
183
155
|
end
|
184
156
|
|
@@ -0,0 +1,187 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
module Fluent
|
17
|
+
require 'fluent/match'
|
18
|
+
|
19
|
+
#
|
20
|
+
# EventRouter is responsible to route events to a collector.
|
21
|
+
#
|
22
|
+
# It has a list of MatchPattern and Collector pairs:
|
23
|
+
#
|
24
|
+
# +----------------+ +-----------------+
|
25
|
+
# | MatchPattern | | Collector |
|
26
|
+
# +----------------+ +-----------------+
|
27
|
+
# | access.** ---------> type forward |
|
28
|
+
# | logs.** ---------> type copy |
|
29
|
+
# | archive.** ---------> type s3 |
|
30
|
+
# +----------------+ +-----------------+
|
31
|
+
#
|
32
|
+
# EventRouter does:
|
33
|
+
#
|
34
|
+
# 1) receive an event at `#emit` methods
|
35
|
+
# 2) match the event's tag with the MatchPatterns
|
36
|
+
# 3) forward the event to the corresponding Collector
|
37
|
+
#
|
38
|
+
# Collector is either of Output, Filter or other EventRouter.
|
39
|
+
#
|
40
|
+
class EventRouter
|
41
|
+
def initialize(emit_error_handler, default_collector)
|
42
|
+
@match_rules = []
|
43
|
+
@match_cache = MatchCache.new
|
44
|
+
@default_collector = default_collector
|
45
|
+
@emit_error_handler = emit_error_handler || RaiseEmitErrorHandler.new
|
46
|
+
@chain = NullOutputChain.instance
|
47
|
+
end
|
48
|
+
|
49
|
+
# Agent implements EmitErrorHandler. See 'fluentd/agent.rb'
|
50
|
+
class RaiseEmitErrorHandler
|
51
|
+
def handle_emits_error(tag, es, error)
|
52
|
+
raise error
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_accessor :default_collector
|
57
|
+
attr_accessor :emit_error_handler
|
58
|
+
|
59
|
+
class Rule
|
60
|
+
def initialize(pattern, collector)
|
61
|
+
patterns = pattern.split(/\s+/).map { |str| MatchPattern.create(str) }
|
62
|
+
@pattern = if patterns.length == 1
|
63
|
+
patterns[0]
|
64
|
+
else
|
65
|
+
OrMatchPattern.new(patterns)
|
66
|
+
end
|
67
|
+
@pattern_str = pattern
|
68
|
+
@collector = collector
|
69
|
+
end
|
70
|
+
|
71
|
+
def match?(tag)
|
72
|
+
@pattern.match(tag)
|
73
|
+
end
|
74
|
+
|
75
|
+
attr_reader :collector
|
76
|
+
attr_reader :patatern_str
|
77
|
+
end
|
78
|
+
|
79
|
+
# called by Agent to add new match pattern and collector
|
80
|
+
def add_rule(pattern, collector)
|
81
|
+
@match_rules << Rule.new(pattern, collector)
|
82
|
+
end
|
83
|
+
|
84
|
+
def emit(tag, time, record)
|
85
|
+
unless record.nil?
|
86
|
+
emit_stream(tag, OneEventStream.new(time, record))
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def emit_array(tag, array)
|
91
|
+
emit_stream(tag, ArrayEventStream.new(array))
|
92
|
+
end
|
93
|
+
|
94
|
+
def emit_stream(tag, es)
|
95
|
+
match(tag).emit(tag, es, @chain)
|
96
|
+
rescue => e
|
97
|
+
@emit_error_handler.handle_emits_error(tag, es, e)
|
98
|
+
end
|
99
|
+
|
100
|
+
def match?(tag)
|
101
|
+
!!find(tag)
|
102
|
+
end
|
103
|
+
|
104
|
+
def match(tag)
|
105
|
+
collector = @match_cache.get(tag) {
|
106
|
+
c = find(tag) || @default_collector
|
107
|
+
}
|
108
|
+
collector
|
109
|
+
end
|
110
|
+
|
111
|
+
class MatchCache
|
112
|
+
MATCH_CACHE_SIZE = 1024
|
113
|
+
|
114
|
+
def initialize
|
115
|
+
super
|
116
|
+
@map = {}
|
117
|
+
@keys = []
|
118
|
+
end
|
119
|
+
|
120
|
+
def get(key)
|
121
|
+
if collector = @map[key]
|
122
|
+
return collector
|
123
|
+
end
|
124
|
+
collector = @map[key] = yield
|
125
|
+
if @keys.size >= MATCH_CACHE_SIZE
|
126
|
+
# expire the oldest key
|
127
|
+
@map.delete @keys.shift
|
128
|
+
end
|
129
|
+
@keys << key
|
130
|
+
collector
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
class Pipeline
|
137
|
+
def initialize
|
138
|
+
@filters = []
|
139
|
+
@output = nil
|
140
|
+
end
|
141
|
+
|
142
|
+
def add_filter(filter)
|
143
|
+
@filters << filter
|
144
|
+
end
|
145
|
+
|
146
|
+
def set_output(output)
|
147
|
+
@output = output
|
148
|
+
end
|
149
|
+
|
150
|
+
def emit(tag, es, chain)
|
151
|
+
processed = es
|
152
|
+
@filters.each { |filter|
|
153
|
+
processed = filter.filter_stream(tag, processed)
|
154
|
+
}
|
155
|
+
@output.emit(tag, processed, chain)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def find(tag)
|
160
|
+
pipeline = nil
|
161
|
+
@match_rules.each_with_index { |rule, i|
|
162
|
+
if rule.match?(tag)
|
163
|
+
if rule.collector.is_a?(Filter)
|
164
|
+
pipeline ||= Pipeline.new
|
165
|
+
pipeline.add_filter(rule.collector)
|
166
|
+
else
|
167
|
+
if pipeline
|
168
|
+
pipeline.set_output(rule.collector)
|
169
|
+
else
|
170
|
+
# Use Output directly when filter is not matched
|
171
|
+
pipeline = rule.collector
|
172
|
+
end
|
173
|
+
return pipeline
|
174
|
+
end
|
175
|
+
end
|
176
|
+
}
|
177
|
+
|
178
|
+
if pipeline
|
179
|
+
# filter is matched but no match
|
180
|
+
pipeline.set_output(@default_collector)
|
181
|
+
pipeline
|
182
|
+
else
|
183
|
+
nil
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Fluent
|
2
|
+
class Filter
|
3
|
+
include Configurable
|
4
|
+
include PluginId
|
5
|
+
include PluginLoggerMixin
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure(conf)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
end
|
17
|
+
|
18
|
+
def shutdown
|
19
|
+
end
|
20
|
+
|
21
|
+
def filter(tag, time, record)
|
22
|
+
end
|
23
|
+
|
24
|
+
def filter_stream(tag, es)
|
25
|
+
new_es = MultiEventStream.new
|
26
|
+
es.each { |time, record|
|
27
|
+
new_es.add(time, filter(tag, time, record))
|
28
|
+
}
|
29
|
+
new_es
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/fluent/formatter.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# Copyright (C) 2014 Fluentd project
|
2
|
+
# Fluentd
|
5
3
|
#
|
6
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
5
|
# you may not use this file except in compliance with the License.
|
@@ -15,21 +13,10 @@
|
|
15
13
|
# See the License for the specific language governing permissions and
|
16
14
|
# limitations under the License.
|
17
15
|
#
|
16
|
+
|
18
17
|
module Fluent
|
19
18
|
require 'fluent/registry'
|
20
19
|
|
21
|
-
class Formatter
|
22
|
-
include Configurable
|
23
|
-
|
24
|
-
def configure(conf)
|
25
|
-
super
|
26
|
-
end
|
27
|
-
|
28
|
-
def format(tag, time, record)
|
29
|
-
raise NotImplementedError, "Implement this method in child class"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
20
|
module TextFormatter
|
34
21
|
module HandleTagAndTimeMixin
|
35
22
|
def self.included(klass)
|
@@ -40,7 +27,6 @@ module Fluent
|
|
40
27
|
config_param :include_tag_key, :bool, :default => false
|
41
28
|
config_param :tag_key, :string, :default => 'tag'
|
42
29
|
config_param :localtime, :bool, :default => true
|
43
|
-
config_param :timezone, :string, :default => nil
|
44
30
|
}
|
45
31
|
end
|
46
32
|
|
@@ -50,7 +36,7 @@ module Fluent
|
|
50
36
|
if conf['utc']
|
51
37
|
@localtime = false
|
52
38
|
end
|
53
|
-
@timef = TimeFormatter.new(@time_format, @localtime
|
39
|
+
@timef = TimeFormatter.new(@time_format, @localtime)
|
54
40
|
end
|
55
41
|
|
56
42
|
def filter_record(tag, time, record)
|
@@ -63,7 +49,8 @@ module Fluent
|
|
63
49
|
end
|
64
50
|
end
|
65
51
|
|
66
|
-
class OutFileFormatter
|
52
|
+
class OutFileFormatter
|
53
|
+
include Configurable
|
67
54
|
include HandleTagAndTimeMixin
|
68
55
|
|
69
56
|
config_param :output_time, :bool, :default => true
|
@@ -76,6 +63,10 @@ module Fluent
|
|
76
63
|
end
|
77
64
|
end
|
78
65
|
|
66
|
+
def configure(conf)
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
79
70
|
def format(tag, time, record)
|
80
71
|
filter_record(tag, time, record)
|
81
72
|
header = ''
|
@@ -85,12 +76,11 @@ module Fluent
|
|
85
76
|
end
|
86
77
|
end
|
87
78
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
79
|
+
class JSONFormatter
|
80
|
+
include Configurable
|
81
|
+
include HandleTagAndTimeMixin
|
82
|
+
|
83
|
+
config_param :time_as_epoch, :bool, :default => false
|
94
84
|
|
95
85
|
def configure(conf)
|
96
86
|
super
|
@@ -108,29 +98,12 @@ module Fluent
|
|
108
98
|
def format(tag, time, record)
|
109
99
|
filter_record(tag, time, record)
|
110
100
|
record[@time_key] = time if @time_as_epoch
|
111
|
-
format_record(record)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
class JSONFormatter < Formatter
|
116
|
-
include HandleTagAndTimeMixin
|
117
|
-
include StructuredFormatMixin
|
118
|
-
|
119
|
-
def format_record(record)
|
120
101
|
"#{Yajl.dump(record)}\n"
|
121
102
|
end
|
122
103
|
end
|
123
104
|
|
124
|
-
class
|
125
|
-
include
|
126
|
-
include StructuredFormatMixin
|
127
|
-
|
128
|
-
def format_record(record)
|
129
|
-
record.to_msgpack
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
class LabeledTSVFormatter < Formatter
|
105
|
+
class LabeledTSVFormatter
|
106
|
+
include Configurable
|
134
107
|
include HandleTagAndTimeMixin
|
135
108
|
|
136
109
|
config_param :delimiter, :string, :default => "\t"
|
@@ -147,37 +120,9 @@ module Fluent
|
|
147
120
|
end
|
148
121
|
end
|
149
122
|
|
150
|
-
class
|
151
|
-
include
|
152
|
-
|
153
|
-
config_param :delimiter, :default => ',' do |val|
|
154
|
-
['\t', 'TAB'].include?(val) ? "\t" : val
|
155
|
-
end
|
156
|
-
config_param :force_quotes, :bool, :default => true
|
157
|
-
config_param :fields, :default => [] do |val|
|
158
|
-
val.split(',').map do |f|
|
159
|
-
f.strip!
|
160
|
-
f.size > 0 ? f : nil
|
161
|
-
end.compact
|
162
|
-
end
|
163
|
-
|
164
|
-
def initialize
|
165
|
-
super
|
166
|
-
require 'csv'
|
167
|
-
end
|
168
|
-
|
169
|
-
def format(tag, time, record)
|
170
|
-
filter_record(tag, time, record)
|
171
|
-
row = @fields.inject([]) do |memo, key|
|
172
|
-
memo << record[key]
|
173
|
-
memo
|
174
|
-
end
|
175
|
-
CSV.generate_line(row, :col_sep => @delimiter,
|
176
|
-
:force_quotes => @force_quotes)
|
177
|
-
end
|
178
|
-
end
|
123
|
+
class SingleValueFormatter
|
124
|
+
include Configurable
|
179
125
|
|
180
|
-
class SingleValueFormatter < Formatter
|
181
126
|
config_param :message_key, :string, :default => 'message'
|
182
127
|
config_param :add_newline, :bool, :default => true
|
183
128
|
|
@@ -188,58 +133,41 @@ module Fluent
|
|
188
133
|
end
|
189
134
|
end
|
190
135
|
|
191
|
-
class ProcWrappedFormatter < Formatter
|
192
|
-
def initialize(proc)
|
193
|
-
@proc = proc
|
194
|
-
end
|
195
|
-
|
196
|
-
def configure(conf)
|
197
|
-
end
|
198
|
-
|
199
|
-
def format(tag, time, record)
|
200
|
-
@proc.call(tag, time, record)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
136
|
TEMPLATE_REGISTRY = Registry.new(:formatter_type, 'fluent/plugin/formatter_')
|
205
137
|
{
|
206
138
|
'out_file' => Proc.new { OutFileFormatter.new },
|
207
139
|
'json' => Proc.new { JSONFormatter.new },
|
208
|
-
'msgpack' => Proc.new { MessagePackFormatter.new },
|
209
140
|
'ltsv' => Proc.new { LabeledTSVFormatter.new },
|
210
|
-
'csv' => Proc.new { CsvFormatter.new },
|
211
141
|
'single_value' => Proc.new { SingleValueFormatter.new },
|
212
142
|
}.each { |name, factory|
|
213
143
|
TEMPLATE_REGISTRY.register(name, factory)
|
214
144
|
}
|
215
145
|
|
216
146
|
def self.register_template(name, factory_or_proc)
|
217
|
-
factory = if factory_or_proc.
|
218
|
-
Proc.new { factory_or_proc
|
219
|
-
|
220
|
-
Proc.new { ProcWrappedFormatter.new(factory_or_proc) }
|
221
|
-
else # Proc.new { XXXFormatter.new }
|
147
|
+
factory = if factory_or_proc.arity == 3
|
148
|
+
Proc.new { factory_or_proc }
|
149
|
+
else
|
222
150
|
factory_or_proc
|
223
151
|
end
|
224
152
|
|
225
153
|
TEMPLATE_REGISTRY.register(name, factory)
|
226
154
|
end
|
227
155
|
|
228
|
-
def self.lookup(format)
|
229
|
-
TEMPLATE_REGISTRY.lookup(format).call
|
230
|
-
end
|
231
|
-
|
232
|
-
# Keep backward-compatibility
|
233
156
|
def self.create(conf)
|
234
157
|
format = conf['format']
|
235
158
|
if format.nil?
|
236
159
|
raise ConfigError, "'format' parameter is required"
|
237
160
|
end
|
238
161
|
|
239
|
-
|
240
|
-
|
241
|
-
|
162
|
+
# built-in template
|
163
|
+
begin
|
164
|
+
factory = TEMPLATE_REGISTRY.lookup(format)
|
165
|
+
rescue ConfigError => e
|
166
|
+
raise ConfigError, "unknown format: '#{format}'"
|
242
167
|
end
|
168
|
+
|
169
|
+
formatter = factory.call
|
170
|
+
formatter.configure(conf)
|
243
171
|
formatter
|
244
172
|
end
|
245
173
|
end
|