fluentd 1.9.3 → 1.11.1

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/issue-auto-closer.yml +12 -0
  3. data/CHANGELOG.md +182 -0
  4. data/CONTRIBUTING.md +1 -1
  5. data/README.md +4 -0
  6. data/docs/SECURITY_AUDIT.pdf +0 -0
  7. data/lib/fluent/command/debug.rb +1 -0
  8. data/lib/fluent/command/fluentd.rb +25 -1
  9. data/lib/fluent/config.rb +1 -0
  10. data/lib/fluent/daemonizer.rb +88 -0
  11. data/lib/fluent/log.rb +45 -6
  12. data/lib/fluent/match.rb +1 -1
  13. data/lib/fluent/msgpack_factory.rb +13 -6
  14. data/lib/fluent/plugin/buffer.rb +2 -2
  15. data/lib/fluent/plugin/in_dummy.rb +3 -3
  16. data/lib/fluent/plugin/in_forward.rb +2 -2
  17. data/lib/fluent/plugin/in_gc_stat.rb +16 -0
  18. data/lib/fluent/plugin/in_http.rb +146 -75
  19. data/lib/fluent/plugin/in_monitor_agent.rb +1 -1
  20. data/lib/fluent/plugin/in_syslog.rb +4 -4
  21. data/lib/fluent/plugin/in_tail.rb +40 -31
  22. data/lib/fluent/plugin/in_tail/position_file.rb +23 -6
  23. data/lib/fluent/plugin/in_unix.rb +77 -77
  24. data/lib/fluent/plugin/out_copy.rb +1 -1
  25. data/lib/fluent/plugin/out_file.rb +1 -1
  26. data/lib/fluent/plugin/out_forward.rb +25 -22
  27. data/lib/fluent/plugin/out_forward/handshake_protocol.rb +4 -0
  28. data/lib/fluent/plugin/out_forward/load_balancer.rb +1 -1
  29. data/lib/fluent/plugin/out_http.rb +15 -2
  30. data/lib/fluent/plugin/parser_multiline.rb +1 -1
  31. data/lib/fluent/plugin/parser_syslog.rb +303 -62
  32. data/lib/fluent/plugin/sd_file.rb +1 -0
  33. data/lib/fluent/plugin/sd_srv.rb +135 -0
  34. data/lib/fluent/plugin_helper/cert_option.rb +15 -2
  35. data/lib/fluent/plugin_helper/child_process.rb +3 -2
  36. data/lib/fluent/plugin_helper/record_accessor.rb +14 -0
  37. data/lib/fluent/plugin_helper/server.rb +3 -1
  38. data/lib/fluent/plugin_helper/service_discovery.rb +7 -0
  39. data/lib/fluent/plugin_helper/service_discovery/manager.rb +8 -0
  40. data/lib/fluent/plugin_helper/socket.rb +20 -2
  41. data/lib/fluent/plugin_helper/socket_option.rb +21 -3
  42. data/lib/fluent/supervisor.rb +21 -9
  43. data/lib/fluent/system_config.rb +2 -1
  44. data/lib/fluent/test/filter_test.rb +2 -2
  45. data/lib/fluent/test/output_test.rb +3 -3
  46. data/lib/fluent/version.rb +1 -1
  47. data/test/command/test_fluentd.rb +71 -12
  48. data/test/config/test_system_config.rb +2 -0
  49. data/test/helper.rb +2 -2
  50. data/test/plugin/in_tail/test_fifo.rb +121 -0
  51. data/test/plugin/in_tail/test_io_handler.rb +132 -0
  52. data/test/plugin/in_tail/test_position_file.rb +25 -1
  53. data/test/plugin/out_forward/test_handshake_protocol.rb +10 -1
  54. data/test/plugin/out_forward/test_load_balancer.rb +46 -0
  55. data/test/plugin/test_buf_file.rb +3 -1
  56. data/test/plugin/test_buffer.rb +20 -0
  57. data/test/plugin/test_compressable.rb +7 -4
  58. data/test/plugin/test_in_dummy.rb +12 -14
  59. data/test/plugin/test_in_forward.rb +2 -2
  60. data/test/plugin/test_in_gc_stat.rb +24 -1
  61. data/test/plugin/test_in_http.rb +57 -0
  62. data/test/plugin/test_in_syslog.rb +16 -1
  63. data/test/plugin/test_in_tail.rb +43 -20
  64. data/test/plugin/test_in_unix.rb +128 -73
  65. data/test/plugin/test_out_forward.rb +39 -3
  66. data/test/plugin/test_out_http.rb +38 -0
  67. data/test/plugin/test_out_null.rb +1 -1
  68. data/test/plugin/test_output_as_buffered_retries.rb +12 -4
  69. data/test/plugin/test_output_as_buffered_secondary.rb +9 -1
  70. data/test/plugin/test_parser_syslog.rb +106 -46
  71. data/test/plugin/test_sd_file.rb +17 -0
  72. data/test/plugin/test_sd_srv.rb +230 -0
  73. data/test/plugin_helper/data/cert/cert-with-CRLF.pem +19 -0
  74. data/test/plugin_helper/data/cert/cert_chains/ca-cert-key.pem +27 -0
  75. data/test/plugin_helper/data/cert/cert_chains/ca-cert.pem +20 -0
  76. data/test/plugin_helper/data/cert/cert_chains/cert-key.pem +27 -0
  77. data/test/plugin_helper/data/cert/cert_chains/cert.pem +40 -0
  78. data/test/plugin_helper/data/cert/generate_cert.rb +38 -0
  79. data/test/plugin_helper/http_server/test_app.rb +1 -1
  80. data/test/plugin_helper/http_server/test_route.rb +1 -1
  81. data/test/plugin_helper/test_cert_option.rb +2 -0
  82. data/test/plugin_helper/test_child_process.rb +20 -3
  83. data/test/plugin_helper/test_http_server_helper.rb +2 -2
  84. data/test/plugin_helper/test_record_accessor.rb +41 -0
  85. data/test/plugin_helper/test_server.rb +1 -1
  86. data/test/plugin_helper/test_service_discovery.rb +37 -4
  87. data/test/plugin_helper/test_socket.rb +131 -0
  88. data/test/test_daemonizer.rb +91 -0
  89. data/test/test_log.rb +44 -0
  90. data/test/test_msgpack_factory.rb +18 -0
  91. metadata +28 -2
