fluentd 0.12.40 → 0.14.0

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 (252) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +6 -0
  3. data/.gitignore +2 -0
  4. data/.travis.yml +33 -21
  5. data/CONTRIBUTING.md +1 -0
  6. data/ChangeLog +810 -237
  7. data/README.md +0 -25
  8. data/Rakefile +2 -1
  9. data/Vagrantfile +17 -0
  10. data/appveyor.yml +35 -0
  11. data/example/filter_stdout.conf +5 -5
  12. data/example/in_forward.conf +2 -2
  13. data/example/in_http.conf +2 -2
  14. data/example/in_out_forward.conf +17 -0
  15. data/example/in_syslog.conf +2 -2
  16. data/example/in_tail.conf +2 -2
  17. data/example/in_tcp.conf +2 -2
  18. data/example/in_udp.conf +2 -2
  19. data/example/out_copy.conf +4 -4
  20. data/example/out_file.conf +2 -2
  21. data/example/out_forward.conf +2 -2
  22. data/example/out_forward_buf_file.conf +23 -0
  23. data/example/v0_12_filter.conf +8 -8
  24. data/fluent.conf +29 -0
  25. data/fluentd.gemspec +18 -11
  26. data/lib/fluent/agent.rb +60 -58
  27. data/lib/fluent/command/cat.rb +1 -1
  28. data/lib/fluent/command/debug.rb +7 -5
  29. data/lib/fluent/command/fluentd.rb +97 -2
  30. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  31. data/lib/fluent/compat/filter.rb +50 -0
  32. data/lib/fluent/compat/formatter.rb +109 -0
  33. data/lib/fluent/compat/input.rb +50 -0
  34. data/lib/fluent/compat/output.rb +617 -0
  35. data/lib/fluent/compat/output_chain.rb +60 -0
  36. data/lib/fluent/compat/parser.rb +163 -0
  37. data/lib/fluent/compat/propagate_default.rb +62 -0
  38. data/lib/fluent/config.rb +23 -20
  39. data/lib/fluent/config/configure_proxy.rb +119 -70
  40. data/lib/fluent/config/dsl.rb +5 -18
  41. data/lib/fluent/config/element.rb +72 -8
  42. data/lib/fluent/config/error.rb +0 -3
  43. data/lib/fluent/config/literal_parser.rb +0 -2
  44. data/lib/fluent/config/parser.rb +4 -4
  45. data/lib/fluent/config/section.rb +39 -28
  46. data/lib/fluent/config/types.rb +2 -13
  47. data/lib/fluent/config/v1_parser.rb +1 -3
  48. data/lib/fluent/configurable.rb +48 -16
  49. data/lib/fluent/daemon.rb +15 -0
  50. data/lib/fluent/engine.rb +26 -52
  51. data/lib/fluent/env.rb +6 -4
  52. data/lib/fluent/event.rb +58 -11
  53. data/lib/fluent/event_router.rb +5 -5
  54. data/lib/fluent/filter.rb +2 -50
  55. data/lib/fluent/formatter.rb +4 -293
  56. data/lib/fluent/input.rb +2 -32
  57. data/lib/fluent/label.rb +2 -2
  58. data/lib/fluent/load.rb +3 -2
  59. data/lib/fluent/log.rb +107 -38
  60. data/lib/fluent/match.rb +0 -36
  61. data/lib/fluent/mixin.rb +117 -7
  62. data/lib/fluent/msgpack_factory.rb +62 -0
  63. data/lib/fluent/output.rb +7 -612
  64. data/lib/fluent/output_chain.rb +23 -0
  65. data/lib/fluent/parser.rb +4 -800
  66. data/lib/fluent/plugin.rb +100 -121
  67. data/lib/fluent/plugin/bare_output.rb +63 -0
  68. data/lib/fluent/plugin/base.rb +121 -0
  69. data/lib/fluent/plugin/buf_file.rb +101 -182
  70. data/lib/fluent/plugin/buf_memory.rb +9 -92
  71. data/lib/fluent/plugin/buffer.rb +473 -0
  72. data/lib/fluent/plugin/buffer/chunk.rb +135 -0
  73. data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
  74. data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
  75. data/lib/fluent/plugin/exec_util.rb +80 -75
  76. data/lib/fluent/plugin/file_util.rb +33 -28
  77. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  78. data/lib/fluent/plugin/filter.rb +51 -0
  79. data/lib/fluent/plugin/filter_grep.rb +13 -40
  80. data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
  81. data/lib/fluent/plugin/formatter.rb +93 -0
  82. data/lib/fluent/plugin/formatter_csv.rb +48 -0
  83. data/lib/fluent/plugin/formatter_hash.rb +32 -0
  84. data/lib/fluent/plugin/formatter_json.rb +47 -0
  85. data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
  86. data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
  87. data/lib/fluent/plugin/formatter_out_file.rb +45 -0
  88. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  89. data/lib/fluent/plugin/formatter_stdout.rb +39 -0
  90. data/lib/fluent/plugin/in_debug_agent.rb +4 -0
  91. data/lib/fluent/plugin/in_dummy.rb +22 -18
  92. data/lib/fluent/plugin/in_exec.rb +18 -8
  93. data/lib/fluent/plugin/in_forward.rb +36 -79
  94. data/lib/fluent/plugin/in_gc_stat.rb +4 -0
  95. data/lib/fluent/plugin/in_http.rb +21 -18
  96. data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
  97. data/lib/fluent/plugin/in_object_space.rb +6 -1
  98. data/lib/fluent/plugin/in_stream.rb +7 -3
  99. data/lib/fluent/plugin/in_syslog.rb +46 -95
  100. data/lib/fluent/plugin/in_tail.rb +51 -595
  101. data/lib/fluent/plugin/in_tcp.rb +8 -1
  102. data/lib/fluent/plugin/in_udp.rb +8 -14
  103. data/lib/fluent/plugin/input.rb +33 -0
  104. data/lib/fluent/plugin/multi_output.rb +95 -0
  105. data/lib/fluent/plugin/out_buffered_null.rb +59 -0
  106. data/lib/fluent/plugin/out_copy.rb +11 -7
  107. data/lib/fluent/plugin/out_exec.rb +15 -11
  108. data/lib/fluent/plugin/out_exec_filter.rb +18 -10
  109. data/lib/fluent/plugin/out_file.rb +34 -5
  110. data/lib/fluent/plugin/out_forward.rb +19 -9
  111. data/lib/fluent/plugin/out_null.rb +0 -14
  112. data/lib/fluent/plugin/out_roundrobin.rb +11 -7
  113. data/lib/fluent/plugin/out_stdout.rb +5 -7
  114. data/lib/fluent/plugin/out_stream.rb +3 -1
  115. data/lib/fluent/plugin/output.rb +979 -0
  116. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  117. data/lib/fluent/plugin/parser.rb +244 -0
  118. data/lib/fluent/plugin/parser_apache.rb +24 -0
  119. data/lib/fluent/plugin/parser_apache2.rb +84 -0
  120. data/lib/fluent/plugin/parser_apache_error.rb +21 -0
  121. data/lib/fluent/plugin/parser_csv.rb +31 -0
  122. data/lib/fluent/plugin/parser_json.rb +79 -0
  123. data/lib/fluent/plugin/parser_ltsv.rb +50 -0
  124. data/lib/fluent/plugin/parser_multiline.rb +102 -0
  125. data/lib/fluent/plugin/parser_nginx.rb +24 -0
  126. data/lib/fluent/plugin/parser_none.rb +36 -0
  127. data/lib/fluent/plugin/parser_syslog.rb +82 -0
  128. data/lib/fluent/plugin/parser_tsv.rb +37 -0
  129. data/lib/fluent/plugin/socket_util.rb +120 -114
  130. data/lib/fluent/plugin/storage.rb +84 -0
  131. data/lib/fluent/plugin/storage_local.rb +116 -0
  132. data/lib/fluent/plugin/string_util.rb +16 -13
  133. data/lib/fluent/plugin_helper.rb +39 -0
  134. data/lib/fluent/plugin_helper/child_process.rb +298 -0
  135. data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
  136. data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
  137. data/lib/fluent/plugin_helper/event_loop.rb +118 -0
  138. data/lib/fluent/plugin_helper/retry_state.rb +177 -0
  139. data/lib/fluent/plugin_helper/storage.rb +308 -0
  140. data/lib/fluent/plugin_helper/thread.rb +147 -0
  141. data/lib/fluent/plugin_helper/timer.rb +85 -0
  142. data/lib/fluent/plugin_id.rb +63 -0
  143. data/lib/fluent/process.rb +21 -30
  144. data/lib/fluent/registry.rb +21 -9
  145. data/lib/fluent/root_agent.rb +115 -40
  146. data/lib/fluent/supervisor.rb +330 -320
  147. data/lib/fluent/system_config.rb +42 -18
  148. data/lib/fluent/test.rb +6 -1
  149. data/lib/fluent/test/base.rb +23 -3
  150. data/lib/fluent/test/driver/base.rb +247 -0
  151. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  152. data/lib/fluent/test/driver/filter.rb +35 -0
  153. data/lib/fluent/test/driver/input.rb +31 -0
  154. data/lib/fluent/test/driver/output.rb +78 -0
  155. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  156. data/lib/fluent/test/filter_test.rb +0 -1
  157. data/lib/fluent/test/formatter_test.rb +2 -1
  158. data/lib/fluent/test/input_test.rb +23 -17
  159. data/lib/fluent/test/output_test.rb +28 -39
  160. data/lib/fluent/test/parser_test.rb +1 -1
  161. data/lib/fluent/time.rb +104 -1
  162. data/lib/fluent/{status.rb → unique_id.rb} +15 -24
  163. data/lib/fluent/version.rb +1 -1
  164. data/lib/fluent/winsvc.rb +72 -0
  165. data/test/compat/test_calls_super.rb +164 -0
  166. data/test/config/test_config_parser.rb +83 -0
  167. data/test/config/test_configurable.rb +547 -274
  168. data/test/config/test_configure_proxy.rb +146 -29
  169. data/test/config/test_dsl.rb +3 -181
  170. data/test/config/test_element.rb +274 -0
  171. data/test/config/test_literal_parser.rb +1 -1
  172. data/test/config/test_section.rb +79 -7
  173. data/test/config/test_system_config.rb +21 -0
  174. data/test/config/test_types.rb +3 -26
  175. data/test/helper.rb +78 -8
  176. data/test/plugin/test_bare_output.rb +118 -0
  177. data/test/plugin/test_base.rb +75 -0
  178. data/test/plugin/test_buf_file.rb +420 -521
  179. data/test/plugin/test_buf_memory.rb +32 -194
  180. data/test/plugin/test_buffer.rb +981 -0
  181. data/test/plugin/test_buffer_chunk.rb +110 -0
  182. data/test/plugin/test_buffer_file_chunk.rb +770 -0
  183. data/test/plugin/test_buffer_memory_chunk.rb +265 -0
  184. data/test/plugin/test_filter.rb +255 -0
  185. data/test/plugin/test_filter_grep.rb +2 -73
  186. data/test/plugin/test_filter_record_transformer.rb +24 -68
  187. data/test/plugin/test_filter_stdout.rb +6 -6
  188. data/test/plugin/test_in_debug_agent.rb +2 -0
  189. data/test/plugin/test_in_dummy.rb +11 -17
  190. data/test/plugin/test_in_exec.rb +6 -25
  191. data/test/plugin/test_in_forward.rb +112 -151
  192. data/test/plugin/test_in_gc_stat.rb +2 -0
  193. data/test/plugin/test_in_http.rb +106 -157
  194. data/test/plugin/test_in_object_space.rb +21 -5
  195. data/test/plugin/test_in_stream.rb +14 -13
  196. data/test/plugin/test_in_syslog.rb +30 -275
  197. data/test/plugin/test_in_tail.rb +95 -234
  198. data/test/plugin/test_in_tcp.rb +14 -0
  199. data/test/plugin/test_in_udp.rb +21 -13
  200. data/test/plugin/test_input.rb +122 -0
  201. data/test/plugin/test_multi_output.rb +180 -0
  202. data/test/plugin/test_out_buffered_null.rb +79 -0
  203. data/test/plugin/test_out_copy.rb +15 -2
  204. data/test/plugin/test_out_exec.rb +75 -25
  205. data/test/plugin/test_out_exec_filter.rb +74 -8
  206. data/test/plugin/test_out_file.rb +61 -7
  207. data/test/plugin/test_out_forward.rb +92 -15
  208. data/test/plugin/test_out_roundrobin.rb +1 -0
  209. data/test/plugin/test_out_stdout.rb +22 -13
  210. data/test/plugin/test_out_stream.rb +18 -0
  211. data/test/plugin/test_output.rb +515 -0
  212. data/test/plugin/test_output_as_buffered.rb +1540 -0
  213. data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
  214. data/test/plugin/test_output_as_buffered_retries.rb +808 -0
  215. data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
  216. data/test/plugin/test_output_as_standard.rb +362 -0
  217. data/test/plugin/test_owned_by.rb +35 -0
  218. data/test/plugin/test_storage.rb +167 -0
  219. data/test/plugin/test_storage_local.rb +8 -0
  220. data/test/plugin_helper/test_child_process.rb +599 -0
  221. data/test/plugin_helper/test_compat_parameters.rb +175 -0
  222. data/test/plugin_helper/test_event_emitter.rb +51 -0
  223. data/test/plugin_helper/test_event_loop.rb +52 -0
  224. data/test/plugin_helper/test_retry_state.rb +399 -0
  225. data/test/plugin_helper/test_storage.rb +411 -0
  226. data/test/plugin_helper/test_thread.rb +164 -0
  227. data/test/plugin_helper/test_timer.rb +100 -0
  228. data/test/scripts/exec_script.rb +0 -6
  229. data/test/scripts/fluent/plugin/out_test.rb +3 -0
  230. data/test/test_config.rb +13 -4
  231. data/test/test_event.rb +24 -13
  232. data/test/test_event_router.rb +8 -7
  233. data/test/test_event_time.rb +187 -0
  234. data/test/test_formatter.rb +13 -51
  235. data/test/test_input.rb +1 -1
  236. data/test/test_log.rb +239 -16
  237. data/test/test_mixin.rb +1 -1
  238. data/test/test_output.rb +53 -66
  239. data/test/test_parser.rb +105 -323
  240. data/test/test_plugin_helper.rb +81 -0
  241. data/test/test_root_agent.rb +4 -52
  242. data/test/test_supervisor.rb +272 -0
  243. data/test/test_unique_id.rb +47 -0
  244. metadata +180 -54
  245. data/lib/fluent/buffer.rb +0 -365
  246. data/lib/fluent/plugin/filter_parser.rb +0 -107
  247. data/lib/fluent/plugin/in_status.rb +0 -76
  248. data/lib/fluent/test/helpers.rb +0 -86
  249. data/test/plugin/data/log/foo/bar2 +0 -0
  250. data/test/plugin/test_filter_parser.rb +0 -744
  251. data/test/plugin/test_in_status.rb +0 -38
  252. data/test/test_buffer.rb +0 -624
