fluentd 1.11.5 → 1.12.0.rc1
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/stale.yml +22 -0
- data/.travis.yml +22 -2
- data/CHANGELOG.md +1 -0
- data/appveyor.yml +3 -0
- data/bin/fluent-cap-ctl +7 -0
- data/fluentd.gemspec +1 -0
- data/lib/fluent/capability.rb +87 -0
- data/lib/fluent/command/cap_ctl.rb +174 -0
- data/lib/fluent/env.rb +4 -0
- data/lib/fluent/plugin/buffer.rb +2 -21
- data/lib/fluent/plugin/formatter.rb +2 -2
- data/lib/fluent/plugin/formatter_csv.rb +1 -1
- data/lib/fluent/plugin/formatter_hash.rb +1 -1
- data/lib/fluent/plugin/formatter_ltsv.rb +3 -3
- data/lib/fluent/plugin/formatter_out_file.rb +3 -3
- data/lib/fluent/plugin/formatter_single_value.rb +2 -2
- data/lib/fluent/plugin/formatter_tsv.rb +2 -2
- data/lib/fluent/plugin/in_tail.rb +8 -1
- data/lib/fluent/version.rb +1 -1
- data/test/command/test_cap_ctl.rb +100 -0
- data/test/plugin/test_in_tail.rb +47 -1
- data/test/test_capability.rb +74 -0
- metadata +27 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea33aa9fbbca10538b329676df8dc024f38836b8c0a3bd78ff8afe9b21e59a27
|
4
|
+
data.tar.gz: d3500418626d7f49305b4dee07ab6dfa10c84687ee754fd967aee1200a815dc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a43d215a3a026042028643ca627f81411379efe8eb5090c4c98f8886c22efe33595362b82273889b97ecc8a95af8c93d0d2dbf5d8494c3c8e680942dd8c0c67
|
7
|
+
data.tar.gz: a17be6c1b92193649412e223ce7bba96d94f1122b309e459dc72a6e7f0a5339874e2a9d9d352a88612c3d7e603c2276b8109af97b8b26cc3967d81cae7925071
|
data/.github/stale.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Number of days of inactivity before an issue becomes stale
|
2
|
+
daysUntilStale: 90
|
3
|
+
# Number of days of inactivity before a stale issue is closed
|
4
|
+
daysUntilClose: 30
|
5
|
+
# Issues with these labels will never be considered stale
|
6
|
+
exemptLabels:
|
7
|
+
- bug
|
8
|
+
- enhancement
|
9
|
+
- feature request
|
10
|
+
- pending
|
11
|
+
- work_in_progress
|
12
|
+
- v1
|
13
|
+
- v2
|
14
|
+
# Label to use when marking an issue as stale
|
15
|
+
staleLabel: stale
|
16
|
+
# Comment to post when marking an issue as stale. Set to `false` to disable
|
17
|
+
markComment: >
|
18
|
+
This issue has been automatically marked as stale because it has not had
|
19
|
+
recent activity. It will be closed if no further activity occurs. Thank you
|
20
|
+
for your contributions.
|
21
|
+
# Comment to post when closing a stale issue. Set to `false` to disable
|
22
|
+
closeComment: true
|
data/.travis.yml
CHANGED
@@ -9,44 +9,63 @@ matrix:
|
|
9
9
|
include:
|
10
10
|
- rvm: 2.4.9
|
11
11
|
os: linux
|
12
|
+
env: USE_CAPNG=false
|
12
13
|
- rvm: 2.4.9
|
13
14
|
os: linux-ppc64le
|
15
|
+
env: USE_CAPNG=false
|
14
16
|
- rvm: 2.5.7
|
15
17
|
os: linux
|
18
|
+
env: USE_CAPNG=false
|
16
19
|
- rvm: 2.5.7
|
17
20
|
os: linux
|
18
21
|
arch: s390x
|
19
22
|
dist: xenial
|
23
|
+
env: USE_CAPNG=false
|
20
24
|
- rvm: 2.6.5
|
21
25
|
os: linux
|
26
|
+
env: USE_CAPNG=false
|
27
|
+
- rvm: 2.6.6
|
28
|
+
os: linux
|
29
|
+
env: USE_CAPNG=true
|
22
30
|
- rvm: 2.7.0
|
23
31
|
os: linux
|
32
|
+
env: USE_CAPNG=false
|
24
33
|
- rvm: ruby-head
|
25
34
|
os: linux
|
35
|
+
env: USE_CAPNG=false
|
26
36
|
- rvm: ruby-head
|
27
37
|
os: linux-ppc64le
|
38
|
+
env: USE_CAPNG=false
|
28
39
|
- rvm: 2.4.6
|
29
40
|
os: osx
|
30
41
|
osx_image: xcode8.3 # OSX 10.12
|
42
|
+
env: USE_CAPNG=false
|
31
43
|
- rvm: ruby-head
|
32
44
|
os: osx
|
33
45
|
osx_image: xcode8.3 # OSX 10.12
|
46
|
+
env: USE_CAPNG=false
|
34
47
|
allow_failures:
|
35
48
|
- rvm: 2.4.6
|
36
49
|
os: osx
|
37
50
|
osx_image: xcode8.3
|
51
|
+
env: USE_CAPNG=false
|
38
52
|
- rvm: 2.5.7
|
39
53
|
os: linux
|
40
54
|
arch: s390x
|
41
55
|
dist: xenial
|
56
|
+
env: USE_CAPNG=false
|
42
57
|
- rvm: ruby-head
|
58
|
+
env: USE_CAPNG=false
|
43
59
|
|
44
60
|
branches:
|
45
61
|
only:
|
46
62
|
- master
|
47
63
|
|
48
|
-
before_install:
|
49
|
-
|
64
|
+
before_install: |
|
65
|
+
gem update --system=3.1.2
|
66
|
+
if [[ x"${USE_CAPNG}" == "xtrue" ]]; then
|
67
|
+
echo 'gem "capng_c"' >> Gemfile.local
|
68
|
+
fi
|
50
69
|
|
51
70
|
sudo: false
|
52
71
|
dist: trusty # for TLSv1.2 support
|
@@ -55,3 +74,4 @@ addons:
|
|
55
74
|
apt:
|
56
75
|
packages:
|
57
76
|
- libgmp3-dev
|
77
|
+
- libcap-ng-dev
|
data/CHANGELOG.md
CHANGED
data/appveyor.yml
CHANGED
@@ -7,6 +7,9 @@ install:
|
|
7
7
|
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
|
8
8
|
- ruby --version
|
9
9
|
- gem --version
|
10
|
+
# stay 0.14.0 for Windows CI until https://github.com/socketry/protocol-http2/issues/6 will be fixed
|
11
|
+
- ps: Write-Output "gem 'protocol-http2', ['<= 0.14.0']" | Out-File -FilePath Gemfile.local -Encoding default
|
12
|
+
- type Gemfile.local
|
10
13
|
- ridk.cmd exec bundle install
|
11
14
|
build: off
|
12
15
|
test_script:
|
data/bin/fluent-cap-ctl
ADDED
data/fluentd.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
|
19
19
|
gem.required_ruby_version = '>= 2.4'
|
20
20
|
|
21
|
+
gem.add_runtime_dependency("bundler")
|
21
22
|
gem.add_runtime_dependency("msgpack", [">= 1.3.1", "< 2.0.0"])
|
22
23
|
gem.add_runtime_dependency("yajl-ruby", ["~> 1.0"])
|
23
24
|
gem.add_runtime_dependency("cool.io", [">= 1.4.5", "< 2.0.0"])
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#
|
2
|
+
# Fluent
|
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/env"
|
18
|
+
|
19
|
+
if Fluent.linux?
|
20
|
+
begin
|
21
|
+
require 'capng'
|
22
|
+
rescue LoadError
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Fluent
|
27
|
+
if defined?(CapNG)
|
28
|
+
class Capability
|
29
|
+
def initialize(target = nil, pid = nil)
|
30
|
+
@capng = CapNG.new(target, pid)
|
31
|
+
end
|
32
|
+
|
33
|
+
def usable?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def apply(select_set)
|
38
|
+
@capng.apply(select_set)
|
39
|
+
end
|
40
|
+
|
41
|
+
def clear(select_set)
|
42
|
+
@capng.clear(select_set)
|
43
|
+
end
|
44
|
+
|
45
|
+
def have_capability?(type, capability)
|
46
|
+
@capng.have_capability?(type, capability)
|
47
|
+
end
|
48
|
+
|
49
|
+
def update(action, type, capability_or_capability_array)
|
50
|
+
@capng.update(action, type, capability_or_capability_array)
|
51
|
+
end
|
52
|
+
|
53
|
+
def have_capabilities?(select_set)
|
54
|
+
@capng.have_capabilities?(select_set)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
else
|
58
|
+
class Capability
|
59
|
+
def initialize(target = nil, pid = nil)
|
60
|
+
end
|
61
|
+
|
62
|
+
def usable?
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
66
|
+
def apply(select_set)
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
70
|
+
def clear(select_set)
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
def have_capability?(type, capability)
|
75
|
+
false
|
76
|
+
end
|
77
|
+
|
78
|
+
def update(action, type, capability_or_capability_array)
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
def have_capabilities?(select_set)
|
83
|
+
false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,174 @@
|
|
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 'optparse'
|
18
|
+
require 'fluent/log'
|
19
|
+
require 'fluent/env'
|
20
|
+
require 'fluent/capability'
|
21
|
+
|
22
|
+
module Fluent
|
23
|
+
class CapCtl
|
24
|
+
def prepare_option_parser
|
25
|
+
@op = OptionParser.new
|
26
|
+
|
27
|
+
@op.on('--clear', "Clear Fluentd Ruby capability") {|s|
|
28
|
+
@opts[:clear_capabilities] = true
|
29
|
+
}
|
30
|
+
|
31
|
+
@op.on('--add [CAPABILITITY1,CAPABILITY2, ...]', "Add capabilities into Fluentd Ruby") {|s|
|
32
|
+
@opts[:add_capabilities] = s
|
33
|
+
}
|
34
|
+
|
35
|
+
@op.on('--drop [CAPABILITITY1,CAPABILITY2, ...]', "Drop capabilities from Fluentd Ruby") {|s|
|
36
|
+
@opts[:drop_capabilities] = s
|
37
|
+
}
|
38
|
+
|
39
|
+
@op.on('--get', "Get capabilities for Fluentd Ruby") {|s|
|
40
|
+
@opts[:get_capabilities] = true
|
41
|
+
}
|
42
|
+
|
43
|
+
@op.on('-f', '--file FILE', "Specify target file to add Linux capabilities") {|s|
|
44
|
+
@opts[:target_file] = s
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def usage(msg)
|
49
|
+
puts @op.to_s
|
50
|
+
puts "error: #{msg}" if msg
|
51
|
+
exit 1
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize(argv = ARGV)
|
55
|
+
@opts = {}
|
56
|
+
@argv = argv
|
57
|
+
|
58
|
+
if Fluent.linux?
|
59
|
+
begin
|
60
|
+
require 'capng'
|
61
|
+
|
62
|
+
@capng = CapNG.new
|
63
|
+
rescue LoadError
|
64
|
+
puts "Error: capng_c is not loaded. Please install it first."
|
65
|
+
exit 1
|
66
|
+
end
|
67
|
+
else
|
68
|
+
puts "Error: This environment is not supported."
|
69
|
+
exit 2
|
70
|
+
end
|
71
|
+
|
72
|
+
prepare_option_parser
|
73
|
+
end
|
74
|
+
|
75
|
+
def call
|
76
|
+
parse_options!(@argv)
|
77
|
+
|
78
|
+
target_file = if !!@opts[:target_file]
|
79
|
+
@opts[:target_file]
|
80
|
+
else
|
81
|
+
File.readlink("/proc/self/exe")
|
82
|
+
end
|
83
|
+
|
84
|
+
if @opts[:clear_capabilities]
|
85
|
+
clear_capabilities(@opts, target_file)
|
86
|
+
elsif @opts[:add_capabilities]
|
87
|
+
add_capabilities(@opts, target_file)
|
88
|
+
elsif @opts[:drop_capabilities]
|
89
|
+
drop_capabilities(@opts, target_file)
|
90
|
+
end
|
91
|
+
if @opts[:get_capabilities]
|
92
|
+
get_capabilities(@opts, target_file)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def clear_capabilities(opts, target_file)
|
97
|
+
if !!opts[:clear_capabilities]
|
98
|
+
@capng.clear(:caps)
|
99
|
+
ret = @capng.apply_caps_file(target_file)
|
100
|
+
puts "Clear capabilities #{ret ? 'done' : 'fail'}."
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def add_capabilities(opts, target_file)
|
105
|
+
if add_caps = opts[:add_capabilities]
|
106
|
+
@capng.clear(:caps)
|
107
|
+
@capng.caps_file(target_file)
|
108
|
+
capabilities = add_caps.split(/\s*,\s*/)
|
109
|
+
check_capabilities(capabilities, get_valid_capabilities)
|
110
|
+
ret = @capng.update(:add,
|
111
|
+
CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED,
|
112
|
+
capabilities)
|
113
|
+
puts "Updating #{add_caps} #{ret ? 'done' : 'fail'}."
|
114
|
+
ret = @capng.apply_caps_file(target_file)
|
115
|
+
puts "Adding #{add_caps} #{ret ? 'done' : 'fail'}."
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def drop_capabilities(opts, target_file)
|
120
|
+
if drop_caps = opts[:drop_capabilities]
|
121
|
+
@capng.clear(:caps)
|
122
|
+
@capng.caps_file(target_file)
|
123
|
+
capabilities = drop_caps.split(/\s*,\s*/)
|
124
|
+
check_capabilities(capabilities, get_valid_capabilities)
|
125
|
+
ret = @capng.update(:drop,
|
126
|
+
CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED,
|
127
|
+
capabilities)
|
128
|
+
puts "Updating #{drop_caps} #{ret ? 'done' : 'fail'}."
|
129
|
+
@capng.apply_caps_file(target_file)
|
130
|
+
puts "Dropping #{drop_caps} #{ret ? 'done' : 'fail'}."
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def get_capabilities(opts, target_file)
|
135
|
+
if opts[:get_capabilities]
|
136
|
+
@capng.caps_file(target_file)
|
137
|
+
print = CapNG::Print.new
|
138
|
+
puts "Capabilities in '#{target_file}',"
|
139
|
+
puts "Effective: #{print.caps_text(:buffer, :effective)}"
|
140
|
+
puts "Inheritable: #{print.caps_text(:buffer, :inheritable)}"
|
141
|
+
puts "Permitted: #{print.caps_text(:buffer, :permitted)}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def get_valid_capabilities
|
146
|
+
capabilities = []
|
147
|
+
cap = CapNG::Capability.new
|
148
|
+
cap.each do |_code, capability|
|
149
|
+
capabilities << capability
|
150
|
+
end
|
151
|
+
capabilities
|
152
|
+
end
|
153
|
+
|
154
|
+
def check_capabilities(capabilities, valid_capabilities)
|
155
|
+
capabilities.each do |capability|
|
156
|
+
unless valid_capabilities.include?(capability)
|
157
|
+
raise ArgumentError, "'#{capability}' is not valid capability. Valid Capabilities are: #{valid_capabilities.join(", ")}"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def parse_options!(argv)
|
163
|
+
begin
|
164
|
+
rest = @op.parse(argv)
|
165
|
+
|
166
|
+
if rest.length != 0
|
167
|
+
usage nil
|
168
|
+
end
|
169
|
+
rescue
|
170
|
+
usage $!.to_s
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
data/lib/fluent/env.rb
CHANGED
data/lib/fluent/plugin/buffer.rb
CHANGED
@@ -143,33 +143,14 @@ module Fluent
|
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
-
# timekey should be unixtime as usual.
|
147
|
-
# So, unixtime should be bigger than 2^30 - 1 (= 1073741823) nowadays.
|
148
|
-
# We should check object_id stability to use object_id as optimization for comparing operations.
|
149
|
-
# e.g.)
|
150
|
-
# irb> Time.parse("2020/07/31 18:30:00+09:00").to_i
|
151
|
-
# => 1596187800
|
152
|
-
# irb> Time.parse("2020/07/31 18:30:00+09:00").to_i > 2**30 -1
|
153
|
-
# => true
|
154
|
-
def self.enable_optimize?
|
155
|
-
a1 = 2**30 - 1
|
156
|
-
a2 = 2**30 - 1
|
157
|
-
b1 = 2**62 - 1
|
158
|
-
b2 = 2**62 - 1
|
159
|
-
(a1.object_id == a2.object_id) && (b1.object_id == b2.object_id)
|
160
|
-
end
|
161
|
-
|
162
146
|
# This is an optimization code. Current Struct's implementation is comparing all data.
|
163
147
|
# https://github.com/ruby/ruby/blob/0623e2b7cc621b1733a760b72af246b06c30cf96/struct.c#L1200-L1203
|
164
148
|
# Actually this overhead is very small but this class is generated *per chunk* (and used in hash object).
|
165
149
|
# This means that this class is one of the most called object in Fluentd.
|
166
150
|
# See https://github.com/fluent/fluentd/pull/2560
|
167
|
-
# But, this optimization has a side effect on Windows and 32bit environment(s) due to differing object_id.
|
168
|
-
# This difference causes flood of buffer files.
|
169
|
-
# So, this optimization should be enabled on `enable_optimize?` as true platforms.
|
170
151
|
def hash
|
171
|
-
timekey.
|
172
|
-
end
|
152
|
+
timekey.hash
|
153
|
+
end
|
173
154
|
end
|
174
155
|
|
175
156
|
# for tests
|
@@ -27,7 +27,7 @@ module Fluent
|
|
27
27
|
helpers :record_accessor
|
28
28
|
|
29
29
|
config_param :delimiter, default: ',' do |val|
|
30
|
-
['\t', 'TAB'].include?(val) ? "\t" : val
|
30
|
+
['\t', 'TAB'].include?(val) ? "\t".freeze : val.freeze
|
31
31
|
end
|
32
32
|
config_param :force_quotes, :bool, default: true
|
33
33
|
# "array" looks good for type of :fields, but this implementation removes tailing comma
|
@@ -25,8 +25,8 @@ module Fluent
|
|
25
25
|
|
26
26
|
# http://ltsv.org/
|
27
27
|
|
28
|
-
config_param :delimiter, :string, default: "\t"
|
29
|
-
config_param :label_delimiter, :string, default: ":"
|
28
|
+
config_param :delimiter, :string, default: "\t".freeze
|
29
|
+
config_param :label_delimiter, :string, default: ":".freeze
|
30
30
|
config_param :add_newline, :bool, default: true
|
31
31
|
|
32
32
|
# TODO: escaping for \t in values
|
@@ -36,7 +36,7 @@ module Fluent
|
|
36
36
|
formatted << @delimiter if formatted.length.nonzero?
|
37
37
|
formatted << "#{label}#{@label_delimiter}#{value}"
|
38
38
|
end
|
39
|
-
formatted << @newline
|
39
|
+
formatted << @newline if @add_newline
|
40
40
|
formatted
|
41
41
|
end
|
42
42
|
end
|
@@ -29,9 +29,9 @@ module Fluent
|
|
29
29
|
config_param :output_tag, :bool, default: true
|
30
30
|
config_param :delimiter, default: "\t" do |val|
|
31
31
|
case val
|
32
|
-
when /SPACE/i then ' '
|
33
|
-
when /COMMA/i then ','
|
34
|
-
else "\t"
|
32
|
+
when /SPACE/i then ' '.freeze
|
33
|
+
when /COMMA/i then ','.freeze
|
34
|
+
else "\t".freeze
|
35
35
|
end
|
36
36
|
end
|
37
37
|
config_set_default :time_type, :string
|
@@ -23,12 +23,12 @@ module Fluent
|
|
23
23
|
|
24
24
|
Plugin.register_formatter('single_value', self)
|
25
25
|
|
26
|
-
config_param :message_key, :string, default: 'message'
|
26
|
+
config_param :message_key, :string, default: 'message'.freeze
|
27
27
|
config_param :add_newline, :bool, default: true
|
28
28
|
|
29
29
|
def format(tag, time, record)
|
30
30
|
text = record[@message_key].to_s.dup
|
31
|
-
text << @newline
|
31
|
+
text << @newline if @add_newline
|
32
32
|
text
|
33
33
|
end
|
34
34
|
end
|
@@ -26,13 +26,13 @@ module Fluent
|
|
26
26
|
desc 'Field names included in each lines'
|
27
27
|
config_param :keys, :array, value_type: :string
|
28
28
|
desc 'The delimiter character (or string) of TSV values'
|
29
|
-
config_param :delimiter, :string, default: "\t"
|
29
|
+
config_param :delimiter, :string, default: "\t".freeze
|
30
30
|
desc 'The parameter to enable writing to new lines'
|
31
31
|
config_param :add_newline, :bool, default: true
|
32
32
|
|
33
33
|
def format(tag, time, record)
|
34
34
|
formatted = @keys.map{|k| record[k].to_s }.join(@delimiter)
|
35
|
-
formatted << @newline
|
35
|
+
formatted << @newline if @add_newline
|
36
36
|
formatted
|
37
37
|
end
|
38
38
|
end
|
@@ -22,6 +22,7 @@ require 'fluent/event'
|
|
22
22
|
require 'fluent/plugin/buffer'
|
23
23
|
require 'fluent/plugin/parser_multiline'
|
24
24
|
require 'fluent/variable_store'
|
25
|
+
require 'fluent/capability'
|
25
26
|
require 'fluent/plugin/in_tail/position_file'
|
26
27
|
|
27
28
|
if Fluent.windows?
|
@@ -171,6 +172,7 @@ module Fluent::Plugin
|
|
171
172
|
@dir_perm = system_config.dir_permission || Fluent::DEFAULT_DIR_PERMISSION
|
172
173
|
# parser is already created by parser helper
|
173
174
|
@parser = parser_create(usage: parser_config['usage'] || @parser_configs.first.usage)
|
175
|
+
@capability = Fluent::Capability.new(:current_process)
|
174
176
|
end
|
175
177
|
|
176
178
|
def configure_tag
|
@@ -250,6 +252,11 @@ module Fluent::Plugin
|
|
250
252
|
close_watcher_handles
|
251
253
|
end
|
252
254
|
|
255
|
+
def have_read_capability?
|
256
|
+
@capability.have_capability?(:effective, :dac_read_search) ||
|
257
|
+
@capability.have_capability?(:effective, :dac_override)
|
258
|
+
end
|
259
|
+
|
253
260
|
def expand_paths
|
254
261
|
date = Fluent::EventTime.now
|
255
262
|
paths = []
|
@@ -263,7 +270,7 @@ module Fluent::Plugin
|
|
263
270
|
paths += Dir.glob(path).select { |p|
|
264
271
|
begin
|
265
272
|
is_file = !File.directory?(p)
|
266
|
-
if File.readable?(p) && is_file
|
273
|
+
if (File.readable?(p) || have_read_capability?) && is_file
|
267
274
|
if @limit_recently_modified && File.mtime(p) < (date.to_time - @limit_recently_modified)
|
268
275
|
false
|
269
276
|
else
|
data/lib/fluent/version.rb
CHANGED
@@ -0,0 +1,100 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
require 'fluent/command/cap_ctl'
|
5
|
+
|
6
|
+
class TestFluentCapCtl < Test::Unit::TestCase
|
7
|
+
setup do
|
8
|
+
omit "This environment does not handle Linux capability" unless defined?(CapNG)
|
9
|
+
end
|
10
|
+
|
11
|
+
sub_test_case "success" do
|
12
|
+
test "clear capability" do
|
13
|
+
logs = capture_stdout do
|
14
|
+
Fluent::CapCtl.new(["--clear"]).call
|
15
|
+
end
|
16
|
+
expression = /\AClear capabilities .*\n/m
|
17
|
+
assert_match expression, logs
|
18
|
+
end
|
19
|
+
|
20
|
+
test "add capability" do
|
21
|
+
logs = capture_stdout do
|
22
|
+
Fluent::CapCtl.new(["--add", "dac_override"]).call
|
23
|
+
end
|
24
|
+
expression = /\AUpdating .* done.\nAdding .*\n/m
|
25
|
+
assert_match expression, logs
|
26
|
+
end
|
27
|
+
|
28
|
+
test "drop capability" do
|
29
|
+
logs = capture_stdout do
|
30
|
+
Fluent::CapCtl.new(["--drop", "chown"]).call
|
31
|
+
end
|
32
|
+
expression = /\AUpdating .* done.\nDropping .*\n/m
|
33
|
+
assert_match expression, logs
|
34
|
+
end
|
35
|
+
|
36
|
+
test "get capability" do
|
37
|
+
logs = capture_stdout do
|
38
|
+
Fluent::CapCtl.new(["--get"]).call
|
39
|
+
end
|
40
|
+
expression = /\ACapabilities in .*,\nEffective: .*\nInheritable: .*\nPermitted: .*/m
|
41
|
+
assert_match expression, logs
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
sub_test_case "success with file" do
|
46
|
+
test "clear capability" do
|
47
|
+
logs = capture_stdout do
|
48
|
+
Tempfile.create("fluent-cap-") do |tempfile|
|
49
|
+
Fluent::CapCtl.new(["--clear-cap", "-f", tempfile.path]).call
|
50
|
+
end
|
51
|
+
end
|
52
|
+
expression = /\AClear capabilities .*\n/m
|
53
|
+
assert_match expression, logs
|
54
|
+
end
|
55
|
+
|
56
|
+
test "add capability" do
|
57
|
+
logs = capture_stdout do
|
58
|
+
Tempfile.create("fluent-cap-") do |tempfile|
|
59
|
+
Fluent::CapCtl.new(["--add", "dac_override", "-f", tempfile.path]).call
|
60
|
+
end
|
61
|
+
end
|
62
|
+
expression = /\AUpdating .* done.\nAdding .*\n/m
|
63
|
+
assert_match expression, logs
|
64
|
+
end
|
65
|
+
|
66
|
+
test "drop capability" do
|
67
|
+
logs = capture_stdout do
|
68
|
+
Tempfile.create("fluent-cap-") do |tempfile|
|
69
|
+
Fluent::CapCtl.new(["--drop", "chown", "-f", tempfile.path]).call
|
70
|
+
end
|
71
|
+
end
|
72
|
+
expression = /\AUpdating .* done.\nDropping .*\n/m
|
73
|
+
assert_match expression, logs
|
74
|
+
end
|
75
|
+
|
76
|
+
test "get capability" do
|
77
|
+
logs = capture_stdout do
|
78
|
+
Tempfile.create("fluent-cap-") do |tempfile|
|
79
|
+
Fluent::CapCtl.new(["--get", "-f", tempfile.path]).call
|
80
|
+
end
|
81
|
+
end
|
82
|
+
expression = /\ACapabilities in .*,\nEffective: .*\nInheritable: .*\nPermitted: .*/m
|
83
|
+
assert_match expression, logs
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
sub_test_case "invalid" do
|
88
|
+
test "add capability" do
|
89
|
+
assert_raise(ArgumentError) do
|
90
|
+
Fluent::CapCtl.new(["--add", "nonexitent"]).call
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
test "drop capability" do
|
95
|
+
assert_raise(ArgumentError) do
|
96
|
+
Fluent::CapCtl.new(["--drop", "invalid"]).call
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/test/plugin/test_in_tail.rb
CHANGED
@@ -86,6 +86,9 @@ class TailInputTest < Test::Unit::TestCase
|
|
86
86
|
assert_equal "#{TMP_DIR}/tail.pos", d.instance.pos_file
|
87
87
|
assert_equal 1000, d.instance.read_lines_limit
|
88
88
|
assert_equal false, d.instance.ignore_repeated_permission_error
|
89
|
+
assert_nothing_raised do
|
90
|
+
d.instance.have_read_capability?
|
91
|
+
end
|
89
92
|
end
|
90
93
|
|
91
94
|
data("empty" => config_element,
|
@@ -229,7 +232,7 @@ class TailInputTest < Test::Unit::TestCase
|
|
229
232
|
d = create_driver(config)
|
230
233
|
msg = 'test' * 2000 # in_tail reads 8192 bytes at once.
|
231
234
|
|
232
|
-
d.run(expect_emits: num_events, timeout:
|
235
|
+
d.run(expect_emits: num_events, timeout: 2) do
|
233
236
|
File.open("#{TMP_DIR}/tail.txt", "ab") {|f|
|
234
237
|
f.puts msg
|
235
238
|
f.puts msg
|
@@ -1112,6 +1115,49 @@ class TailInputTest < Test::Unit::TestCase
|
|
1112
1115
|
end
|
1113
1116
|
end
|
1114
1117
|
|
1118
|
+
sub_test_case "path w/ Linux capability" do
|
1119
|
+
def capability_enabled?
|
1120
|
+
if Fluent.linux?
|
1121
|
+
begin
|
1122
|
+
require 'capng'
|
1123
|
+
true
|
1124
|
+
rescue LoadError
|
1125
|
+
false
|
1126
|
+
end
|
1127
|
+
else
|
1128
|
+
false
|
1129
|
+
end
|
1130
|
+
end
|
1131
|
+
|
1132
|
+
setup do
|
1133
|
+
omit "This environment is not enabled Linux capability handling feature" unless capability_enabled?
|
1134
|
+
|
1135
|
+
@capng = CapNG.new(:current_process)
|
1136
|
+
flexstub(Fluent::Capability) do |klass|
|
1137
|
+
klass.should_receive(:new).with(:current_process).and_return(@capng)
|
1138
|
+
end
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
data("dac_read_search" => [:dac_read_search, true, 1],
|
1142
|
+
"dac_override" => [:dac_override, true, 1],
|
1143
|
+
"chown" => [:chown, false, 0],
|
1144
|
+
)
|
1145
|
+
test "with partially elevated privileges" do |data|
|
1146
|
+
cap, result, readable_paths = data
|
1147
|
+
@capng.update(:add, :effective, cap)
|
1148
|
+
|
1149
|
+
d = create_driver(
|
1150
|
+
config_element("ROOT", "", {
|
1151
|
+
"path" => "/var/log/ker*.log", # Use /var/log/kern.log
|
1152
|
+
"tag" => "t1",
|
1153
|
+
"rotate_wait" => "2s"
|
1154
|
+
}) + PARSE_SINGLE_LINE_CONFIG, false)
|
1155
|
+
|
1156
|
+
assert_equal readable_paths, d.instance.expand_paths.length
|
1157
|
+
assert_equal result, d.instance.have_read_capability?
|
1158
|
+
end
|
1159
|
+
end
|
1160
|
+
|
1115
1161
|
def test_pos_file_dir_creation
|
1116
1162
|
config = config_element("", "", {
|
1117
1163
|
"tag" => "tail",
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'fluent/test'
|
3
|
+
require 'fluent/capability'
|
4
|
+
|
5
|
+
class FluentCapabilityTest < ::Test::Unit::TestCase
|
6
|
+
setup do
|
7
|
+
@capability = Fluent::Capability.new(:current_process)
|
8
|
+
omit "Fluent::Capability class is not usable on this environment" unless @capability.usable?
|
9
|
+
end
|
10
|
+
|
11
|
+
sub_test_case "check capability" do
|
12
|
+
test "effective" do
|
13
|
+
@capability.clear(:both)
|
14
|
+
assert_true @capability.update(:add, :effective, :dac_read_search)
|
15
|
+
assert_equal CapNG::Result::PARTIAL, @capability.have_capabilities?(:caps)
|
16
|
+
assert_nothing_raised do
|
17
|
+
@capability.apply(:caps)
|
18
|
+
end
|
19
|
+
assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:bounds)
|
20
|
+
assert_true @capability.have_capability?(:effective, :dac_read_search)
|
21
|
+
assert_false @capability.have_capability?(:inheritable, :dac_read_search)
|
22
|
+
assert_false @capability.have_capability?(:permitted, :dac_read_search)
|
23
|
+
end
|
24
|
+
|
25
|
+
test "inheritable" do
|
26
|
+
@capability.clear(:both)
|
27
|
+
capabilities = [:chown, :dac_override]
|
28
|
+
assert_equal [true, true], @capability.update(:add, :inheritable, capabilities)
|
29
|
+
assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:caps)
|
30
|
+
assert_nothing_raised do
|
31
|
+
@capability.apply(:caps)
|
32
|
+
end
|
33
|
+
assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:bounds)
|
34
|
+
capabilities.each do |capability|
|
35
|
+
assert_false @capability.have_capability?(:effective, capability)
|
36
|
+
assert_true @capability.have_capability?(:inheritable, capability)
|
37
|
+
assert_false @capability.have_capability?(:permitted, capability)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
test "permitted" do
|
42
|
+
@capability.clear(:both)
|
43
|
+
capabilities = [:fowner, :fsetid, :kill]
|
44
|
+
assert_equal [true, true, true], @capability.update(:add, :permitted, capabilities)
|
45
|
+
assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:caps)
|
46
|
+
assert_nothing_raised do
|
47
|
+
@capability.apply(:caps)
|
48
|
+
end
|
49
|
+
assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:bounds)
|
50
|
+
capabilities.each do |capability|
|
51
|
+
assert_false @capability.have_capability?(:effective, capability)
|
52
|
+
assert_false @capability.have_capability?(:inheritable, capability)
|
53
|
+
assert_true @capability.have_capability?(:permitted, capability)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
test "effective/inheritable/permitted" do
|
58
|
+
@capability.clear(:both)
|
59
|
+
capabilities = [:setpcap, :net_admin, :net_raw, :sys_boot, :sys_time]
|
60
|
+
update_type = CapNG::Type::EFFECTIVE | CapNG::Type::INHERITABLE | CapNG::Type::PERMITTED
|
61
|
+
assert_equal [true, true, true, true, true], @capability.update(:add, update_type, capabilities)
|
62
|
+
assert_equal CapNG::Result::PARTIAL, @capability.have_capabilities?(:caps)
|
63
|
+
assert_nothing_raised do
|
64
|
+
@capability.apply(:caps)
|
65
|
+
end
|
66
|
+
assert_equal CapNG::Result::NONE, @capability.have_capabilities?(:bounds)
|
67
|
+
capabilities.each do |capability|
|
68
|
+
assert_true @capability.have_capability?(:effective, capability)
|
69
|
+
assert_true @capability.have_capability?(:inheritable, capability)
|
70
|
+
assert_true @capability.have_capability?(:permitted, capability)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluentd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: msgpack
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -345,6 +359,7 @@ email:
|
|
345
359
|
executables:
|
346
360
|
- fluent-binlog-reader
|
347
361
|
- fluent-ca-generate
|
362
|
+
- fluent-cap-ctl
|
348
363
|
- fluent-cat
|
349
364
|
- fluent-debug
|
350
365
|
- fluent-gem
|
@@ -359,6 +374,7 @@ files:
|
|
359
374
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
360
375
|
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
361
376
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
377
|
+
- ".github/stale.yml"
|
362
378
|
- ".github/workflows/issue-auto-closer.yml"
|
363
379
|
- ".gitignore"
|
364
380
|
- ".gitlab-ci.yml"
|
@@ -377,6 +393,7 @@ files:
|
|
377
393
|
- appveyor.yml
|
378
394
|
- bin/fluent-binlog-reader
|
379
395
|
- bin/fluent-ca-generate
|
396
|
+
- bin/fluent-cap-ctl
|
380
397
|
- bin/fluent-cat
|
381
398
|
- bin/fluent-debug
|
382
399
|
- bin/fluent-gem
|
@@ -425,10 +442,12 @@ files:
|
|
425
442
|
- fluent.conf
|
426
443
|
- fluentd.gemspec
|
427
444
|
- lib/fluent/agent.rb
|
445
|
+
- lib/fluent/capability.rb
|
428
446
|
- lib/fluent/clock.rb
|
429
447
|
- lib/fluent/command/binlog_reader.rb
|
430
448
|
- lib/fluent/command/bundler_injection.rb
|
431
449
|
- lib/fluent/command/ca_generate.rb
|
450
|
+
- lib/fluent/command/cap_ctl.rb
|
432
451
|
- lib/fluent/command/cat.rb
|
433
452
|
- lib/fluent/command/debug.rb
|
434
453
|
- lib/fluent/command/fluentd.rb
|
@@ -675,6 +694,7 @@ files:
|
|
675
694
|
- templates/plugin_config_formatter/section.md.erb
|
676
695
|
- test/command/test_binlog_reader.rb
|
677
696
|
- test/command/test_ca_generate.rb
|
697
|
+
- test/command/test_cap_ctl.rb
|
678
698
|
- test/command/test_fluentd.rb
|
679
699
|
- test/command/test_plugin_config_formatter.rb
|
680
700
|
- test/command/test_plugin_generator.rb
|
@@ -851,6 +871,7 @@ files:
|
|
851
871
|
- test/scripts/fluent/plugin/out_test.rb
|
852
872
|
- test/scripts/fluent/plugin/out_test2.rb
|
853
873
|
- test/scripts/fluent/plugin/parser_known.rb
|
874
|
+
- test/test_capability.rb
|
854
875
|
- test/test_clock.rb
|
855
876
|
- test/test_config.rb
|
856
877
|
- test/test_configdsl.rb
|
@@ -898,9 +919,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
898
919
|
version: '2.4'
|
899
920
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
900
921
|
requirements:
|
901
|
-
- - "
|
922
|
+
- - ">"
|
902
923
|
- !ruby/object:Gem::Version
|
903
|
-
version:
|
924
|
+
version: 1.3.1
|
904
925
|
requirements: []
|
905
926
|
rubygems_version: 3.0.3
|
906
927
|
signing_key:
|
@@ -909,6 +930,7 @@ summary: Fluentd event collector
|
|
909
930
|
test_files:
|
910
931
|
- test/command/test_binlog_reader.rb
|
911
932
|
- test/command/test_ca_generate.rb
|
933
|
+
- test/command/test_cap_ctl.rb
|
912
934
|
- test/command/test_fluentd.rb
|
913
935
|
- test/command/test_plugin_config_formatter.rb
|
914
936
|
- test/command/test_plugin_generator.rb
|
@@ -1085,6 +1107,7 @@ test_files:
|
|
1085
1107
|
- test/scripts/fluent/plugin/out_test.rb
|
1086
1108
|
- test/scripts/fluent/plugin/out_test2.rb
|
1087
1109
|
- test/scripts/fluent/plugin/parser_known.rb
|
1110
|
+
- test/test_capability.rb
|
1088
1111
|
- test/test_clock.rb
|
1089
1112
|
- test/test_config.rb
|
1090
1113
|
- test/test_configdsl.rb
|