@@ -223,7 +223,7 @@ module Fluent::Plugin
223
223
  opts = {with_config: false, with_retry: false}
224
224
  timer_execute(:in_monitor_agent_emit, @emit_interval, repeat: true) {
225
225
  es = Fluent::MultiEventStream.new
226
- now = Fluent::Engine.now
226
+ now = Fluent::EventTime.now
227
227
  plugins_info_all(opts).each { |record|
228
228
  es.add(now, record)
229
229
  }
@@ -181,12 +181,12 @@ module Fluent::Plugin
181
181
  if octet_count_frame
182
182
  while idx = buffer.index(delimiter, pos)
183
183
  num = Integer(buffer[pos..idx])
184
- pos = idx + num
185
- msg = buffer[idx + 1...pos]
186
- if msg.size < num - 1
187
- pos = pos - num - num.to_s.size
184
+ msg = buffer[idx + delimiter_size, num]
185
+ if msg.size != num
188
186
  break
189
187
  end
188
+
189
+ pos = idx + delimiter_size + num
190
190
  message_handler(msg, conn)
191
191
  end
192
192
  else
@@ -70,7 +70,7 @@ module Fluent::Plugin
70
70
  desc 'Fluentd will record the position it last read into this file.'
71
71
  config_param :pos_file, :string, default: nil
72
72
  desc 'The cleanup interval of pos file'
73
- config_param :pos_file_compaction_interval, :integer, default: nil
73
+ config_param :pos_file_compaction_interval, :time, default: nil
74
74
  desc 'Start to read the logs from the head of file, not bottom.'
75
75
  config_param :read_from_head, :bool, default: false
76
76
  # When the program deletes log file and re-creates log file with same filename after passed refresh_interval,
@@ -136,7 +136,7 @@ module Fluent::Plugin
136
136
  raise Fluent::ConfigError, "#{rc} are reserved words: #{@path_delimiter}"
137
137
  end
138
138
 
139
- @paths = @path.split(@path_delimiter).map(&:strip)
139
+ @paths = @path.split(@path_delimiter).map(&:strip).uniq
140
140
  if @paths.empty?
141
141
  raise Fluent::ConfigError, "tail: 'path' parameter is required on tail input"
142
142
  end
@@ -271,9 +271,9 @@ module Fluent::Plugin
271
271
  end
272
272
  else
273
273
  if is_file
274
- unless @ignore_list.include?(path)
274
+ unless @ignore_list.include?(p)
275
275
  log.warn "#{p} unreadable. It is excluded and would be examined next time."
276
- @ignore_list << path if @ignore_repeated_permission_error
276
+ @ignore_list << p if @ignore_repeated_permission_error
277
277
  end
278
278
  end
279
279
  false
@@ -296,7 +296,7 @@ module Fluent::Plugin
296
296
  end
297
297
  path.include?('*') ? Dir.glob(path) : path
298
298
  }.flatten.uniq
