fluentd 0.12.43 → 0.14.0
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/.github/ISSUE_TEMPLATE.md +6 -0
- data/.gitignore +2 -0
- data/.travis.yml +33 -21
- data/CONTRIBUTING.md +1 -0
- data/ChangeLog +1239 -0
- data/README.md +0 -25
- data/Rakefile +2 -1
- data/Vagrantfile +17 -0
- data/appveyor.yml +35 -0
- data/example/filter_stdout.conf +5 -5
- data/example/in_forward.conf +2 -2
- data/example/in_http.conf +2 -2
- data/example/in_out_forward.conf +17 -0
- data/example/in_syslog.conf +2 -2
- data/example/in_tail.conf +2 -2
- data/example/in_tcp.conf +2 -2
- data/example/in_udp.conf +2 -2
- data/example/out_copy.conf +4 -4
- data/example/out_file.conf +2 -2
- data/example/out_forward.conf +2 -2
- data/example/out_forward_buf_file.conf +23 -0
- data/example/v0_12_filter.conf +8 -8
- data/fluent.conf +29 -0
- data/fluentd.gemspec +18 -11
- data/lib/fluent/agent.rb +60 -58
- data/lib/fluent/command/cat.rb +1 -1
- data/lib/fluent/command/debug.rb +7 -5
- data/lib/fluent/command/fluentd.rb +97 -2
- data/lib/fluent/compat/call_super_mixin.rb +67 -0
- data/lib/fluent/compat/filter.rb +50 -0
- data/lib/fluent/compat/formatter.rb +109 -0
- data/lib/fluent/compat/input.rb +50 -0
- data/lib/fluent/compat/output.rb +617 -0
- data/lib/fluent/compat/output_chain.rb +60 -0
- data/lib/fluent/compat/parser.rb +163 -0
- data/lib/fluent/compat/propagate_default.rb +62 -0
- data/lib/fluent/config.rb +23 -20
- data/lib/fluent/config/configure_proxy.rb +119 -70
- data/lib/fluent/config/dsl.rb +5 -18
- data/lib/fluent/config/element.rb +72 -8
- data/lib/fluent/config/error.rb +0 -3
- data/lib/fluent/config/literal_parser.rb +0 -2
- data/lib/fluent/config/parser.rb +4 -4
- data/lib/fluent/config/section.rb +39 -28
- data/lib/fluent/config/types.rb +2 -13
- data/lib/fluent/config/v1_parser.rb +1 -3
- data/lib/fluent/configurable.rb +48 -16
- data/lib/fluent/daemon.rb +15 -0
- data/lib/fluent/engine.rb +26 -52
- data/lib/fluent/env.rb +6 -4
- data/lib/fluent/event.rb +58 -11
- data/lib/fluent/event_router.rb +5 -5
- data/lib/fluent/filter.rb +2 -50
- data/lib/fluent/formatter.rb +4 -293
- data/lib/fluent/input.rb +2 -32
- data/lib/fluent/label.rb +2 -2
- data/lib/fluent/load.rb +3 -2
- data/lib/fluent/log.rb +107 -38
- data/lib/fluent/match.rb +0 -36
- data/lib/fluent/mixin.rb +117 -7
- data/lib/fluent/msgpack_factory.rb +62 -0
- data/lib/fluent/output.rb +7 -612
- data/lib/fluent/output_chain.rb +23 -0
- data/lib/fluent/parser.rb +4 -800
- data/lib/fluent/plugin.rb +100 -121
- data/lib/fluent/plugin/bare_output.rb +63 -0
- data/lib/fluent/plugin/base.rb +121 -0
- data/lib/fluent/plugin/buf_file.rb +101 -182
- data/lib/fluent/plugin/buf_memory.rb +9 -92
- data/lib/fluent/plugin/buffer.rb +473 -0
- data/lib/fluent/plugin/buffer/chunk.rb +135 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
- data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
- data/lib/fluent/plugin/exec_util.rb +80 -75
- data/lib/fluent/plugin/file_util.rb +33 -28
- data/lib/fluent/plugin/file_wrapper.rb +120 -0
- data/lib/fluent/plugin/filter.rb +51 -0
- data/lib/fluent/plugin/filter_grep.rb +13 -40
- data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
- data/lib/fluent/plugin/formatter.rb +93 -0
- data/lib/fluent/plugin/formatter_csv.rb +48 -0
- data/lib/fluent/plugin/formatter_hash.rb +32 -0
- data/lib/fluent/plugin/formatter_json.rb +47 -0
- data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
- data/lib/fluent/plugin/formatter_out_file.rb +45 -0
- data/lib/fluent/plugin/formatter_single_value.rb +34 -0
- data/lib/fluent/plugin/formatter_stdout.rb +39 -0
- data/lib/fluent/plugin/in_debug_agent.rb +4 -0
- data/lib/fluent/plugin/in_dummy.rb +22 -18
- data/lib/fluent/plugin/in_exec.rb +18 -8
- data/lib/fluent/plugin/in_forward.rb +36 -79
- data/lib/fluent/plugin/in_gc_stat.rb +4 -0
- data/lib/fluent/plugin/in_http.rb +21 -18
- data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
- data/lib/fluent/plugin/in_object_space.rb +6 -1
- data/lib/fluent/plugin/in_stream.rb +7 -3
- data/lib/fluent/plugin/in_syslog.rb +46 -95
- data/lib/fluent/plugin/in_tail.rb +58 -640
- data/lib/fluent/plugin/in_tcp.rb +8 -1
- data/lib/fluent/plugin/in_udp.rb +8 -18
- data/lib/fluent/plugin/input.rb +33 -0
- data/lib/fluent/plugin/multi_output.rb +95 -0
- data/lib/fluent/plugin/out_buffered_null.rb +59 -0
- data/lib/fluent/plugin/out_copy.rb +11 -7
- data/lib/fluent/plugin/out_exec.rb +15 -11
- data/lib/fluent/plugin/out_exec_filter.rb +18 -10
- data/lib/fluent/plugin/out_file.rb +34 -5
- data/lib/fluent/plugin/out_forward.rb +25 -19
- data/lib/fluent/plugin/out_null.rb +0 -14
- data/lib/fluent/plugin/out_roundrobin.rb +11 -7
- data/lib/fluent/plugin/out_stdout.rb +5 -7
- data/lib/fluent/plugin/out_stream.rb +3 -1
- data/lib/fluent/plugin/output.rb +979 -0
- data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
- data/lib/fluent/plugin/parser.rb +244 -0
- data/lib/fluent/plugin/parser_apache.rb +24 -0
- data/lib/fluent/plugin/parser_apache2.rb +84 -0
- data/lib/fluent/plugin/parser_apache_error.rb +21 -0
- data/lib/fluent/plugin/parser_csv.rb +31 -0
- data/lib/fluent/plugin/parser_json.rb +79 -0
- data/lib/fluent/plugin/parser_ltsv.rb +50 -0
- data/lib/fluent/plugin/parser_multiline.rb +102 -0
- data/lib/fluent/plugin/parser_nginx.rb +24 -0
- data/lib/fluent/plugin/parser_none.rb +36 -0
- data/lib/fluent/plugin/parser_syslog.rb +82 -0
- data/lib/fluent/plugin/parser_tsv.rb +37 -0
- data/lib/fluent/plugin/socket_util.rb +119 -117
- data/lib/fluent/plugin/storage.rb +84 -0
- data/lib/fluent/plugin/storage_local.rb +116 -0
- data/lib/fluent/plugin/string_util.rb +16 -13
- data/lib/fluent/plugin_helper.rb +39 -0
- data/lib/fluent/plugin_helper/child_process.rb +298 -0
- data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
- data/lib/fluent/plugin_helper/event_loop.rb +118 -0
- data/lib/fluent/plugin_helper/retry_state.rb +177 -0
- data/lib/fluent/plugin_helper/storage.rb +308 -0
- data/lib/fluent/plugin_helper/thread.rb +147 -0
- data/lib/fluent/plugin_helper/timer.rb +85 -0
- data/lib/fluent/plugin_id.rb +63 -0
- data/lib/fluent/process.rb +21 -30
- data/lib/fluent/registry.rb +21 -9
- data/lib/fluent/root_agent.rb +115 -40
- data/lib/fluent/supervisor.rb +330 -320
- data/lib/fluent/system_config.rb +42 -18
- data/lib/fluent/test.rb +6 -1
- data/lib/fluent/test/base.rb +23 -3
- data/lib/fluent/test/driver/base.rb +247 -0
- data/lib/fluent/test/driver/event_feeder.rb +98 -0
- data/lib/fluent/test/driver/filter.rb +35 -0
- data/lib/fluent/test/driver/input.rb +31 -0
- data/lib/fluent/test/driver/output.rb +78 -0
- data/lib/fluent/test/driver/test_event_router.rb +45 -0
- data/lib/fluent/test/filter_test.rb +0 -1
- data/lib/fluent/test/formatter_test.rb +2 -1
- data/lib/fluent/test/input_test.rb +23 -17
- data/lib/fluent/test/output_test.rb +28 -39
- data/lib/fluent/test/parser_test.rb +1 -1
- data/lib/fluent/time.rb +104 -1
- data/lib/fluent/{status.rb → unique_id.rb} +15 -24
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +72 -0
- data/test/compat/test_calls_super.rb +164 -0
- data/test/config/test_config_parser.rb +83 -0
- data/test/config/test_configurable.rb +547 -274
- data/test/config/test_configure_proxy.rb +146 -29
- data/test/config/test_dsl.rb +3 -181
- data/test/config/test_element.rb +274 -0
- data/test/config/test_literal_parser.rb +1 -1
- data/test/config/test_section.rb +79 -7
- data/test/config/test_system_config.rb +21 -0
- data/test/config/test_types.rb +3 -26
- data/test/helper.rb +78 -8
- data/test/plugin/test_bare_output.rb +118 -0
- data/test/plugin/test_base.rb +75 -0
- data/test/plugin/test_buf_file.rb +420 -521
- data/test/plugin/test_buf_memory.rb +32 -194
- data/test/plugin/test_buffer.rb +981 -0
- data/test/plugin/test_buffer_chunk.rb +110 -0
- data/test/plugin/test_buffer_file_chunk.rb +770 -0
- data/test/plugin/test_buffer_memory_chunk.rb +265 -0
- data/test/plugin/test_filter.rb +255 -0
- data/test/plugin/test_filter_grep.rb +2 -73
- data/test/plugin/test_filter_record_transformer.rb +24 -68
- data/test/plugin/test_filter_stdout.rb +6 -6
- data/test/plugin/test_in_debug_agent.rb +2 -0
- data/test/plugin/test_in_dummy.rb +11 -17
- data/test/plugin/test_in_exec.rb +6 -25
- data/test/plugin/test_in_forward.rb +112 -151
- data/test/plugin/test_in_gc_stat.rb +2 -0
- data/test/plugin/test_in_http.rb +106 -157
- data/test/plugin/test_in_object_space.rb +21 -5
- data/test/plugin/test_in_stream.rb +14 -13
- data/test/plugin/test_in_syslog.rb +30 -275
- data/test/plugin/test_in_tail.rb +95 -282
- data/test/plugin/test_in_tcp.rb +14 -0
- data/test/plugin/test_in_udp.rb +21 -67
- data/test/plugin/test_input.rb +122 -0
- data/test/plugin/test_multi_output.rb +180 -0
- data/test/plugin/test_out_buffered_null.rb +79 -0
- data/test/plugin/test_out_copy.rb +15 -2
- data/test/plugin/test_out_exec.rb +75 -25
- data/test/plugin/test_out_exec_filter.rb +74 -8
- data/test/plugin/test_out_file.rb +61 -7
- data/test/plugin/test_out_forward.rb +92 -15
- data/test/plugin/test_out_roundrobin.rb +1 -0
- data/test/plugin/test_out_stdout.rb +22 -13
- data/test/plugin/test_out_stream.rb +18 -0
- data/test/plugin/test_output.rb +515 -0
- data/test/plugin/test_output_as_buffered.rb +1540 -0
- data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
- data/test/plugin/test_output_as_buffered_retries.rb +808 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
- data/test/plugin/test_output_as_standard.rb +362 -0
- data/test/plugin/test_owned_by.rb +35 -0
- data/test/plugin/test_storage.rb +167 -0
- data/test/plugin/test_storage_local.rb +8 -0
- data/test/plugin_helper/test_child_process.rb +599 -0
- data/test/plugin_helper/test_compat_parameters.rb +175 -0
- data/test/plugin_helper/test_event_emitter.rb +51 -0
- data/test/plugin_helper/test_event_loop.rb +52 -0
- data/test/plugin_helper/test_retry_state.rb +399 -0
- data/test/plugin_helper/test_storage.rb +411 -0
- data/test/plugin_helper/test_thread.rb +164 -0
- data/test/plugin_helper/test_timer.rb +100 -0
- data/test/scripts/exec_script.rb +0 -6
- data/test/scripts/fluent/plugin/out_test.rb +3 -0
- data/test/test_config.rb +13 -4
- data/test/test_event.rb +24 -13
- data/test/test_event_router.rb +8 -7
- data/test/test_event_time.rb +187 -0
- data/test/test_formatter.rb +13 -51
- data/test/test_input.rb +1 -1
- data/test/test_log.rb +239 -16
- data/test/test_mixin.rb +1 -1
- data/test/test_output.rb +53 -66
- data/test/test_parser.rb +105 -323
- data/test/test_plugin_helper.rb +81 -0
- data/test/test_root_agent.rb +4 -52
- data/test/test_supervisor.rb +272 -0
- data/test/test_unique_id.rb +47 -0
- metadata +181 -55
- data/CHANGELOG.md +0 -710
- data/lib/fluent/buffer.rb +0 -365
- data/lib/fluent/plugin/filter_parser.rb +0 -107
- data/lib/fluent/plugin/in_status.rb +0 -76
- data/lib/fluent/test/helpers.rb +0 -86
- data/test/plugin/data/log/foo/bar2 +0 -0
- data/test/plugin/test_filter_parser.rb +0 -744
- data/test/plugin/test_in_status.rb +0 -38
- data/test/test_buffer.rb +0 -624
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
here = File.dirname(__FILE__)
|
5
|
+
$LOAD_PATH << File.expand_path(File.join(here, '..'))
|
6
|
+
|
7
|
+
require 'serverengine'
|
8
|
+
require 'fluent/supervisor'
|
9
|
+
|
10
|
+
server_module = Fluent.const_get(ARGV[0])
|
11
|
+
worker_module = Fluent.const_get(ARGV[1])
|
12
|
+
# it doesn't call ARGV in block because when reloading config, params will be initialized and then it can't use previous config.
|
13
|
+
config_path = ARGV[2]
|
14
|
+
params = JSON.parse(ARGV[3])
|
15
|
+
ServerEngine::Daemon.run_server(server_module, worker_module) { Fluent::Supervisor.load_config(config_path, params) }
|
data/lib/fluent/engine.rb
CHANGED
@@ -16,12 +16,12 @@
|
|
16
16
|
|
17
17
|
require 'socket'
|
18
18
|
|
19
|
-
require 'msgpack'
|
20
19
|
require 'cool.io'
|
21
20
|
|
22
21
|
require 'fluent/config'
|
23
22
|
require 'fluent/event'
|
24
23
|
require 'fluent/event_router'
|
24
|
+
require 'fluent/msgpack_factory'
|
25
25
|
require 'fluent/root_agent'
|
26
26
|
require 'fluent/time'
|
27
27
|
require 'fluent/system_config'
|
@@ -29,15 +29,7 @@ require 'fluent/plugin'
|
|
29
29
|
|
30
30
|
module Fluent
|
31
31
|
class EngineClass
|
32
|
-
|
33
|
-
def packer(*args)
|
34
|
-
MessagePack::Packer.new(*args)
|
35
|
-
end
|
36
|
-
|
37
|
-
def unpacker(*args)
|
38
|
-
MessagePack::Unpacker.new(*args)
|
39
|
-
end
|
40
|
-
end
|
32
|
+
include Fluent::MessagePackFactory::Mixin
|
41
33
|
|
42
34
|
def initialize
|
43
35
|
@root_agent = nil
|
@@ -51,32 +43,30 @@ module Fluent
|
|
51
43
|
|
52
44
|
@suppress_config_dump = false
|
53
45
|
|
54
|
-
@
|
46
|
+
@system_config = SystemConfig.new
|
55
47
|
end
|
56
48
|
|
49
|
+
MAINLOOP_SLEEP_INTERVAL = 0.3
|
50
|
+
|
57
51
|
MATCH_CACHE_SIZE = 1024
|
58
52
|
LOG_EMIT_INTERVAL = 0.1
|
59
53
|
|
60
54
|
attr_reader :root_agent
|
61
55
|
attr_reader :matches, :sources
|
62
|
-
attr_reader :msgpack_factory
|
63
56
|
attr_reader :system_config
|
64
57
|
|
65
58
|
def init(system_config)
|
66
59
|
@system_config = system_config
|
67
60
|
|
68
61
|
BasicSocket.do_not_reverse_lookup = true
|
69
|
-
Plugin.load_plugins
|
70
|
-
if defined?(Encoding)
|
71
|
-
Encoding.default_internal = 'ASCII-8BIT' if Encoding.respond_to?(:default_internal)
|
72
|
-
Encoding.default_external = 'ASCII-8BIT' if Encoding.respond_to?(:default_external)
|
73
|
-
end
|
74
62
|
|
75
63
|
suppress_interval(system_config.emit_error_log_interval) unless system_config.emit_error_log_interval.nil?
|
76
64
|
@suppress_config_dump = system_config.suppress_config_dump unless system_config.suppress_config_dump.nil?
|
77
65
|
@without_source = system_config.without_source unless system_config.without_source.nil?
|
78
66
|
|
79
|
-
@root_agent = RootAgent.new(@system_config)
|
67
|
+
@root_agent = RootAgent.new(log: log, system_config: @system_config)
|
68
|
+
|
69
|
+
MessagePackFactory.init
|
80
70
|
|
81
71
|
self
|
82
72
|
end
|
@@ -134,22 +124,20 @@ module Fluent
|
|
134
124
|
end
|
135
125
|
end
|
136
126
|
|
137
|
-
def
|
138
|
-
Plugin.
|
127
|
+
def add_plugin_dir(dir)
|
128
|
+
Plugin.add_plugin_dir(dir)
|
139
129
|
end
|
140
130
|
|
141
131
|
def emit(tag, time, record)
|
142
|
-
|
143
|
-
emit_stream tag, OneEventStream.new(time, record)
|
144
|
-
end
|
132
|
+
raise "BUG: use router.emit instead of Engine.emit"
|
145
133
|
end
|
146
134
|
|
147
135
|
def emit_array(tag, array)
|
148
|
-
|
136
|
+
raise "BUG: use router.emit_array instead of Engine.emit_array"
|
149
137
|
end
|
150
138
|
|
151
139
|
def emit_stream(tag, es)
|
152
|
-
|
140
|
+
raise "BUG: use router.emit_stream instead of Engine.emit_stream"
|
153
141
|
end
|
154
142
|
|
155
143
|
def flush!
|
@@ -158,7 +146,7 @@ module Fluent
|
|
158
146
|
|
159
147
|
def now
|
160
148
|
# TODO thread update
|
161
|
-
|
149
|
+
Fluent::EventTime.now
|
162
150
|
end
|
163
151
|
|
164
152
|
def log_event_loop
|
@@ -176,7 +164,7 @@ module Fluent
|
|
176
164
|
begin
|
177
165
|
@event_router.emit(tag, time, record)
|
178
166
|
rescue => e
|
179
|
-
$log.error "failed to emit fluentd's log event", tag: tag, event: record,
|
167
|
+
$log.error "failed to emit fluentd's log event", tag: tag, event: record, error: e
|
180
168
|
end
|
181
169
|
}
|
182
170
|
end
|
@@ -191,38 +179,24 @@ module Fluent
|
|
191
179
|
@log_emit_thread = Thread.new(&method(:log_event_loop))
|
192
180
|
end
|
193
181
|
|
194
|
-
|
195
|
-
# for empty loop
|
196
|
-
@default_loop = Coolio::Loop.default
|
197
|
-
@default_loop.attach Coolio::TimerWatcher.new(1, true)
|
198
|
-
# TODO attach async watch for thread pool
|
199
|
-
@default_loop.run
|
200
|
-
end
|
201
|
-
|
202
|
-
if @engine_stopped and @default_loop
|
203
|
-
@default_loop.stop
|
204
|
-
@default_loop = nil
|
205
|
-
end
|
182
|
+
sleep MAINLOOP_SLEEP_INTERVAL until @engine_stopped
|
206
183
|
|
207
|
-
rescue => e
|
208
|
-
$log.error "unexpected error",
|
184
|
+
rescue Exception => e
|
185
|
+
$log.error "unexpected error", error: e
|
209
186
|
$log.error_backtrace
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
187
|
+
raise
|
188
|
+
end
|
189
|
+
|
190
|
+
$log.info "shutting down fluentd"
|
191
|
+
shutdown
|
192
|
+
if @log_emit_thread
|
193
|
+
@log_event_loop_stop = true
|
194
|
+
@log_emit_thread.join
|
217
195
|
end
|
218
196
|
end
|
219
197
|
|
220
198
|
def stop
|
221
199
|
@engine_stopped = true
|
222
|
-
if @default_loop
|
223
|
-
@default_loop.stop
|
224
|
-
@default_loop = nil
|
225
|
-
end
|
226
200
|
nil
|
227
201
|
end
|
228
202
|
|
data/lib/fluent/env.rb
CHANGED
@@ -18,8 +18,10 @@ module Fluent
|
|
18
18
|
DEFAULT_CONFIG_PATH = ENV['FLUENT_CONF'] || '/etc/fluent/fluent.conf'
|
19
19
|
DEFAULT_PLUGIN_DIR = ENV['FLUENT_PLUGIN'] || '/etc/fluent/plugin'
|
20
20
|
DEFAULT_SOCKET_PATH = ENV['FLUENT_SOCKET'] || '/var/run/fluent/fluent.sock'
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
IS_WINDOWS = /mswin|mingw/ === RUBY_PLATFORM
|
22
|
+
private_constant :IS_WINDOWS
|
23
|
+
|
24
|
+
def self.windows?
|
25
|
+
IS_WINDOWS
|
26
|
+
end
|
25
27
|
end
|
data/lib/fluent/event.rb
CHANGED
@@ -14,11 +14,17 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
-
require 'fluent/
|
17
|
+
require 'fluent/msgpack_factory'
|
18
18
|
|
19
19
|
module Fluent
|
20
20
|
class EventStream
|
21
21
|
include Enumerable
|
22
|
+
include MessagePackFactory::Mixin
|
23
|
+
|
24
|
+
def size
|
25
|
+
raise NotImplementedError, "DO NOT USE THIS CLASS directly."
|
26
|
+
end
|
27
|
+
alias :length :size
|
22
28
|
|
23
29
|
def repeatable?
|
24
30
|
false
|
@@ -28,15 +34,23 @@ module Fluent
|
|
28
34
|
raise NotImplementedError, "DO NOT USE THIS CLASS directly."
|
29
35
|
end
|
30
36
|
|
31
|
-
def to_msgpack_stream
|
32
|
-
|
37
|
+
def to_msgpack_stream(time_int: false)
|
38
|
+
return to_msgpack_stream_forced_integer if time_int
|
39
|
+
out = msgpack_packer
|
33
40
|
each {|time,record|
|
34
41
|
out.write([time,record])
|
35
42
|
}
|
36
43
|
out.to_s
|
37
44
|
end
|
38
|
-
end
|
39
45
|
|
46
|
+
def to_msgpack_stream_forced_integer
|
47
|
+
out = msgpack_packer
|
48
|
+
each {|time,record|
|
49
|
+
out.write([time.to_i,record])
|
50
|
+
}
|
51
|
+
out.to_s
|
52
|
+
end
|
53
|
+
end
|
40
54
|
|
41
55
|
class OneEventStream < EventStream
|
42
56
|
def initialize(time, record)
|
@@ -48,6 +62,10 @@ module Fluent
|
|
48
62
|
OneEventStream.new(@time, @record.dup)
|
49
63
|
end
|
50
64
|
|
65
|
+
def size
|
66
|
+
1
|
67
|
+
end
|
68
|
+
|
51
69
|
def repeatable?
|
52
70
|
true
|
53
71
|
end
|
@@ -72,6 +90,10 @@ module Fluent
|
|
72
90
|
ArrayEventStream.new(entries)
|
73
91
|
end
|
74
92
|
|
93
|
+
def size
|
94
|
+
@entries.size
|
95
|
+
end
|
96
|
+
|
75
97
|
def repeatable?
|
76
98
|
true
|
77
99
|
end
|
@@ -93,7 +115,7 @@ module Fluent
|
|
93
115
|
#
|
94
116
|
# Use this class as below, in loop of data-enumeration:
|
95
117
|
# 1. initialize blank stream:
|
96
|
-
# streams[tag] ||= MultiEventStream
|
118
|
+
# streams[tag] ||= MultiEventStream.new
|
97
119
|
# 2. add events
|
98
120
|
# stream[tag].add(time, record)
|
99
121
|
class MultiEventStream < EventStream
|
@@ -110,6 +132,10 @@ module Fluent
|
|
110
132
|
es
|
111
133
|
end
|
112
134
|
|
135
|
+
def size
|
136
|
+
@time_array.size
|
137
|
+
end
|
138
|
+
|
113
139
|
def add(time, record)
|
114
140
|
@time_array << time
|
115
141
|
@record_array << record
|
@@ -135,8 +161,13 @@ module Fluent
|
|
135
161
|
|
136
162
|
class MessagePackEventStream < EventStream
|
137
163
|
# Keep cached_unpacker argument for existence plugins
|
138
|
-
def initialize(data, cached_unpacker = nil)
|
164
|
+
def initialize(data, cached_unpacker = nil, size = 0)
|
139
165
|
@data = data
|
166
|
+
@size = size
|
167
|
+
end
|
168
|
+
|
169
|
+
def size
|
170
|
+
@size
|
140
171
|
end
|
141
172
|
|
142
173
|
def repeatable?
|
@@ -144,15 +175,31 @@ module Fluent
|
|
144
175
|
end
|
145
176
|
|
146
177
|
def each(&block)
|
147
|
-
|
148
|
-
unpacker = Fluent::Engine.msgpack_factory.unpacker
|
149
|
-
unpacker.feed_each(@data, &block)
|
178
|
+
msgpack_unpacker.feed_each(@data, &block)
|
150
179
|
nil
|
151
180
|
end
|
152
181
|
|
153
|
-
def to_msgpack_stream
|
182
|
+
def to_msgpack_stream(time_int: false)
|
183
|
+
# time_int is always ignored because @data is always packed binary in this class
|
154
184
|
@data
|
155
185
|
end
|
156
186
|
end
|
157
|
-
end
|
158
187
|
|
188
|
+
module ChunkMessagePackEventStreamer
|
189
|
+
include MessagePackFactory::Mixin
|
190
|
+
# chunk.extend(ChunkEventStreamer)
|
191
|
+
# => chunk.each{|time, record| ... }
|
192
|
+
def each(&block)
|
193
|
+
open do |io|
|
194
|
+
msgpack_unpacker(io).each(&block)
|
195
|
+
end
|
196
|
+
nil
|
197
|
+
end
|
198
|
+
alias :msgpack_each :each
|
199
|
+
|
200
|
+
def to_msgpack_stream(time_int: false)
|
201
|
+
# time_int is always ignored because data is already packed and written in chunk
|
202
|
+
read
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
data/lib/fluent/event_router.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
require 'fluent/match'
|
18
18
|
require 'fluent/event'
|
19
|
+
require 'fluent/filter'
|
19
20
|
|
20
21
|
module Fluent
|
21
22
|
#
|
@@ -45,7 +46,6 @@ module Fluent
|
|
45
46
|
@match_cache = MatchCache.new
|
46
47
|
@default_collector = default_collector
|
47
48
|
@emit_error_handler = emit_error_handler
|
48
|
-
@chain = NullOutputChain.instance
|
49
49
|
end
|
50
50
|
|
51
51
|
attr_accessor :default_collector
|
@@ -87,7 +87,7 @@ module Fluent
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def emit_stream(tag, es)
|
90
|
-
match(tag).
|
90
|
+
match(tag).emit_events(tag, es)
|
91
91
|
rescue => e
|
92
92
|
@emit_error_handler.handle_emits_error(tag, es, e)
|
93
93
|
end
|
@@ -102,7 +102,7 @@ module Fluent
|
|
102
102
|
|
103
103
|
def match(tag)
|
104
104
|
collector = @match_cache.get(tag) {
|
105
|
-
|
105
|
+
find(tag) || @default_collector
|
106
106
|
}
|
107
107
|
collector
|
108
108
|
end
|
@@ -146,12 +146,12 @@ module Fluent
|
|
146
146
|
@output = output
|
147
147
|
end
|
148
148
|
|
149
|
-
def
|
149
|
+
def emit_events(tag, es)
|
150
150
|
processed = es
|
151
151
|
@filters.each { |filter|
|
152
152
|
processed = filter.filter_stream(tag, processed)
|
153
153
|
}
|
154
|
-
@output.
|
154
|
+
@output.emit_events(tag, processed)
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
data/lib/fluent/filter.rb
CHANGED
@@ -14,56 +14,8 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
-
require 'fluent/
|
18
|
-
require 'fluent/configurable'
|
19
|
-
require 'fluent/engine'
|
20
|
-
require 'fluent/event'
|
21
|
-
require 'fluent/log'
|
17
|
+
require 'fluent/compat/filter'
|
22
18
|
|
23
19
|
module Fluent
|
24
|
-
|
25
|
-
include Configurable
|
26
|
-
include PluginId
|
27
|
-
include PluginLoggerMixin
|
28
|
-
|
29
|
-
attr_accessor :router
|
30
|
-
|
31
|
-
def initialize
|
32
|
-
super
|
33
|
-
end
|
34
|
-
|
35
|
-
def configure(conf)
|
36
|
-
super
|
37
|
-
|
38
|
-
if label_name = conf['@label']
|
39
|
-
label = Engine.root_agent.find_label(label_name)
|
40
|
-
@router = label.event_router
|
41
|
-
elsif @router.nil?
|
42
|
-
@router = Engine.root_agent.event_router
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def start
|
47
|
-
end
|
48
|
-
|
49
|
-
def shutdown
|
50
|
-
end
|
51
|
-
|
52
|
-
def filter(tag, time, record)
|
53
|
-
raise NotImplementedError, "Implement this method in child class"
|
54
|
-
end
|
55
|
-
|
56
|
-
def filter_stream(tag, es)
|
57
|
-
new_es = MultiEventStream.new
|
58
|
-
es.each { |time, record|
|
59
|
-
begin
|
60
|
-
filtered_record = filter(tag, time, record)
|
61
|
-
new_es.add(time, filtered_record) if filtered_record
|
62
|
-
rescue => e
|
63
|
-
router.emit_error_event(tag, time, record, e)
|
64
|
-
end
|
65
|
-
}
|
66
|
-
new_es
|
67
|
-
end
|
68
|
-
end
|
20
|
+
Filter = Fluent::Compat::Filter
|
69
21
|
end
|
data/lib/fluent/formatter.rb
CHANGED
@@ -14,299 +14,10 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
-
require 'fluent/
|
18
|
-
require 'fluent/env'
|
19
|
-
require 'fluent/registry'
|
20
|
-
require 'fluent/mixin'
|
17
|
+
require 'fluent/compat/formatter'
|
21
18
|
|
22
19
|
module Fluent
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def configure(conf)
|
27
|
-
super
|
28
|
-
end
|
29
|
-
|
30
|
-
def format(tag, time, record)
|
31
|
-
raise NotImplementedError, "Implement this method in child class"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
module TextFormatter
|
36
|
-
module HandleTagAndTimeMixin
|
37
|
-
def self.included(klass)
|
38
|
-
klass.instance_eval {
|
39
|
-
config_param :include_time_key, :bool, default: false
|
40
|
-
config_param :time_key, :string, default: 'time'
|
41
|
-
config_param :time_format, :string, default: nil
|
42
|
-
config_param :include_tag_key, :bool, default: false
|
43
|
-
config_param :tag_key, :string, default: 'tag'
|
44
|
-
config_param :localtime, :bool, default: true
|
45
|
-
config_param :timezone, :string, default: nil
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
def configure(conf)
|
50
|
-
super
|
51
|
-
|
52
|
-
if conf['utc']
|
53
|
-
@localtime = false
|
54
|
-
end
|
55
|
-
@timef = TimeFormatter.new(@time_format, @localtime, @timezone)
|
56
|
-
end
|
57
|
-
|
58
|
-
def filter_record(tag, time, record)
|
59
|
-
if @include_tag_key
|
60
|
-
record[@tag_key] = tag
|
61
|
-
end
|
62
|
-
if @include_time_key
|
63
|
-
record[@time_key] = @timef.format(time)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
class OutFileFormatter < Formatter
|
69
|
-
include HandleTagAndTimeMixin
|
70
|
-
|
71
|
-
config_param :output_time, :bool, default: true
|
72
|
-
config_param :output_tag, :bool, default: true
|
73
|
-
config_param :delimiter, default: "\t" do |val|
|
74
|
-
case val
|
75
|
-
when /SPACE/i then ' '
|
76
|
-
when /COMMA/i then ','
|
77
|
-
else "\t"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def format(tag, time, record)
|
82
|
-
filter_record(tag, time, record)
|
83
|
-
header = ''
|
84
|
-
header << "#{@timef.format(time)}#{@delimiter}" if @output_time
|
85
|
-
header << "#{tag}#{@delimiter}" if @output_tag
|
86
|
-
"#{header}#{Yajl.dump(record)}\n"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
class StdoutFormatter < Formatter
|
91
|
-
config_param :output_type, :string, default: 'json'
|
92
|
-
|
93
|
-
def configure(conf)
|
94
|
-
super
|
95
|
-
|
96
|
-
@formatter = Plugin.new_formatter(@output_type)
|
97
|
-
@formatter.configure(conf)
|
98
|
-
end
|
99
|
-
|
100
|
-
def format(tag, time, record)
|
101
|
-
header = "#{Time.now.localtime} #{tag}: "
|
102
|
-
"#{header}#{@formatter.format(tag, time, record)}"
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
module StructuredFormatMixin
|
107
|
-
def self.included(klass)
|
108
|
-
klass.instance_eval {
|
109
|
-
config_param :time_as_epoch, :bool, default: false
|
110
|
-
}
|
111
|
-
end
|
112
|
-
|
113
|
-
def configure(conf)
|
114
|
-
super
|
115
|
-
|
116
|
-
if @time_as_epoch
|
117
|
-
if @include_time_key
|
118
|
-
@include_time_key = false
|
119
|
-
else
|
120
|
-
$log.warn "include_time_key is false so ignore time_as_epoch"
|
121
|
-
@time_as_epoch = false
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def format(tag, time, record)
|
127
|
-
filter_record(tag, time, record)
|
128
|
-
record[@time_key] = time if @time_as_epoch
|
129
|
-
format_record(record)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
class JSONFormatter < Formatter
|
134
|
-
include HandleTagAndTimeMixin
|
135
|
-
include StructuredFormatMixin
|
136
|
-
|
137
|
-
config_param :json_parser, :string, default: 'oj'
|
138
|
-
config_param :add_newline, :bool, default: true
|
139
|
-
|
140
|
-
def configure(conf)
|
141
|
-
super
|
142
|
-
|
143
|
-
begin
|
144
|
-
raise LoadError unless @json_parser == 'oj'
|
145
|
-
require 'oj'
|
146
|
-
Oj.default_options = Fluent::DEFAULT_OJ_OPTIONS
|
147
|
-
@dump_proc = Oj.method(:dump)
|
148
|
-
rescue LoadError
|
149
|
-
@dump_proc = Yajl.method(:dump)
|
150
|
-
end
|
151
|
-
|
152
|
-
# format json is used on various highload environment, so re-define method to skip if check
|
153
|
-
unless @add_newline
|
154
|
-
define_singleton_method(:format, method(:format_without_nl))
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def format_record(record)
|
159
|
-
"#{@dump_proc.call(record)}\n"
|
160
|
-
end
|
161
|
-
|
162
|
-
def format_without_nl(tag, time, record)
|
163
|
-
@dump_proc.call(record)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
class HashFormatter < Formatter
|
168
|
-
include HandleTagAndTimeMixin
|
169
|
-
include StructuredFormatMixin
|
170
|
-
|
171
|
-
config_param :add_newline, :bool, default: true
|
172
|
-
|
173
|
-
def format_record(record)
|
174
|
-
if @add_newline
|
175
|
-
"#{record.to_s}\n"
|
176
|
-
else
|
177
|
-
record.to_s
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
class MessagePackFormatter < Formatter
|
183
|
-
include HandleTagAndTimeMixin
|
184
|
-
include StructuredFormatMixin
|
185
|
-
|
186
|
-
def format_record(record)
|
187
|
-
record.to_msgpack
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
class LabeledTSVFormatter < Formatter
|
192
|
-
include HandleTagAndTimeMixin
|
193
|
-
|
194
|
-
config_param :delimiter, :string, default: "\t"
|
195
|
-
config_param :label_delimiter, :string, default: ":"
|
196
|
-
config_param :add_newline, :bool, default: true
|
197
|
-
|
198
|
-
def format(tag, time, record)
|
199
|
-
filter_record(tag, time, record)
|
200
|
-
formatted = record.inject('') { |result, pair|
|
201
|
-
result << @delimiter if result.length.nonzero?
|
202
|
-
result << "#{pair.first}#{@label_delimiter}#{pair.last}"
|
203
|
-
}
|
204
|
-
formatted << "\n".freeze if @add_newline
|
205
|
-
formatted
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
class CsvFormatter < Formatter
|
210
|
-
include HandleTagAndTimeMixin
|
211
|
-
|
212
|
-
config_param :delimiter, default: ',' do |val|
|
213
|
-
['\t', 'TAB'].include?(val) ? "\t" : val
|
214
|
-
end
|
215
|
-
config_param :force_quotes, :bool, default: true
|
216
|
-
config_param :fields, :array, value_type: :string
|
217
|
-
config_param :add_newline, :bool, default: true
|
218
|
-
|
219
|
-
def initialize
|
220
|
-
super
|
221
|
-
require 'csv'
|
222
|
-
end
|
223
|
-
|
224
|
-
def configure(conf)
|
225
|
-
super
|
226
|
-
@fields = fields.select { |f| !f.empty? }
|
227
|
-
raise ConfigError, "empty value is specified in fields parameter" if @fields.empty?
|
228
|
-
|
229
|
-
@generate_opts = {col_sep: @delimiter, force_quotes: @force_quotes}
|
230
|
-
end
|
231
|
-
|
232
|
-
def format(tag, time, record)
|
233
|
-
filter_record(tag, time, record)
|
234
|
-
row = @fields.inject([]) do |memo, key|
|
235
|
-
memo << record[key]
|
236
|
-
memo
|
237
|
-
end
|
238
|
-
line = CSV.generate_line(row, @generate_opts)
|
239
|
-
line.chomp! unless @add_newline
|
240
|
-
line
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
class SingleValueFormatter < Formatter
|
245
|
-
config_param :message_key, :string, default: 'message'
|
246
|
-
config_param :add_newline, :bool, default: true
|
247
|
-
|
248
|
-
def format(tag, time, record)
|
249
|
-
text = record[@message_key].to_s.dup
|
250
|
-
text << "\n" if @add_newline
|
251
|
-
text
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
class ProcWrappedFormatter < Formatter
|
256
|
-
def initialize(proc)
|
257
|
-
@proc = proc
|
258
|
-
end
|
259
|
-
|
260
|
-
def configure(conf)
|
261
|
-
end
|
262
|
-
|
263
|
-
def format(tag, time, record)
|
264
|
-
@proc.call(tag, time, record)
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
TEMPLATE_REGISTRY = Registry.new(:formatter_type, 'fluent/plugin/formatter_')
|
269
|
-
{
|
270
|
-
'out_file' => Proc.new { OutFileFormatter.new },
|
271
|
-
'stdout' => Proc.new { StdoutFormatter.new },
|
272
|
-
'json' => Proc.new { JSONFormatter.new },
|
273
|
-
'hash' => Proc.new { HashFormatter.new },
|
274
|
-
'msgpack' => Proc.new { MessagePackFormatter.new },
|
275
|
-
'ltsv' => Proc.new { LabeledTSVFormatter.new },
|
276
|
-
'csv' => Proc.new { CsvFormatter.new },
|
277
|
-
'single_value' => Proc.new { SingleValueFormatter.new },
|
278
|
-
}.each { |name, factory|
|
279
|
-
TEMPLATE_REGISTRY.register(name, factory)
|
280
|
-
}
|
281
|
-
|
282
|
-
def self.register_template(name, factory_or_proc)
|
283
|
-
factory = if factory_or_proc.is_a?(Class) # XXXFormatter
|
284
|
-
Proc.new { factory_or_proc.new }
|
285
|
-
elsif factory_or_proc.arity == 3 # Proc.new { |tag, time, record| }
|
286
|
-
Proc.new { ProcWrappedFormatter.new(factory_or_proc) }
|
287
|
-
else # Proc.new { XXXFormatter.new }
|
288
|
-
factory_or_proc
|
289
|
-
end
|
290
|
-
|
291
|
-
TEMPLATE_REGISTRY.register(name, factory)
|
292
|
-
end
|
293
|
-
|
294
|
-
def self.lookup(format)
|
295
|
-
TEMPLATE_REGISTRY.lookup(format).call
|
296
|
-
end
|
297
|
-
|
298
|
-
# Keep backward-compatibility
|
299
|
-
def self.create(conf)
|
300
|
-
format = conf['format']
|
301
|
-
if format.nil?
|
302
|
-
raise ConfigError, "'format' parameter is required"
|
303
|
-
end
|
304
|
-
|
305
|
-
formatter = lookup(format)
|
306
|
-
if formatter.respond_to?(:configure)
|
307
|
-
formatter.configure(conf)
|
308
|
-
end
|
309
|
-
formatter
|
310
|
-
end
|
311
|
-
end
|
20
|
+
Formatter = Fluent::Compat::Formatter
|
21
|
+
TextFormatter = Fluent::Compat::TextFormatter
|
22
|
+
# deprecate_constant is ruby 2.3 feature
|
312
23
|
end
|