@@ -0,0 +1,100 @@
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/buffer/chunk'
18
+
19
+ module Fluent
20
+ module Plugin
21
+ class Buffer
22
+ class MemoryChunk < Chunk
23
+ def initialize(metadata)
24
+ super
25
+ @chunk = ''.force_encoding(Encoding::ASCII_8BIT)
26
+ @chunk_bytes = 0
27
+ @adding_bytes = 0
28
+ @adding_size = 0
29
+ end
30
+
31
+ def append(data)
32
+ raise "BUG: appending to non-staged chunk, now '#{self.state}'" unless self.staged?
33
+
34
+ adding = data.join.force_encoding(Encoding::ASCII_8BIT)
35
+ @chunk << adding
36
+ @adding_bytes += adding.bytesize
37
+ @adding_size += data.size
38
+ true
39
+ end
40
+
41
+ def concat(bulk, bulk_size)
42
+ raise "BUG: appending to non-staged chunk, now '#{self.state}'" unless self.staged?
43
+
44
+ bulk.force_encoding(Encoding::ASCII_8BIT)
45
+ @chunk << bulk
46
+ @adding_bytes += bulk.bytesize
47
+ @adding_size += bulk_size
48
+ true
49
+ end
50
+
51
+ def commit
52
+ @size += @adding_size
53
+ @chunk_bytes += @adding_bytes
54
+
55
+ @adding_bytes = @adding_size = 0
56
+ @modified_at = Time.now
57
+ true
58
+ end
59
+
60
+ def rollback
61
+ @chunk.slice!(@chunk_bytes, @adding_bytes)
62
+ @adding_bytes = @adding_size = 0
63
+ true
64
+ end
65
+
66
+ def bytesize
67
+ @chunk_bytes + @adding_bytes
68
+ end
69
+
70
+ def size
71
+ @size + @adding_size
72
+ end
73
+
74
+ def empty?
75
+ @chunk.empty?
76
+ end
77
+
78
+ def purge
79
+ super
80
+ @chunk = ''.force_encoding("ASCII-8BIT")
81
+ @chunk_bytes = @size = @adding_bytes = @adding_size = 0
82
+ true
83
+ end
84
+
85
+ def read
86
+ @chunk
87
+ end
88
+
89
+ def open(&block)
90
+ StringIO.open(@chunk, &block)
91
+ end
92
+
93
+ def write_to(io)
94
+ # re-implementation to optimize not to create StringIO
95
+ io.write @chunk
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -22,106 +22,111 @@ require 'fluent/plugin'
22
22
  require 'fluent/parser'
