fluentd 0.10.58 → 0.10.59
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 -0
- data/ChangeLog +12 -0
- data/Gemfile +6 -0
- data/fluent.conf +20 -20
- data/lib/fluent/config/v1_parser.rb +8 -1
- data/lib/fluent/engine.rb +2 -2
- data/lib/fluent/output.rb +14 -4
- data/lib/fluent/parser.rb +2 -2
- data/lib/fluent/plugin/buf_file.rb +1 -5
- data/lib/fluent/plugin/in_tail.rb +13 -10
- data/lib/fluent/supervisor.rb +10 -4
- data/lib/fluent/version.rb +1 -1
- data/test/test_output.rb +87 -0
- data/test/test_parser.rb +25 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 434f3deef039256104205794d09c06668a82e8c4
|
4
|
+
data.tar.gz: 296981ab483797547447a60ce944987be7ff7431
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f5cd6aef58345917d17e5ab6560d610954eba3f3043cad59d9a446f5b4aa4964e2d118e94a9b1be31610558fba1cccb74430fda55eb9e1e8744b6afee865af8
|
7
|
+
data.tar.gz: 2e6a4d27834b6cff8f8b7efe1cb1da480f935dd2e958f78aec5ded158e490216e311bcfc40437cf4caeba01248b88c4be4825dfd8f1ca36ba5673a4079f2209f
|
data/.gitignore
CHANGED
data/ChangeLog
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
Release 0.10.59 - 2014/01/23
|
2
|
+
|
3
|
+
* in_tail: Support 64bit inode environment in in_tail
|
4
|
+
* parser: nginx and apache2 format can now parse access log without http-version
|
5
|
+
* buffer: Fix broken calc_retry_wait if Integer is used for retry_wait parameter
|
6
|
+
* buffer: Fix to flush a buffer by USR1 signal even on retrying
|
7
|
+
* buffer: Fix TimeSlicedOutput doesn't flush with SIGUSR1
|
8
|
+
* config: Support @ prefix build-in parameters
|
9
|
+
* engine:Fix ThreadError occuring on Signal.trap SIGHUP
|
10
|
+
* engine: Fix SIGHUP does not reload config
|
11
|
+
* Revert fluent.conf since @type, @id are not available with v0 config
|
12
|
+
|
1
13
|
Release 0.10.58 - 2014/12/14
|
2
14
|
|
3
15
|
* parser/formatter: Add base class and Plugin.new_xxx/Plugin.register_xxx APIs
|
data/Gemfile
CHANGED
@@ -1,3 +1,9 @@
|
|
1
1
|
source 'https://rubygems.org/'
|
2
2
|
|
3
3
|
gemspec
|
4
|
+
|
5
|
+
local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
|
6
|
+
if File.exist?(local_gemfile)
|
7
|
+
puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v`
|
8
|
+
instance_eval File.read(local_gemfile)
|
9
|
+
end
|
data/fluent.conf
CHANGED
@@ -4,20 +4,20 @@
|
|
4
4
|
## built-in TCP input
|
5
5
|
## $ echo <json> | fluent-cat <tag>
|
6
6
|
<source>
|
7
|
-
|
8
|
-
|
7
|
+
type forward
|
8
|
+
id forward_input
|
9
9
|
</source>
|
10
10
|
|
11
11
|
## built-in UNIX socket input
|
12
12
|
#<source>
|
13
|
-
#
|
13
|
+
# type unix
|
14
14
|
#</source>
|
15
15
|
|
16
16
|
# HTTP input
|
17
17
|
# http://localhost:8888/<tag>?json=<json>
|
18
18
|
<source>
|
19
|
-
|
20
|
-
|
19
|
+
type http
|
20
|
+
id http_input
|
21
21
|
|
22
22
|
port 8888
|
23
23
|
</source>
|
@@ -25,7 +25,7 @@
|
|
25
25
|
## File input
|
26
26
|
## read apache logs with tag=apache.access
|
27
27
|
#<source>
|
28
|
-
#
|
28
|
+
# type tail
|
29
29
|
# format apache
|
30
30
|
# path /var/log/httpd-access.log
|
31
31
|
# tag apache.access
|
@@ -36,16 +36,16 @@
|
|
36
36
|
# http://localhost:24220/api/plugins?type=TYPE
|
37
37
|
# http://localhost:24220/api/plugins?tag=MYTAG
|
38
38
|
<source>
|
39
|
-
|
40
|
-
|
39
|
+
type monitor_agent
|
40
|
+
id monitor_agent_input
|
41
41
|
|
42
42
|
port 24220
|
43
43
|
</source>
|
44
44
|
|
45
45
|
# Listen DRb for debug
|
46
46
|
<source>
|
47
|
-
|
48
|
-
|
47
|
+
type debug_agent
|
48
|
+
id debug_agent_input
|
49
49
|
|
50
50
|
bind 127.0.0.1
|
51
51
|
port 24230
|
@@ -53,20 +53,20 @@
|
|
53
53
|
|
54
54
|
## match tag=apache.access and write to file
|
55
55
|
#<match apache.access>
|
56
|
-
#
|
56
|
+
# type file
|
57
57
|
# path /var/log/fluent/access
|
58
58
|
#</match>
|
59
59
|
|
60
60
|
## match tag=debug.** and dump to console
|
61
61
|
<match debug.**>
|
62
|
-
|
63
|
-
|
62
|
+
type stdout
|
63
|
+
id stdout_output
|
64
64
|
</match>
|
65
65
|
|
66
66
|
# match tag=system.** and forward to another fluent server
|
67
67
|
<match system.**>
|
68
|
-
|
69
|
-
|
68
|
+
type forward
|
69
|
+
id forward_output
|
70
70
|
|
71
71
|
<server>
|
72
72
|
host 192.168.0.11
|
@@ -80,9 +80,9 @@
|
|
80
80
|
|
81
81
|
## match tag=myapp.** and forward and write to file
|
82
82
|
#<match myapp.**>
|
83
|
-
#
|
83
|
+
# type copy
|
84
84
|
# <store>
|
85
|
-
#
|
85
|
+
# type forward
|
86
86
|
# buffer_type file
|
87
87
|
# buffer_path /var/log/fluent/myapp-forward
|
88
88
|
# retry_limit 50
|
@@ -92,19 +92,19 @@
|
|
92
92
|
# </server>
|
93
93
|
# </store>
|
94
94
|
# <store>
|
95
|
-
#
|
95
|
+
# type file
|
96
96
|
# path /var/log/fluent/myapp
|
97
97
|
# </store>
|
98
98
|
#</match>
|
99
99
|
|
100
100
|
## match fluent's internal events
|
101
101
|
#<match fluent.**>
|
102
|
-
#
|
102
|
+
# type null
|
103
103
|
#</match>
|
104
104
|
|
105
105
|
## match not matched logs and write to file
|
106
106
|
#<match **>
|
107
|
-
#
|
107
|
+
# type file
|
108
108
|
# path /var/log/fluent/else
|
109
109
|
# compress gz
|
110
110
|
#</match>
|
@@ -13,6 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
|
+
|
16
17
|
module Fluent
|
17
18
|
module Config
|
18
19
|
|
@@ -50,7 +51,7 @@ module Fluent
|
|
50
51
|
end
|
51
52
|
|
52
53
|
ELEM_SYMBOLS = ['match', 'source', 'filter', 'system']
|
53
|
-
RESERVED_PARAMS = %W(@type @id
|
54
|
+
RESERVED_PARAMS = %W(@type @id)
|
54
55
|
|
55
56
|
def parse_element(root_element, elem_name, attrs = {}, elems = [])
|
56
57
|
while true
|
@@ -108,6 +109,12 @@ module Fluent
|
|
108
109
|
else
|
109
110
|
if k == '@include'
|
110
111
|
parse_include(attrs, elems)
|
112
|
+
elsif RESERVED_PARAMS.include?(k)
|
113
|
+
v = parse_literal
|
114
|
+
unless line_end
|
115
|
+
parse_error! "expected end of line"
|
116
|
+
end
|
117
|
+
attrs[k] = v
|
111
118
|
else
|
112
119
|
if k.start_with?('@')
|
113
120
|
if root_element || ELEM_SYMBOLS.include?(elem_name)
|
data/lib/fluent/engine.rb
CHANGED
@@ -100,7 +100,7 @@ module Fluent
|
|
100
100
|
conf.elements.select {|e|
|
101
101
|
e.name == 'source'
|
102
102
|
}.each {|e|
|
103
|
-
type = e['type']
|
103
|
+
type = e['@type'] || e['type']
|
104
104
|
unless type
|
105
105
|
raise ConfigError, "Missing 'type' parameter on <source> directive"
|
106
106
|
end
|
@@ -116,7 +116,7 @@ module Fluent
|
|
116
116
|
conf.elements.select {|e|
|
117
117
|
e.name == 'match'
|
118
118
|
}.each {|e|
|
119
|
-
type = e['type']
|
119
|
+
type = e['@type'] || e['type']
|
120
120
|
pattern = e.arg
|
121
121
|
unless type
|
122
122
|
raise ConfigError, "Missing 'type' parameter on <match #{e.arg}> directive"
|
data/lib/fluent/output.rb
CHANGED
@@ -188,6 +188,7 @@ module Fluent
|
|
188
188
|
def configure(conf)
|
189
189
|
super
|
190
190
|
|
191
|
+
@retry_wait = @retry_wait.to_f # converted to Float for calc_retry_wait
|
191
192
|
@buffer = Plugin.new_buffer(@buffer_type)
|
192
193
|
@buffer.configure(conf)
|
193
194
|
|
@@ -267,7 +268,7 @@ module Fluent
|
|
267
268
|
#def write(chunk)
|
268
269
|
#end
|
269
270
|
|
270
|
-
def enqueue_buffer
|
271
|
+
def enqueue_buffer(force = false)
|
271
272
|
@buffer.keys.each {|key|
|
272
273
|
@buffer.push(key)
|
273
274
|
}
|
@@ -378,7 +379,10 @@ module Fluent
|
|
378
379
|
end
|
379
380
|
|
380
381
|
def force_flush
|
381
|
-
|
382
|
+
@num_errors_lock.synchronize do
|
383
|
+
@next_retry_time = Engine.now - 1
|
384
|
+
end
|
385
|
+
enqueue_buffer(true)
|
382
386
|
submit_flush
|
383
387
|
end
|
384
388
|
|
@@ -546,8 +550,14 @@ module Fluent
|
|
546
550
|
}
|
547
551
|
end
|
548
552
|
|
549
|
-
def enqueue_buffer
|
550
|
-
|
553
|
+
def enqueue_buffer(force = false)
|
554
|
+
if force
|
555
|
+
@buffer.keys.each {|key|
|
556
|
+
@buffer.push(key)
|
557
|
+
}
|
558
|
+
else
|
559
|
+
@enqueue_buffer_proc.call
|
560
|
+
end
|
551
561
|
end
|
552
562
|
|
553
563
|
#def format(tag, event)
|
data/lib/fluent/parser.rb
CHANGED
@@ -408,7 +408,7 @@ module Fluent
|
|
408
408
|
end
|
409
409
|
|
410
410
|
class ApacheParser < Parser
|
411
|
-
REGEXP = /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[
|
411
|
+
REGEXP = /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
|
412
412
|
TIME_FORMAT = "%d/%b/%Y:%H:%M:%S %z"
|
413
413
|
|
414
414
|
def initialize
|
@@ -632,7 +632,7 @@ module Fluent
|
|
632
632
|
'tsv' => Proc.new { TSVParser.new },
|
633
633
|
'ltsv' => Proc.new { LabeledTSVParser.new },
|
634
634
|
'csv' => Proc.new { CSVParser.new },
|
635
|
-
'nginx' => Proc.new { RegexpParser.new(/^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]
|
635
|
+
'nginx' => Proc.new { RegexpParser.new(/^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/, {'time_format'=>"%d/%b/%Y:%H:%M:%S %z"}) },
|
636
636
|
'none' => Proc.new { NoneParser.new },
|
637
637
|
'multiline' => Proc.new { MultilineParser.new },
|
638
638
|
}.each { |name, factory|
|
@@ -84,6 +84,7 @@ module Fluent
|
|
84
84
|
end
|
85
85
|
|
86
86
|
config_param :buffer_path, :string
|
87
|
+
config_param :flush_at_shutdown, :bool, :default => false
|
87
88
|
|
88
89
|
attr_accessor :symlink_path
|
89
90
|
|
@@ -104,11 +105,6 @@ module Fluent
|
|
104
105
|
@buffer_path_suffix = ".log"
|
105
106
|
end
|
106
107
|
|
107
|
-
if flush_at_shutdown = conf['flush_at_shutdown']
|
108
|
-
@flush_at_shutdown = true
|
109
|
-
else
|
110
|
-
@flush_at_shutdown = false
|
111
|
-
end
|
112
108
|
end
|
113
109
|
|
114
110
|
def start
|
@@ -598,7 +598,7 @@ module Fluent
|
|
598
598
|
@file.write path
|
599
599
|
@file.write "\t"
|
600
600
|
seek = @file.pos
|
601
|
-
@file.write "0000000000000000\
|
601
|
+
@file.write "0000000000000000\t0000000000000000\n"
|
602
602
|
@last_pos = @file.pos
|
603
603
|
|
604
604
|
@map[path] = FilePositionEntry.new(@file, seek)
|
@@ -624,12 +624,15 @@ module Fluent
|
|
624
624
|
# Clean up unwatched file entries
|
625
625
|
def self.compact(file)
|
626
626
|
file.pos = 0
|
627
|
-
existent_entries = file.each_line.
|
627
|
+
existent_entries = file.each_line.map { |line|
|
628
628
|
m = /^([^\t]+)\t([0-9a-fA-F]+)\t([0-9a-fA-F]+)/.match(line)
|
629
629
|
next unless m
|
630
|
+
path = m[1]
|
630
631
|
pos = m[2].to_i(16)
|
631
|
-
|
632
|
-
|
632
|
+
ino = m[3].to_i(16)
|
633
|
+
# 32bit inode converted to 64bit at this phase
|
634
|
+
pos == UNWATCHED_POSITION ? nil : ("%s\t%016x\t%016x\n" % [path, pos, ino])
|
635
|
+
}.compact
|
633
636
|
|
634
637
|
file.pos = 0
|
635
638
|
file.truncate(0)
|
@@ -638,13 +641,13 @@ module Fluent
|
|
638
641
|
end
|
639
642
|
|
640
643
|
# pos inode
|
641
|
-
# ffffffffffffffff\
|
644
|
+
# ffffffffffffffff\tffffffffffffffff\n
|
642
645
|
class FilePositionEntry
|
643
646
|
POS_SIZE = 16
|
644
647
|
INO_OFFSET = 17
|
645
|
-
INO_SIZE =
|
646
|
-
LN_OFFSET =
|
647
|
-
SIZE =
|
648
|
+
INO_SIZE = 16
|
649
|
+
LN_OFFSET = 33
|
650
|
+
SIZE = 34
|
648
651
|
|
649
652
|
def initialize(file, seek)
|
650
653
|
@file = file
|
@@ -653,7 +656,7 @@ module Fluent
|
|
653
656
|
|
654
657
|
def update(ino, pos)
|
655
658
|
@file.pos = @seek
|
656
|
-
@file.write "%016x\t%
|
659
|
+
@file.write "%016x\t%016x" % [pos, ino]
|
657
660
|
end
|
658
661
|
|
659
662
|
def update_pos(pos)
|
@@ -663,7 +666,7 @@ module Fluent
|
|
663
666
|
|
664
667
|
def read_inode
|
665
668
|
@file.pos = @seek + INO_OFFSET
|
666
|
-
raw = @file.read(
|
669
|
+
raw = @file.read(16)
|
667
670
|
raw ? raw.to_i(16) : 0
|
668
671
|
end
|
669
672
|
|
data/lib/fluent/supervisor.rb
CHANGED
@@ -323,10 +323,16 @@ module Fluent
|
|
323
323
|
trap :HUP do
|
324
324
|
$log.debug "fluentd supervisor process get SIGHUP"
|
325
325
|
$log.info "restarting"
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
326
|
+
# Creating new thread due to mutex can't lock
|
327
|
+
# in main thread during trap context
|
328
|
+
Thread.new {
|
329
|
+
read_config
|
330
|
+
apply_system_config
|
331
|
+
if pid = @main_pid
|
332
|
+
Process.kill(:TERM, pid)
|
333
|
+
# don't resuce Erro::ESRSH here (invalid status)
|
334
|
+
end
|
335
|
+
}.run
|
330
336
|
end
|
331
337
|
|
332
338
|
trap :USR1 do
|
data/lib/fluent/version.rb
CHANGED
data/test/test_output.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require_relative 'helper'
|
2
2
|
require 'fluent/test'
|
3
3
|
require 'fluent/output'
|
4
|
+
require 'timecop'
|
5
|
+
require 'flexmock'
|
4
6
|
|
5
7
|
module FluentOutputTest
|
6
8
|
include Fluent
|
9
|
+
include FlexMock::TestCase
|
7
10
|
|
8
11
|
class BufferedOutputTest < ::Test::Unit::TestCase
|
9
12
|
include FluentOutputTest
|
@@ -42,6 +45,10 @@ module FluentOutputTest
|
|
42
45
|
# disable_retry_limit
|
43
46
|
d = create_driver(CONFIG + %[disable_retry_limit true])
|
44
47
|
assert_equal true, d.instance.disable_retry_limit
|
48
|
+
|
49
|
+
# retry_wait is converted to Float for calc_retry_wait
|
50
|
+
d = create_driver(CONFIG + %[retry_wait 1s])
|
51
|
+
assert_equal Float, d.instance.retry_wait.class
|
45
52
|
end
|
46
53
|
|
47
54
|
def test_calc_retry_wait
|
@@ -62,6 +69,14 @@ module FluentOutputTest
|
|
62
69
|
assert_equal 4, d.instance.calc_retry_wait
|
63
70
|
end
|
64
71
|
|
72
|
+
def test_calc_retry_wait_with_integer_retry_wait
|
73
|
+
d = create_driver(CONFIG + %[retry_wait 2s])
|
74
|
+
d.instance.retry_limit.times {
|
75
|
+
d.instance.instance_eval { @num_errors += 1 }
|
76
|
+
}
|
77
|
+
assert_equal true, d.instance.calc_retry_wait.finite?
|
78
|
+
end
|
79
|
+
|
65
80
|
def test_large_num_retries
|
66
81
|
# Test that everything works properly after a very large number of
|
67
82
|
# retries and we hit the expected max_retry_wait.
|
@@ -146,5 +161,77 @@ module FluentOutputTest
|
|
146
161
|
assert_true d.instance.respond_to?(:router=)
|
147
162
|
assert_true d.instance.router.respond_to?(:emit)
|
148
163
|
end
|
164
|
+
|
165
|
+
sub_test_case "test_force_flush" do
|
166
|
+
setup do
|
167
|
+
time = Time.parse("2011-01-02 13:14:15 UTC")
|
168
|
+
Timecop.freeze(time)
|
169
|
+
@time = time.to_i
|
170
|
+
end
|
171
|
+
|
172
|
+
teardown do
|
173
|
+
Timecop.return
|
174
|
+
end
|
175
|
+
|
176
|
+
test "force_flush works on retrying" do
|
177
|
+
d = create_driver(CONFIG)
|
178
|
+
d.instance.start
|
179
|
+
buffer = d.instance.instance_variable_get(:@buffer)
|
180
|
+
# imitate 10 failures
|
181
|
+
d.instance.instance_variable_set(:@num_errors, 10)
|
182
|
+
d.instance.instance_variable_set(:@next_retry_time, @time + d.instance.calc_retry_wait)
|
183
|
+
# buffer should be popped (flushed) immediately
|
184
|
+
flexmock(buffer).should_receive(:pop).once
|
185
|
+
# force_flush
|
186
|
+
buffer.emit("test", 'test', NullOutputChain.instance)
|
187
|
+
d.instance.force_flush
|
188
|
+
10.times { sleep 0.05 }
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
class TimeSlicedOutputTest < ::Test::Unit::TestCase
|
194
|
+
include FluentOutputTest
|
195
|
+
include FlexMock::TestCase
|
196
|
+
|
197
|
+
def setup
|
198
|
+
Fluent::Test.setup
|
199
|
+
FileUtils.rm_rf(TMP_DIR)
|
200
|
+
FileUtils.mkdir_p(TMP_DIR)
|
201
|
+
end
|
202
|
+
|
203
|
+
TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/../tmp/time_sliced_output")
|
204
|
+
|
205
|
+
CONFIG = %[]
|
206
|
+
|
207
|
+
def create_driver(conf=CONFIG)
|
208
|
+
Fluent::Test::TimeSlicedOutputTestDriver.new(Fluent::TimeSlicedOutput).configure(conf, true)
|
209
|
+
end
|
210
|
+
|
211
|
+
sub_test_case "test_force_flush" do
|
212
|
+
setup do
|
213
|
+
time = Time.parse("2011-01-02 13:14:15 UTC")
|
214
|
+
Timecop.freeze(time)
|
215
|
+
@es = OneEventStream.new(time.to_i, {"message" => "foo"})
|
216
|
+
end
|
217
|
+
|
218
|
+
teardown do
|
219
|
+
Timecop.return
|
220
|
+
end
|
221
|
+
|
222
|
+
test "force_flush immediately flushes" do
|
223
|
+
d = create_driver(CONFIG + %[
|
224
|
+
time_format %Y%m%d%H%M%S
|
225
|
+
buffer_path #{TMP_DIR}/foo
|
226
|
+
])
|
227
|
+
d.instance.start
|
228
|
+
# buffer should be popped (flushed) immediately
|
229
|
+
flexmock(d.instance.instance_variable_get(:@buffer)).should_receive(:pop).once
|
230
|
+
# force_flush
|
231
|
+
d.instance.emit('test', @es, NullOutputChain.instance)
|
232
|
+
d.instance.force_flush
|
233
|
+
10.times { sleep 0.05 }
|
234
|
+
end
|
235
|
+
end
|
149
236
|
end
|
150
237
|
end
|
data/test/test_parser.rb
CHANGED
@@ -199,25 +199,33 @@ module ParserTest
|
|
199
199
|
|
200
200
|
def setup
|
201
201
|
@parser = TextParser::ApacheParser.new
|
202
|
+
@expected = {
|
203
|
+
'user' => nil,
|
204
|
+
'method' => 'GET',
|
205
|
+
'code' => 200,
|
206
|
+
'size' => 777,
|
207
|
+
'host' => '192.168.0.1',
|
208
|
+
'path' => '/',
|
209
|
+
'referer' => nil,
|
210
|
+
'agent' => 'Opera/12.0'
|
211
|
+
}
|
202
212
|
end
|
203
213
|
|
204
214
|
def test_parse
|
205
215
|
@parser.parse('192.168.0.1 - - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0"') { |time, record|
|
206
216
|
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
207
|
-
assert_equal(
|
208
|
-
'user' => nil,
|
209
|
-
'method' => 'GET',
|
210
|
-
'code' => 200,
|
211
|
-
'size' => 777,
|
212
|
-
'host' => '192.168.0.1',
|
213
|
-
'path' => '/',
|
214
|
-
'referer' => nil,
|
215
|
-
'agent' => 'Opera/12.0'
|
216
|
-
}, record)
|
217
|
+
assert_equal(@expected, record)
|
217
218
|
}
|
218
219
|
assert_equal(TextParser::ApacheParser::REGEXP, @parser.patterns['format'])
|
219
220
|
assert_equal(TextParser::ApacheParser::TIME_FORMAT, @parser.patterns['time_format'])
|
220
221
|
end
|
222
|
+
|
223
|
+
def test_parse_without_http_version
|
224
|
+
@parser.parse('192.168.0.1 - - [28/Feb/2013:12:00:00 +0900] "GET /" 200 777 "-" "Opera/12.0"') { |time, record|
|
225
|
+
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
226
|
+
assert_equal(@expected, record)
|
227
|
+
}
|
228
|
+
end
|
221
229
|
end
|
222
230
|
|
223
231
|
class SyslogParserTest < ::Test::Unit::TestCase
|
@@ -354,6 +362,13 @@ module ParserTest
|
|
354
362
|
assert_equal(@expected.merge('path' => '/a[ ]b'), record)
|
355
363
|
}
|
356
364
|
end
|
365
|
+
|
366
|
+
def test_parse_without_http_version
|
367
|
+
@parser.parse('127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET /" 200 777 "-" "Opera/12.0"') { |time, record|
|
368
|
+
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
369
|
+
assert_equal(@expected, record)
|
370
|
+
}
|
371
|
+
end
|
357
372
|
end
|
358
373
|
|
359
374
|
class TSVParserTest < ::Test::Unit::TestCase
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluentd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.59
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|