299
- paths - excluded
299
+ paths.uniq - excluded
300
300
  end
301
301
 
302
302
  # in_tail with '*' path doesn't check rotation file equality at refresh phase.
@@ -319,7 +319,7 @@ module Fluent::Plugin
319
319
 
320
320
  def setup_watcher(path, pe)
321
321
  line_buffer_timer_flusher = @multiline_mode ? TailWatcher::LineBufferTimerFlusher.new(log, @multiline_flush_interval, &method(:flush_buffer)) : nil
322
- tw = TailWatcher.new(path, pe, log, @read_from_head, @read_lines_limit, method(:update_watcher), line_buffer_timer_flusher, @from_encoding, @encoding, open_on_every_update, &method(:receive_lines))
322
+ tw = TailWatcher.new(path, pe, log, @read_from_head, method(:update_watcher), line_buffer_timer_flusher, method(:io_handler))
323
323
 
324
324
  if @enable_watch_timer
325
325
  tt = TimerTrigger.new(1, log) { tw.on_notify }
@@ -555,6 +555,21 @@ module Fluent::Plugin
555
555
  es
556
556
  end
557
557
 
558
+ private
559
+
560
+ def io_handler(watcher, path)
561
+ TailWatcher::IOHandler.new(
562
+ watcher,
563
+ path: path,
564
+ log: log,
565
+ read_lines_limit: @read_lines_limit,
566
+ open_on_every_update: @open_on_every_update,
567
+ from_encoding: @from_encoding,
568
+ encoding: @encoding,
569
+ &method(:receive_lines)
570
+ )
571
+ end
572
+
558
573
  class StatWatcher < Coolio::StatWatcher
559
574
  def initialize(path, log, &callback)
560
575
  @callback = callback
@@ -586,22 +601,16 @@ module Fluent::Plugin
586
601
  end
587
602
 
588
603
  class TailWatcher
589
- def initialize(path, pe, log, read_from_head, read_lines_limit, update_watcher, line_buffer_timer_flusher, from_encoding, encoding, open_on_every_update, &receive_lines)
604
+ def initialize(path, pe, log, read_from_head, update_watcher, line_buffer_timer_flusher, io_handler_build)
590
605
  @path = path
591
606
  @pe = pe || MemoryPositionEntry.new
592
607
  @read_from_head = read_from_head
593
- @read_lines_limit = read_lines_limit
594
- @receive_lines = receive_lines
595
608
  @update_watcher = update_watcher
596
-
597
- @rotate_handler = RotateHandler.new(log, &method(:on_rotate))
598
- @io_handler = nil
599
609
  @log = log
600
-
610
+ @rotate_handler = RotateHandler.new(log, &method(:on_rotate))
601
611
  @line_buffer_timer_flusher = line_buffer_timer_flusher
602
- @from_encoding = from_encoding
603
- @encoding = encoding
604
- @open_on_every_update = open_on_every_update
612
+ @io_handler = nil
613
+ @io_handler_build = io_handler_build
605
614
  @watchers = []
606
615
  end
607
616
 
@@ -709,9 +718,7 @@ module Fluent::Plugin
709
718
  end
710
719
 
711
720
  def io_handler
712
- IOHandler.new(self, path: @path, log: @log, read_lines_limit: @read_lines_limit, open_on_every_update: @open_on_every_update, from_encoding: @from_encoding, encoding: @encoding) do |lines|
713
- @receive_lines.call(lines, self)
714
- end
721
+ @io_handler_build.call(self, @path)
715
722
  end
716
723
 
