fluentd 0.10.35 → 0.10.36
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/.travis.yml +13 -0
- data/ChangeLog +9 -0
- data/fluentd.gemspec +1 -1
- data/lib/fluent/buffer.rb +210 -214
- data/lib/fluent/command/fluentd.rb +4 -0
- data/lib/fluent/config.rb +1 -0
- data/lib/fluent/engine.rb +10 -10
- data/lib/fluent/output.rb +404 -406
- data/lib/fluent/plugin/buf_file.rb +146 -151
- data/lib/fluent/plugin/buf_memory.rb +62 -67
- data/lib/fluent/plugin/in_debug_agent.rb +27 -31
- data/lib/fluent/plugin/in_exec.rb +86 -90
- data/lib/fluent/plugin/in_forward.rb +171 -171
- data/lib/fluent/plugin/in_gc_stat.rb +43 -47
- data/lib/fluent/plugin/in_http.rb +214 -216
- data/lib/fluent/plugin/in_monitor_agent.rb +212 -214
- data/lib/fluent/plugin/in_object_space.rb +75 -79
- data/lib/fluent/plugin/in_status.rb +44 -50
- data/lib/fluent/plugin/in_stream.rb +159 -160
- data/lib/fluent/plugin/in_syslog.rb +149 -153
- data/lib/fluent/plugin/in_tail.rb +382 -387
- data/lib/fluent/plugin/out_copy.rb +40 -45
- data/lib/fluent/plugin/out_exec.rb +52 -57
- data/lib/fluent/plugin/out_exec_filter.rb +327 -331
- data/lib/fluent/plugin/out_file.rb +78 -74
- data/lib/fluent/plugin/out_forward.rb +410 -414
- data/lib/fluent/plugin/out_null.rb +15 -19
- data/lib/fluent/plugin/out_roundrobin.rb +63 -68
- data/lib/fluent/plugin/out_stdout.rb +9 -14
- data/lib/fluent/plugin/out_stream.rb +83 -90
- data/lib/fluent/plugin/out_test.rb +42 -46
- data/lib/fluent/supervisor.rb +15 -0
- data/lib/fluent/version.rb +1 -1
- data/test/plugin/in_stream.rb +2 -0
- data/test/plugin/out_file.rb +19 -1
- metadata +6 -5
@@ -16,192 +16,187 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
module Fluent
|
19
|
+
class FileBufferChunk < BufferChunk
|
20
|
+
def initialize(key, path, unique_id, mode="a+")
|
21
|
+
super(key)
|
22
|
+
@path = path
|
23
|
+
@unique_id = unique_id
|
24
|
+
@file = File.open(@path, mode, DEFAULT_FILE_PERMISSION)
|
25
|
+
@file.sync = true
|
26
|
+
@size = @file.stat.size
|
27
|
+
end
|
19
28
|
|
29
|
+
attr_reader :unique_id
|
20
30
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
@unique_id = unique_id
|
26
|
-
@file = File.open(@path, mode, DEFAULT_FILE_PERMISSION)
|
27
|
-
@file.sync = true
|
28
|
-
@size = @file.stat.size
|
29
|
-
end
|
30
|
-
|
31
|
-
attr_reader :unique_id
|
32
|
-
|
33
|
-
def <<(data)
|
34
|
-
@file.write(data)
|
35
|
-
@size += data.bytesize
|
36
|
-
end
|
31
|
+
def <<(data)
|
32
|
+
@file.write(data)
|
33
|
+
@size += data.bytesize
|
34
|
+
end
|
37
35
|
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
def size
|
37
|
+
@size
|
38
|
+
end
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
def empty?
|
41
|
+
@size == 0
|
42
|
+
end
|
45
43
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
44
|
+
def close
|
45
|
+
stat = @file.stat
|
46
|
+
@file.close
|
47
|
+
if stat.size == 0
|
48
|
+
File.unlink(@path)
|
49
|
+
end
|
51
50
|
end
|
52
|
-
end
|
53
51
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
def purge
|
53
|
+
@file.close
|
54
|
+
File.unlink(@path) rescue nil # TODO rescue?
|
55
|
+
end
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
def read
|
58
|
+
@file.pos = 0
|
59
|
+
@file.read
|
60
|
+
end
|
63
61
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
def open(&block)
|
63
|
+
@file.pos = 0
|
64
|
+
yield @file
|
65
|
+
end
|
68
66
|
|
69
|
-
|
67
|
+
attr_reader :path
|
70
68
|
|
71
|
-
|
72
|
-
|
73
|
-
|
69
|
+
def mv(path)
|
70
|
+
File.rename(@path, path)
|
71
|
+
@path = path
|
72
|
+
end
|
74
73
|
end
|
75
|
-
end
|
76
74
|
|
75
|
+
class FileBuffer < BasicBuffer
|
76
|
+
Plugin.register_buffer('file', self)
|
77
77
|
|
78
|
-
|
79
|
-
|
78
|
+
def initialize
|
79
|
+
require 'uri'
|
80
|
+
super
|
81
|
+
end
|
80
82
|
|
81
|
-
|
82
|
-
require 'uri'
|
83
|
-
super
|
84
|
-
end
|
83
|
+
config_param :buffer_path, :string
|
85
84
|
|
86
|
-
|
85
|
+
def configure(conf)
|
86
|
+
super
|
87
87
|
|
88
|
-
|
89
|
-
|
88
|
+
if pos = @buffer_path.index('*')
|
89
|
+
@buffer_path_prefix = @buffer_path[0,pos]
|
90
|
+
@buffer_path_suffix = @buffer_path[pos+1..-1]
|
91
|
+
else
|
92
|
+
@buffer_path_prefix = @buffer_path+"."
|
93
|
+
@buffer_path_suffix = ".log"
|
94
|
+
end
|
90
95
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
@buffer_path_suffix = ".log"
|
96
|
+
if flush_at_shutdown = conf['flush_at_shutdown']
|
97
|
+
@flush_at_shutdown = true
|
98
|
+
else
|
99
|
+
@flush_at_shutdown = false
|
100
|
+
end
|
97
101
|
end
|
98
102
|
|
99
|
-
|
100
|
-
@
|
101
|
-
|
102
|
-
@flush_at_shutdown = false
|
103
|
+
def start
|
104
|
+
FileUtils.mkdir_p File.dirname(@buffer_path_prefix+"path")
|
105
|
+
super
|
103
106
|
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def start
|
107
|
-
FileUtils.mkdir_p File.dirname(@buffer_path_prefix+"path")
|
108
|
-
super
|
109
|
-
end
|
110
107
|
|
111
|
-
|
108
|
+
PATH_MATCH = /^(.*)[\._](b|q)([0-9a-fA-F]{1,32})$/
|
112
109
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
110
|
+
def new_chunk(key)
|
111
|
+
encoded_key = encode_key(key)
|
112
|
+
path, tsuffix = make_path(encoded_key, "b")
|
113
|
+
unique_id = tsuffix_to_unique_id(tsuffix)
|
114
|
+
FileBufferChunk.new(key, path, unique_id)
|
115
|
+
end
|
119
116
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
117
|
+
def resume
|
118
|
+
maps = []
|
119
|
+
queues = []
|
120
|
+
|
121
|
+
Dir.glob("#{@buffer_path_prefix}*#{@buffer_path_suffix}") {|path|
|
122
|
+
match = path[@buffer_path_prefix.length..-(@buffer_path_suffix.length+1)]
|
123
|
+
if m = PATH_MATCH.match(match)
|
124
|
+
key = decode_key(m[1])
|
125
|
+
bq = m[2]
|
126
|
+
tsuffix = m[3]
|
127
|
+
timestamp = m[3].to_i(16)
|
128
|
+
unique_id = tsuffix_to_unique_id(tsuffix)
|
129
|
+
|
130
|
+
if bq == 'b'
|
131
|
+
chunk = FileBufferChunk.new(key, path, unique_id, "a+")
|
132
|
+
maps << [timestamp, chunk]
|
133
|
+
elsif bq == 'q'
|
134
|
+
chunk = FileBufferChunk.new(key, path, unique_id, "r")
|
135
|
+
queues << [timestamp, chunk]
|
136
|
+
end
|
139
137
|
end
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
timestamp
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
timestamp
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
end
|
138
|
+
}
|
139
|
+
|
140
|
+
map = {}
|
141
|
+
maps.sort_by {|(timestamp,chunk)|
|
142
|
+
timestamp
|
143
|
+
}.each {|(timestamp,chunk)|
|
144
|
+
map[chunk.key] = chunk
|
145
|
+
}
|
146
|
+
|
147
|
+
queue = queues.sort_by {|(timestamp,chunk)|
|
148
|
+
timestamp
|
149
|
+
}.map {|(timestamp,chunk)|
|
150
|
+
chunk
|
151
|
+
}
|
152
|
+
|
153
|
+
return queue, map
|
154
|
+
end
|
158
155
|
|
159
|
-
|
160
|
-
|
161
|
-
|
156
|
+
def enqueue(chunk)
|
157
|
+
path = chunk.path
|
158
|
+
mp = path[@buffer_path_prefix.length..-(@buffer_path_suffix.length+1)]
|
162
159
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
160
|
+
m = PATH_MATCH.match(mp)
|
161
|
+
encoded_key = m ? m[1] : ""
|
162
|
+
tsuffix = m[3]
|
163
|
+
npath = "#{@buffer_path_prefix}#{encoded_key}.q#{tsuffix}#{@buffer_path_suffix}"
|
167
164
|
|
168
|
-
|
169
|
-
|
165
|
+
chunk.mv(npath)
|
166
|
+
end
|
170
167
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
168
|
+
def before_shutdown(out)
|
169
|
+
if @flush_at_shutdown
|
170
|
+
synchronize do
|
171
|
+
@map.each_key {|key|
|
172
|
+
push(key)
|
173
|
+
}
|
174
|
+
while pop(out)
|
175
|
+
end
|
178
176
|
end
|
179
177
|
end
|
180
178
|
end
|
181
|
-
end
|
182
179
|
|
183
|
-
|
184
|
-
def encode_key(key)
|
185
|
-
URI.escape(key, /[^-_.a-zA-Z0-9]/n)
|
186
|
-
end
|
180
|
+
protected
|
187
181
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
def make_path(encoded_key, bq)
|
193
|
-
now = Time.now.utc
|
194
|
-
timestamp = ((now.to_i*1000*1000+now.usec) << 12 | rand(0xfff))
|
195
|
-
tsuffix = timestamp.to_s(16)
|
196
|
-
path = "#{@buffer_path_prefix}#{encoded_key}.#{bq}#{tsuffix}#{@buffer_path_suffix}"
|
197
|
-
return path, tsuffix
|
198
|
-
end
|
182
|
+
def encode_key(key)
|
183
|
+
URI.escape(key, /[^-_.a-zA-Z0-9]/n)
|
184
|
+
end
|
199
185
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
end
|
186
|
+
def decode_key(encoded_key)
|
187
|
+
URI.unescape(encoded_key)
|
188
|
+
end
|
204
189
|
|
190
|
+
def make_path(encoded_key, bq)
|
191
|
+
now = Time.now.utc
|
192
|
+
timestamp = ((now.to_i*1000*1000+now.usec) << 12 | rand(0xfff))
|
193
|
+
tsuffix = timestamp.to_s(16)
|
194
|
+
path = "#{@buffer_path_prefix}#{encoded_key}.#{bq}#{tsuffix}#{@buffer_path_suffix}"
|
195
|
+
return path, tsuffix
|
196
|
+
end
|
205
197
|
|
198
|
+
def tsuffix_to_unique_id(tsuffix)
|
199
|
+
tsuffix.scan(/../).map {|x| x.to_i(16) }.pack('C*') * 2
|
200
|
+
end
|
201
|
+
end
|
206
202
|
end
|
207
|
-
|
@@ -16,93 +16,88 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
module Fluent
|
19
|
+
class MemoryBufferChunk < BufferChunk
|
20
|
+
def initialize(key, data='')
|
21
|
+
@data = data
|
22
|
+
@data.force_encoding('ASCII-8BIT')
|
23
|
+
now = Time.now.utc
|
24
|
+
u1 = ((now.to_i*1000*1000+now.usec) << 12 | rand(0xfff))
|
25
|
+
@unique_id = [u1 >> 32, u1 & u1 & 0xffffffff, rand(0xffffffff), rand(0xffffffff)].pack('NNNN')
|
26
|
+
super(key)
|
27
|
+
end
|
19
28
|
|
29
|
+
attr_reader :unique_id
|
20
30
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
now = Time.now.utc
|
26
|
-
u1 = ((now.to_i*1000*1000+now.usec) << 12 | rand(0xfff))
|
27
|
-
@unique_id = [u1 >> 32, u1 & u1 & 0xffffffff, rand(0xffffffff), rand(0xffffffff)].pack('NNNN')
|
28
|
-
super(key)
|
29
|
-
end
|
30
|
-
|
31
|
-
attr_reader :unique_id
|
32
|
-
|
33
|
-
def <<(data)
|
34
|
-
data.force_encoding('ASCII-8BIT')
|
35
|
-
@data << data
|
36
|
-
end
|
31
|
+
def <<(data)
|
32
|
+
data.force_encoding('ASCII-8BIT')
|
33
|
+
@data << data
|
34
|
+
end
|
37
35
|
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
def size
|
37
|
+
@data.bytesize
|
38
|
+
end
|
41
39
|
|
42
|
-
|
43
|
-
|
40
|
+
def close
|
41
|
+
end
|
44
42
|
|
45
|
-
|
46
|
-
|
43
|
+
def purge
|
44
|
+
end
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
def read
|
47
|
+
@data
|
48
|
+
end
|
51
49
|
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
def open(&block)
|
51
|
+
StringIO.open(@data, &block)
|
52
|
+
end
|
55
53
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
54
|
+
# optimize
|
55
|
+
def write_to(io)
|
56
|
+
io.write @data
|
57
|
+
end
|
60
58
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
59
|
+
# optimize
|
60
|
+
def msgpack_each(&block)
|
61
|
+
u = MessagePack::Unpacker.new
|
62
|
+
u.feed_each(@data, &block)
|
63
|
+
end
|
65
64
|
end
|
66
|
-
end
|
67
65
|
|
68
66
|
|
69
|
-
class MemoryBuffer < BasicBuffer
|
70
|
-
|
67
|
+
class MemoryBuffer < BasicBuffer
|
68
|
+
Plugin.register_buffer('memory', self)
|
71
69
|
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
def initialize
|
71
|
+
super
|
72
|
+
end
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
# Overwrite default BasicBuffer#buffer_queue_limit
|
75
|
+
# to limit total memory usage upto 512MB.
|
76
|
+
config_set_default :buffer_queue_limit, 64
|
79
77
|
|
80
|
-
|
81
|
-
|
82
|
-
|
78
|
+
def configure(conf)
|
79
|
+
super
|
80
|
+
end
|
83
81
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
82
|
+
def before_shutdown(out)
|
83
|
+
synchronize do
|
84
|
+
@map.each_key {|key|
|
85
|
+
push(key)
|
86
|
+
}
|
87
|
+
while pop(out)
|
88
|
+
end
|
90
89
|
end
|
91
90
|
end
|
92
|
-
end
|
93
91
|
|
94
|
-
|
95
|
-
|
96
|
-
|
92
|
+
def new_chunk(key)
|
93
|
+
MemoryBufferChunk.new(key)
|
94
|
+
end
|
97
95
|
|
98
|
-
|
99
|
-
|
100
|
-
|
96
|
+
def resume
|
97
|
+
return [], {}
|
98
|
+
end
|
101
99
|
|
102
|
-
|
100
|
+
def enqueue(chunk)
|
101
|
+
end
|
103
102
|
end
|
104
103
|
end
|
105
|
-
|
106
|
-
|
107
|
-
end
|
108
|
-
|