fluentd 1.12.0-x64-mingw32 → 1.13.0-x64-mingw32

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.deepsource.toml +13 -0
  3. data/.github/ISSUE_TEMPLATE/config.yml +2 -2
  4. data/.github/workflows/linux-test.yaml +36 -0
  5. data/.github/workflows/macos-test.yaml +30 -0
  6. data/.github/workflows/windows-test.yaml +46 -0
  7. data/.gitlab-ci.yml +41 -19
  8. data/CHANGELOG.md +164 -2
  9. data/CONTRIBUTING.md +2 -2
  10. data/MAINTAINERS.md +5 -2
  11. data/README.md +7 -4
  12. data/example/counter.conf +1 -1
  13. data/fluentd.gemspec +5 -4
  14. data/lib/fluent/command/bundler_injection.rb +1 -1
  15. data/lib/fluent/command/ca_generate.rb +6 -3
  16. data/lib/fluent/command/cat.rb +19 -4
  17. data/lib/fluent/command/fluentd.rb +5 -2
  18. data/lib/fluent/command/plugin_config_formatter.rb +16 -1
  19. data/lib/fluent/command/plugin_generator.rb +31 -1
  20. data/lib/fluent/compat/parser.rb +2 -2
  21. data/lib/fluent/config/section.rb +2 -2
  22. data/lib/fluent/config/types.rb +2 -2
  23. data/lib/fluent/event.rb +3 -13
  24. data/lib/fluent/load.rb +0 -1
  25. data/lib/fluent/log.rb +1 -0
  26. data/lib/fluent/plugin/file_wrapper.rb +49 -4
  27. data/lib/fluent/plugin/formatter_ltsv.rb +2 -2
  28. data/lib/fluent/plugin/in_http.rb +11 -1
  29. data/lib/fluent/plugin/in_monitor_agent.rb +1 -1
  30. data/lib/fluent/plugin/in_tail.rb +141 -41
  31. data/lib/fluent/plugin/in_tail/position_file.rb +15 -1
  32. data/lib/fluent/plugin/out_copy.rb +18 -5
  33. data/lib/fluent/plugin/out_exec_filter.rb +3 -3
  34. data/lib/fluent/plugin/out_forward.rb +74 -58
  35. data/lib/fluent/plugin/out_http.rb +9 -2
  36. data/lib/fluent/plugin/output.rb +11 -9
  37. data/lib/fluent/plugin/parser_csv.rb +2 -2
  38. data/lib/fluent/plugin/parser_syslog.rb +2 -2
  39. data/lib/fluent/plugin/storage_local.rb +4 -4
  40. data/lib/fluent/plugin_helper/server.rb +4 -2
  41. data/lib/fluent/plugin_helper/service_discovery.rb +39 -1
  42. data/lib/fluent/plugin_helper/service_discovery/manager.rb +11 -5
  43. data/lib/fluent/plugin_helper/socket_option.rb +2 -2
  44. data/lib/fluent/supervisor.rb +28 -5
  45. data/lib/fluent/system_config.rb +16 -1
  46. data/lib/fluent/time.rb +57 -1
  47. data/lib/fluent/version.rb +1 -1
  48. data/templates/new_gem/fluent-plugin.gemspec.erb +3 -3
  49. data/templates/plugin_config_formatter/param.md-table.erb +10 -0
  50. data/test/command/test_cat.rb +96 -0
  51. data/test/command/test_fluentd.rb +38 -0
  52. data/test/command/test_plugin_config_formatter.rb +67 -0
  53. data/test/config/test_configurable.rb +1 -1
  54. data/test/config/test_system_config.rb +46 -0
  55. data/test/plugin/in_tail/test_io_handler.rb +4 -4
  56. data/test/plugin/in_tail/test_position_file.rb +59 -5
  57. data/test/plugin/test_file_wrapper.rb +115 -0
  58. data/test/plugin/test_in_exec.rb +1 -1
  59. data/test/plugin/test_in_http.rb +15 -0
  60. data/test/plugin/test_in_tail.rb +309 -26
  61. data/test/plugin/test_out_copy.rb +87 -0
  62. data/test/plugin/test_out_forward.rb +104 -11
  63. data/test/plugin/test_out_http.rb +20 -1
  64. data/test/plugin/test_output.rb +15 -3
  65. data/test/plugin/test_output_as_buffered_backup.rb +2 -0
  66. data/test/plugin/test_parser_csv.rb +14 -0
  67. data/test/plugin/test_parser_syslog.rb +14 -0
  68. data/test/plugin/test_sd_file.rb +1 -1
  69. data/test/plugin_helper/service_discovery/test_manager.rb +1 -1
  70. data/test/plugin_helper/test_child_process.rb +5 -2
  71. data/test/plugin_helper/test_http_server_helper.rb +4 -2
  72. data/test/plugin_helper/test_server.rb +26 -7
  73. data/test/plugin_helper/test_service_discovery.rb +74 -14
  74. data/test/test_config.rb +2 -1
  75. data/test/test_event.rb +16 -0
  76. data/test/test_formatter.rb +30 -0
  77. data/test/test_output.rb +2 -2
  78. data/test/test_supervisor.rb +66 -0
  79. data/test/test_time_parser.rb +109 -0
  80. metadata +58 -31
  81. data/.travis.yml +0 -77
  82. data/appveyor.yml +0 -31