717
724
  def swap_state(pe)
@@ -801,6 +808,19 @@ module Fluent::Plugin
801
808
  @notify_mutex.synchronize { handle_notify }
802
809
  end
803
810
 
811
+ def close
812
+ if @io && !@io.closed?
813
+ @io.close
814
+ @io = nil
815
+ end
816
+ end
817
+
818
+ def opened?
819
+ !!@io
820
+ end
821
+
822
+ private
823
+
804
824
  def handle_notify
805
825
  with_io do |io|
806
826
  begin
@@ -822,7 +842,7 @@ module Fluent::Plugin
822
842
  end
823
843
 
824
844
  unless @lines.empty?
825
- if @receive_lines.call(@lines)
845
+ if @receive_lines.call(@lines, @watcher)
826
846
  @watcher.pe.update_pos(io.pos - @fifo.bytesize)
827
847
  @lines.clear
828
848
  else
@@ -833,17 +853,6 @@ module Fluent::Plugin
833
853
  end
834
854
  end
835
855
 
836
- def close
837
- if @io && !@io.closed?
838
- @io.close
839
- @io = nil
840
- end
841
- end
842
-
843
- def opened?
844
- !!@io
845
- end
846
-
847
856
  def open
848
857
  io = Fluent::FileWrapper.open(@path)
849
858
  io.seek(@watcher.pe.read_pos + @fifo.bytesize)
@@ -21,7 +21,6 @@ module Fluent::Plugin
21
21
  class PositionFile
22
22
  UNWATCHED_POSITION = 0xffffffffffffffff
23
23
  POSITION_FILE_ENTRY_REGEX = /^([^\t]+)\t([0-9a-fA-F]+)\t([0-9a-fA-F]+)/.freeze
24
- POSITION_FILE_ENTRY_FORMAT = "%s\t%016x\t%016x\n".freeze
25
24
 
26
25
  def self.load(file, logger:)
27
26
  pf = new(file, logger: logger)
@@ -83,8 +82,8 @@ module Fluent::Plugin
83
82
  size = nil
84
83
 
85
84
  @file_mutex.synchronize do
86
- last_modified = @file.mtime
87
85
  size = @file.size
86
+ last_modified = @file.mtime
88
87
  end
89
88
 
90
89
  entries = fetch_compacted_entries
@@ -93,7 +92,13 @@ module Fluent::Plugin
93
92
  if last_modified == @file.mtime && size == @file.size
94
93
  @file.pos = 0
95
94
  @file.truncate(0)
96
- @file.write(entries.join)
95
+ @file.write(entries.values.map(&:to_entry_fmt).join)
96
+
97
+ entries.each do |path, val|
98
+ if (m = @map[path])
99
+ m.seek = val.seek
100
+ end
101
+ end
97
102
  else
98
103
  # skip
99
104
  end
@@ -104,7 +109,7 @@ module Fluent::Plugin
104
109
 
105
110
  def compact
106
111
  @file_mutex.synchronize do
107
- entries = fetch_compacted_entries
112
+ entries = fetch_compacted_entries.values.map(&:to_entry_fmt)
108
113
 
109
114
  @file.pos = 0
110
115
  @file.truncate(0)
@@ -116,6 +121,7 @@ module Fluent::Plugin
116
121
  entries = {}
117
122
 
118
123
  @file.pos = 0
124
+ file_pos = 0
119
125
  @file.each_line do |line|
120
126
  m = POSITION_FILE_ENTRY_REGEX.match(line)
121
127
  if m.nil?
@@ -133,11 +139,20 @@ module Fluent::Plugin
133
139
  @logger.warn("#{path} already exists. use latest one: deleted #{entries[path]}") if @logger
134
140
  end
135
141
 
136
- entries[path] = (POSITION_FILE_ENTRY_FORMAT % [path, pos, ino])
142
+ entries[path] = Entry.new(path, pos, ino, file_pos + path.size + 1)
143
+ file_pos += line.size
137
144
  end
138
145
  end
139
146
 
140
- entries.values
147
+ entries
148
+ end
149
+ end
150
+
151
+ Entry = Struct.new(:path, :pos, :ino, :seek) do
152
+ POSITION_FILE_ENTRY_FORMAT = "%s\t%016x\t%016x\n".freeze
153
+
154
+ def to_entry_fmt
155
+ POSITION_FILE_ENTRY_FORMAT % [path, pos, ino]
141
156
  end