23
23
 
24
24
  module Fluent
25
- module ExecUtil
26
- SUPPORTED_FORMAT = {
27
- 'tsv' => :tsv,
28
- 'json' => :json,
29
- 'msgpack' => :msgpack,
30
- }
31
-
32
- class Parser
33
- def initialize(on_message)
34
- @on_message = on_message
25
+ module Plugin
26
+ module ExecUtil
27
+ SUPPORTED_FORMAT = {
28
+ 'tsv' => :tsv,
29
+ 'json' => :json,
30
+ 'msgpack' => :msgpack,
31
+ }
32
+
33
+ class Parser
34
+ def initialize(on_message)
35
+ @on_message = on_message
36
+ end
35
37
  end
36
- end
37
38
 
38
- class TextParserWrapperParser < Parser
39
- def initialize(conf, on_message)
40
- @parser = Plugin.new_parser(conf['format'])
41
- @parser.configure(conf)
42
- super(on_message)
43
- end
39
+ class TextParserWrapperParser < Parser
40
+ def initialize(conf, on_message)
41
+ @parser = Plugin.new_parser(conf['format'])
42
+ @parser.configure(conf)
43
+ super(on_message)
44
+ end
44
45
 
45
- def call(io)
46
- io.each_line(&method(:each_line))
47
- end
46
+ def call(io)
47
+ io.each_line(&method(:each_line))
48
+ end
48
49
 
