fluent-plugin-tail-multiline 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +42 -0
- data/fluent-plugin-tail-multiline.gemspec +1 -1
- data/lib/fluent/plugin/in_tail_multiline.rb +28 -1
- data/test/plugin/test_in_tail_multiline.rb +73 -1
- 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: dff2631e00656f109380d6b27c4f145d8149dc45
|
4
|
+
data.tar.gz: 1a14e17bae8ef5f85754e766321354e9d6620351
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0205218e761d286422953179e61bcce121b89af151a5e277ae7a4ae9c84198bf9d127ed24d6942a830e0b9b2229a65c587298c2cac8ac37e59b5af18dbe38de
|
7
|
+
data.tar.gz: fa0c1f06d70ad1a08bf25644f8804085ecb07e33a186f2db9e575706f4a66af69696d72c4c549e1ca581d0afdc7ca888c910e31520f5599f5a9dc1d55e98056b
|
data/README.md
CHANGED
@@ -26,6 +26,7 @@ Tail-Multiline extends [tail plugin](http://docs.fluentd.org/categories/in_tail)
|
|
26
26
|
----------------------|---------------------------------|---------------------------
|
27
27
|
format_firstline | string(default = format) | RegEx to detect first line of multiple line log, no name capture required
|
28
28
|
rawdata_key | string(default = null) | Store raw data with given key
|
29
|
+
format{1..20} | string(default = null) | The substitute for too long `format`
|
29
30
|
|
30
31
|
## Examples
|
31
32
|
### Java log with exception
|
@@ -73,6 +74,47 @@ format_firstline /----/
|
|
73
74
|
2013-03-03 14:27:34 +0900 test: {"message":"test2"}
|
74
75
|
```
|
75
76
|
|
77
|
+
### Case where too long regexp is required
|
78
|
+
#### Input
|
79
|
+
```
|
80
|
+
Started GET "/users/" for 127.0.0.1 at 2013-06-14 12:00:04 +0900
|
81
|
+
Processing by UsersController#index as HTML
|
82
|
+
Rendered users/index.html.erb within layouts/application (0.5ms)
|
83
|
+
Completed 200 OK in 821ms (Views: 819.5ms | ActiveRecord: 0.0ms)
|
84
|
+
|
85
|
+
|
86
|
+
Started GET "/users/123/" for 127.0.0.1 at 2013-06-14 12:00:11 +0900
|
87
|
+
Processing by UsersController#show as HTML
|
88
|
+
Parameters: {"user_id"=>"123"}
|
89
|
+
Rendered users/show.html.erb within layouts/application (0.3ms)
|
90
|
+
Completed 200 OK in 4ms (Views: 3.2ms | ActiveRecord: 0.0ms)
|
91
|
+
```
|
92
|
+
|
93
|
+
#### Parameters
|
94
|
+
```
|
95
|
+
tag test
|
96
|
+
format_firstline /^Started/
|
97
|
+
format /Started (?<method>[^ ]+) "(?<path>[^"]+)" for (?<host>[^ ]+) at (?<time>[^ ]+ [^ ]+ [^ ]+)\nProcessing by (?<controller>[^\u0023]+)\u0023(?<controller_method>[^ ]+) as (?<format>[^ ]+?)\n( Parameters: (?<parameters>[^ ]+)\n)? Rendered (?<template>[^ ]+) within (?<layout>.+) \([\d\.]+ms\)\nCompleted (?<code>[^ ]+) [^ ]+ in (?<runtime>[\d\.]+)ms \(Views: (?<view_runtime>[\d\.]+)ms \| ActiveRecord: (?<ar_runtime>[\d\.]+)ms\)/
|
98
|
+
```
|
99
|
+
|
100
|
+
It's too long format. You can rewrite above parameters with `format{1..20}`.
|
101
|
+
|
102
|
+
```
|
103
|
+
tag test
|
104
|
+
format_firstline /^Started/
|
105
|
+
format1 /Started (?<method>[^ ]+) "(?<path>[^"]+)" for (?<host>[^ ]+) at (?<time>[^ ]+ [^ ]+ [^ ]+)\n/
|
106
|
+
format2 /Processing by (?<controller>[^\u0023]+)\u0023(?<controller_method>[^ ]+) as (?<format>[^ ]+?)\n/
|
107
|
+
format3 /( Parameters: (?<parameters>[^ ]+)\n)?/
|
108
|
+
format4 / Rendered (?<template>[^ ]+) within (?<layout>.+) \([\d\.]+ms\)\n/
|
109
|
+
format5 /Completed (?<code>[^ ]+) [^ ]+ in (?<runtime>[\d\.]+)ms \(Views: (?<view_runtime>[\d\.]+)ms \| ActiveRecord: (?<ar_runtime>[\d\.]+)ms\)/
|
110
|
+
```
|
111
|
+
|
112
|
+
#### Output
|
113
|
+
```
|
114
|
+
2013-06-14 12:00:04 +0900 test: {"method":"GET","path":"/users/","host":"127.0.0.1","controller":"UsersController","controller_method":"index","format":"HTML","template":"users/index.html.erb","layout":"layouts/application","code":"200","runtime":"821","view_runtime":"819.5","ar_runtime":"0.0"}
|
115
|
+
2013-06-14 12:00:11 +0900 test: {"method":"GET","path":"/users/123/","host":"127.0.0.1","controller":"UsersController","controller_method":"show","format":"HTML","parameters":"{\"user_id\"=>\"123\"}","template":"users/show.html.erb","layout":"layouts/application","code":"200","runtime":"4","view_runtime":"3.2","ar_runtime":"0.0"}
|
116
|
+
```
|
117
|
+
|
76
118
|
## Contributing
|
77
119
|
|
78
120
|
1. Fork it
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.name = "fluent-plugin-tail-multiline"
|
7
|
-
gem.version = "0.1.
|
7
|
+
gem.version = "0.1.2"
|
8
8
|
gem.authors = ["Tomohisa Ota"]
|
9
9
|
gem.email = ["tomohisa.ota+github@gmail.com"]
|
10
10
|
gem.description = "Extend tail plugin to support log with multiple line"
|
@@ -45,11 +45,16 @@ module Fluent
|
|
45
45
|
end
|
46
46
|
|
47
47
|
Plugin.register_input('tail_multiline', self)
|
48
|
+
|
49
|
+
FORMAT_MAX_NUM = 20
|
48
50
|
|
49
51
|
config_param :format, :string
|
50
52
|
config_param :format_firstline, :string, :default => nil
|
51
53
|
config_param :rawdata_key, :string, :default => nil
|
52
54
|
config_param :auto_flush_sec, :integer, :default => 1
|
55
|
+
(1..FORMAT_MAX_NUM).each do |i|
|
56
|
+
config_param "format#{i}".to_sym, :string, :default => nil
|
57
|
+
end
|
53
58
|
|
54
59
|
def initialize
|
55
60
|
super
|
@@ -57,6 +62,28 @@ module Fluent
|
|
57
62
|
@logbuf = nil
|
58
63
|
@logbuf_flusher = CallLater::new
|
59
64
|
end
|
65
|
+
|
66
|
+
def configure(conf)
|
67
|
+
if conf['format'].nil?
|
68
|
+
invalids = conf.keys.select{|k| k =~ /^format(\d+)$/ and not (1..FORMAT_MAX_NUM).include?($1.to_i)}
|
69
|
+
if invalids.size > 0
|
70
|
+
raise ConfigError, "invalid number formats (valid format number:1-#{FORMAT_MAX_NUM}):" + invalids.join(",")
|
71
|
+
end
|
72
|
+
format_index_list = conf.keys.select{|s| s =~ /^format\d+$/}.map{|v| (/^format(\d+)$/.match(v))[1].to_i}
|
73
|
+
if (1..format_index_list.max).map{|i| conf["format#{i}"]}.include?(nil)
|
74
|
+
raise Fluent::ConfigError, "jump of format index found"
|
75
|
+
end
|
76
|
+
formats = (1..FORMAT_MAX_NUM).map {|i|
|
77
|
+
conf["format#{i}"]
|
78
|
+
}.delete_if {|format|
|
79
|
+
format.nil?
|
80
|
+
}.map {|format|
|
81
|
+
format[1..-2]
|
82
|
+
}.join
|
83
|
+
conf['format'] = '/' + formats + '/'
|
84
|
+
end
|
85
|
+
super
|
86
|
+
end
|
60
87
|
|
61
88
|
def configure_parser(conf)
|
62
89
|
@parser = MultilineTextParser.new
|
@@ -127,8 +154,8 @@ module Fluent
|
|
127
154
|
class CallLater
|
128
155
|
def initialize
|
129
156
|
@locker = Monitor::new
|
130
|
-
@thread = Thread.new(&method(:run))
|
131
157
|
initExecBlock()
|
158
|
+
@thread = Thread.new(&method(:run))
|
132
159
|
end
|
133
160
|
|
134
161
|
def call_later(delay,&block)
|
@@ -200,4 +200,76 @@ class TailMultilineInputTest < Test::Unit::TestCase
|
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
203
|
-
|
203
|
+
def test_multilinelog_with_serial_number_format
|
204
|
+
tmpFile = Tempfile.new("in_tail_multiline-")
|
205
|
+
begin
|
206
|
+
d = create_driver %[
|
207
|
+
path #{tmpFile.path}
|
208
|
+
tag test
|
209
|
+
format1 /^s (?<message1>[^\\n]+)\\n?/
|
210
|
+
format2 /(f (?<message2>[^\\n]+)\\n?)?/
|
211
|
+
format3 /(f (?<message3>.*))?/
|
212
|
+
format_firstline /^[s]/
|
213
|
+
rawdata_key rawdata
|
214
|
+
]
|
215
|
+
d.run do
|
216
|
+
File.open(tmpFile.path, "w") {|f|
|
217
|
+
f.puts "f test1"
|
218
|
+
f.puts "s test2"
|
219
|
+
f.puts "f test3"
|
220
|
+
f.puts "f test4"
|
221
|
+
f.puts "s test5"
|
222
|
+
f.puts "s test6"
|
223
|
+
f.puts "f test7"
|
224
|
+
f.puts "s test8"
|
225
|
+
}
|
226
|
+
sleep 1
|
227
|
+
end
|
228
|
+
|
229
|
+
emits = d.emits
|
230
|
+
assert_equal(true, emits.length > 0)
|
231
|
+
n = -1
|
232
|
+
assert_equal({"message1"=>"test2","message2"=>"test3","message3"=>"test4","rawdata"=>"s test2\nf test3\nf test4"}, emits[0][2])
|
233
|
+
assert_equal({"message1"=>"test5","rawdata"=>"s test5"}, emits[1][2])
|
234
|
+
assert_equal({"message1"=>"test6","message2"=>"test7","rawdata"=>"s test6\nf test7"}, emits[2][2])
|
235
|
+
assert_equal({"message1"=>"test8","rawdata"=>"s test8"}, emits[3][2])
|
236
|
+
ensure
|
237
|
+
tmpFile.close(true)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_multilinelog_with_invalid_number_format
|
242
|
+
tmpFile = Tempfile.new("in_tail_multiline-")
|
243
|
+
begin
|
244
|
+
e = assert_raise(Fluent::ConfigError) {
|
245
|
+
create_driver %[
|
246
|
+
path #{tmpFile.path}
|
247
|
+
tag test
|
248
|
+
format21 /(?<message1>.*)/
|
249
|
+
format22 /(?<message2>.*)/
|
250
|
+
]
|
251
|
+
}
|
252
|
+
assert_equal(e.message, "invalid number formats (valid format number:1-20):format21,format22")
|
253
|
+
ensure
|
254
|
+
tmpFile.close(true)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_multilinelog_with_jump_of_number_format
|
259
|
+
tmpFile = Tempfile.new("in_tail_multiline-")
|
260
|
+
begin
|
261
|
+
e = assert_raise(Fluent::ConfigError) {
|
262
|
+
create_driver %[
|
263
|
+
path #{tmpFile.path}
|
264
|
+
tag test
|
265
|
+
format1 /(?<message1>.*)/
|
266
|
+
format3 /(?<message2>.*)/
|
267
|
+
]
|
268
|
+
}
|
269
|
+
assert_equal(e.message, "jump of format index found")
|
270
|
+
ensure
|
271
|
+
tmpFile.close(true)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-tail-multiline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomohisa Ota
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|