142
157
  end
143
158
 
@@ -158,6 +173,8 @@ module Fluent::Plugin
158
173
  @inode = inode
159
174
  end
160
175
 
176
+ attr_writer :seek
177
+
161
178
  def update(ino, pos)
162
179
  @file_mutex.synchronize {
163
180
  @file.pos = @seek
@@ -14,50 +14,68 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'fileutils'
18
- require 'socket'
17
+ require 'fluent/env'
18
+ require 'fluent/plugin/input'
19
+ require 'fluent/msgpack_factory'
19
20
 
20
21
  require 'cool.io'
21
22
  require 'yajl'
23
+ require 'fileutils'
24
+ require 'socket'
25
+
26
+ module Fluent::Plugin
27
+ # TODO: This plugin will be 3rd party plugin
28
+ class UnixInput < Input
29
+ Fluent::Plugin.register_input('unix', self)
30
+
31
+ helpers :event_loop
32
+
33
+ def initialize
34
+ super
22
35
 
23
- require 'fluent/input'
24
- require 'fluent/event'
36
+ @lsock = nil
37
+ end
25
38
 
26
- module Fluent
27
- # obsolete
28
- class StreamInput < Input
29
- config_param :blocking_timeout, :time, default: 0.5
39
+ desc 'The path to your Unix Domain Socket.'
40
+ config_param :path, :string, default: Fluent::DEFAULT_SOCKET_PATH
41
+ desc 'The backlog of Unix Domain Socket.'
42
+ config_param :backlog, :integer, default: nil
43
+ desc "New tag instead of incoming tag"
44
+ config_param :tag, :string, default: nil
45
+
46
+ def configure(conf)
47
+ super
48
+ end
30
49
 
31
50
  def start
32
51
  super
33
52
 
34
- @loop = Coolio::Loop.new
35
53
  @lsock = listen
36
- @loop.attach(@lsock)
37
- @thread = Thread.new(&method(:run))
54
+ event_loop_attach(@lsock)
38
55
  end
39
56
 
40
57
  def shutdown
41
- @loop.watchers.each {|w| w.detach }
42
- @loop.stop
43
- @lsock.close
44
- @thread.join
58
+ if @lsock
59
+ event_loop_detach(@lsock)
60
+ @lsock.close
61
+ end
45
62
 
46
63
  super
47
64
  end
48
65
 
49
- #def listen
50
- #end
66
+ def listen
67
+ if File.exist?(@path)
68
+ log.warn "Found existing '#{@path}'. Remove this file for in_unix plugin"
69
+ File.unlink(@path)
70
+ end
71
+ FileUtils.mkdir_p(File.dirname(@path))
51
72
 
52
- def run
53
- @loop.run(@blocking_timeout)
54
- rescue
55
- log.error "unexpected error", error: $!.to_s
56
- log.error_backtrace
73
+ log.info "listening fluent socket on #{@path}"
74
+ s = Coolio::UNIXServer.new(@path, Handler, log, method(:on_message))
75
+ s.listen(@backlog) unless @backlog.nil?
76
+ s
57
77
  end
58
78
 
59
- private
60
-
61
79
  # message Entry {
62
80
  # 1: long time
63
81
  # 2: object record
@@ -79,23 +97,27 @@ module Fluent
79
97
  # 3: object record
80
98
  # }
81
99
  def on_message(msg)
82
- # TODO format error
83
- tag = msg[0].to_s
100
+ unless msg.is_a?(Array)
101
+ log.warn "incoming data is broken:", msg: msg
102
+ return
103
+ end
104
+
105
+ tag = @tag || (msg[0].to_s)
84
106
  entries = msg[1]
85
107
 
86
- if entries.class == String
108
+ case entries
109
+ when String
87
110
  # PackedForward
88
- es = MessagePackEventStream.new(entries)
111
+ es = Fluent::MessagePackEventStream.new(entries)
89
112
  router.emit_stream(tag, es)
90
113
 
91
- elsif entries.class == Array
114
+ when Array
92
115
  # Forward
93
- es = MultiEventStream.new
116
+ es = Fluent::MultiEventStream.new
94
117
  entries.each {|e|
95
118
  record = e[1]
96
119
  next if record.nil?
97
- time = e[0]
98
- time = (now ||= Engine.now) if time.to_i == 0
120
+ time = convert_time(e[0])
99
121
  es.add(time, record)
100
122
  }
101
123
  router.emit_stream(tag, es)
@@ -105,25 +127,28 @@ module Fluent
105
127
  record = msg[2]
106
128
  return if record.nil?
107
129
 
108
- time = msg[1]
109
- time = Engine.now if time.to_i == 0
130
+ time = convert_time(msg[1])
110
131
  router.emit(tag, time, record)
111
132
  end
112
133
  end
113
134
 
135
+ def convert_time(time)
136
+ case time
137
+ when nil, 0
138
+ Fluent::EventTime.now
139
+ when Fluent::EventTime
140
+ time
141
+ else
142
+ Fluent::EventTime.from_time(Time.at(time))
143
+ end
144
+ end
145
+
114
146
  class Handler < Coolio::Socket
115
147
  def initialize(io, log, on_message)
116
148
  super(io)
117
- if io.is_a?(TCPSocket)
118
- opt = [1, @timeout.to_i].pack('I!I!') # { int l_onoff; int l_linger; }
119
- io.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, opt)
120
- end
149
+
121
150
  @on_message = on_message