49
- def each_line(line)
50
- line.chomp!
51
- @parser.parse(line) { |time, record|
52
- @on_message.call(record, time)
53
- }
50
+ def each_line(line)
51
+ line.chomp!
52
+ @parser.parse(line) { |time, record|
53
+ @on_message.call(record, time)
54
+ }
55
+ end
54
56
  end
55
- end
56
57
 
57
- class TSVParser < Parser
58
- def initialize(keys, on_message)
59
- @keys = keys
60
- super(on_message)
61
- end
58
+ class TSVParser < Parser
59
+ def initialize(keys, on_message)
60
+ @keys = keys
61
+ super(on_message)
62
+ end
62
63
 
63
- def call(io)
64
- io.each_line(&method(:each_line))
65
- end
64
+ def call(io)
65
+ io.each_line(&method(:each_line))
66
+ end
66
67
 
67
- def each_line(line)
68
- line.chomp!
69
- vals = line.split("\t")
68
+ def each_line(line)
69
+ line.chomp!
70
+ vals = line.split("\t")
70
71
 
71
- record = Hash[@keys.zip(vals)]
72
+ record = Hash[@keys.zip(vals)]
72
73
 
73
- @on_message.call(record)
74
+ @on_message.call(record)
75
+ end
74
76
  end
75
- end
76
77
 
