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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +6 -0
- data/.gitignore +2 -0
- data/.travis.yml +33 -21
- data/CONTRIBUTING.md +1 -0
- data/ChangeLog +810 -237
- data/README.md +0 -25
- data/Rakefile +2 -1
- data/Vagrantfile +17 -0
- data/appveyor.yml +35 -0
- data/example/filter_stdout.conf +5 -5
- data/example/in_forward.conf +2 -2
- data/example/in_http.conf +2 -2
- data/example/in_out_forward.conf +17 -0
- data/example/in_syslog.conf +2 -2
- data/example/in_tail.conf +2 -2
- data/example/in_tcp.conf +2 -2
- data/example/in_udp.conf +2 -2
- data/example/out_copy.conf +4 -4
- data/example/out_file.conf +2 -2
- data/example/out_forward.conf +2 -2
- data/example/out_forward_buf_file.conf +23 -0
- data/example/v0_12_filter.conf +8 -8
- data/fluent.conf +29 -0
- data/fluentd.gemspec +18 -11
- data/lib/fluent/agent.rb +60 -58
- data/lib/fluent/command/cat.rb +1 -1
- data/lib/fluent/command/debug.rb +7 -5
- data/lib/fluent/command/fluentd.rb +97 -2
- data/lib/fluent/compat/call_super_mixin.rb +67 -0
- data/lib/fluent/compat/filter.rb +50 -0
- data/lib/fluent/compat/formatter.rb +109 -0
- data/lib/fluent/compat/input.rb +50 -0
- data/lib/fluent/compat/output.rb +617 -0
- data/lib/fluent/compat/output_chain.rb +60 -0
- data/lib/fluent/compat/parser.rb +163 -0
- data/lib/fluent/compat/propagate_default.rb +62 -0
- data/lib/fluent/config.rb +23 -20
- data/lib/fluent/config/configure_proxy.rb +119 -70
- data/lib/fluent/config/dsl.rb +5 -18
- data/lib/fluent/config/element.rb +72 -8
- data/lib/fluent/config/error.rb +0 -3
- data/lib/fluent/config/literal_parser.rb +0 -2
- data/lib/fluent/config/parser.rb +4 -4
- data/lib/fluent/config/section.rb +39 -28
- data/lib/fluent/config/types.rb +2 -13
- data/lib/fluent/config/v1_parser.rb +1 -3
- data/lib/fluent/configurable.rb +48 -16
- data/lib/fluent/daemon.rb +15 -0
- data/lib/fluent/engine.rb +26 -52
- data/lib/fluent/env.rb +6 -4
- data/lib/fluent/event.rb +58 -11
- data/lib/fluent/event_router.rb +5 -5
- data/lib/fluent/filter.rb +2 -50
- data/lib/fluent/formatter.rb +4 -293
- data/lib/fluent/input.rb +2 -32
- data/lib/fluent/label.rb +2 -2
- data/lib/fluent/load.rb +3 -2
- data/lib/fluent/log.rb +107 -38
- data/lib/fluent/match.rb +0 -36
- data/lib/fluent/mixin.rb +117 -7
- data/lib/fluent/msgpack_factory.rb +62 -0
- data/lib/fluent/output.rb +7 -612
- data/lib/fluent/output_chain.rb +23 -0
- data/lib/fluent/parser.rb +4 -800
- data/lib/fluent/plugin.rb +100 -121
- data/lib/fluent/plugin/bare_output.rb +63 -0
- data/lib/fluent/plugin/base.rb +121 -0
- data/lib/fluent/plugin/buf_file.rb +101 -182
- data/lib/fluent/plugin/buf_memory.rb +9 -92
- data/lib/fluent/plugin/buffer.rb +473 -0
- data/lib/fluent/plugin/buffer/chunk.rb +135 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
- data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
- data/lib/fluent/plugin/exec_util.rb +80 -75
- data/lib/fluent/plugin/file_util.rb +33 -28
- data/lib/fluent/plugin/file_wrapper.rb +120 -0
- data/lib/fluent/plugin/filter.rb +51 -0
- data/lib/fluent/plugin/filter_grep.rb +13 -40
- data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
- data/lib/fluent/plugin/formatter.rb +93 -0
- data/lib/fluent/plugin/formatter_csv.rb +48 -0
- data/lib/fluent/plugin/formatter_hash.rb +32 -0
- data/lib/fluent/plugin/formatter_json.rb +47 -0
- data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
- data/lib/fluent/plugin/formatter_out_file.rb +45 -0
- data/lib/fluent/plugin/formatter_single_value.rb +34 -0
- data/lib/fluent/plugin/formatter_stdout.rb +39 -0
- data/lib/fluent/plugin/in_debug_agent.rb +4 -0
- data/lib/fluent/plugin/in_dummy.rb +22 -18
- data/lib/fluent/plugin/in_exec.rb +18 -8
- data/lib/fluent/plugin/in_forward.rb +36 -79
- data/lib/fluent/plugin/in_gc_stat.rb +4 -0
- data/lib/fluent/plugin/in_http.rb +21 -18
- data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
- data/lib/fluent/plugin/in_object_space.rb +6 -1
- data/lib/fluent/plugin/in_stream.rb +7 -3
- data/lib/fluent/plugin/in_syslog.rb +46 -95
- data/lib/fluent/plugin/in_tail.rb +51 -595
- data/lib/fluent/plugin/in_tcp.rb +8 -1
- data/lib/fluent/plugin/in_udp.rb +8 -14
- data/lib/fluent/plugin/input.rb +33 -0
- data/lib/fluent/plugin/multi_output.rb +95 -0
- data/lib/fluent/plugin/out_buffered_null.rb +59 -0
- data/lib/fluent/plugin/out_copy.rb +11 -7
- data/lib/fluent/plugin/out_exec.rb +15 -11
- data/lib/fluent/plugin/out_exec_filter.rb +18 -10
- data/lib/fluent/plugin/out_file.rb +34 -5
- data/lib/fluent/plugin/out_forward.rb +19 -9
- data/lib/fluent/plugin/out_null.rb +0 -14
- data/lib/fluent/plugin/out_roundrobin.rb +11 -7
- data/lib/fluent/plugin/out_stdout.rb +5 -7
- data/lib/fluent/plugin/out_stream.rb +3 -1
- data/lib/fluent/plugin/output.rb +979 -0
- data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
- data/lib/fluent/plugin/parser.rb +244 -0
- data/lib/fluent/plugin/parser_apache.rb +24 -0
- data/lib/fluent/plugin/parser_apache2.rb +84 -0
- data/lib/fluent/plugin/parser_apache_error.rb +21 -0
- data/lib/fluent/plugin/parser_csv.rb +31 -0
- data/lib/fluent/plugin/parser_json.rb +79 -0
- data/lib/fluent/plugin/parser_ltsv.rb +50 -0
- data/lib/fluent/plugin/parser_multiline.rb +102 -0
- data/lib/fluent/plugin/parser_nginx.rb +24 -0
- data/lib/fluent/plugin/parser_none.rb +36 -0
- data/lib/fluent/plugin/parser_syslog.rb +82 -0
- data/lib/fluent/plugin/parser_tsv.rb +37 -0
- data/lib/fluent/plugin/socket_util.rb +120 -114
- data/lib/fluent/plugin/storage.rb +84 -0
- data/lib/fluent/plugin/storage_local.rb +116 -0
- data/lib/fluent/plugin/string_util.rb +16 -13
- data/lib/fluent/plugin_helper.rb +39 -0
- data/lib/fluent/plugin_helper/child_process.rb +298 -0
- data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
- data/lib/fluent/plugin_helper/event_loop.rb +118 -0
- data/lib/fluent/plugin_helper/retry_state.rb +177 -0
- data/lib/fluent/plugin_helper/storage.rb +308 -0
- data/lib/fluent/plugin_helper/thread.rb +147 -0
- data/lib/fluent/plugin_helper/timer.rb +85 -0
- data/lib/fluent/plugin_id.rb +63 -0
- data/lib/fluent/process.rb +21 -30
- data/lib/fluent/registry.rb +21 -9
- data/lib/fluent/root_agent.rb +115 -40
- data/lib/fluent/supervisor.rb +330 -320
- data/lib/fluent/system_config.rb +42 -18
- data/lib/fluent/test.rb +6 -1
- data/lib/fluent/test/base.rb +23 -3
- data/lib/fluent/test/driver/base.rb +247 -0
- data/lib/fluent/test/driver/event_feeder.rb +98 -0
- data/lib/fluent/test/driver/filter.rb +35 -0
- data/lib/fluent/test/driver/input.rb +31 -0
- data/lib/fluent/test/driver/output.rb +78 -0
- data/lib/fluent/test/driver/test_event_router.rb +45 -0
- data/lib/fluent/test/filter_test.rb +0 -1
- data/lib/fluent/test/formatter_test.rb +2 -1
- data/lib/fluent/test/input_test.rb +23 -17
- data/lib/fluent/test/output_test.rb +28 -39
- data/lib/fluent/test/parser_test.rb +1 -1
- data/lib/fluent/time.rb +104 -1
- data/lib/fluent/{status.rb → unique_id.rb} +15 -24
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +72 -0
- data/test/compat/test_calls_super.rb +164 -0
- data/test/config/test_config_parser.rb +83 -0
- data/test/config/test_configurable.rb +547 -274
- data/test/config/test_configure_proxy.rb +146 -29
- data/test/config/test_dsl.rb +3 -181
- data/test/config/test_element.rb +274 -0
- data/test/config/test_literal_parser.rb +1 -1
- data/test/config/test_section.rb +79 -7
- data/test/config/test_system_config.rb +21 -0
- data/test/config/test_types.rb +3 -26
- data/test/helper.rb +78 -8
- data/test/plugin/test_bare_output.rb +118 -0
- data/test/plugin/test_base.rb +75 -0
- data/test/plugin/test_buf_file.rb +420 -521
- data/test/plugin/test_buf_memory.rb +32 -194
- data/test/plugin/test_buffer.rb +981 -0
- data/test/plugin/test_buffer_chunk.rb +110 -0
- data/test/plugin/test_buffer_file_chunk.rb +770 -0
- data/test/plugin/test_buffer_memory_chunk.rb +265 -0
- data/test/plugin/test_filter.rb +255 -0
- data/test/plugin/test_filter_grep.rb +2 -73
- data/test/plugin/test_filter_record_transformer.rb +24 -68
- data/test/plugin/test_filter_stdout.rb +6 -6
- data/test/plugin/test_in_debug_agent.rb +2 -0
- data/test/plugin/test_in_dummy.rb +11 -17
- data/test/plugin/test_in_exec.rb +6 -25
- data/test/plugin/test_in_forward.rb +112 -151
- data/test/plugin/test_in_gc_stat.rb +2 -0
- data/test/plugin/test_in_http.rb +106 -157
- data/test/plugin/test_in_object_space.rb +21 -5
- data/test/plugin/test_in_stream.rb +14 -13
- data/test/plugin/test_in_syslog.rb +30 -275
- data/test/plugin/test_in_tail.rb +95 -234
- data/test/plugin/test_in_tcp.rb +14 -0
- data/test/plugin/test_in_udp.rb +21 -13
- data/test/plugin/test_input.rb +122 -0
- data/test/plugin/test_multi_output.rb +180 -0
- data/test/plugin/test_out_buffered_null.rb +79 -0
- data/test/plugin/test_out_copy.rb +15 -2
- data/test/plugin/test_out_exec.rb +75 -25
- data/test/plugin/test_out_exec_filter.rb +74 -8
- data/test/plugin/test_out_file.rb +61 -7
- data/test/plugin/test_out_forward.rb +92 -15
- data/test/plugin/test_out_roundrobin.rb +1 -0
- data/test/plugin/test_out_stdout.rb +22 -13
- data/test/plugin/test_out_stream.rb +18 -0
- data/test/plugin/test_output.rb +515 -0
- data/test/plugin/test_output_as_buffered.rb +1540 -0
- data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
- data/test/plugin/test_output_as_buffered_retries.rb +808 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
- data/test/plugin/test_output_as_standard.rb +362 -0
- data/test/plugin/test_owned_by.rb +35 -0
- data/test/plugin/test_storage.rb +167 -0
- data/test/plugin/test_storage_local.rb +8 -0
- data/test/plugin_helper/test_child_process.rb +599 -0
- data/test/plugin_helper/test_compat_parameters.rb +175 -0
- data/test/plugin_helper/test_event_emitter.rb +51 -0
- data/test/plugin_helper/test_event_loop.rb +52 -0
- data/test/plugin_helper/test_retry_state.rb +399 -0
- data/test/plugin_helper/test_storage.rb +411 -0
- data/test/plugin_helper/test_thread.rb +164 -0
- data/test/plugin_helper/test_timer.rb +100 -0
- data/test/scripts/exec_script.rb +0 -6
- data/test/scripts/fluent/plugin/out_test.rb +3 -0
- data/test/test_config.rb +13 -4
- data/test/test_event.rb +24 -13
- data/test/test_event_router.rb +8 -7
- data/test/test_event_time.rb +187 -0
- data/test/test_formatter.rb +13 -51
- data/test/test_input.rb +1 -1
- data/test/test_log.rb +239 -16
- data/test/test_mixin.rb +1 -1
- data/test/test_output.rb +53 -66
- data/test/test_parser.rb +105 -323
- data/test/test_plugin_helper.rb +81 -0
- data/test/test_root_agent.rb +4 -52
- data/test/test_supervisor.rb +272 -0
- data/test/test_unique_id.rb +47 -0
- metadata +180 -54
- data/lib/fluent/buffer.rb +0 -365
- data/lib/fluent/plugin/filter_parser.rb +0 -107
- data/lib/fluent/plugin/in_status.rb +0 -76
- data/lib/fluent/test/helpers.rb +0 -86
- data/test/plugin/data/log/foo/bar2 +0 -0
- data/test/plugin/test_filter_parser.rb +0 -744
- data/test/plugin/test_in_status.rb +0 -38
- data/test/test_buffer.rb +0 -624
@@ -0,0 +1,135 @@
|
|
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'
|
18
|
+
require 'fluent/unique_id'
|
19
|
+
require 'fluent/event'
|
20
|
+
|
21
|
+
require 'monitor'
|
22
|
+
|
23
|
+
module Fluent
|
24
|
+
module Plugin
|
25
|
+
class Buffer # fluent/plugin/buffer is alread loaded
|
26
|
+
class Chunk
|
27
|
+
include MonitorMixin
|
28
|
+
include UniqueId::Mixin
|
29
|
+
include ChunkMessagePackEventStreamer
|
30
|
+
|
31
|
+
# Chunks has 2 part:
|
32
|
+
# * metadata: contains metadata which should be restored after resume (if possible)
|
33
|
+
# v: {key=>value,key=>value,...} (optional)
|
34
|
+
# t: tag as string (optional)
|
35
|
+
# k: time slice key (optional)
|
36
|
+
#
|
37
|
+
# id: unique_id of chunk (*)
|
38
|
+
# s: size (number of events in chunk) (*)
|
39
|
+
# c: created_at as unix time (*)
|
40
|
+
# m: modified_at as unix time (*)
|
41
|
+
# (*): fields automatically injected by chunk itself
|
42
|
+
# * data: binary data, combined records represented as String, maybe compressed
|
43
|
+
|
44
|
+
# NOTE: keys of metadata are named with a single letter
|
45
|
+
# to decread bytesize of metadata I/O
|
46
|
+
|
47
|
+
# TODO: CompressedPackedMessage of forward protocol?
|
48
|
+
|
49
|
+
def initialize(metadata)
|
50
|
+
super()
|
51
|
+
@unique_id = generate_unique_id
|
52
|
+
@metadata = metadata
|
53
|
+
|
54
|
+
# state: staged/queued/closed
|
55
|
+
@state = :staged
|
56
|
+
|
57
|
+
@size = 0
|
58
|
+
@created_at = Time.now
|
59
|
+
@modified_at = Time.now
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_reader :unique_id, :metadata, :created_at, :modified_at, :state
|
63
|
+
|
64
|
+
# data is array of formatted record string
|
65
|
+
def append(data)
|
66
|
+
raise NotImplementedError, "Implement this method in child class"
|
67
|
+
end
|
68
|
+
|
69
|
+
# for event streams which is packed or zipped (and we want not to unpack/uncompress)
|
70
|
+
def concat(bulk, records)
|
71
|
+
raise NotImplementedError, "Implement this method in child class"
|
72
|
+
end
|
73
|
+
|
74
|
+
def commit
|
75
|
+
raise NotImplementedError, "Implement this method in child class"
|
76
|
+
end
|
77
|
+
|
78
|
+
def rollback
|
79
|
+
raise NotImplementedError, "Implement this method in child class"
|
80
|
+
end
|
81
|
+
|
82
|
+
def bytesize
|
83
|
+
raise NotImplementedError, "Implement this method in child class"
|
84
|
+
end
|
85
|
+
|
86
|
+
def size
|
87
|
+
raise NotImplementedError, "Implement this method in child class"
|
88
|
+
end
|
89
|
+
alias :length :size
|
90
|
+
|
91
|
+
def empty?
|
92
|
+
size == 0
|
93
|
+
end
|
94
|
+
|
95
|
+
def staged?
|
96
|
+
@state == :staged
|
97
|
+
end
|
98
|
+
|
99
|
+
def queued?
|
100
|
+
@state == :queued
|
101
|
+
end
|
102
|
+
|
103
|
+
def closed?
|
104
|
+
@state == :closed
|
105
|
+
end
|
106
|
+
|
107
|
+
def enqueued!
|
108
|
+
@state = :queued
|
109
|
+
end
|
110
|
+
|
111
|
+
def close
|
112
|
+
@state = :closed
|
113
|
+
end
|
114
|
+
|
115
|
+
def purge
|
116
|
+
@state = :closed
|
117
|
+
end
|
118
|
+
|
119
|
+
def read
|
120
|
+
raise NotImplementedError, "Implement this method in child class"
|
121
|
+
end
|
122
|
+
|
123
|
+
def open(&block)
|
124
|
+
raise NotImplementedError, "Implement this method in child class"
|
125
|
+
end
|
126
|
+
|
127
|
+
def write_to(io)
|
128
|
+
open do |i|
|
129
|
+
IO.copy_stream(i, io)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,339 @@
|
|
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
|
+
require 'fluent/unique_id'
|
19
|
+
require 'fluent/msgpack_factory'
|
20
|
+
|
21
|
+
module Fluent
|
22
|
+
module Plugin
|
23
|
+
class Buffer
|
24
|
+
class FileChunk < Chunk
|
25
|
+
### buffer path user specified : /path/to/directory/user_specified_prefix.*.log
|
26
|
+
### buffer chunk path : /path/to/directory/user_specified_prefix.b513b61c9791029c2513b61c9791029c2.log
|
27
|
+
### buffer chunk metadata path : /path/to/directory/user_specified_prefix.b513b61c9791029c2513b61c9791029c2.log.meta
|
28
|
+
|
29
|
+
# NOTE: Old style buffer path of time sliced output plugins had a part of key: prefix.20150414.b513b61...suffix
|
30
|
+
# But this part is not used now for any purpose. (Now metadata is used instead.)
|
31
|
+
|
32
|
+
# state: b/q - 'b'(on stage, compatible with v0.12), 'q'(enqueued)
|
33
|
+
# path_prefix: path prefix string, ended with '.'
|
34
|
+
# path_suffix: path suffix string, like '.log' (or any other user specified)
|
35
|
+
|
36
|
+
include SystemConfig::Mixin
|
37
|
+
include MessagePackFactory::Mixin
|
38
|
+
|
39
|
+
FILE_PERMISSION = 0644
|
40
|
+
|
41
|
+
attr_reader :path, :permission
|
42
|
+
|
43
|
+
def initialize(metadata, path, mode, perm: system_config.file_permission || FILE_PERMISSION)
|
44
|
+
super(metadata)
|
45
|
+
@permission = perm
|
46
|
+
@bytesize = @size = @adding_bytes = @adding_size = 0
|
47
|
+
@meta = nil
|
48
|
+
|
49
|
+
case mode
|
50
|
+
when :create then create_new_chunk(path, perm)
|
51
|
+
when :staged then load_existing_staged_chunk(path)
|
52
|
+
when :queued then load_existing_enqueued_chunk(path)
|
53
|
+
else
|
54
|
+
raise ArgumentError, "Invalid file chunk mode: #{mode}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def append(data)
|
59
|
+
raise "BUG: appending to non-staged chunk, now '#{self.state}'" unless self.staged?
|
60
|
+
|
61
|
+
bytes = 0
|
62
|
+
adding = ''.force_encoding(Encoding::ASCII_8BIT)
|
63
|
+
data.each do |d|
|
64
|
+
x = d.force_encoding(Encoding::ASCII_8BIT)
|
65
|
+
bytes += x.bytesize
|
66
|
+
adding << x
|
67
|
+
end
|
68
|
+
@chunk.write adding
|
69
|
+
|
70
|
+
@adding_bytes += bytes
|
71
|
+
@adding_size += data.size
|
72
|
+
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
76
|
+
def concat(bulk, bulk_size)
|
77
|
+
raise "BUG: appending to non-staged chunk, now '#{self.state}'" unless self.staged?
|
78
|
+
|
79
|
+
bulk.force_encoding(Encoding::ASCII_8BIT)
|
80
|
+
@chunk.write bulk
|
81
|
+
@adding_bytes += bulk.bytesize
|
82
|
+
@adding_size += bulk_size
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
def commit
|
87
|
+
write_metadata # this should be at first: of course, this operation may fail
|
88
|
+
|
89
|
+
@commit_position = @chunk.pos
|
90
|
+
@size += @adding_size
|
91
|
+
@bytesize += @adding_bytes
|
92
|
+
@adding_bytes = @adding_size = 0
|
93
|
+
@modified_at = Time.now
|
94
|
+
|
95
|
+
true
|
96
|
+
end
|
97
|
+
|
98
|
+
def rollback
|
99
|
+
if @chunk.pos != @commit_position
|
100
|
+
@chunk.seek(@commit_position, IO::SEEK_SET)
|
101
|
+
@chunk.truncate(@commit_position)
|
102
|
+
end
|
103
|
+
@adding_bytes = @adding_size = 0
|
104
|
+
true
|
105
|
+
end
|
106
|
+
|
107
|
+
def bytesize
|
108
|
+
@bytesize + @adding_bytes
|
109
|
+
end
|
110
|
+
|
111
|
+
def size
|
112
|
+
@size + @adding_size
|
113
|
+
end
|
114
|
+
|
115
|
+
def empty?
|
116
|
+
@bytesize == 0
|
117
|
+
end
|
118
|
+
|
119
|
+
def enqueued!
|
120
|
+
return unless self.staged?
|
121
|
+
|
122
|
+
new_chunk_path = self.class.generate_queued_chunk_path(@path, @unique_id)
|
123
|
+
new_meta_path = new_chunk_path + '.meta'
|
124
|
+
|
125
|
+
write_metadata(update: false) # re-write metadata w/ finalized records
|
126
|
+
|
127
|
+
file_rename(@chunk, @path, new_chunk_path, ->(new_io){ @chunk = new_io })
|
128
|
+
@path = new_chunk_path
|
129
|
+
|
130
|
+
file_rename(@meta, @meta_path, new_meta_path, ->(new_io){ @meta = new_io })
|
131
|
+
@meta_path = new_meta_path
|
132
|
+
|
133
|
+
super
|
134
|
+
end
|
135
|
+
|
136
|
+
def close
|
137
|
+
super
|
138
|
+
size = @chunk.size
|
139
|
+
@chunk.close
|
140
|
+
@meta.close if @meta # meta may be missing if chunk is queued at first
|
141
|
+
if size == 0
|
142
|
+
File.unlink(@path, @meta_path)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def purge
|
147
|
+
super
|
148
|
+
@chunk.close
|
149
|
+
@meta.close if @meta
|
150
|
+
@bytesize = @size = @adding_bytes = @adding_size = 0
|
151
|
+
File.unlink(@path, @meta_path)
|
152
|
+
end
|
153
|
+
|
154
|
+
def read
|
155
|
+
@chunk.seek(0, IO::SEEK_SET)
|
156
|
+
@chunk.read
|
157
|
+
end
|
158
|
+
|
159
|
+
def open(&block)
|
160
|
+
@chunk.seek(0, IO::SEEK_SET)
|
161
|
+
val = yield @chunk
|
162
|
+
@chunk.seek(0, IO::SEEK_END) if self.staged?
|
163
|
+
val
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.assume_chunk_state(path)
|
167
|
+
if /\.(b|q)([0-9a-f]+)\.[^\/]*\Z/n =~ path # //n switch means explicit 'ASCII-8BIT' pattern
|
168
|
+
$1 == 'b' ? :staged : :queued
|
169
|
+
else
|
170
|
+
:queued
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.generate_stage_chunk_path(path, unique_id)
|
175
|
+
pos = path.index('.*.')
|
176
|
+
raise "BUG: buffer chunk path on stage MUST have '.*.'" unless pos
|
177
|
+
|
178
|
+
prefix = path[0...pos]
|
179
|
+
suffix = path[(pos+3)..-1]
|
180
|
+
|
181
|
+
chunk_id = Fluent::UniqueId.hex(unique_id)
|
182
|
+
state = 'b'
|
183
|
+
"#{prefix}.#{state}#{chunk_id}.#{suffix}"
|
184
|
+
end
|
185
|
+
|
186
|
+
def self.generate_queued_chunk_path(path, unique_id)
|
187
|
+
chunk_id = Fluent::UniqueId.hex(unique_id)
|
188
|
+
if path.index(".b#{chunk_id}.")
|
189
|
+
path.sub(".b#{chunk_id}.", ".q#{chunk_id}.")
|
190
|
+
else # for unexpected cases (ex: users rename files while opened by fluentd)
|
191
|
+
path + ".q#{chunk_id}.chunk"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# used only for queued v0.12 buffer path
|
196
|
+
def self.unique_id_from_path(path)
|
197
|
+
if /\.(b|q)([0-9a-f]+)\.[^\/]*\Z/n =~ path # //n switch means explicit 'ASCII-8BIT' pattern
|
198
|
+
return $2.scan(/../).map{|x| x.to_i(16) }.pack('C*')
|
199
|
+
end
|
200
|
+
nil
|
201
|
+
end
|
202
|
+
|
203
|
+
def restore_metadata(bindata)
|
204
|
+
data = msgpack_unpacker(symbolize_keys: true).feed(bindata).read rescue {}
|
205
|
+
|
206
|
+
now = Time.now
|
207
|
+
|
208
|
+
@unique_id = data[:id] || self.class.unique_id_from_path(@path) || @unique_id
|
209
|
+
@size = data[:s] || 0
|
210
|
+
@created_at = Time.at(data.fetch(:c, now.to_i))
|
211
|
+
@modified_at = Time.at(data.fetch(:m, now.to_i))
|
212
|
+
|
213
|
+
@metadata.timekey = data[:timekey]
|
214
|
+
@metadata.tag = data[:tag]
|
215
|
+
@metadata.variables = data[:variables]
|
216
|
+
end
|
217
|
+
|
218
|
+
def restore_metadata_partially(chunk)
|
219
|
+
@unique_id = self.class.unique_id_from_path(chunk.path) || @unique_id
|
220
|
+
@size = 0
|
221
|
+
@created_at = chunk.ctime # birthtime isn't supported on Windows (and Travis?)
|
222
|
+
@modified_at = chunk.mtime
|
223
|
+
|
224
|
+
@metadata.timekey = nil
|
225
|
+
@metadata.tag = nil
|
226
|
+
@metadata.variables = nil
|
227
|
+
end
|
228
|
+
|
229
|
+
def write_metadata(update: true)
|
230
|
+
data = @metadata.to_h.merge({
|
231
|
+
id: @unique_id,
|
232
|
+
s: (update ? @size + @adding_size : @size),
|
233
|
+
c: @created_at.to_i,
|
234
|
+
m: (update ? Time.now : @modified_at).to_i,
|
235
|
+
})
|
236
|
+
@meta.seek(0, IO::SEEK_SET)
|
237
|
+
@meta.truncate(0)
|
238
|
+
@meta.write(msgpack_packer.pack(data))
|
239
|
+
end
|
240
|
+
|
241
|
+
def file_rename(file, old_path, new_path, callback=nil)
|
242
|
+
pos = file.pos
|
243
|
+
if Fluent.windows?
|
244
|
+
file.close
|
245
|
+
File.rename(old_path, new_path)
|
246
|
+
file = File.open(new_path, 'rb', @permission)
|
247
|
+
else
|
248
|
+
File.rename(old_path, new_path)
|
249
|
+
file.reopen(new_path, 'rb')
|
250
|
+
end
|
251
|
+
file.set_encoding(Encoding::ASCII_8BIT)
|
252
|
+
file.sync = true
|
253
|
+
file.binmode
|
254
|
+
file.pos = pos
|
255
|
+
callback.call(file) if callback
|
256
|
+
end
|
257
|
+
|
258
|
+
def create_new_chunk(path, perm)
|
259
|
+
@path = self.class.generate_stage_chunk_path(path, @unique_id)
|
260
|
+
@meta_path = @path + '.meta'
|
261
|
+
@chunk = File.open(@path, 'wb+', perm)
|
262
|
+
@chunk.set_encoding(Encoding::ASCII_8BIT)
|
263
|
+
@chunk.sync = true
|
264
|
+
@chunk.binmode
|
265
|
+
@meta = File.open(@meta_path, 'wb', perm)
|
266
|
+
@meta.set_encoding(Encoding::ASCII_8BIT)
|
267
|
+
@meta.sync = true
|
268
|
+
@meta.binmode
|
269
|
+
|
270
|
+
@state = :staged
|
271
|
+
@bytesize = 0
|
272
|
+
@commit_position = @chunk.pos # must be 0
|
273
|
+
@adding_bytes = 0
|
274
|
+
@adding_size = 0
|
275
|
+
end
|
276
|
+
|
277
|
+
def load_existing_staged_chunk(path)
|
278
|
+
@path = path
|
279
|
+
@meta_path = @path + '.meta'
|
280
|
+
|
281
|
+
@meta = nil
|
282
|
+
# staging buffer chunk without metadata is classic buffer chunk file
|
283
|
+
# and it should be enqueued immediately
|
284
|
+
if File.exist?(@meta_path)
|
285
|
+
@chunk = File.open(@path, 'rb+')
|
286
|
+
@chunk.set_encoding(Encoding::ASCII_8BIT)
|
287
|
+
@chunk.sync = true
|
288
|
+
@chunk.seek(0, IO::SEEK_END)
|
289
|
+
@chunk.binmode
|
290
|
+
|
291
|
+
@meta = File.open(@meta_path, 'rb+')
|
292
|
+
@meta.set_encoding(Encoding::ASCII_8BIT)
|
293
|
+
@meta.sync = true
|
294
|
+
@meta.binmode
|
295
|
+
restore_metadata(@meta.read)
|
296
|
+
@meta.seek(0, IO::SEEK_SET)
|
297
|
+
|
298
|
+
@state = :staged
|
299
|
+
@bytesize = @chunk.size
|
300
|
+
@commit_position = @chunk.pos
|
301
|
+
@adding_bytes = 0
|
302
|
+
@adding_size = 0
|
303
|
+
else
|
304
|
+
# classic buffer chunk - read only chunk
|
305
|
+
@chunk = File.open(@path, 'rb')
|
306
|
+
@chunk.set_encoding(Encoding::ASCII_8BIT)
|
307
|
+
@chunk.binmode
|
308
|
+
@chunk.seek(0, IO::SEEK_SET)
|
309
|
+
@state = :queued
|
310
|
+
@bytesize = @chunk.size
|
311
|
+
|
312
|
+
restore_metadata_partially(@chunk)
|
313
|
+
|
314
|
+
@commit_position = @chunk.size
|
315
|
+
@unique_id = self.class.unique_id_from_path(@path) || @unique_id
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def load_existing_enqueued_chunk(path)
|
320
|
+
@path = path
|
321
|
+
@chunk = File.open(@path, 'rb')
|
322
|
+
@chunk.set_encoding(Encoding::ASCII_8BIT)
|
323
|
+
@chunk.binmode
|
324
|
+
@chunk.seek(0, IO::SEEK_SET)
|
325
|
+
@bytesize = @chunk.size
|
326
|
+
@commit_position = @chunk.size
|
327
|
+
|
328
|
+
@meta_path = @path + '.meta'
|
329
|
+
if File.readable?(@meta_path)
|
330
|
+
restore_metadata(File.open(@meta_path){|f| f.set_encoding(Encoding::ASCII_8BIT); f.binmode; f.read })
|
331
|
+
else
|
332
|
+
restore_metadata_partially(@chunk)
|
333
|
+
end
|
334
|
+
@state = :queued
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|