122
151
  @log = log
123
- @log.trace {
124
- remote_port, remote_addr = *Socket.unpack_sockaddr_in(@_io.getpeername) rescue nil
125
- "accepted fluent socket from '#{remote_addr}:#{remote_port}': object_id=#{self.object_id}"
126
- }
127
152
  end
128
153
 
129
154
  def on_connect
@@ -131,13 +156,13 @@ module Fluent
131
156
 
132
157
  def on_read(data)
133
158
  first = data[0]
134
- if first == '{' || first == '['
159
+ if first == '{'.freeze || first == '['.freeze
135
160
  m = method(:on_read_json)
136
- @y = Yajl::Parser.new
137
- @y.on_parse_complete = @on_message
161
+ @parser = Yajl::Parser.new
162
+ @parser.on_parse_complete = @on_message
138
163
  else
139
164
  m = method(:on_read_msgpack)
140
- @u = Fluent::MessagePackFactory.msgpack_unpacker
165
+ @parser = Fluent::MessagePackFactory.msgpack_unpacker
141
166
  end
142
167
 
143
168
  singleton_class.module_eval do
@@ -147,17 +172,17 @@ module Fluent
147
172
  end
148
173
 
149
174
  def on_read_json(data)
150
- @y << data
151
- rescue
152
- @log.error "unexpected error", error: $!.to_s
175
+ @parser << data
176
+ rescue => e
177
+ @log.error "unexpected error in json payload", error: e.to_s
153
178
  @log.error_backtrace
154
179
  close
155
180
  end
156
181
 
157
182
  def on_read_msgpack(data)
158
- @u.feed_each(data, &@on_message)
159
- rescue
160
- @log.error "unexpected error", error: $!.to_s
183
+ @parser.feed_each(data, &@on_message)
184
+ rescue => e
185
+ @log.error "unexpected error in msgpack payload", error: e.to_s
161
186
  @log.error_backtrace
162
187
  close
163
188
  end
@@ -167,29 +192,4 @@ module Fluent
167
192
  end
168
193
  end
169
194
  end
170
-
171
- class UnixInput < StreamInput
172
- Plugin.register_input('unix', self)
173
-
174
- desc 'The path to your Unix Domain Socket.'
175
- config_param :path, :string, default: DEFAULT_SOCKET_PATH
176
- desc 'The backlog of Unix Domain Socket.'
177
- config_param :backlog, :integer, default: nil
178
-
179
- def configure(conf)
180
- super
181
- #log.warn "'unix' input is obsoleted and will be removed. Use 'forward' instead."
182
- end
183
-
184
- def listen
185
- if File.exist?(@path)
186
- File.unlink(@path)
187
- end
188
- FileUtils.mkdir_p File.dirname(@path)
189
- log.info "listening fluent socket on #{@path}"
190
- s = Coolio::UNIXServer.new(@path, Handler, log, method(:on_message))
191
- s.listen(@backlog) unless @backlog.nil?
192
- s
193
- end
194
- end
195
195
  end