77
- class JSONParser < Parser
78
- def call(io)
79
- y = Yajl::Parser.new
80
- y.on_parse_complete = @on_message
81
- y.parse(io)
78
+ class JSONParser < Parser
79
+ def call(io)
80
+ y = Yajl::Parser.new
81
+ y.on_parse_complete = @on_message
82
+ y.parse(io)
83
+ end
82
84
  end
83
- end
84
85
 
85
- class MessagePackParser < Parser
86
- def call(io)
87
- @u = Fluent::Engine.msgpack_factory.unpacker(io)
88
- begin
89
- @u.each(&@on_message)
90
- rescue EOFError
86
+ class MessagePackParser < Parser
87
+ def call(io)
88
+ @u = Fluent::Engine.msgpack_factory.unpacker(io)
89
+ begin
90
+ @u.each(&@on_message)
91
+ rescue EOFError
92
+ end
91
93
  end
92
94
  end
93
- end
94
95
 
95
- class Formatter
96
- end
97
-
98
- class TSVFormatter < Formatter
99
- def initialize(in_keys)
100
- @in_keys = in_keys
101
- super()
96
+ class Formatter
102
97
  end
103
98
 
104
- def call(record, out)
105
- last = @in_keys.length-1
106
- for i in 0..last
107
- key = @in_keys[i]
108
- out << record[key].to_s
109
- out << "\t" if i != last
99
+ class TSVFormatter < Formatter
100
+ def initialize(in_keys)
101
+ @in_keys = in_keys
102
+ super()
103
+ end
104
+
105
+ def call(record, out)
106
+ last = @in_keys.length-1
107
+ for i in 0..last
108
+ key = @in_keys[i]
109
+ out << record[key].to_s
110
+ out << "\t" if i != last
111
+ end
112
+ out << "\n"
110
113
  end
