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.

Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.drone.yml +6 -6
  3. data/.github/ISSUE_TEMPLATE/bug_report.yaml +1 -0
  4. data/.github/workflows/windows-test.yaml +3 -3
  5. data/CHANGELOG.md +96 -0
  6. data/fluentd.gemspec +1 -1
  7. data/lib/fluent/command/cat.rb +13 -3
  8. data/lib/fluent/command/fluentd.rb +8 -0
  9. data/lib/fluent/compat/output.rb +9 -6
  10. data/lib/fluent/config/parser.rb +1 -1
  11. data/lib/fluent/config/v1_parser.rb +1 -1
  12. data/lib/fluent/event_router.rb +28 -1
  13. data/lib/fluent/plugin/bare_output.rb +49 -8
  14. data/lib/fluent/plugin/buf_file.rb +2 -2
  15. data/lib/fluent/plugin/buffer.rb +84 -22
  16. data/lib/fluent/plugin/filter.rb +35 -1
  17. data/lib/fluent/plugin/in_http.rb +21 -2
  18. data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
  19. data/lib/fluent/plugin/in_syslog.rb +13 -1
  20. data/lib/fluent/plugin/in_tail/position_file.rb +1 -1
  21. data/lib/fluent/plugin/in_tail.rb +37 -5
  22. data/lib/fluent/plugin/input.rb +39 -1
  23. data/lib/fluent/plugin/metrics.rb +119 -0
  24. data/lib/fluent/plugin/metrics_local.rb +96 -0
  25. data/lib/fluent/plugin/multi_output.rb +43 -6
  26. data/lib/fluent/plugin/out_copy.rb +1 -1
  27. data/lib/fluent/plugin/out_forward.rb +15 -7
  28. data/lib/fluent/plugin/output.rb +80 -38
  29. data/lib/fluent/plugin/parser_apache2.rb +1 -1
  30. data/lib/fluent/plugin/storage_local.rb +3 -5
  31. data/lib/fluent/plugin.rb +10 -1
  32. data/lib/fluent/plugin_helper/event_emitter.rb +8 -1
  33. data/lib/fluent/plugin_helper/metrics.rb +129 -0
  34. data/lib/fluent/plugin_helper/server.rb +4 -2
  35. data/lib/fluent/plugin_helper.rb +1 -0
  36. data/lib/fluent/plugin_id.rb +2 -1
  37. data/lib/fluent/root_agent.rb +6 -0
  38. data/lib/fluent/supervisor.rb +4 -2
  39. data/lib/fluent/system_config.rb +9 -1
  40. data/lib/fluent/time.rb +21 -20
  41. data/lib/fluent/version.rb +1 -1
  42. data/test/command/test_cat.rb +31 -2
  43. data/test/config/test_system_config.rb +6 -0
  44. data/test/plugin/in_tail/test_io_handler.rb +12 -4
  45. data/test/plugin/in_tail/test_position_file.rb +26 -4
  46. data/test/plugin/test_bare_output.rb +13 -0
  47. data/test/plugin/test_buffer.rb +8 -2
  48. data/test/plugin/test_filter.rb +11 -0
  49. data/test/plugin/test_in_http.rb +40 -0
  50. data/test/plugin/test_in_monitor_agent.rb +214 -8
  51. data/test/plugin/test_in_syslog.rb +35 -0
  52. data/test/plugin/test_in_tail.rb +28 -29
  53. data/test/plugin/test_input.rb +11 -0
  54. data/test/plugin/test_metrics.rb +294 -0
  55. data/test/plugin/test_metrics_local.rb +96 -0
  56. data/test/plugin/test_multi_output.rb +25 -1
  57. data/test/plugin/test_output.rb +16 -0
  58. data/test/plugin_helper/test_event_emitter.rb +29 -0
  59. data/test/plugin_helper/test_metrics.rb +137 -0
  60. data/test/test_plugin_classes.rb +102 -0
  61. data/test/test_root_agent.rb +30 -1
  62. data/test/test_time_parser.rb +22 -0
  63. 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
