fluentd 1.13.3 → 1.14.2
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/.drone.yml +6 -6
- data/.github/ISSUE_TEMPLATE/bug_report.yaml +1 -0
- data/.github/workflows/windows-test.yaml +3 -3
- data/CHANGELOG.md +96 -0
- data/fluentd.gemspec +1 -1
- data/lib/fluent/command/cat.rb +13 -3
- data/lib/fluent/command/fluentd.rb +8 -0
- data/lib/fluent/compat/output.rb +9 -6
- data/lib/fluent/config/parser.rb +1 -1
- data/lib/fluent/config/v1_parser.rb +1 -1
- data/lib/fluent/event_router.rb +28 -1
- data/lib/fluent/plugin/bare_output.rb +49 -8
- data/lib/fluent/plugin/buf_file.rb +2 -2
- data/lib/fluent/plugin/buffer.rb +84 -22
- data/lib/fluent/plugin/filter.rb +35 -1
- data/lib/fluent/plugin/in_http.rb +21 -2
- data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
- data/lib/fluent/plugin/in_syslog.rb +13 -1
- data/lib/fluent/plugin/in_tail/position_file.rb +1 -1
- data/lib/fluent/plugin/in_tail.rb +37 -5
- data/lib/fluent/plugin/input.rb +39 -1
- data/lib/fluent/plugin/metrics.rb +119 -0
- data/lib/fluent/plugin/metrics_local.rb +96 -0
- data/lib/fluent/plugin/multi_output.rb +43 -6
- data/lib/fluent/plugin/out_copy.rb +1 -1
- data/lib/fluent/plugin/out_forward.rb +15 -7
- data/lib/fluent/plugin/output.rb +80 -38
- data/lib/fluent/plugin/parser_apache2.rb +1 -1
- data/lib/fluent/plugin/storage_local.rb +3 -5
- data/lib/fluent/plugin.rb +10 -1
- data/lib/fluent/plugin_helper/event_emitter.rb +8 -1
- data/lib/fluent/plugin_helper/metrics.rb +129 -0
- data/lib/fluent/plugin_helper/server.rb +4 -2
- data/lib/fluent/plugin_helper.rb +1 -0
- data/lib/fluent/plugin_id.rb +2 -1
- data/lib/fluent/root_agent.rb +6 -0
- data/lib/fluent/supervisor.rb +4 -2
- data/lib/fluent/system_config.rb +9 -1
- data/lib/fluent/time.rb +21 -20
- data/lib/fluent/version.rb +1 -1
- data/test/command/test_cat.rb +31 -2
- data/test/config/test_system_config.rb +6 -0
- data/test/plugin/in_tail/test_io_handler.rb +12 -4
- data/test/plugin/in_tail/test_position_file.rb +26 -4
- data/test/plugin/test_bare_output.rb +13 -0
- data/test/plugin/test_buffer.rb +8 -2
- data/test/plugin/test_filter.rb +11 -0
- data/test/plugin/test_in_http.rb +40 -0
- data/test/plugin/test_in_monitor_agent.rb +214 -8
- data/test/plugin/test_in_syslog.rb +35 -0
- data/test/plugin/test_in_tail.rb +28 -29
- data/test/plugin/test_input.rb +11 -0
- data/test/plugin/test_metrics.rb +294 -0
- data/test/plugin/test_metrics_local.rb +96 -0
- data/test/plugin/test_multi_output.rb +25 -1
- data/test/plugin/test_output.rb +16 -0
- data/test/plugin_helper/test_event_emitter.rb +29 -0
- data/test/plugin_helper/test_metrics.rb +137 -0
- data/test/test_plugin_classes.rb +102 -0
- data/test/test_root_agent.rb +30 -1
- data/test/test_time_parser.rb +22 -0
- metadata +13 -4
@@ -0,0 +1,119 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'socket'
|
18
|
+
|
19
|
+
require 'fluent/plugin/base'
|
20
|
+
|
21
|
+
require 'fluent/log'
|
22
|
+
require 'fluent/unique_id'
|
23
|
+
require 'fluent/plugin_id'
|
24
|
+
|
25
|
+
module Fluent
|
26
|
+
module Plugin
|
27
|
+
class Metrics < Base
|
28
|
+
include PluginId
|
29
|
+
include PluginLoggerMixin
|
30
|
+
include UniqueId::Mixin
|
31
|
+
|
32
|
+
DEFAULT_TYPE = 'local'
|
33
|
+
|
34
|
+
configured_in :metrics
|
35
|
+
|
36
|
+
config_param :default_labels, :hash, default: {agent: "Fluentd", hostname: "#{Socket.gethostname}"}
|
37
|
+
config_param :labels, :hash, default: {}
|
38
|
+
|
39
|
+
attr_reader :use_gauge_metric
|
40
|
+
attr_reader :has_methods_for_gauge, :has_methods_for_counter
|
41
|
+
|
42
|
+
def initialize
|
43
|
+
super
|
44
|
+
|
45
|
+
@has_methods_for_counter = false
|
46
|
+
@has_methods_for_gauge = false
|
47
|
+
@use_gauge_metric = false
|
48
|
+
end
|
49
|
+
|
50
|
+
def configure(conf)
|
51
|
+
super
|
52
|
+
|
53
|
+
if use_gauge_metric
|
54
|
+
@has_methods_for_gauge = has_methods_for_gauge?
|
55
|
+
else
|
56
|
+
@has_methods_for_counter = has_methods_for_counter?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Some metrics should be counted by gauge.
|
61
|
+
# ref: https://prometheus.io/docs/concepts/metric_types/#gauge
|
62
|
+
def use_gauge_metric=(use_gauge_metric=false)
|
63
|
+
@use_gauge_metric = use_gauge_metric
|
64
|
+
end
|
65
|
+
|
66
|
+
def create(namespace:, subsystem:,name:,help_text:,labels: {})
|
67
|
+
# This API is for cmetrics type.
|
68
|
+
end
|
69
|
+
|
70
|
+
def get
|
71
|
+
raise NotImplementedError, "Implement this method in child class"
|
72
|
+
end
|
73
|
+
|
74
|
+
def inc
|
75
|
+
raise NotImplementedError, "Implement this method in child class"
|
76
|
+
end
|
77
|
+
|
78
|
+
def dec
|
79
|
+
raise NotImplementedError, "Implement this method in child class"
|
80
|
+
end
|
81
|
+
|
82
|
+
def add(value)
|
83
|
+
raise NotImplementedError, "Implement this method in child class"
|
84
|
+
end
|
85
|
+
|
86
|
+
def sub(value)
|
87
|
+
raise NotImplementedError, "Implement this method in child class"
|
88
|
+
end
|
89
|
+
|
90
|
+
def set(value)
|
91
|
+
raise NotImplementedError, "Implement this method in child class"
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def has_methods_for_counter?
|
97
|
+
implemented_methods = self.class.instance_methods(false)
|
98
|
+
|
99
|
+
if [:get, :inc, :add].all? {|e| implemented_methods.include?(e)} &&
|
100
|
+
[:set].all?{|e| self.class.method_defined?(e)}
|
101
|
+
true
|
102
|
+
else
|
103
|
+
raise "BUG: metrics plugin on counter mode MUST implement `get`, `inc`, `add` methods. And aliased `set` methods should be aliased from another method"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def has_methods_for_gauge?
|
108
|
+
implemented_methods = self.class.instance_methods(false)
|
109
|
+
|
110
|
+
if [:get, :inc, :add].all? {|e| implemented_methods.include?(e)} &&
|
111
|
+
[:set, :dec, :sub].all?{|e| self.class.method_defined?(e)}
|
112
|
+
true
|
113
|
+
else
|
114
|
+
raise "BUG: metrics plugin on gauge mode MUST implement `get`, `inc`, and `add` methods. And `dec`, `sub`, and `set` methods should be aliased from other methods"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fluent/plugin'
|
18
|
+
require 'fluent/plugin/metrics'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
module Plugin
|
22
|
+
class LocalMetrics < Metrics
|
23
|
+
Fluent::Plugin.register_metrics('local', self)
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
super
|
27
|
+
@store = 0
|
28
|
+
@monitor = Monitor.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def configure(conf)
|
32
|
+
super
|
33
|
+
|
34
|
+
if use_gauge_metric
|
35
|
+
class << self
|
36
|
+
alias_method :dec, :dec_gauge
|
37
|
+
alias_method :set, :set_gauge
|
38
|
+
alias_method :sub, :sub_gauge
|
39
|
+
end
|
40
|
+
else
|
41
|
+
class << self
|
42
|
+
alias_method :set, :set_counter
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def multi_workers_ready?
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
def get
|
52
|
+
@monitor.synchronize do
|
53
|
+
@store
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def inc
|
58
|
+
@monitor.synchronize do
|
59
|
+
@store += 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def dec_gauge
|
64
|
+
@monitor.synchronize do
|
65
|
+
@store -= 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def add(value)
|
70
|
+
@monitor.synchronize do
|
71
|
+
@store += value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def sub_gauge(value)
|
76
|
+
@monitor.synchronize do
|
77
|
+
@store -= value
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_counter(value)
|
82
|
+
return if @store > value
|
83
|
+
|
84
|
+
@monitor.synchronize do
|
85
|
+
@store = value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def set_gauge(value)
|
90
|
+
@monitor.synchronize do
|
91
|
+
@store = value
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -27,6 +27,7 @@ module Fluent
|
|
27
27
|
include PluginHelper::Mixin # for event_emitter
|
28
28
|
|
29
29
|
helpers :event_emitter # to get router from agent, which will be supplied to child plugins
|
30
|
+
helpers_internal :metrics
|
30
31
|
|
31
32
|
config_section :store, param_name: :stores, multi: true, required: true do
|
32
33
|
config_argument :arg, :string, default: ''
|
@@ -46,11 +47,40 @@ module Fluent
|
|
46
47
|
|
47
48
|
@counter_mutex = Mutex.new
|
48
49
|
# TODO: well organized counters
|
49
|
-
@
|
50
|
-
@
|
51
|
-
@
|
50
|
+
@num_errors_metrics = nil
|
51
|
+
@emit_count_metrics = nil
|
52
|
+
@emit_records_metrics = nil
|
53
|
+
@emit_size_metrics = nil
|
52
54
|
# @write_count = 0
|
53
55
|
# @rollback_count = 0
|
56
|
+
@enable_size_metrics = false
|
57
|
+
end
|
58
|
+
|
59
|
+
def num_errors
|
60
|
+
@num_errors_metrics.get
|
61
|
+
end
|
62
|
+
|
63
|
+
def emit_count
|
64
|
+
@emit_count_metrics.get
|
65
|
+
end
|
66
|
+
|
67
|
+
def emit_size
|
68
|
+
@emit_size_metrics.get
|
69
|
+
end
|
70
|
+
|
71
|
+
def emit_records
|
72
|
+
@emit_records_metrics.get
|
73
|
+
end
|
74
|
+
|
75
|
+
def statistics
|
76
|
+
stats = {
|
77
|
+
'num_errors' => @num_errors_metrics.get,
|
78
|
+
'emit_records' => @emit_records_metrics.get,
|
79
|
+
'emit_count' => @emit_count_metrics.get,
|
80
|
+
'emit_size' => @emit_size_metrics.get,
|
81
|
+
}
|
82
|
+
|
83
|
+
{ 'multi_output' => stats }
|
54
84
|
end
|
55
85
|
|
56
86
|
def multi_output?
|
@@ -60,6 +90,12 @@ module Fluent
|
|
60
90
|
def configure(conf)
|
61
91
|
super
|
62
92
|
|
93
|
+
@num_errors_metrics = metrics_create(namespace: "fluentd", subsystem: "multi_output", name: "num_errors", help_text: "Number of count num errors")
|
94
|
+
@emit_count_metrics = metrics_create(namespace: "fluentd", subsystem: "multi_output", name: "emit_records", help_text: "Number of count emits")
|
95
|
+
@emit_records_metrics = metrics_create(namespace: "fluentd", subsystem: "multi_output", name: "emit_records", help_text: "Number of emit records")
|
96
|
+
@emit_size_metrics = metrics_create(namespace: "fluentd", subsystem: "multi_output", name: "emit_size", help_text: "Total size of emit events")
|
97
|
+
@enable_size_metrics = !!system_config.enable_size_metrics
|
98
|
+
|
63
99
|
@stores.each do |store|
|
64
100
|
store_conf = store.corresponding_config_element
|
65
101
|
type = store_conf['@type']
|
@@ -143,12 +179,13 @@ module Fluent
|
|
143
179
|
end
|
144
180
|
|
145
181
|
def emit_sync(tag, es)
|
146
|
-
@
|
182
|
+
@emit_count_metrics.inc
|
147
183
|
begin
|
148
184
|
process(tag, es)
|
149
|
-
@
|
185
|
+
@emit_records_metrics.add(es.size)
|
186
|
+
@emit_size_metrics.add(es.to_msgpack_stream.bytesize) if @enable_size_metrics
|
150
187
|
rescue
|
151
|
-
@
|
188
|
+
@num_errors_metrics.inc
|
152
189
|
raise
|
153
190
|
end
|
154
191
|
end
|
@@ -46,7 +46,7 @@ module Fluent::Plugin
|
|
46
46
|
@ignore_errors << (store.arg.include?('ignore_error'))
|
47
47
|
@ignore_if_prev_successes << (store.arg.include?('ignore_if_prev_success'))
|
48
48
|
}
|
49
|
-
if @ignore_errors.uniq.size == 1 && @ignore_errors.include?(true) &&
|
49
|
+
if @ignore_errors.uniq.size == 1 && @ignore_errors.include?(true) && !@ignore_if_prev_successes.include?(true)
|
50
50
|
log.warn "ignore_errors are specified in all <store>, but ignore_if_prev_success is not specified. Is this intended?"
|
51
51
|
end
|
52
52
|
end
|
@@ -167,6 +167,8 @@ module Fluent::Plugin
|
|
167
167
|
@usock = nil
|
168
168
|
@keep_alive_watcher_interval = 5 # TODO
|
169
169
|
@suspend_flush = false
|
170
|
+
@healthy_nodes_count_metrics = nil
|
171
|
+
@registered_nodes_count_metrics = nil
|
170
172
|
end
|
171
173
|
|
172
174
|
def configure(conf)
|
@@ -265,6 +267,9 @@ module Fluent::Plugin
|
|
265
267
|
end
|
266
268
|
|
267
269
|
raise Fluent::ConfigError, "ack_response_timeout must be a positive integer" if @ack_response_timeout < 1
|
270
|
+
@healthy_nodes_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "healthy_nodes_count", help_text: "Number of count healthy nodes", prefer_gauge: true)
|
271
|
+
@registered_nodes_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "registered_nodes_count", help_text: "Number of count registered nodes", prefer_gauge: true)
|
272
|
+
|
268
273
|
end
|
269
274
|
|
270
275
|
def multi_workers_ready?
|
@@ -418,18 +423,21 @@ module Fluent::Plugin
|
|
418
423
|
def statistics
|
419
424
|
stats = super
|
420
425
|
services = service_discovery_services
|
421
|
-
|
422
|
-
|
426
|
+
@healthy_nodes_count_metrics.set(0)
|
427
|
+
@registered_nodes_count_metrics.set(services.size)
|
423
428
|
services.each do |s|
|
424
429
|
if s.available?
|
425
|
-
|
430
|
+
@healthy_nodes_count_metrics.inc
|
426
431
|
end
|
427
432
|
end
|
428
433
|
|
429
|
-
stats
|
430
|
-
'
|
431
|
-
|
432
|
-
|
434
|
+
stats = {
|
435
|
+
'output' => stats["output"].merge({
|
436
|
+
'healthy_nodes_count' => @healthy_nodes_count_metrics.get,
|
437
|
+
'registered_nodes_count' => @registered_nodes_count_metrics.get,
|
438
|
+
})
|
439
|
+
}
|
440
|
+
stats
|
433
441
|
end
|
434
442
|
|
435
443
|
# MessagePack FixArray length is 3
|
data/lib/fluent/plugin/output.rb
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
+
require 'fluent/env'
|
17
18
|
require 'fluent/error'
|
18
19
|
require 'fluent/plugin/base'
|
19
20
|
require 'fluent/plugin/buffer'
|
@@ -37,7 +38,7 @@ module Fluent
|
|
37
38
|
include PluginHelper::Mixin
|
38
39
|
include UniqueId::Mixin
|
39
40
|
|
40
|
-
helpers_internal :thread, :retry_state
|
41
|
+
helpers_internal :thread, :retry_state, :metrics
|
41
42
|
|
42
43
|
CHUNK_KEY_PATTERN = /^[-_.@a-zA-Z0-9]+$/
|
43
44
|
CHUNK_KEY_PLACEHOLDER_PATTERN = /\$\{([-_.@$a-zA-Z0-9]+)\}/
|
@@ -164,7 +165,6 @@ module Fluent
|
|
164
165
|
end
|
165
166
|
|
166
167
|
attr_reader :as_secondary, :delayed_commit, :delayed_commit_timeout, :timekey_zone
|
167
|
-
attr_reader :num_errors, :emit_count, :emit_records, :write_count, :rollback_count
|
168
168
|
|
169
169
|
# for tests
|
170
170
|
attr_reader :buffer, :retry, :secondary, :chunk_keys, :chunk_key_accessors, :chunk_key_time, :chunk_key_tag
|
@@ -172,6 +172,30 @@ module Fluent
|
|
172
172
|
# output_enqueue_thread_waiting: for test of output.rb itself
|
173
173
|
attr_accessor :retry_for_error_chunk # if true, error flush will be retried even if under_plugin_development is true
|
174
174
|
|
175
|
+
def num_errors
|
176
|
+
@num_errors_metrics.get
|
177
|
+
end
|
178
|
+
|
179
|
+
def emit_count
|
180
|
+
@emit_count_metrics.get
|
181
|
+
end
|
182
|
+
|
183
|
+
def emit_size
|
184
|
+
@emit_size_metrics.get
|
185
|
+
end
|
186
|
+
|
187
|
+
def emit_records
|
188
|
+
@emit_records_metrics.get
|
189
|
+
end
|
190
|
+
|
191
|
+
def write_count
|
192
|
+
@write_count_metrics.get
|
193
|
+
end
|
194
|
+
|
195
|
+
def rollback_count
|
196
|
+
@rollback_count_metrics.get
|
197
|
+
end
|
198
|
+
|
175
199
|
def initialize
|
176
200
|
super
|
177
201
|
@counter_mutex = Mutex.new
|
@@ -181,13 +205,15 @@ module Fluent
|
|
181
205
|
@primary_instance = nil
|
182
206
|
|
183
207
|
# TODO: well organized counters
|
184
|
-
@
|
185
|
-
@
|
186
|
-
@
|
187
|
-
@
|
188
|
-
@
|
189
|
-
@
|
190
|
-
@
|
208
|
+
@num_errors_metrics = nil
|
209
|
+
@emit_count_metrics = nil
|
210
|
+
@emit_records_metrics = nil
|
211
|
+
@emit_size_metrics = nil
|
212
|
+
@write_count_metrics = nil
|
213
|
+
@rollback_count_metrics = nil
|
214
|
+
@flush_time_count_metrics = nil
|
215
|
+
@slow_flush_count_metrics = nil
|
216
|
+
@enable_size_metrics = false
|
191
217
|
|
192
218
|
# How to process events is decided here at once, but it will be decided in delayed way on #configure & #start
|
193
219
|
if implement?(:synchronous)
|
@@ -246,6 +272,15 @@ module Fluent
|
|
246
272
|
|
247
273
|
super
|
248
274
|
|
275
|
+
@num_errors_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "num_errors", help_text: "Number of count num errors")
|
276
|
+
@emit_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "emit_records", help_text: "Number of count emits")
|
277
|
+
@emit_records_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "emit_records", help_text: "Number of emit records")
|
278
|
+
@emit_size_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "emit_size", help_text: "Total size of emit events")
|
279
|
+
@write_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "write_count", help_text: "Number of writing events")
|
280
|
+
@rollback_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "rollback_count", help_text: "Number of rollbacking operations")
|
281
|
+
@flush_time_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "flush_time_count", help_text: "Count of flush time")
|
282
|
+
@slow_flush_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "slow_flush_count", help_text: "Count of slow flush occurred time(s)")
|
283
|
+
|
249
284
|
if has_buffer_section
|
250
285
|
unless implement?(:buffered) || implement?(:delayed_commit)
|
251
286
|
raise Fluent::ConfigError, "<buffer> section is configured, but plugin '#{self.class}' doesn't support buffering"
|
@@ -271,6 +306,8 @@ module Fluent
|
|
271
306
|
@buffering = true
|
272
307
|
end
|
273
308
|
end
|
309
|
+
# Enable to update record size metrics or not
|
310
|
+
@enable_size_metrics = !!system_config.enable_size_metrics
|
274
311
|
|
275
312
|
if @as_secondary
|
276
313
|
if !@buffering && !@buffering.nil?
|
@@ -797,18 +834,19 @@ module Fluent
|
|
797
834
|
end
|
798
835
|
|
799
836
|
def emit_sync(tag, es)
|
800
|
-
@
|
837
|
+
@emit_count_metrics.inc
|
801
838
|
begin
|
802
839
|
process(tag, es)
|
803
|
-
@
|
840
|
+
@emit_records_metrics.add(es.size)
|
841
|
+
@emit_size_metrics.add(es.to_msgpack_stream.bytesize) if @enable_size_metrics
|
804
842
|
rescue
|
805
|
-
@
|
843
|
+
@num_errors_metrics.inc
|
806
844
|
raise
|
807
845
|
end
|
808
846
|
end
|
809
847
|
|
810
848
|
def emit_buffered(tag, es)
|
811
|
-
@
|
849
|
+
@emit_count_metrics.inc
|
812
850
|
begin
|
813
851
|
execute_chunking(tag, es, enqueue: (@flush_mode == :immediate))
|
814
852
|
if !@retry && @buffer.queued?(nil, optimistic: true)
|
@@ -816,7 +854,7 @@ module Fluent
|
|
816
854
|
end
|
817
855
|
rescue
|
818
856
|
# TODO: separate number of errors into emit errors and write/flush errors
|
819
|
-
@
|
857
|
+
@num_errors_metrics.inc
|
820
858
|
raise
|
821
859
|
end
|
822
860
|
end
|
@@ -966,7 +1004,8 @@ module Fluent
|
|
966
1004
|
write_guard do
|
967
1005
|
@buffer.write(meta_and_data, enqueue: enqueue)
|
968
1006
|
end
|
969
|
-
@
|
1007
|
+
@emit_records_metrics.add(es.size)
|
1008
|
+
@emit_size_metrics.add(es.to_msgpack_stream.bytesize) if @enable_size_metrics
|
970
1009
|
true
|
971
1010
|
end
|
972
1011
|
|
@@ -983,7 +1022,8 @@ module Fluent
|
|
983
1022
|
write_guard do
|
984
1023
|
@buffer.write(meta_and_data, format: format_proc, enqueue: enqueue)
|
985
1024
|
end
|
986
|
-
@
|
1025
|
+
@emit_records_metrics.add(es.size)
|
1026
|
+
@emit_size_metrics.add(es.to_msgpack_stream.bytesize) if @enable_size_metrics
|
987
1027
|
true
|
988
1028
|
end
|
989
1029
|
|
@@ -1008,7 +1048,8 @@ module Fluent
|
|
1008
1048
|
write_guard do
|
1009
1049
|
@buffer.write({meta => data}, format: format_proc, enqueue: enqueue)
|
1010
1050
|
end
|
1011
|
-
@
|
1051
|
+
@emit_records_metrics.add(es.size)
|
1052
|
+
@emit_size_metrics.add(es.to_msgpack_stream.bytesize) if @enable_size_metrics
|
1012
1053
|
true
|
1013
1054
|
end
|
1014
1055
|
|
@@ -1046,7 +1087,7 @@ module Fluent
|
|
1046
1087
|
# false if chunk was already flushed and couldn't be rollbacked unexpectedly
|
1047
1088
|
# in many cases, false can be just ignored
|
1048
1089
|
if @buffer.takeback_chunk(chunk_id)
|
1049
|
-
@
|
1090
|
+
@rollback_count_metrics.inc
|
1050
1091
|
if update_retry
|
1051
1092
|
primary = @as_secondary ? @primary_instance : self
|
1052
1093
|
primary.update_retry_state(chunk_id, @as_secondary)
|
@@ -1062,7 +1103,7 @@ module Fluent
|
|
1062
1103
|
while @dequeued_chunks.first && @dequeued_chunks.first.expired?
|
1063
1104
|
info = @dequeued_chunks.shift
|
1064
1105
|
if @buffer.takeback_chunk(info.chunk_id)
|
1065
|
-
@
|
1106
|
+
@rollback_count_metrics.inc
|
1066
1107
|
log.warn "failed to flush the buffer chunk, timeout to commit.", chunk_id: dump_unique_id_hex(info.chunk_id), flushed_at: info.time
|
1067
1108
|
primary = @as_secondary ? @primary_instance : self
|
1068
1109
|
primary.update_retry_state(info.chunk_id, @as_secondary)
|
@@ -1077,7 +1118,7 @@ module Fluent
|
|
1077
1118
|
until @dequeued_chunks.empty?
|
1078
1119
|
info = @dequeued_chunks.shift
|
1079
1120
|
if @buffer.takeback_chunk(info.chunk_id)
|
1080
|
-
@
|
1121
|
+
@rollback_count_metrics.inc
|
1081
1122
|
log.info "delayed commit for buffer chunks was cancelled in shutdown", chunk_id: dump_unique_id_hex(info.chunk_id)
|
1082
1123
|
primary = @as_secondary ? @primary_instance : self
|
1083
1124
|
primary.update_retry_state(info.chunk_id, @as_secondary)
|
@@ -1120,7 +1161,7 @@ module Fluent
|
|
1120
1161
|
|
1121
1162
|
if output.delayed_commit
|
1122
1163
|
log.trace "executing delayed write and commit", chunk: dump_unique_id_hex(chunk.unique_id)
|
1123
|
-
@
|
1164
|
+
@write_count_metrics.inc
|
1124
1165
|
@dequeued_chunks_mutex.synchronize do
|
1125
1166
|
# delayed_commit_timeout for secondary is configured in <buffer> of primary (<secondary> don't get <buffer>)
|
1126
1167
|
@dequeued_chunks << DequeuedChunkInfo.new(chunk.unique_id, Time.now, self.delayed_commit_timeout)
|
@@ -1132,7 +1173,7 @@ module Fluent
|
|
1132
1173
|
chunk_id = chunk.unique_id
|
1133
1174
|
dump_chunk_id = dump_unique_id_hex(chunk_id)
|
1134
1175
|
log.trace "adding write count", instance: self.object_id
|
1135
|
-
@
|
1176
|
+
@write_count_metrics.inc
|
1136
1177
|
log.trace "executing sync write", chunk: dump_chunk_id
|
1137
1178
|
|
1138
1179
|
output.write(chunk)
|
@@ -1188,7 +1229,7 @@ module Fluent
|
|
1188
1229
|
end
|
1189
1230
|
|
1190
1231
|
if @buffer.takeback_chunk(chunk.unique_id)
|
1191
|
-
@
|
1232
|
+
@rollback_count_metrics.inc
|
1192
1233
|
end
|
1193
1234
|
|
1194
1235
|
update_retry_state(chunk.unique_id, using_secondary, e)
|
@@ -1208,8 +1249,8 @@ module Fluent
|
|
1208
1249
|
backup_dir = File.dirname(backup_file)
|
1209
1250
|
|
1210
1251
|
log.warn "bad chunk is moved to #{backup_file}"
|
1211
|
-
FileUtils.mkdir_p(backup_dir, mode: system_config.dir_permission ||
|
1212
|
-
File.open(backup_file, 'ab', system_config.file_permission ||
|
1252
|
+
FileUtils.mkdir_p(backup_dir, mode: system_config.dir_permission || Fluent::DEFAULT_DIR_PERMISSION) unless Dir.exist?(backup_dir)
|
1253
|
+
File.open(backup_file, 'ab', system_config.file_permission || Fluent::DEFAULT_FILE_PERMISSION) { |f|
|
1213
1254
|
chunk.write_to(f)
|
1214
1255
|
}
|
1215
1256
|
end
|
@@ -1219,9 +1260,9 @@ module Fluent
|
|
1219
1260
|
def check_slow_flush(start)
|
1220
1261
|
elapsed_time = Fluent::Clock.now - start
|
1221
1262
|
elapsed_millsec = (elapsed_time * 1000).to_i
|
1222
|
-
@
|
1263
|
+
@flush_time_count_metrics.add(elapsed_millsec)
|
1223
1264
|
if elapsed_time > @slow_flush_log_threshold
|
1224
|
-
@
|
1265
|
+
@slow_flush_count_metrics.inc
|
1225
1266
|
log.warn "buffer flush took longer time than slow_flush_log_threshold:",
|
1226
1267
|
elapsed_time: elapsed_time, slow_flush_log_threshold: @slow_flush_log_threshold, plugin_id: self.plugin_id
|
1227
1268
|
end
|
@@ -1229,13 +1270,13 @@ module Fluent
|
|
1229
1270
|
|
1230
1271
|
def update_retry_state(chunk_id, using_secondary, error = nil)
|
1231
1272
|
@retry_mutex.synchronize do
|
1232
|
-
@
|
1273
|
+
@num_errors_metrics.inc
|
1233
1274
|
chunk_id_hex = dump_unique_id_hex(chunk_id)
|
1234
1275
|
|
1235
1276
|
unless @retry
|
1236
1277
|
@retry = retry_state(@buffer_config.retry_randomize)
|
1237
1278
|
if error
|
1238
|
-
log.warn "failed to flush the buffer.",
|
1279
|
+
log.warn "failed to flush the buffer.", retry_times: @retry.steps, next_retry_time: @retry.next_time.round, chunk: chunk_id_hex, error: error
|
1239
1280
|
log.warn_backtrace error.backtrace
|
1240
1281
|
end
|
1241
1282
|
return
|
@@ -1264,11 +1305,11 @@ module Fluent
|
|
1264
1305
|
if error
|
1265
1306
|
if using_secondary
|
1266
1307
|
msg = "failed to flush the buffer with secondary output."
|
1267
|
-
log.warn msg,
|
1308
|
+
log.warn msg, retry_times: @retry.steps, next_retry_time: @retry.next_time.round, chunk: chunk_id_hex, error: error
|
1268
1309
|
log.warn_backtrace error.backtrace
|
1269
1310
|
else
|
1270
1311
|
msg = "failed to flush the buffer."
|
1271
|
-
log.warn msg,
|
1312
|
+
log.warn msg, retry_times: @retry.steps, next_retry_time: @retry.next_time.round, chunk: chunk_id_hex, error: error
|
1272
1313
|
log.warn_backtrace error.backtrace
|
1273
1314
|
end
|
1274
1315
|
end
|
@@ -1490,15 +1531,16 @@ module Fluent
|
|
1490
1531
|
|
1491
1532
|
def statistics
|
1492
1533
|
stats = {
|
1493
|
-
'emit_records' => @
|
1534
|
+
'emit_records' => @emit_records_metrics.get,
|
1535
|
+
'emit_size' => @emit_size_metrics.get,
|
1494
1536
|
# Respect original name
|
1495
1537
|
# https://github.com/fluent/fluentd/blob/45c7b75ba77763eaf87136864d4942c4e0c5bfcd/lib/fluent/plugin/in_monitor_agent.rb#L284
|
1496
|
-
'retry_count' => @
|
1497
|
-
'emit_count' => @
|
1498
|
-
'write_count' => @
|
1499
|
-
'rollback_count' => @
|
1500
|
-
'slow_flush_count' => @
|
1501
|
-
'flush_time_count' => @
|
1538
|
+
'retry_count' => @num_errors_metrics.get,
|
1539
|
+
'emit_count' => @emit_count_metrics.get,
|
1540
|
+
'write_count' => @write_count_metrics.get,
|
1541
|
+
'rollback_count' => @rollback_count_metrics.get,
|
1542
|
+
'slow_flush_count' => @slow_flush_count_metrics.get,
|
1543
|
+
'flush_time_count' => @flush_time_count_metrics.get,
|
1502
1544
|
}
|
1503
1545
|
|
1504
1546
|
if @buffer && @buffer.respond_to?(:statistics)
|
@@ -21,7 +21,7 @@ module Fluent
|
|
21
21
|
class Apache2Parser < Parser
|
22
22
|
Plugin.register_parser('apache2', self)
|
23
23
|
|
24
|
-
REGEXP = /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>(?:[^\"]
|
24
|
+
REGEXP = /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>(?:[^\"]|\\")*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>(?:[^\"]|\\")*)" "(?<agent>(?:[^\"]|\\")*)")?$/
|
25
25
|
TIME_FORMAT = "%d/%b/%Y:%H:%M:%S %z"
|
26
26
|
|
27
27
|
def initialize
|
@@ -14,6 +14,7 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
+
require 'fluent/env'
|
17
18
|
require 'fluent/plugin'
|
18
19
|
require 'fluent/plugin/storage'
|
19
20
|
|
@@ -25,14 +26,11 @@ module Fluent
|
|
25
26
|
class LocalStorage < Storage
|
26
27
|
Fluent::Plugin.register_storage('local', self)
|
27
28
|
|
28
|
-
DEFAULT_DIR_MODE = 0755
|
29
|
-
DEFAULT_FILE_MODE = 0644
|
30
|
-
|
31
29
|
config_param :path, :string, default: nil
|
32
|
-
config_param :mode, default:
|
30
|
+
config_param :mode, default: Fluent::DEFAULT_FILE_PERMISSION do |v|
|
33
31
|
v.to_i(8)
|
34
32
|
end
|
35
|
-
config_param :dir_mode, default:
|
33
|
+
config_param :dir_mode, default: Fluent::DEFAULT_DIR_PERMISSION do |v|
|
36
34
|
v.to_i(8)
|
37
35
|
end
|
38
36
|
config_param :pretty_print, :bool, default: false
|