111
- out << "\n"
112
114
  end
113
- end
114
115
 
115
- class JSONFormatter < Formatter
116
- def call(record, out)
117
- out << Yajl.dump(record) << "\n"
116
+ class JSONFormatter < Formatter
117
+ def call(record, out)
118
+ out << Yajl.dump(record) << "\n"
119
+ end
118
120
  end
119
- end
120
121
 
121
- class MessagePackFormatter < Formatter
122
- def call(record, out)
123
- record.to_msgpack(out)
122
+ class MessagePackFormatter < Formatter
123
+ def call(record, out)
124
+ record.to_msgpack(out)
125
+ end
124
126
  end
125
127
  end
126
128
  end
129
+
130
+ # obsolete
131
+ ExecUtil = Fluent::Plugin::ExecUtil
127
132
  end
@@ -15,38 +15,43 @@
15
15
  #
16
16
 
17
17
  module Fluent
18
- module FileUtil
19
- # Check file is writable if file exists
20
- # Check directory is writable if file does not exist
21
- #
22
- # @param [String] path File path
23
- # @return [Boolean] file is writable or not
24
- def writable?(path)
25
- return false if File.directory?(path)
26
- return File.writable?(path) if File.exist?(path)
18
+ module Plugin
19
+ module FileUtil
20
+ # Check file is writable if file exists
21
+ # Check directory is writable if file does not exist
22
+ #
23
+ # @param [String] path File path
24
+ # @return [Boolean] file is writable or not
25
+ def writable?(path)
26
+ return false if File.directory?(path)
27
+ return File.writable?(path) if File.exist?(path)
27
28
 
28
- dirname = File.dirname(path)
29
- return false if !File.directory?(dirname)
30
- File.writable?(dirname)
31
- end
32
- module_function :writable?
29
+ dirname = File.dirname(path)
30
+ return false if !File.directory?(dirname)
31
+ File.writable?(dirname)
32
+ end
33
+ module_function :writable?
33
34
 
34
- # Check file is writable in conjunction wtih mkdir_p(dirname(path))
35
- #
36
- # @param [String] path File path
37
- # @return [Boolean] file writable or not
38
- def writable_p?(path)
39
- return false if File.directory?(path)
40
- return File.writable?(path) if File.exist?(path)
35
+ # Check file is writable in conjunction wtih mkdir_p(dirname(path))
36
+ #
37
+ # @param [String] path File path
38
+ # @return [Boolean] file writable or not
39
+ def writable_p?(path)
40
+ return false if File.directory?(path)
41
+ return File.writable?(path) if File.exist?(path)
41
42
 
42
- dirname = File.dirname(path)
43
- until File.exist?(dirname)
44
- dirname = File.dirname(dirname)
45
- end
43
+ dirname = File.dirname(path)
44
+ until File.exist?(dirname)
45
+ dirname = File.dirname(dirname)
46
+ end
46
47
 