- @num_errors = 0
50
- @emit_count = 0
51
- @emit_records = 0
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
- @counter_mutex.synchronize{ @emit_count += 1 }
182
+ @emit_count_metrics.inc
147
183
  begin
148
184
  process(tag, es)
149
- @counter_mutex.synchronize{ @emit_records += es.size }
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
- @counter_mutex.synchronize{ @num_errors += 1 }
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) && @ignore_if_prev_successes.include?(false)
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
- healthy_nodes_count = 0
422
- registed_nodes_count = services.size
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
- healthy_nodes_count += 1
430
+ @healthy_nodes_count_metrics.inc
426
431
  end
427
432
  end
428
433
 
429
- stats.merge(
430
- 'healthy_nodes_count' => healthy_nodes_count,
431
- 'registered_nodes_count' => registed_nodes_count,
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
@@ -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
- @num_errors = 0
185
- @emit_count = 0
186
- @emit_records = 0
187
- @write_count = 0
188
- @rollback_count = 0
189
- @flush_time_count = 0
190
- @slow_flush_count = 0
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
- @counter_mutex.synchronize{ @emit_count += 1 }
837
+ @emit_count_metrics.inc
801
838
  begin
802
839
  process(tag, es)
803
- @counter_mutex.synchronize{ @emit_records += es.size }
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
- @counter_mutex.synchronize{ @num_errors += 1 }
843
+ @num_errors_metrics.inc
806
844
  raise
807
845
  end
808
846
  end
809
847
 
810
848
  def emit_buffered(tag, es)
811
- @counter_mutex.synchronize{ @emit_count += 1 }
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
- @counter_mutex.synchronize{ @num_errors += 1 }
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
- @counter_mutex.synchronize{ @emit_records += records }
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
- @counter_mutex.synchronize{ @emit_records += records }
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
- @counter_mutex.synchronize{ @emit_records += records }
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
- @counter_mutex.synchronize{ @rollback_count += 1 }
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
- @counter_mutex.synchronize{ @rollback_count += 1 }
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
- @counter_mutex.synchronize{ @rollback_count += 1 }
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
- @counter_mutex.synchronize{ @write_count += 1 }
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
- @counter_mutex.synchronize{ @write_count += 1 }
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
- @counter_mutex.synchronize { @rollback_count += 1 }
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 || 0755) unless Dir.exist?(backup_dir)
1212
- File.open(backup_file, 'ab', system_config.file_permission || 0644) { |f|
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
- @counter_mutex.synchronize { @flush_time_count += elapsed_millsec }
1263
+ @flush_time_count_metrics.add(elapsed_millsec)
1223
1264
  if elapsed_time > @slow_flush_log_threshold
1224
- @counter_mutex.synchronize { @slow_flush_count += 1 }
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
- @counter_mutex.synchronize{ @num_errors += 1 }
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.", retry_time: @retry.steps, next_retry_seconds: @retry.next_time, chunk: chunk_id_hex, error: error
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, retry_time: @retry.steps, next_retry_seconds: @retry.next_time, chunk: chunk_id_hex, error: error
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, retry_time: @retry.steps, next_retry_seconds: @retry.next_time, chunk: chunk_id_hex, error: error
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' => @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' => @num_errors,
1497
- 'emit_count' => @emit_count,
1498
- 'write_count' => @write_count,
1499
- 'rollback_count' => @rollback_count,
1500
- 'slow_flush_count' => @slow_flush_count,
1501
- 'flush_time_count' => @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>(?:[^\"]|\\.)*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>(?:[^\"]|\\.)*)" "(?<agent>(?:[^\"]|\\.)*)")?$/
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: DEFAULT_FILE_MODE do |v|
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: DEFAULT_DIR_MODE do |v|
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