fluentd 0.10.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.
- data/AUTHORS +1 -0
- data/COPYING +14 -0
- data/ChangeLog +178 -0
- data/README.rdoc +57 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/bin/fluent-cat +6 -0
- data/bin/fluent-gem +10 -0
- data/bin/fluentd +6 -0
- data/fluent.conf +78 -0
- data/fluentd.gemspec +116 -0
- data/lib/fluent/buffer.rb +274 -0
- data/lib/fluent/command/cat.rb +299 -0
- data/lib/fluent/command/fluentd.rb +245 -0
- data/lib/fluent/config.rb +304 -0
- data/lib/fluent/engine.rb +224 -0
- data/lib/fluent/env.rb +6 -0
- data/lib/fluent/event.rb +159 -0
- data/lib/fluent/input.rb +41 -0
- data/lib/fluent/load.rb +23 -0
- data/lib/fluent/log.rb +277 -0
- data/lib/fluent/match.rb +189 -0
- data/lib/fluent/mixin.rb +170 -0
- data/lib/fluent/output.rb +466 -0
- data/lib/fluent/parser.rb +115 -0
- data/lib/fluent/plugin.rb +145 -0
- data/lib/fluent/plugin/buf_file.rb +181 -0
- data/lib/fluent/plugin/buf_memory.rb +97 -0
- data/lib/fluent/plugin/buf_zfile.rb +84 -0
- data/lib/fluent/plugin/in_http.rb +282 -0
- data/lib/fluent/plugin/in_stream.rb +187 -0
- data/lib/fluent/plugin/in_syslog.rb +174 -0
- data/lib/fluent/plugin/in_tail.rb +150 -0
- data/lib/fluent/plugin/out_copy.rb +72 -0
- data/lib/fluent/plugin/out_file.rb +111 -0
- data/lib/fluent/plugin/out_null.rb +44 -0
- data/lib/fluent/plugin/out_roundrobin.rb +72 -0
- data/lib/fluent/plugin/out_stdout.rb +34 -0
- data/lib/fluent/plugin/out_stream.rb +128 -0
- data/lib/fluent/plugin/out_test.rb +68 -0
- data/lib/fluent/test.rb +8 -0
- data/lib/fluent/test/base.rb +63 -0
- data/lib/fluent/test/input_test.rb +89 -0
- data/lib/fluent/test/output_test.rb +93 -0
- data/lib/fluent/version.rb +5 -0
- data/test/helper.rb +6 -0
- data/test/match.rb +115 -0
- data/test/plugin/in_http.rb +84 -0
- data/test/plugin/in_stream.rb +136 -0
- data/test/plugin/out_copy.rb +55 -0
- data/test/plugin/out_file.rb +82 -0
- data/test/plugin/out_roundrobin.rb +65 -0
- data/test/plugin/out_stream.rb +74 -0
- metadata +224 -0
@@ -0,0 +1,224 @@
|
|
1
|
+
#
|
2
|
+
# Fluent
|
3
|
+
#
|
4
|
+
# Copyright (C) 2011 FURUHASHI Sadayuki
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
module Fluent
|
19
|
+
|
20
|
+
|
21
|
+
class EngineClass
|
22
|
+
def initialize
|
23
|
+
@matches = []
|
24
|
+
@sources = []
|
25
|
+
@match_cache = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def init
|
29
|
+
BasicSocket.do_not_reverse_lookup = true
|
30
|
+
Plugin.load_plugins
|
31
|
+
if defined?(Encoding)
|
32
|
+
Encoding.default_internal = 'ASCII-8BIT' if Encoding.respond_to?(:default_internal)
|
33
|
+
Encoding.default_external = 'ASCII-8BIT' if Encoding.respond_to?(:default_external)
|
34
|
+
end
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def read_config(path)
|
39
|
+
$log.info "reading config file", :path=>path
|
40
|
+
conf = Config.read(path)
|
41
|
+
configure(conf)
|
42
|
+
conf.check_not_fetched {|key,e|
|
43
|
+
$log.warn "parameter '#{key}' in #{e.to_s.strip} is not used."
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def configure(conf)
|
48
|
+
conf.elements.select {|e|
|
49
|
+
e.name == 'source'
|
50
|
+
}.each {|e|
|
51
|
+
type = e['type']
|
52
|
+
unless type
|
53
|
+
raise ConfigError, "Missing 'type' parameter on <source> directive"
|
54
|
+
end
|
55
|
+
$log.info "adding source type=#{type.dump}"
|
56
|
+
|
57
|
+
input = Plugin.new_input(type)
|
58
|
+
input.configure(e)
|
59
|
+
|
60
|
+
@sources << input
|
61
|
+
}
|
62
|
+
|
63
|
+
conf.elements.select {|e|
|
64
|
+
e.name == 'match'
|
65
|
+
}.each {|e|
|
66
|
+
type = e['type']
|
67
|
+
pattern = e.arg
|
68
|
+
unless type
|
69
|
+
raise ConfigError, "Missing 'type' parameter on <match #{e.arg}> directive"
|
70
|
+
end
|
71
|
+
$log.info "adding match", :pattern=>pattern, :type=>type
|
72
|
+
|
73
|
+
output = Plugin.new_output(type)
|
74
|
+
output.configure(e)
|
75
|
+
|
76
|
+
match = Match.new(pattern, output)
|
77
|
+
@matches << match
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def load_plugin_dir(dir)
|
82
|
+
Plugin.load_plugin_dir(dir)
|
83
|
+
end
|
84
|
+
|
85
|
+
def emit(tag, time, record)
|
86
|
+
emit_stream tag, OneEventStream.new(time, record)
|
87
|
+
end
|
88
|
+
|
89
|
+
def emit_array(tag, array)
|
90
|
+
emit_stream tag, ArrayEventStream.new(array)
|
91
|
+
end
|
92
|
+
|
93
|
+
def emit_stream(tag, es)
|
94
|
+
match = @match_cache[tag]
|
95
|
+
unless match
|
96
|
+
match = @matches.find {|m| m.match(tag) } || NoMatchMatch.new
|
97
|
+
if @match_cache.size < 1024 # TODO size limit
|
98
|
+
@match_cache[tag] = match
|
99
|
+
end
|
100
|
+
end
|
101
|
+
match.emit(tag, es)
|
102
|
+
rescue
|
103
|
+
$log.warn "emit transaction faild ", :error=>$!.to_s
|
104
|
+
$log.warn_backtrace
|
105
|
+
raise
|
106
|
+
end
|
107
|
+
|
108
|
+
def match?(tag)
|
109
|
+
@matches.find {|m| m.match(tag) }
|
110
|
+
end
|
111
|
+
|
112
|
+
def flush!
|
113
|
+
flush_recursive(@matches)
|
114
|
+
end
|
115
|
+
|
116
|
+
def now
|
117
|
+
# TODO thread update
|
118
|
+
Time.now.to_i
|
119
|
+
end
|
120
|
+
|
121
|
+
def run
|
122
|
+
start
|
123
|
+
|
124
|
+
if match?($log.tag)
|
125
|
+
$log.enable_event
|
126
|
+
end
|
127
|
+
|
128
|
+
# for empty loop
|
129
|
+
Coolio::Loop.default.attach Coolio::TimerWatcher.new(1, true)
|
130
|
+
# TODO attach async watch for thread pool
|
131
|
+
Coolio::Loop.default.run
|
132
|
+
|
133
|
+
shutdown
|
134
|
+
end
|
135
|
+
|
136
|
+
def stop
|
137
|
+
$log.info "shutting down fluentd"
|
138
|
+
Coolio::Loop.default.stop
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
def start
|
144
|
+
@matches.each {|m|
|
145
|
+
m.start
|
146
|
+
}
|
147
|
+
@sources.each {|s|
|
148
|
+
s.start
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
def shutdown
|
153
|
+
@matches.each {|m|
|
154
|
+
m.shutdown rescue nil
|
155
|
+
}
|
156
|
+
@sources.each {|s|
|
157
|
+
s.shutdown rescue nil
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
def flush_recursive(array)
|
162
|
+
array.each {|m|
|
163
|
+
begin
|
164
|
+
if m.is_a?(Match)
|
165
|
+
m = m.output
|
166
|
+
end
|
167
|
+
if m.is_a?(BufferedOutput)
|
168
|
+
m.try_flush
|
169
|
+
elsif m.is_a?(MultiOutput)
|
170
|
+
flush_recursive(m.outputs)
|
171
|
+
end
|
172
|
+
rescue
|
173
|
+
$log.debug "error while force flushing", :error=>$!.to_s
|
174
|
+
$log.debug_backtrace
|
175
|
+
end
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
class NoMatchMatch
|
180
|
+
def emit(tag, es)
|
181
|
+
$log.on_trace { $log.trace "no pattern matched", :tag=>tag }
|
182
|
+
end
|
183
|
+
|
184
|
+
def start
|
185
|
+
end
|
186
|
+
|
187
|
+
def shutdown
|
188
|
+
end
|
189
|
+
|
190
|
+
def match(tag)
|
191
|
+
false
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
Engine = EngineClass.new
|
197
|
+
|
198
|
+
|
199
|
+
module Test
|
200
|
+
@@test = false
|
201
|
+
|
202
|
+
def test?
|
203
|
+
@@test
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.setup
|
207
|
+
@@test = true
|
208
|
+
|
209
|
+
Fluent.__send__(:remove_const, :Engine)
|
210
|
+
engine = Fluent.const_set(:Engine, EngineClass.new).init
|
211
|
+
|
212
|
+
engine.define_singleton_method(:now=) {|n|
|
213
|
+
@now = n.to_i
|
214
|
+
}
|
215
|
+
engine.define_singleton_method(:now) {
|
216
|
+
@now || super()
|
217
|
+
}
|
218
|
+
|
219
|
+
nil
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
|
data/lib/fluent/env.rb
ADDED
data/lib/fluent/event.rb
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
#
|
2
|
+
# Fluent
|
3
|
+
#
|
4
|
+
# Copyright (C) 2011 FURUHASHI Sadayuki
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
module Fluent
|
19
|
+
|
20
|
+
|
21
|
+
class EventStream
|
22
|
+
include Enumerable
|
23
|
+
|
24
|
+
def repeatable?
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
#def each(&block)
|
29
|
+
#end
|
30
|
+
|
31
|
+
def to_msgpack_stream
|
32
|
+
out = ''
|
33
|
+
each {|record|
|
34
|
+
record.to_msgpack(out)
|
35
|
+
}
|
36
|
+
out
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
class OneEventStream < EventStream
|
42
|
+
def initialize(time, record)
|
43
|
+
@time = time
|
44
|
+
@record = record
|
45
|
+
end
|
46
|
+
|
47
|
+
def repeatable?
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
def each(&block)
|
52
|
+
block.call(@time, @record)
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
class ArrayEventStream < EventStream
|
59
|
+
def initialize(entries)
|
60
|
+
@entries = entries
|
61
|
+
end
|
62
|
+
|
63
|
+
def repeatable?
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
def empty?
|
68
|
+
@time_array.empty?
|
69
|
+
end
|
70
|
+
|
71
|
+
def each(&block)
|
72
|
+
@entries.each(&block)
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
|
76
|
+
#attr_reader :entries
|
77
|
+
#
|
78
|
+
#def to_a
|
79
|
+
# @entries
|
80
|
+
#end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
class MultiEventStream < EventStream
|
85
|
+
def initialize
|
86
|
+
@time_array = []
|
87
|
+
@record_array = []
|
88
|
+
end
|
89
|
+
|
90
|
+
def add(time, record)
|
91
|
+
@time_array << time
|
92
|
+
@record_array << record
|
93
|
+
end
|
94
|
+
|
95
|
+
def repeatable?
|
96
|
+
true
|
97
|
+
end
|
98
|
+
|
99
|
+
def empty?
|
100
|
+
@time_array.empty?
|
101
|
+
end
|
102
|
+
|
103
|
+
def each(&block)
|
104
|
+
time_array = @time_array
|
105
|
+
record_array = @record_array
|
106
|
+
for i in 0..time_array.length-1
|
107
|
+
block.call(time_array[i], record_array[i])
|
108
|
+
end
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
class MessagePackEventStream < EventStream
|
115
|
+
def initialize(data, cached_unpacker=nil)
|
116
|
+
@data = data
|
117
|
+
@unpacker = cached_unpacker || MessagePack::Unpacker.new
|
118
|
+
end
|
119
|
+
|
120
|
+
def repeatable?
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
def each(&block)
|
125
|
+
@unpacker.reset
|
126
|
+
# TODO format check
|
127
|
+
@unpacker.feed_each(@data, &block)
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
|
131
|
+
def to_msgpack_stream
|
132
|
+
@data
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
#class IoEventStream < EventStream
|
138
|
+
# def initialize(io, num)
|
139
|
+
# @io = io
|
140
|
+
# @num = num
|
141
|
+
# @u = MessagePack::Unpacker.new(@io)
|
142
|
+
# end
|
143
|
+
#
|
144
|
+
# def repeatable?
|
145
|
+
# false
|
146
|
+
# end
|
147
|
+
#
|
148
|
+
# def each(&block)
|
149
|
+
# return nil if @num == 0
|
150
|
+
# @u.each {|obj|
|
151
|
+
# block.call(obj[0], obj[1])
|
152
|
+
# break if @array.size >= @num
|
153
|
+
# }
|
154
|
+
# end
|
155
|
+
#end
|
156
|
+
|
157
|
+
|
158
|
+
end
|
159
|
+
|
data/lib/fluent/input.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#
|
2
|
+
# Fluent
|
3
|
+
#
|
4
|
+
# Copyright (C) 2011 FURUHASHI Sadayuki
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
module Fluent
|
19
|
+
|
20
|
+
|
21
|
+
class Input
|
22
|
+
include Configurable
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def configure(conf)
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def start
|
33
|
+
end
|
34
|
+
|
35
|
+
def shutdown
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
|
data/lib/fluent/load.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'socket'
|
3
|
+
require 'time'
|
4
|
+
require 'monitor'
|
5
|
+
require 'stringio'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'json'
|
8
|
+
require 'msgpack'
|
9
|
+
require 'cool.io'
|
10
|
+
require 'cool.io/eventmachine'
|
11
|
+
require 'fluent/env'
|
12
|
+
require 'fluent/version'
|
13
|
+
require 'fluent/log'
|
14
|
+
require 'fluent/config'
|
15
|
+
require 'fluent/engine'
|
16
|
+
require 'fluent/mixin'
|
17
|
+
require 'fluent/plugin'
|
18
|
+
require 'fluent/parser'
|
19
|
+
require 'fluent/event'
|
20
|
+
require 'fluent/buffer'
|
21
|
+
require 'fluent/input'
|
22
|
+
require 'fluent/output'
|
23
|
+
require 'fluent/match'
|