47
- return false if !File.directory?(dirname)
48
- File.writable?(dirname)
48
+ return false if !File.directory?(dirname)
49
+ File.writable?(dirname)
50
+ end
51
+ module_function :writable_p?
49
52
  end
50
- module_function :writable_p?
51
53
  end
54
+
55
+ # obsolete
56
+ FileUtil = Fluent::Plugin::FileUtil
52
57
  end
@@ -0,0 +1,120 @@
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
+ module Fluent
18
+ module FileWrapper
19
+ def self.open(*args)
20
+ io = WindowsFile.new(*args).io
21
+ if block_given?
22
+ v = yield io
23
+ io.close
24
+ v
25
+ else
26
+ io
27
+ end
28
+ end
29
+
30
+ def self.stat(path)
31
+ f = WindowsFile.new(path)
32
+ s = f.stat
33
+ f.close
34
+ s
35
+ end
36
+ end
37
+
38
+ module WindowsFileExtension
39
+ attr_reader :path
40
+
41
+ def stat
42
+ s = super
43
+ s.instance_variable_set :@ino, @ino
44
+ def s.ino; @ino; end
45
+ s
46
+ end
47
+ end
48
+
49
+ # To open and get stat with setting FILE_SHARE_DELETE
50
+ class WindowsFile
51
+ require 'windows/file'
52
+ require 'windows/error'
53
+ require 'windows/handle'
54
+ require 'windows/nio'
55
+
56
+ include Windows::Error
57
+ include Windows::File
58
+ include Windows::Handle
59
+ include Windows::NIO
60
+
61
+ def initialize(path, mode='r', sharemode=FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE)
62
+ @path = path
63
+ @file_handle = INVALID_HANDLE_VALUE
64
+ @mode = mode
65
+
66
+
67
+ access, creationdisposition, seektoend = case mode.delete('b')
68
+ when "r" ; [FILE_GENERIC_READ , OPEN_EXISTING, false]
69
+ when "r+"; [FILE_GENERIC_READ | FILE_GENERIC_WRITE, OPEN_ALWAYS , false]
70
+ when "w" ; [FILE_GENERIC_WRITE , CREATE_ALWAYS, false]
71
+ when "w+"; [FILE_GENERIC_READ | FILE_GENERIC_WRITE, CREATE_ALWAYS, false]
72
+ when "a" ; [FILE_GENERIC_WRITE , OPEN_ALWAYS , true]
73
+ when "a+"; [FILE_GENERIC_READ | FILE_GENERIC_WRITE, OPEN_ALWAYS , true]
74
+ else raise "unknown mode '#{mode}'"
75
+ end
76
+
77
+ @file_handle = CreateFile.call(@path, access, sharemode,
78
+ 0, creationdisposition, FILE_ATTRIBUTE_NORMAL, 0)
79
+ if @file_handle == INVALID_HANDLE_VALUE
80
+ err = GetLastError.call
81
+ if err == ERROR_FILE_NOT_FOUND || err == ERROR_ACCESS_DENIED
82
+ raise SystemCallError.new(2)
83
+ end
84
+ raise SystemCallError.new(err)
85
+ end
86
+ end
87
+
88
+ def close
89
+ CloseHandle.call(@file_handle)
90
+ @file_handle = INVALID_HANDLE_VALUE
91
+ end
92
+
93
+ def io
94
+ fd = _open_osfhandle(@file_handle, 0)
95
+ raise Errno::ENOENT if fd == -1
96
+ io = File.for_fd(fd, @mode)
97
+ io.instance_variable_set :@ino, self.ino
98
+ io.instance_variable_set :@path, @path
99
+ io.extend WindowsFileExtension
100
+ io
101
+ end
102
+
103
+ def ino
104
+ by_handle_file_information = '\0'*(4+8+8+8+4+4+4+4+4+4) #72bytes
105
+
106
+ unless GetFileInformationByHandle.call(@file_handle, by_handle_file_information)
107
+ return 0
108
+ end
109
+
110
+ by_handle_file_information.unpack("I11Q1")[11] # fileindex
111
+ end
112
+
113
+ def stat
114
+ s = File.stat(@path)
115
+ s.instance_variable_set :@ino, self.ino
116
+ def s.ino; @ino; end
117
+ s
118
+ end
119
+ end
120
+ end if Fluent.windows?