fluentd 0.14.13-x86-mingw32 → 0.14.17-x86-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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -5
- data/ChangeLog +106 -0
- data/MAINTAINERS.md +5 -0
- data/README.md +25 -0
- data/example/worker_section.conf +36 -0
- data/fluentd.gemspec +1 -1
- data/lib/fluent/agent.rb +5 -2
- data/lib/fluent/command/binlog_reader.rb +1 -0
- data/lib/fluent/command/fluentd.rb +28 -12
- data/lib/fluent/command/plugin_config_formatter.rb +0 -1
- data/lib/fluent/command/plugin_generator.rb +1 -1
- data/lib/fluent/compat/detach_process_mixin.rb +8 -0
- data/lib/fluent/compat/input.rb +0 -10
- data/lib/fluent/compat/output.rb +0 -10
- data/lib/fluent/config/element.rb +22 -0
- data/lib/fluent/config/literal_parser.rb +2 -0
- data/lib/fluent/config/types.rb +2 -2
- data/lib/fluent/engine.rb +27 -10
- data/lib/fluent/env.rb +3 -3
- data/lib/fluent/log.rb +4 -1
- data/lib/fluent/plugin/base.rb +3 -0
- data/lib/fluent/plugin/filter.rb +2 -2
- data/lib/fluent/plugin/filter_parser.rb +17 -6
- data/lib/fluent/plugin/in_forward.rb +1 -1
- data/lib/fluent/plugin/in_http.rb +4 -0
- data/lib/fluent/plugin/in_monitor_agent.rb +8 -3
- data/lib/fluent/plugin/in_syslog.rb +3 -2
- data/lib/fluent/plugin/in_tail.rb +14 -3
- data/lib/fluent/plugin/in_udp.rb +6 -2
- data/lib/fluent/plugin/out_file.rb +5 -0
- data/lib/fluent/plugin/out_forward.rb +5 -2
- data/lib/fluent/plugin/output.rb +13 -8
- data/lib/fluent/plugin/parser_apache2.rb +1 -1
- data/lib/fluent/plugin/parser_syslog.rb +40 -1
- data/lib/fluent/plugin_helper/cert_option.rb +2 -2
- data/lib/fluent/plugin_helper/compat_parameters.rb +1 -1
- data/lib/fluent/plugin_helper/storage.rb +1 -1
- data/lib/fluent/root_agent.rb +36 -4
- data/lib/fluent/supervisor.rb +37 -6
- data/lib/fluent/system_config.rb +7 -0
- data/lib/fluent/time.rb +1 -0
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +25 -11
- data/test/command/test_fluentd.rb +253 -4
- data/test/config/test_element.rb +63 -0
- data/test/config/test_literal_parser.rb +1 -1
- data/test/config/test_system_config.rb +36 -6
- data/test/config/test_types.rb +19 -0
- data/test/plugin/test_filter_parser.rb +35 -0
- data/test/plugin/test_in_http.rb +58 -4
- data/test/plugin/test_in_monitor_agent.rb +90 -9
- data/test/plugin/test_in_tail.rb +16 -0
- data/test/plugin/test_in_udp.rb +11 -1
- data/test/plugin/test_out_file.rb +9 -0
- data/test/plugin/test_out_forward.rb +45 -0
- data/test/plugin/test_output.rb +15 -15
- data/test/plugin/test_output_as_buffered.rb +30 -2
- data/test/plugin/test_parser_apache2.rb +8 -0
- data/test/plugin/test_parser_syslog.rb +176 -0
- data/test/plugin_helper/test_server.rb +37 -31
- data/test/plugin_helper/test_storage.rb +9 -0
- data/test/test_log.rb +6 -0
- data/test/test_plugin_classes.rb +50 -0
- data/test/test_root_agent.rb +245 -14
- data/test/test_time_parser.rb +12 -0
- metadata +13 -5
@@ -105,6 +105,11 @@ module Fluent::Plugin
|
|
105
105
|
buffer_conf['path'] = conf['path'] || '/tmp/dummy_path'
|
106
106
|
end
|
107
107
|
|
108
|
+
if conf.has_key?('utc') || conf.has_key?('localtime')
|
109
|
+
param_name = conf.has_key?('utc') ? 'utc' : 'localtime'
|
110
|
+
log.warn "'#{param_name}' is deperecated for output plugin. This parameter is used for formatter plugin in compatibility layer. If you want to use same feature, use timekey_use_utc parameter in <buffer> directive instead"
|
111
|
+
end
|
112
|
+
|
108
113
|
super
|
109
114
|
|
110
115
|
@compress_method = SUPPORTED_COMPRESS_MAP[@compress]
|
@@ -420,7 +420,7 @@ module Fluent::Plugin
|
|
420
420
|
# return chunk id to be committed
|
421
421
|
def read_ack_from_sock(sock, unpacker)
|
422
422
|
begin
|
423
|
-
raw_data = sock.recv(@read_length)
|
423
|
+
raw_data = sock.instance_of?(Fluent::PluginHelper::Socket::WrappedSocket::TLS) ? sock.readpartial(@read_length) : sock.recv(@read_length)
|
424
424
|
rescue Errno::ECONNRESET
|
425
425
|
raw_data = ""
|
426
426
|
end
|
@@ -431,6 +431,7 @@ module Fluent::Plugin
|
|
431
431
|
if raw_data.empty?
|
432
432
|
log.warn "destination node closed the connection. regard it as unavailable.", host: info.node.host, port: info.node.port
|
433
433
|
info.node.disable!
|
434
|
+
rollback_write(info.chunk_id)
|
434
435
|
return nil
|
435
436
|
else
|
436
437
|
unpacker.feed(raw_data)
|
@@ -450,6 +451,8 @@ module Fluent::Plugin
|
|
450
451
|
log.error "unexpected error while receiving ack message", error: e
|
451
452
|
log.error_backtrace
|
452
453
|
ensure
|
454
|
+
info.sock.close_write rescue nil
|
455
|
+
info.sock.close rescue nil
|
453
456
|
@sock_ack_waiting_mutex.synchronize do
|
454
457
|
@sock_ack_waiting.delete(info)
|
455
458
|
end
|
@@ -492,7 +495,7 @@ module Fluent::Plugin
|
|
492
495
|
|
493
496
|
readable_sockets.each do |sock|
|
494
497
|
chunk_id = read_ack_from_sock(sock, unpacker)
|
495
|
-
commit_write(chunk_id)
|
498
|
+
commit_write(chunk_id) if chunk_id
|
496
499
|
end
|
497
500
|
rescue => e
|
498
501
|
log.error "unexpected error while receiving ack", error: e
|
data/lib/fluent/plugin/output.rb
CHANGED
@@ -122,12 +122,17 @@ module Fluent
|
|
122
122
|
raise NotImplementedError, "BUG: output plugins MUST implement this method"
|
123
123
|
end
|
124
124
|
|
125
|
-
def formatted_to_msgpack_binary
|
125
|
+
def formatted_to_msgpack_binary?
|
126
126
|
# To indicate custom format method (#format) returns msgpack binary or not.
|
127
127
|
# If #format returns msgpack binary, override this method to return true.
|
128
128
|
false
|
129
129
|
end
|
130
130
|
|
131
|
+
# Compatibility for existing plugins
|
132
|
+
def formatted_to_msgpack_binary
|
133
|
+
formatted_to_msgpack_binary?
|
134
|
+
end
|
135
|
+
|
131
136
|
def prefer_buffered_processing
|
132
137
|
# override this method to return false only when all of these are true:
|
133
138
|
# * plugin has both implementation for buffered and non-buffered methods
|
@@ -589,13 +594,13 @@ module Fluent
|
|
589
594
|
example = @argument[:example]
|
590
595
|
timekey = @argument[:timekey]
|
591
596
|
if !sec && timekey
|
592
|
-
raise Fluent::ConfigError, "Parameter '#{name}' doesn't have timestamp placeholders for timekey #{timekey.to_i}"
|
597
|
+
raise Fluent::ConfigError, "Parameter '#{name}: #{string}' doesn't have timestamp placeholders for timekey #{timekey.to_i}"
|
593
598
|
end
|
594
599
|
if sec && !timekey
|
595
|
-
raise Fluent::ConfigError, "Parameter '#{name}' has timestamp placeholders, but chunk key 'time' is not configured"
|
600
|
+
raise Fluent::ConfigError, "Parameter '#{name}: #{string}' has timestamp placeholders, but chunk key 'time' is not configured"
|
596
601
|
end
|
597
602
|
if sec && timekey && timekey < sec
|
598
|
-
raise Fluent::ConfigError, "Parameter '#{
|
603
|
+
raise Fluent::ConfigError, "Parameter '#{name}: #{string}' doesn't have timestamp placeholder for #{title}('#{example}') for timekey #{timekey.to_i}"
|
599
604
|
end
|
600
605
|
end
|
601
606
|
|
@@ -603,10 +608,10 @@ module Fluent
|
|
603
608
|
parts = @argument[:parts]
|
604
609
|
tagkey = @argument[:tagkey]
|
605
610
|
if tagkey && parts.empty?
|
606
|
-
raise Fluent::ConfigError, "Parameter '#{
|
611
|
+
raise Fluent::ConfigError, "Parameter '#{name}: #{string}' doesn't have tag placeholder"
|
607
612
|
end
|
608
613
|
if !tagkey && !parts.empty?
|
609
|
-
raise Fluent::ConfigError, "Parameter '#{
|
614
|
+
raise Fluent::ConfigError, "Parameter '#{name}: #{string}' has tag placeholders, but chunk key 'tag' is not configured"
|
610
615
|
end
|
611
616
|
end
|
612
617
|
|
@@ -615,11 +620,11 @@ module Fluent
|
|
615
620
|
chunk_keys = @argument[:chunkkeys]
|
616
621
|
if (chunk_keys - keys).size > 0
|
617
622
|
not_specified = (chunk_keys - keys).sort
|
618
|
-
raise Fluent::ConfigError, "Parameter '#{
|
623
|
+
raise Fluent::ConfigError, "Parameter '#{name}: #{string}' doesn't have enough placeholders for keys #{not_specified.join(',')}"
|
619
624
|
end
|
620
625
|
if (keys - chunk_keys).size > 0
|
621
626
|
not_satisfied = (keys - chunk_keys).sort
|
622
|
-
raise Fluent::ConfigError, "Parameter '#{
|
627
|
+
raise Fluent::ConfigError, "Parameter '#{name}: #{string}' has placeholders, but chunk keys doesn't have keys #{not_satisfied.join(',')}"
|
623
628
|
end
|
624
629
|
end
|
625
630
|
end
|
@@ -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
|
@@ -27,9 +27,13 @@ module Fluent
|
|
27
27
|
REGEXP = /^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
|
28
28
|
# From in_syslog default pattern
|
29
29
|
REGEXP_WITH_PRI = /^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
|
30
|
+
REGEXP_RFC5424 = /\A^\<(?<pri>[0-9]{1,3})\>[1-9]\d{0,2} (?<time>[^ ]+) (?<host>[^ ]+) (?<ident>[^ ]+) (?<pid>[-0-9]+) (?<msgid>[^ ]+) (?<extradata>(\[(.*)\]|[^ ])) (?<message>.+)$\z/
|
31
|
+
REGEXP_DETECT_RFC5424 = /^\<.*\>[1-9]\d{0,2}/
|
30
32
|
|
31
33
|
config_set_default :time_format, "%b %d %H:%M:%S"
|
32
34
|
config_param :with_priority, :bool, default: false
|
35
|
+
config_param :message_format, :enum, list: [:rfc3164, :rfc5424, :auto], default: :rfc3164
|
36
|
+
config_param :rfc5424_time_format, :string, default: "%Y-%m-%dT%H:%M:%S.%L%z"
|
33
37
|
|
34
38
|
def initialize
|
35
39
|
super
|
@@ -39,7 +43,27 @@ module Fluent
|
|
39
43
|
def configure(conf)
|
40
44
|
super
|
41
45
|
|
42
|
-
@
|
46
|
+
@time_parser_rfc3164 = @time_parser_rfc5424 = nil
|
47
|
+
@regexp = case @message_format
|
48
|
+
when :rfc3164
|
49
|
+
class << self
|
50
|
+
alias_method :parse, :parse_plain
|
51
|
+
end
|
52
|
+
@with_priority ? REGEXP_WITH_PRI : REGEXP
|
53
|
+
when :rfc5424
|
54
|
+
class << self
|
55
|
+
alias_method :parse, :parse_plain
|
56
|
+
end
|
57
|
+
@time_format = @rfc5424_time_format unless conf.has_key?('time_format')
|
58
|
+
REGEXP_RFC5424
|
59
|
+
when :auto
|
60
|
+
class << self
|
61
|
+
alias_method :parse, :parse_auto
|
62
|
+
end
|
63
|
+
@time_parser_rfc3164 = time_parser_create(format: @time_format)
|
64
|
+
@time_parser_rfc5424 = time_parser_create(format: @rfc5424_time_format)
|
65
|
+
nil
|
66
|
+
end
|
43
67
|
@time_parser = time_parser_create
|
44
68
|
end
|
45
69
|
|
@@ -48,6 +72,21 @@ module Fluent
|
|
48
72
|
end
|
49
73
|
|
50
74
|
def parse(text)
|
75
|
+
# This is overwritten in configure
|
76
|
+
end
|
77
|
+
|
78
|
+
def parse_auto(text, &block)
|
79
|
+
if REGEXP_DETECT_RFC5424.match(text)
|
80
|
+
@regexp = REGEXP_RFC5424
|
81
|
+
@time_parser = @time_parser_rfc5424
|
82
|
+
else
|
83
|
+
@regexp = @with_priority ? REGEXP_WITH_PRI : REGEXP
|
84
|
+
@time_parser = @time_parser_rfc3164
|
85
|
+
end
|
86
|
+
parse_plain(text, &block)
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse_plain(text, &block)
|
51
90
|
m = @regexp.match(text)
|
52
91
|
unless m
|
53
92
|
yield nil, nil
|
@@ -46,12 +46,12 @@ module Fluent
|
|
46
46
|
case
|
47
47
|
when conf.cert_path
|
48
48
|
raise Fluent::ConfigError, "private_key_path is required when cert_path is specified" unless conf.private_key_path
|
49
|
-
|
49
|
+
log.warn "For security reason, setting private_key_passphrase is recommended when cert_path is specified" unless conf.private_key_passphrase
|
50
50
|
cert_option_load(conf.cert_path, conf.private_key_path, conf.private_key_passphrase)
|
51
51
|
|
52
52
|
when conf.ca_cert_path
|
53
53
|
raise Fluent::ConfigError, "ca_private_key_path is required when ca_cert_path is specified" unless conf.ca_private_key_path
|
54
|
-
|
54
|
+
log.warn "For security reason, setting ca_private_key_passphrase is recommended when ca_cert_path is specified" unless conf.ca_private_key_passphrase
|
55
55
|
generate_opts = cert_option_cert_generation_opts_from_conf(conf)
|
56
56
|
cert_option_generate_server_pair_by_ca(
|
57
57
|
conf.ca_cert_path,
|
@@ -55,7 +55,7 @@ module Fluent
|
|
55
55
|
"keys" => "keys", # CSVParser, TSVParser (old ValuesParser)
|
56
56
|
"time_key" => "time_key",
|
57
57
|
"time_format" => "time_format",
|
58
|
-
"
|
58
|
+
"localtime" => nil,
|
59
59
|
"utc" => nil,
|
60
60
|
"delimiter" => "delimiter",
|
61
61
|
"keep_time_key" => "keep_time_key",
|
@@ -30,7 +30,7 @@ module Fluent
|
|
30
30
|
StorageState = Struct.new(:storage, :running)
|
31
31
|
|
32
32
|
def storage_create(usage: '', type: nil, conf: nil, default_type: nil)
|
33
|
-
if conf && !conf.arg.empty?
|
33
|
+
if conf && conf.respond_to?(:arg) && !conf.arg.empty?
|
34
34
|
usage = conf.arg
|
35
35
|
end
|
36
36
|
if !usage.empty? && usage !~ /^[a-zA-Z][-_.a-zA-Z0-9]*$/
|
data/lib/fluent/root_agent.rb
CHANGED
@@ -64,11 +64,37 @@ module Fluent
|
|
64
64
|
attr_reader :labels
|
65
65
|
|
66
66
|
def configure(conf)
|
67
|
+
# initialize <worker> elements
|
68
|
+
conf.elements(name: 'worker').each do |e|
|
69
|
+
target_worker_id_str = e.arg
|
70
|
+
if target_worker_id_str.empty?
|
71
|
+
raise ConfigError, "Missing worker id on <worker> directive"
|
72
|
+
end
|
73
|
+
|
74
|
+
target_worker_id = target_worker_id_str.to_i
|
75
|
+
if target_worker_id < 0 || target_worker_id > (Fluent::Engine.system_config.workers - 1)
|
76
|
+
raise ConfigError, "worker id #{target_worker_id} specified by <worker> directive is not allowed. Available worker id is between 0 and #{(Fluent::Engine.system_config.workers - 1)}"
|
77
|
+
end
|
78
|
+
|
79
|
+
## On dry_run mode, all worker sections have to be configured on supervisor (recognized as worker_id = 0).
|
80
|
+
target_worker_id = 0 if Fluent::Engine.dry_run_mode
|
81
|
+
|
82
|
+
e.elements.each do |elem|
|
83
|
+
unless ['source', 'match', 'filter', 'label'].include?(elem.name)
|
84
|
+
raise ConfigError, "<worker> section cannot have <#{elem.name}> directive"
|
85
|
+
end
|
86
|
+
elem.set_target_worker_id(target_worker_id)
|
87
|
+
end
|
88
|
+
conf += e
|
89
|
+
end
|
90
|
+
conf.elements.delete_if{|e| e.name == 'worker'}
|
91
|
+
|
67
92
|
error_label_config = nil
|
68
93
|
|
69
94
|
# initialize <label> elements before configuring all plugins to avoid 'label not found' in input, filter and output.
|
70
95
|
label_configs = {}
|
71
96
|
conf.elements(name: 'label').each { |e|
|
97
|
+
next if e.for_another_worker?
|
72
98
|
name = e.arg
|
73
99
|
raise ConfigError, "Missing symbol argument on <label> directive" if name.empty?
|
74
100
|
|
@@ -90,6 +116,7 @@ module Fluent
|
|
90
116
|
log.info :worker0, "'--without-source' is applied. Ignore <source> sections"
|
91
117
|
else
|
92
118
|
conf.elements(name: 'source').each { |e|
|
119
|
+
next if e.for_another_worker?
|
93
120
|
type = e['@type']
|
94
121
|
raise ConfigError, "Missing '@type' parameter on <source> directive" unless type
|
95
122
|
add_source(type, e)
|
@@ -136,8 +163,12 @@ module Fluent
|
|
136
163
|
def start
|
137
164
|
lifecycle(desc: true) do |i| # instance
|
138
165
|
i.start unless i.started?
|
139
|
-
|
140
|
-
|
166
|
+
# Input#start sometimes emits lots of evetns with in_tail/`read_from_head true` case
|
167
|
+
# and it causes deadlock for small buffer/queue output. To avoid such problem,
|
168
|
+
# buffer related output threads should be run before `Input#start`.
|
169
|
+
# This is why after_start should be called immediately after start call.
|
170
|
+
# This depends on `desc: true` because calling plugin order of `desc: true` is
|
171
|
+
# Output, Filter, Label, Output with Router, then Input.
|
141
172
|
i.after_start unless i.after_started?
|
142
173
|
end
|
143
174
|
end
|
@@ -173,7 +204,7 @@ module Fluent
|
|
173
204
|
log.debug "calling #{method} on #{kind} plugin", type: Plugin.lookup_type_from_class(instance.class), plugin_id: instance.plugin_id
|
174
205
|
instance.send(method) unless instance.send(checker)
|
175
206
|
rescue Exception => e
|
176
|
-
log.warn "unexpected error while calling #{method} on #{kind} plugin",
|
207
|
+
log.warn "unexpected error while calling #{method} on #{kind} plugin", plugin: instance.class, plugin_id: instance.plugin_id, error: e
|
177
208
|
log.warn_backtrace
|
178
209
|
end
|
179
210
|
end
|
@@ -231,7 +262,8 @@ module Fluent
|
|
231
262
|
end
|
232
263
|
|
233
264
|
def add_source(type, conf)
|
234
|
-
|
265
|
+
log_type = conf.for_this_worker? ? :default : :worker0
|
266
|
+
log.info log_type, "adding source", type: type
|
235
267
|
|
236
268
|
input = Plugin.new_input(type)
|
237
269
|
# <source> emits events to the top-level event router (RootAgent#event_router).
|
data/lib/fluent/supervisor.rb
CHANGED
@@ -61,6 +61,7 @@ module Fluent
|
|
61
61
|
|
62
62
|
def after_run
|
63
63
|
stop_rpc_server if @rpc_endpoint
|
64
|
+
Fluent::Supervisor.cleanup_resources
|
64
65
|
end
|
65
66
|
|
66
67
|
def run_rpc_server
|
@@ -383,10 +384,17 @@ module Fluent
|
|
383
384
|
supervise: true,
|
384
385
|
standalone_worker: false,
|
385
386
|
signame: nil,
|
386
|
-
winsvcreg: nil,
|
387
387
|
}
|
388
388
|
end
|
389
389
|
|
390
|
+
def self.cleanup_resources
|
391
|
+
unless Fluent.windows?
|
392
|
+
if ENV.has_key?('SERVERENGINE_SOCKETMANAGER_PATH')
|
393
|
+
FileUtils.rm_f(ENV['SERVERENGINE_SOCKETMANAGER_PATH'])
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
390
398
|
def initialize(opt)
|
391
399
|
@daemonize = opt[:daemonize]
|
392
400
|
@supervise = opt[:supervise]
|
@@ -449,7 +457,7 @@ module Fluent
|
|
449
457
|
end
|
450
458
|
end
|
451
459
|
|
452
|
-
|
460
|
+
dry_run_cmd if @dry_run
|
453
461
|
supervise
|
454
462
|
end
|
455
463
|
|
@@ -482,6 +490,10 @@ module Fluent
|
|
482
490
|
read_config
|
483
491
|
set_system_config
|
484
492
|
|
493
|
+
if @standalone_worker && @workers != 1
|
494
|
+
raise Fluent::ConfigError, "invalid number of workers (must be 1 or unspecified) with --no-supervisor: #{@workers}"
|
495
|
+
end
|
496
|
+
|
485
497
|
install_main_process_signal_handlers
|
486
498
|
|
487
499
|
# This is the only log messsage for @standalone_worker
|
@@ -493,6 +505,7 @@ module Fluent
|
|
493
505
|
init_engine
|
494
506
|
run_configure
|
495
507
|
run_engine
|
508
|
+
self.class.cleanup_resources if @standalone_worker
|
496
509
|
exit 0
|
497
510
|
end
|
498
511
|
end
|
@@ -505,17 +518,32 @@ module Fluent
|
|
505
518
|
ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = socket_manager_path.to_s
|
506
519
|
end
|
507
520
|
|
508
|
-
def
|
521
|
+
def dry_run_cmd
|
509
522
|
$log.info "starting fluentd-#{Fluent::VERSION} as dry run mode"
|
510
|
-
|
511
|
-
|
512
|
-
run_configure
|
523
|
+
@system_config.suppress_config_dump = true
|
524
|
+
dry_run
|
513
525
|
exit 0
|
514
526
|
rescue => e
|
515
527
|
$log.error "dry run failed: #{e}"
|
516
528
|
exit 1
|
517
529
|
end
|
518
530
|
|
531
|
+
## Set Engine's dry_run_mode true to override all target_id of worker sections
|
532
|
+
def dry_run
|
533
|
+
begin
|
534
|
+
Fluent::Engine.dry_run_mode = true
|
535
|
+
change_privilege
|
536
|
+
init_engine
|
537
|
+
run_configure
|
538
|
+
rescue Fluent::ConfigError => e
|
539
|
+
$log.error "config error", file: @config_path, error: e
|
540
|
+
$log.debug_backtrace
|
541
|
+
exit!(1)
|
542
|
+
ensure
|
543
|
+
Fluent::Engine.dry_run_mode = false
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
519
547
|
def show_plugin_config
|
520
548
|
name, type = @show_plugin_config.split(":") # input:tail
|
521
549
|
$log.info "Use fluent-plugin-config-format --format=txt #{name} #{type}"
|
@@ -523,6 +551,9 @@ module Fluent
|
|
523
551
|
end
|
524
552
|
|
525
553
|
def supervise
|
554
|
+
# Make dumpable conf, which is set corresponding_proxies for all elements in all worker sections
|
555
|
+
dry_run
|
556
|
+
|
526
557
|
Process.setproctitle("supervisor:#{@process_name}") if @process_name
|
527
558
|
$log.info "starting fluentd-#{Fluent::VERSION}", pid: Process.pid
|
528
559
|
|
data/lib/fluent/system_config.rb
CHANGED
@@ -98,6 +98,13 @@ module Fluent
|
|
98
98
|
next # doesn't exist in command line options
|
99
99
|
when :emit_error_log_interval
|
100
100
|
system.emit_error_log_interval = @suppress_interval if @suppress_interval
|
101
|
+
when :log_level
|
102
|
+
ll_value = instance_variable_get("@log_level")
|
103
|
+
# info level can't be specified via command line option.
|
104
|
+
# log_level is info here, it is default value and <system>'s log_level should be applied if exists.
|
105
|
+
if ll_value != Fluent::Log::LEVEL_INFO
|
106
|
+
system.log_level = ll_value
|
107
|
+
end
|
101
108
|
else
|
102
109
|
next unless instance_variable_defined?("@#{param}")
|
103
110
|
supervisor_value = instance_variable_get("@#{param}")
|
data/lib/fluent/time.rb
CHANGED
@@ -208,6 +208,7 @@ module Fluent
|
|
208
208
|
@parse = case
|
209
209
|
when format_with_timezone && strptime then ->(v){ Fluent::EventTime.from_time(strptime.exec(v)) }
|
210
210
|
when format_with_timezone then ->(v){ Fluent::EventTime.from_time(Time.strptime(v, format)) }
|
211
|
+
when format == '%iso8601' then ->(v){ Fluent::EventTime.from_time(Time.iso8601(v)) }
|
211
212
|
when strptime then ->(v){ t = strptime.exec(v); Fluent::EventTime.new(t.to_i + offset_diff, t.nsec) }
|
212
213
|
when format then ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + offset_diff, t.nsec) }
|
213
214
|
else ->(v){ Fluent::EventTime.parse(v) }
|
data/lib/fluent/version.rb
CHANGED
data/lib/fluent/winsvc.rb
CHANGED
@@ -14,10 +14,9 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
-
INTEVENTOBJ_NAME = "fluentdwinsvc"
|
18
|
-
|
19
17
|
begin
|
20
18
|
|
19
|
+
require 'optparse'
|
21
20
|
require 'windows/debug'
|
22
21
|
require 'Windows/Library'
|
23
22
|
require 'win32/daemon'
|
@@ -27,34 +26,50 @@ begin
|
|
27
26
|
include Windows::Library
|
28
27
|
include Windows::Debug
|
29
28
|
|
30
|
-
|
29
|
+
op = OptionParser.new
|
30
|
+
opts = {service_name: nil}
|
31
|
+
op.on('--service-name NAME', "The name of the Windows Service") {|name|
|
32
|
+
opts[:service_name] = name
|
33
|
+
}
|
34
|
+
op.parse(ARGV)
|
35
|
+
if opts[:service_name] == nil
|
36
|
+
raise "Error: No Windows Service name set. Use '--service-name'"
|
37
|
+
end
|
38
|
+
|
39
|
+
def read_fluentdopt(service_name)
|
31
40
|
require 'win32/Registry'
|
32
|
-
Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM\\CurrentControlSet\\Services
|
41
|
+
Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM\\CurrentControlSet\\Services\\#{service_name}") do |reg|
|
33
42
|
reg.read("fluentdopt")[1] rescue ""
|
34
43
|
end
|
35
44
|
end
|
36
45
|
|
37
|
-
def service_main_start
|
46
|
+
def service_main_start(service_name)
|
38
47
|
ruby_path = 0.chr * 260
|
39
48
|
GetModuleFileName.call(0, ruby_path,260)
|
40
49
|
ruby_path = ruby_path.rstrip.gsub(/\\/, '/')
|
41
50
|
rubybin_dir = ruby_path[0, ruby_path.rindex("/")]
|
42
|
-
opt = read_fluentdopt
|
43
|
-
Process.spawn(rubybin_dir
|
51
|
+
opt = read_fluentdopt(service_name)
|
52
|
+
Process.spawn("\"#{rubybin_dir}/ruby.exe\" \"#{rubybin_dir}/fluentd\" #{opt} -x #{service_name}")
|
44
53
|
end
|
45
54
|
|
46
55
|
class FluentdService < Daemon
|
47
56
|
@pid = 0
|
57
|
+
@service_name = ''
|
48
58
|
|
59
|
+
def initialize(service_name)
|
60
|
+
@service_name = service_name
|
61
|
+
end
|
62
|
+
|
49
63
|
def service_main
|
50
|
-
|
64
|
+
|
65
|
+
@pid = service_main_start(@service_name)
|
51
66
|
while running?
|
52
67
|
sleep 10
|
53
68
|
end
|
54
69
|
end
|
55
70
|
|
56
71
|
def service_stop
|
57
|
-
ev = Win32::Event.open(
|
72
|
+
ev = Win32::Event.open(@service_name)
|
58
73
|
ev.set
|
59
74
|
ev.close
|
60
75
|
if @pid > 0
|
@@ -63,9 +78,8 @@ begin
|
|
63
78
|
end
|
64
79
|
end
|
65
80
|
|
66
|
-
FluentdService.mainloop
|
81
|
+
FluentdService.new(opts[:service_name]).mainloop
|
67
82
|
|
68
83
|
rescue Exception => err
|
69
84
|
raise
|
70
85
|
end
|
71
|
-
|