fluent-plugin-detect-exceptions 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +10 -10
- data/README.rdoc +31 -7
- data/fluent-plugin-detect-exceptions.gemspec +1 -1
- data/fluent-plugin-detect-exceptions.sublime-project +8 -0
- data/fluent-plugin-detect-exceptions.sublime-workspace +1595 -0
- data/lib/fluent/plugin/out_detect_exceptions.rb +16 -12
- data/measure_memory.sh +28 -0
- data/test/plugin/test_out_detect_exceptions.rb +33 -4
- metadata +5 -2
@@ -22,7 +22,7 @@ module Fluent
|
|
22
22
|
# an exception stack trace, they forwarded as a single, combined JSON
|
23
23
|
# object. Otherwise, the input log data is forwarded as is.
|
24
24
|
class DetectExceptionsOutput < Output
|
25
|
-
desc 'The field which contains the raw message text in the input
|
25
|
+
desc 'The field which contains the raw message text in the input JSON data.'
|
26
26
|
config_param :message, :string, default: ''
|
27
27
|
desc 'The prefix to be removed from the input tag when outputting a record.'
|
28
28
|
config_param :remove_tag_prefix, :string, default: ''
|
@@ -34,6 +34,8 @@ module Fluent
|
|
34
34
|
config_param :max_lines, :integer, default: 1000
|
35
35
|
desc 'Maximum number of bytes to flush (0 means no limit). Default: 0.'
|
36
36
|
config_param :max_bytes, :integer, default: 0
|
37
|
+
desc 'Separate log streams by this field in the input JSON data.'
|
38
|
+
config_param :stream, :string, default: ''
|
37
39
|
|
38
40
|
Fluent::Plugin.register_output('detect_exceptions', self)
|
39
41
|
|
@@ -69,7 +71,7 @@ module Fluent
|
|
69
71
|
# Before shutdown is not available in older fluentd versions.
|
70
72
|
# Hence, we make sure that we flush the buffers here as well.
|
71
73
|
flush_buffers
|
72
|
-
@thread.join if multiline_flush_interval
|
74
|
+
@thread.join if @multiline_flush_interval
|
73
75
|
super
|
74
76
|
end
|
75
77
|
|
@@ -84,17 +86,19 @@ module Fluent
|
|
84
86
|
|
85
87
|
def process_record(tag, time_sec, record)
|
86
88
|
synchronize do
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
89
|
+
log_id = [tag]
|
90
|
+
log_id.push(record.fetch(@stream, '')) unless @stream.empty?
|
91
|
+
unless @accumulators.key?(log_id)
|
92
|
+
out_tag = tag.sub(/^#{Regexp.escape(@remove_tag_prefix)}\./, '')
|
93
|
+
@accumulators[log_id] =
|
94
|
+
Fluent::TraceAccumulator.new(@message, @languages,
|
95
|
+
max_lines: @max_lines,
|
96
|
+
max_bytes: @max_bytes) do |t, r|
|
93
97
|
router.emit(out_tag, t, r)
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
97
|
-
@accumulators[
|
101
|
+
@accumulators[log_id].push(time_sec, record)
|
98
102
|
end
|
99
103
|
end
|
100
104
|
|
@@ -112,8 +116,8 @@ module Fluent
|
|
112
116
|
now = Time.now
|
113
117
|
break if @stop_check
|
114
118
|
@accumulators.each_value do |acc|
|
115
|
-
|
116
|
-
|
119
|
+
acc.force_flush if now - acc.buffer_start_time >
|
120
|
+
@multiline_flush_interval
|
117
121
|
end
|
118
122
|
end
|
119
123
|
end
|
@@ -123,7 +127,7 @@ module Fluent
|
|
123
127
|
end
|
124
128
|
|
125
129
|
def synchronize(&block)
|
126
|
-
if multiline_flush_interval
|
130
|
+
if @multiline_flush_interval
|
127
131
|
@flush_buffer_mutex.synchronize(&block)
|
128
132
|
else
|
129
133
|
yield
|
data/measure_memory.sh
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
DELAY=0.1
|
4
|
+
|
5
|
+
while true
|
6
|
+
do
|
7
|
+
start_timestamp=`date +%s.%N`
|
8
|
+
|
9
|
+
paths=`find /sys/fs/cgroup/memory/docker/* -type d`
|
10
|
+
for path in $paths
|
11
|
+
do
|
12
|
+
id=${path##*/}
|
13
|
+
memory=`cat /sys/fs/cgroup/memory/docker/${id}/memory.usage_in_bytes`
|
14
|
+
echo -ne "${id}\t${memory} "
|
15
|
+
done
|
16
|
+
if [[ "$paths" != "" ]]
|
17
|
+
then
|
18
|
+
echo
|
19
|
+
fi
|
20
|
+
|
21
|
+
end_timestamp=`date +%s.%N`
|
22
|
+
to_wait=`perl -e "print ${DELAY} - ${end_timestamp} + ${start_timestamp}"`
|
23
|
+
|
24
|
+
if [[ `echo ${to_wait}'>'0 | bc -l` -ne 0 ]]
|
25
|
+
then
|
26
|
+
sleep $to_wait
|
27
|
+
fi
|
28
|
+
done
|
@@ -46,11 +46,17 @@ END
|
|
46
46
|
d
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
49
|
+
def log_entry(message, count, stream)
|
50
|
+
log_entry = { 'message' => message, 'count' => count }
|
51
|
+
log_entry['stream'] = stream unless stream.nil?
|
52
|
+
log_entry
|
53
|
+
end
|
54
|
+
|
55
|
+
def feed_lines(driver, t, *messages, stream: nil)
|
50
56
|
count = 0
|
51
57
|
messages.each do |m|
|
52
58
|
m.each_line do |line|
|
53
|
-
driver.emit(
|
59
|
+
driver.emit(log_entry(line, count, stream), t + count)
|
54
60
|
count += 1
|
55
61
|
end
|
56
62
|
end
|
@@ -63,11 +69,11 @@ END
|
|
63
69
|
end
|
64
70
|
end
|
65
71
|
|
66
|
-
def make_logs(t, *messages)
|
72
|
+
def make_logs(t, *messages, stream: nil)
|
67
73
|
count = 0
|
68
74
|
logs = []
|
69
75
|
messages.each do |m|
|
70
|
-
logs << [t + count,
|
76
|
+
logs << [t + count, log_entry(m, count, stream)]
|
71
77
|
count += m.lines.count
|
72
78
|
end
|
73
79
|
logs
|
@@ -175,4 +181,27 @@ END
|
|
175
181
|
[PYTHON_EXC.lines[0..1].join] + PYTHON_EXC.lines[2..-1] + [JAVA_EXC]
|
176
182
|
assert_equal(make_logs(t, *expected), d.events)
|
177
183
|
end
|
184
|
+
|
185
|
+
def test_separate_streams
|
186
|
+
cfg = 'stream stream'
|
187
|
+
d = create_driver(cfg)
|
188
|
+
t = Time.now.to_i
|
189
|
+
d.run do
|
190
|
+
feed_lines(d, t, JAVA_EXC.lines[0], stream: 'java')
|
191
|
+
feed_lines(d, t, PYTHON_EXC.lines[0..1].join, stream: 'python')
|
192
|
+
feed_lines(d, t, JAVA_EXC.lines[1..-1].join, stream: 'java')
|
193
|
+
feed_lines(d, t, JAVA_EXC, stream: 'java')
|
194
|
+
feed_lines(d, t, PYTHON_EXC.lines[2..-1].join, stream: 'python')
|
195
|
+
feed_lines(d, t, 'something else', stream: 'java')
|
196
|
+
end
|
197
|
+
# Expected: the Python and the Java exceptions are handled separately
|
198
|
+
# because they belong to different streams.
|
199
|
+
# Note that the Java exception is only detected when 'something else'
|
200
|
+
# is processed.
|
201
|
+
expected = make_logs(t, JAVA_EXC, stream: 'java') +
|
202
|
+
make_logs(t, PYTHON_EXC, stream: 'python') +
|
203
|
+
make_logs(t, JAVA_EXC, stream: 'java') +
|
204
|
+
make_logs(t, 'something else', stream: 'java')
|
205
|
+
assert_equal(expected, d.events)
|
206
|
+
end
|
178
207
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-detect-exceptions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Schickinger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -90,8 +90,11 @@ files:
|
|
90
90
|
- README.rdoc
|
91
91
|
- Rakefile
|
92
92
|
- fluent-plugin-detect-exceptions.gemspec
|
93
|
+
- fluent-plugin-detect-exceptions.sublime-project
|
94
|
+
- fluent-plugin-detect-exceptions.sublime-workspace
|
93
95
|
- lib/fluent/plugin/exception_detector.rb
|
94
96
|
- lib/fluent/plugin/out_detect_exceptions.rb
|
97
|
+
- measure_memory.sh
|
95
98
|
- test/helper.rb
|
96
99
|
- test/plugin/bench_exception_detector.rb
|
97
100
|
- test/plugin/test_exception_detector.rb
|