data/CONTRIBUTING.md CHANGED
@@ -6,7 +6,7 @@ We'd love your contribution. Here are the guidelines!
6
6
 
7
7
  RESOURCES of [Official site](https://www.fluentd.org/) and [Fluentd documentation](https://docs.fluentd.org/) may help you.
8
8
 
9
- If you have further questions about Fluentd and plugins, please direct these to [Mailing List](https://groups.google.com/forum/#!forum/fluentd).
9
+ If you have further questions about Fluentd and plugins, please direct these to [Community Forum](https://discuss.fluentd.org/).
10
10
  Don't use Github issue for asking questions. Here are examples:
11
11
 
12
12
  - I installed xxx plugin but it doesn't work. Why?
@@ -16,7 +16,7 @@ Don't use Github issue for asking questions. Here are examples:
16
16
  We may close such questions to keep clear repository for developers and users.
17
17
  Github issue is mainly for submitting a bug report or feature request. See below.
18
18
 
19
- If you can't judge your case is a bug or not, use mailing list or slack first.
19
+ If you can't judge your case is a bug or not, use community forum or slack first.
20
20
 
21
21
  ## Found a bug?
22
22
 
data/MAINTAINERS.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # Fluentd Maintainers
2
2
 
3
3
  - [Naotoshi Seo](https://github.com/sonots), [ZOZO Technologies](https://tech.zozo.com/en/)
4
- - [Okkez](https://github.com/okkez), [Clearcode](https://www.clear-code.com/)
5
- - [Hiroshi Hatake](https://github.com/cosmo0920), [Clearcode](https://www.clear-code.com/)
4
+ - [Okkez](https://github.com/okkez)
5
+ - [Hiroshi Hatake](https://github.com/cosmo0920), [Calyptia](https://www.calyptia.com/)
6
6
  - [Masahiro Nakagawa](https://github.com/repeatedly), [Treasure Data](https://www.treasuredata.com/)
7
7
  - [Satoshi Tagomori](https://github.com/tagomoris), [Treasure Data](https://www.treasuredata.com/)
8
8
  - [Eduardo Silva](https://github.com/edsiper), [Arm Treasure Data](https://www.treasuredata.com/)
9
+ - [Fujimoto Seiji](https://github.com/fujimots), [ClearCode](https://www.clear-code.com/)
10
+ - [Takuro Ashie](https://github.com/ashie), [ClearCode](https://www.clear-code.com/)
11
+ - [Kentaro Hayashi](https://github.com/kenhys), [ClearCode](https://www.clear-code.com/)
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  Fluentd: Open-Source Log Collector
2
2
  ===================================
3
- Travis CI:
3
+ GitHub Actions:
4
4
 
5
- [<img src="https://travis-ci.org/fluent/fluentd.svg" />](https://travis-ci.org/fluent/fluentd) [![Code Climate](https://codeclimate.com/github/fluent/fluentd/badges/gpa.svg)](https://codeclimate.com/github/fluent/fluentd)
5
+ [![Testing on Ubuntu](https://github.com/fluent/fluentd/actions/workflows/linux-test.yaml/badge.svg?branch=master)](https://github.com/fluent/fluentd/actions/workflows/linux-test.yaml)
6
+ [![Testing on Windows](https://github.com/fluent/fluentd/actions/workflows/windows-test.yaml/badge.svg?branch=master)](https://github.com/fluent/fluentd/actions/workflows/windows-test.yaml)
7
+ [![Testing on macOS](https://github.com/fluent/fluentd/actions/workflows/macos-test.yaml/badge.svg?branch=master)](https://github.com/fluent/fluentd/actions/workflows/macos-test.yaml)
8
+ [![Code Climate](https://codeclimate.com/github/fluent/fluentd/badges/gpa.svg)](https://codeclimate.com/github/fluent/fluentd)
6
9
  [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1189/badge)](https://bestpractices.coreinfrastructure.org/projects/1189)
7
10
  [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Ffluent%2Ffluentd.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Ffluent%2Ffluentd?ref=badge_shield)
8
11
 
@@ -74,11 +77,11 @@ You can run specified test via `TEST` environment variable:
74
77
  - Website: https://www.fluentd.org/
75
78
  - Documentation: https://docs.fluentd.org/
76
79
  - Project repository: https://github.com/fluent
77
- - Discussion: https://groups.google.com/group/fluentd
80
+ - Discussion: https://discuss.fluentd.org/
78
81
  - Slack / Community: https://slack.fluentd.org
79
82
  - Newsletters: https://www.fluentd.org/newsletter
80
83
  - Author: [Sadayuki Furuhashi](https://github.com/frsyuki)
81
- - Copyright: 2011-2019 Fluentd Authors
84
+ - Copyright: 2011-2021 Fluentd Authors
82
85
  - License: Apache License, Version 2.0
83
86
 
84
87
  ## Security
data/example/counter.conf CHANGED
@@ -3,7 +3,7 @@
3
3
  scope server1
4
4
  bind 127.0.0.1
5
5
  port 24321
6
- path tmp/back
6
+ backup_path tmp/back
7
7
  </counter_server>
8
8
  </system>
9
9
 
data/fluentd.gemspec CHANGED
@@ -28,12 +28,14 @@ Gem::Specification.new do |gem|
28
28
  gem.add_runtime_dependency("tzinfo", [">= 1.0", "< 3.0"])
29
29
  gem.add_runtime_dependency("tzinfo-data", ["~> 1.0"])
30
30
  gem.add_runtime_dependency("strptime", [">= 0.2.2", "< 1.0.0"])
31
+ gem.add_runtime_dependency("webrick", [">= 1.4.2", "< 1.8.0"])
31
32
 
32
33
  # build gem for a certain platform. see also Rakefile
33
34
  fake_platform = ENV['GEM_BUILD_FAKE_PLATFORM'].to_s
34
35
  gem.platform = fake_platform unless fake_platform.empty?
35
36
  if /mswin|mingw/ =~ fake_platform || (/mswin|mingw/ =~ RUBY_PLATFORM && fake_platform.empty?)
36
- gem.add_runtime_dependency("win32-service", ["~> 2.1.5"])
37
+ gem.add_runtime_dependency("win32-api", [">= 1.10", "< 2.0.0"])
38
+ gem.add_runtime_dependency("win32-service", ["~> 2.2.0"])
37
39
  gem.add_runtime_dependency("win32-ipc", ["~> 0.7.0"])
38
40
  gem.add_runtime_dependency("win32-event", ["~> 0.6.3"])
39
41
  gem.add_runtime_dependency("windows-pr", ["~> 1.2.6"])
@@ -44,11 +46,10 @@ Gem::Specification.new do |gem|
44
46
  gem.add_development_dependency("flexmock", ["~> 2.0"])
45
47
  gem.add_development_dependency("parallel_tests", ["~> 0.15.3"])
46
48
  gem.add_development_dependency("simplecov", ["~> 0.7"])
47
- gem.add_development_dependency("rr", ["~> 1.0"])
49
+ gem.add_development_dependency("rr", ["~> 3.0"])
48
50
  gem.add_development_dependency("timecop", ["~> 0.9"])
49
51
  gem.add_development_dependency("test-unit", ["~> 3.3"])
50
52
  gem.add_development_dependency("test-unit-rr", ["~> 1.0"])
51
53
  gem.add_development_dependency("oj", [">= 2.14", "< 4"])
52
- gem.add_development_dependency("ext_monitor", [">= 0.1.2", "< 0.2"])
53
- gem.add_development_dependency("async-http")
54
+ gem.add_development_dependency("async-http", ">= 0.50.0")
54
55
  end
@@ -40,6 +40,6 @@ else
40
40
  File.expand_path(File.join(File.dirname(__FILE__), 'fluentd.rb')),
41
41
  ] + ARGV
42
42
 
43
- exec *cmdline
43
+ exec(*cmdline)
44
44
  exit! 127
45
45
  end
@@ -75,6 +75,8 @@ HELP
75
75
 
76
76
  digest = OpenSSL::Digest::SHA256.new
77
77
 
78
+ factory = OpenSSL::X509::ExtensionFactory.new
79
+
78
80
  cert = OpenSSL::X509::Certificate.new
79
81
  cert.not_before = Time.at(0)
80
82
  cert.not_after = Time.now + 5 * 365 * 86400 # 5 years after
@@ -82,7 +84,7 @@ HELP
82
84
  cert.serial = 1
83
85
  cert.issuer = issuer
84
86
  cert.subject = subject
85
- cert.add_extension OpenSSL::X509::Extension.new('basicConstraints', OpenSSL::ASN1.Sequence([OpenSSL::ASN1::Boolean(true)]))
87
+ cert.add_extension(factory.create_extension('basicConstraints', 'CA:TRUE'))
86
88
  cert.sign(key, digest)
87
89
 
88
90
  return cert, key
@@ -111,8 +113,9 @@ HELP
111
113
  cert.issuer = issuer
112
114
  cert.subject = subject
113
115
 
114
- cert.add_extension OpenSSL::X509::Extension.new('basicConstraints', OpenSSL::ASN1.Sequence([OpenSSL::ASN1::Boolean(false)]))
115
- cert.add_extension OpenSSL::X509::Extension.new('nsCertType', 'server')
116
+ factory = OpenSSL::X509::ExtensionFactory.new
117
+ server_cert.add_extension(factory.create_extension('basicConstraints', 'CA:FALSE'))
118
+ server_cert.add_extension(factory.create_extension('nsCertType', 'server'))
116
119
 
117
120
  cert.sign ca_key, digest
118
121
 
@@ -101,7 +101,6 @@ rescue
101
101
  usage $!.to_s
102
102
  end
103
103
 
104
- require 'thread'
105
104
  require 'socket'
106
105
  require 'yajl'
107
106
  require 'msgpack'
@@ -153,14 +152,30 @@ class Writer
153
152
  super()
154
153
  end
155
154
 
155
+ def secondary_record?(record)
156
+ record.class != Hash &&
157
+ record.size == 2 &&
158
+ record.first.class == Fluent::EventTime &&
159
+ record.last.class == Hash
160
+ end
161
+
156
162
  def write(record)
157
- if record.class != Hash
158
- raise ArgumentError, "Input must be a map (got #{record.class})"
163
+ unless secondary_record?(record)
164
+ if record.class != Hash
165
+ raise ArgumentError, "Input must be a map (got #{record.class})"
166
+ end
159
167
  end
160
168
 
161
169
  time = Fluent::EventTime.now
162
170
  time = time.to_i if @time_as_integer
163
- entry = [time, record]
171
+ entry = if secondary_record?(record)
172
+ # Even though secondary contains Fluent::EventTime in record,
173
+ # fluent-cat just ignore it and set Fluent::EventTime.now instead.
174
+ # This specification is adopted to keep consistency.
175
+ [time, record.last]
176
+ else
177
+ [time, record]
178
+ end
164
179
  synchronize {
165
180
  unless write_impl([entry])
166
181
  # write failed
@@ -85,9 +85,8 @@ op.on('-o', '--log PATH', "log file path") {|s|
85
85
  opts[:log_path] = s
86
86
  }
87
87
 
88
- ROTATE_AGE = %w(daily weekly monthly)
89
88
  op.on('--log-rotate-age AGE', 'generations to keep rotated log files') {|age|
90
- if ROTATE_AGE.include?(age)
89
+ if Fluent::Log::LOG_ROTATE_AGE.include?(age)
91
90
  opts[:log_rotate_age] = age
92
91
  else
93
92
  begin
@@ -163,6 +162,10 @@ op.on('--conf-encoding ENCODING', "specify configuration file encoding") { |s|
163
162
  opts[:conf_encoding] = s
164
163
  }
165
164
 
165
+ op.on('--disable-shared-socket', "Don't open shared socket for multiple workers") { |b|
166
+ opts[:disable_shared_socket] = b
167
+ }
168
+
166
169
  if Fluent.windows?
167
170
  require 'windows/library'
168
171
  include Windows::Library
@@ -44,6 +44,7 @@ class FluentPluginConfigFormatter
44
44
  @verbose = false
45
45
  @libs = []
46
46
  @plugin_dirs = []
47
+ @table = false
47
48
  @options = {}
48
49
 
49
50
  prepare_option_parser
@@ -162,9 +163,20 @@ class FluentPluginConfigFormatter
162
163
  else
163
164
  sections, params = base_section.partition {|_name, value| value[:section] }
164
165
  end
166
+ if @table && (not params.empty?)
167
+ dumped << "### Configuration\n\n"
168
+ dumped << "|parameter|type|description|default|\n"
169
+ dumped << "|---|---|---|---|\n"
170
+ end
165
171
  params.each do |name, config|
166
172
  next if name == :section
167
- template_name = @compact ? "param.md-compact.erb" : "param.md.erb"
173
+ template_name = if @compact
174
+ "param.md-compact.erb"
175
+ elsif @table
176
+ "param.md-table.erb"
177
+ else
178
+ "param.md.erb"
179
+ end
168
180
  template = template_path(template_name).read
169
181
  dumped <<
170
182
  if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
@@ -257,6 +269,9 @@ BANNER
257
269
  @parser.on("-p", "--plugin=DIR", "Add plugin directory") do |s|
258
270
  @plugin_dirs << s
259
271
  end
272
+ @parser.on("-t", "--table", "Use table syntax to dump parameters") do
273
+ @table = true
274
+ end
260
275
  end
261
276
 
262
277
  def parse_options!
@@ -105,7 +105,7 @@ Generate a project skeleton for creating a Fluentd plugin
105
105
 
106
106
  Arguments:
107
107
  \ttype: #{SUPPORTED_TYPES.join(",")}
108
- \tname: Your plugin name
108
+ \tname: Your plugin name (fluent-plugin- prefix will be added to <name>)
109
109
 
110
110
  Options:
111
111
  BANNER
@@ -151,6 +151,36 @@ BANNER
151
151
  underscore_name
152
152
  end
153
153
 
154
+ def gem_file_path
155
+ File.expand_path(File.join(File.dirname(__FILE__),
156
+ "../../../",
157
+ "Gemfile"))
158
+ end
159
+
160
+ def lock_file_path
161
+ File.expand_path(File.join(File.dirname(__FILE__),
162
+ "../../../",
163
+ "Gemfile.lock"))
164
+ end
165
+
166
+ def locked_gem_version(gem_name)
167
+ d = Bundler::Definition.build(gem_file_path, lock_file_path, false)
168
+ d.locked_gems.dependencies[gem_name].requirement.requirements.first.last.version
169
+ end
170
+
171
+ def rake_version
172
+ locked_gem_version("rake")
173
+ end
174
+
175
+ def test_unit_version
176
+ locked_gem_version("test-unit")
177
+ end
178
+
179
+ def bundler_version
180
+ d = Bundler::Definition.build(gem_file_path, lock_file_path, false)
181
+ d.locked_gems.bundler_version.version
182
+ end
183
+
154
184
  def class_name
155
185
  "#{capitalized_name}#{type.capitalize}"
156
186
  end
@@ -244,10 +244,10 @@ module Fluent
244
244
  end
245
245
 
246
246
  def convert_value_to_nil(value)
247
- if value and @null_empty_string
247
+ if value && @null_empty_string
248
248
  value = (value == '') ? nil : value
249
249
  end
250
- if value and @null_value_pattern
250
+ if value && @null_value_pattern
251
251
  value = ::Fluent::StringUtil.match_regexp(@null_value_pattern, value) ? nil : value
252
252
  end
253
253
  value
@@ -179,7 +179,7 @@ module Fluent
179
179
  end
180
180
 
181
181
  if section_params[varname].nil?
182
- unless proxy.defaults.has_key?(varname) and proxy.defaults[varname].nil?
182
+ unless proxy.defaults.has_key?(varname) && proxy.defaults[varname].nil?
183
183
  logger.error "config error in:\n#{conf}" if logger
184
184
  raise ConfigError, "'#{name}' parameter is required but nil is specified"
185
185
  end
@@ -247,7 +247,7 @@ module Fluent
247
247
  def self.check_unused_section(proxy, conf, plugin_class)
248
248
  elems = conf.respond_to?(:elements) ? conf.elements : []
249
249
  elems.each { |e|
250
- next if plugin_class.nil? && Fluent::Config::V1Parser::ELEM_SYMBOLS.include?(e.name) # skip pre-defined non-plugin elements because it doens't have proxy section
250
+ next if plugin_class.nil? && Fluent::Config::V1Parser::ELEM_SYMBOLS.include?(e.name) # skip pre-defined non-plugin elements because it doesn't have proxy section
251
251
  next if e.unused_in && e.unused_in.empty? # the section is used at least once
252
252
 
253
253
  if proxy.sections.any? { |name, subproxy| e.name == subproxy.name.to_s || e.name == subproxy.alias.to_s }
@@ -186,7 +186,7 @@ module Fluent
186
186
  return nil if val.nil?
187
187
 
188
188
  param = if val.is_a?(String)
189
- val.start_with?('{') ? JSON.load(val) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}]
189
+ val.start_with?('{') ? JSON.parse(val) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}]
190
190
  else
191
191
  val
192
192
  end
@@ -213,7 +213,7 @@ module Fluent
213
213
  return nil if val.nil?
214
214
 
215
215
  param = if val.is_a?(String)
216
- val.start_with?('[') ? JSON.load(val) : val.strip.split(/\s*,\s*/)
216
+ val.start_with?('[') ? JSON.parse(val) : val.strip.split(/\s*,\s*/)
217
217
  else
218
218
  val
219
219
  end
data/lib/fluent/event.rb CHANGED
@@ -254,19 +254,9 @@ module Fluent
254
254
  end
255
255
 
256
256
  def each(unpacker: nil, &block)
257
- if @unpacked_times
258
- @unpacked_times.each_with_index do |time, i|
259
- block.call(time, @unpacked_records[i])
260
- end
261
- else
262
- @unpacked_times = []
263
- @unpacked_records = []
264
- (unpacker || Fluent::MessagePackFactory.msgpack_unpacker).feed_each(@data) do |time, record|
265
- @unpacked_times << time
266
- @unpacked_records << record
267
- block.call(time, record)
268
- end
269
- @size = @unpacked_times.size
257
+ ensure_unpacked!(unpacker: unpacker)
258
+ @unpacked_times.each_with_index do |time, i|
259
+ block.call(time, @unpacked_records[i])
270
260
  end
271
261
  nil
272
262
  end
data/lib/fluent/load.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'thread'
2
1
  require 'socket'
3
2
  require 'fcntl'
4
3
  require 'time'
data/lib/fluent/log.rb CHANGED
@@ -49,6 +49,7 @@ module Fluent
49
49
  LOG_TYPE_DEFAULT = :default # show logs in all supervisor/workers, with worker id in workers (default)
50
50
 
51
51
  LOG_TYPES = [LOG_TYPE_SUPERVISOR, LOG_TYPE_WORKER0, LOG_TYPE_DEFAULT].freeze
52
+ LOG_ROTATE_AGE = %w(daily weekly monthly)
52
53
 
53
54
  def self.str_to_level(log_level_str)
54
55
  case log_level_str.downcase
@@ -46,6 +46,48 @@ module Fluent
46
46
  end
47
47
  end
48
48
 
49
+ class Win32Error < StandardError
50
+ require 'windows/error'
51
+ include Windows::Error
52
+
53
+ attr_reader :errcode, :msg
54
+
55
+ WSABASEERR = 10000
56
+
57
+ def initialize(errcode, msg = nil)
58
+ @errcode = errcode
59
+ @msg = msg
60
+ end
61
+
62
+ def format_english_message(errcode)
63
+ buf = 0.chr * 260
64
+ flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY
65
+ english_lang_id = 1033 # The result of MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
66
+ FormatMessageA.call(flags, 0, errcode, english_lang_id, buf, buf.size, 0)
67
+ buf.force_encoding(Encoding.default_external).strip
68
+ end
69
+
70
+ def to_s
71
+ msg = super
72
+ msg << ": code: #{@errcode}, #{format_english_message(@errcode)}"
73
+ msg << " - #{@msg}" if @msg
74
+ msg
75
+ end
76
+
77
+ def inspect
78
+ "#<#{to_s}>"
79
+ end
80
+
81
+ def ==(other)
82
+ return false if other.class != Win32Error
83
+ @errcode == other.errcode && @msg == other.msg
84
+ end
85
+
86
+ def wsaerr?
87
+ @errcode >= WSABASEERR
88
+ end
89
+ end
90
+
49
91
  # To open and get stat with setting FILE_SHARE_DELETE
50
92
  class WindowsFile
51
93
  require 'windows/file'
@@ -77,11 +119,14 @@ module Fluent
77
119
  @file_handle = CreateFile.call(@path, access, sharemode,
78
120
  0, creationdisposition, FILE_ATTRIBUTE_NORMAL, 0)
79
121
  if @file_handle == INVALID_HANDLE_VALUE
80
- err = GetLastError.call
81
- if err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND || err == ERROR_ACCESS_DENIED
82
- raise SystemCallError.new(2)
122
+ win32err = Win32Error.new(Win32::API.last_error, path)
123
+ errno = ServerEngine::RbWinSock.rb_w32_map_errno(win32err.errcode)
124
+ if errno == Errno::EINVAL::Errno || win32err.wsaerr?
125
+ # maybe failed to map
126
+ raise win32err
127
+ else
128
+ raise SystemCallError.new(win32err.message, errno)
83
129
  end
84
- raise SystemCallError.new(err)
85
130
  end
86
131
  end
87
132