logstash-core 5.6.12-java → 5.6.13-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash/instrument/periodic_poller/cgroup.rb +168 -85
- data/spec/logstash/instrument/periodic_poller/cgroup_spec.rb +225 -92
- data/spec/logstash/instrument/periodic_poller/os_spec.rb +29 -32
- data/versions-gem-copy.yml +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1fb7d5d2430aacfe5c50b4e058e1effe78df4be
|
4
|
+
data.tar.gz: 76e166dcf3df950e09ea92caa305077dbd55ef99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c357ba17c5cc8ccc9bc24a13edc8e383d68e1628991df92b1737bbe1ee5ea943876d707fcefe5bf9d62876afcc1e286b00601121b4a9cf2634410613b9a2a33a
|
7
|
+
data.tar.gz: 14201e4fc149d68cbe374c047a91216f9a9a200a9e0885c1f3958343ab700f20e0ba163572f9dd732e7dbf25e1ca39d68cc99d1a35b1fd1040fc257ef9044541
|
Binary file
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require "pathname"
|
3
2
|
require "logstash/util/loggable"
|
4
3
|
|
5
4
|
# Logic from elasticsearch/core/src/main/java/org/elasticsearch/monitor/os/OsProbe.java
|
@@ -7,130 +6,214 @@ require "logstash/util/loggable"
|
|
7
6
|
module LogStash module Instrument module PeriodicPoller
|
8
7
|
class Cgroup
|
9
8
|
include LogStash::Util::Loggable
|
9
|
+
class Override
|
10
|
+
attr_reader :key, :value
|
11
|
+
def initialize(key)
|
12
|
+
@key = key
|
13
|
+
@value = java.lang.System.getProperty(@key)
|
14
|
+
end
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
PROC_SELF_CGROUP_FILE = Pathname.new("/proc/self/cgroup")
|
15
|
-
PROC_CGROUP_CPU_DIR = Pathname.new("/sys/fs/cgroup/cpu")
|
16
|
-
PROC_CGROUP_CPUACCT_DIR = Pathname.new("/sys/fs/cgroup/cpuacct")
|
17
|
-
|
18
|
-
GROUP_CPUACCT = "cpuacct"
|
19
|
-
CPUACCT_USAGE_FILE = "cpuacct.usage"
|
20
|
-
|
21
|
-
GROUP_CPU = "cpu"
|
22
|
-
CPU_FS_PERIOD_US_FILE = "cpu.cfs_period_us"
|
23
|
-
CPU_FS_QUOTA_US_FILE = "cpu.cfs_quota_us"
|
16
|
+
def nil?
|
17
|
+
value.nil?
|
18
|
+
end
|
24
19
|
|
25
|
-
|
20
|
+
def override(other)
|
21
|
+
nil? ? other : value
|
22
|
+
end
|
23
|
+
end
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
## `/proc/self/cgroup` contents look like this
|
26
|
+
# 5:cpu,cpuacct:/
|
27
|
+
# 4:cpuset:/
|
28
|
+
# 2:net_cls,net_prio:/
|
29
|
+
# 0::/user.slice/user-1000.slice/session-932.scope
|
30
|
+
## e.g. N:controller:/path-to-info
|
31
|
+
# we find the controller and path
|
32
|
+
# we skip the line without a controller e.g. 0::/path
|
33
|
+
# we assume there are these symlinks:
|
34
|
+
# `/sys/fs/cgroup/cpu` -> `/sys/fs/cgroup/cpu,cpuacct
|
35
|
+
# `/sys/fs/cgroup/cpuacct` -> `/sys/fs/cgroup/cpu,cpuacct
|
36
|
+
|
37
|
+
CGROUP_FILE = "/proc/self/cgroup"
|
38
|
+
CPUACCT_DIR = "/sys/fs/cgroup/cpuacct"
|
39
|
+
CPU_DIR = "/sys/fs/cgroup/cpu"
|
40
|
+
CRITICAL_PATHS = [CGROUP_FILE, CPUACCT_DIR, CPU_DIR]
|
41
|
+
|
42
|
+
CONTROLLER_CPUACCT_LABEL = "cpuacct"
|
43
|
+
CONTROLLER_CPU_LABEL = "cpu"
|
44
|
+
|
45
|
+
class CGroupResources
|
46
|
+
CONTROL_GROUP_RE = Regexp.compile("\\d+:([^:,]+(?:,[^:,]+)?):(/.*)")
|
47
|
+
CONTROLLER_SEPARATOR_RE = ","
|
48
|
+
|
49
|
+
def cgroup_available?
|
50
|
+
# don't cache to ivar, in case the files are mounted after logstash starts??
|
51
|
+
CRITICAL_PATHS.all?{|path| ::File.exist?(path)}
|
32
52
|
end
|
33
53
|
|
34
|
-
def
|
54
|
+
def controller_groups
|
35
55
|
response = {}
|
36
|
-
|
37
|
-
read_proc_self_cgroup_lines.each do |line|
|
56
|
+
IO.readlines(CGROUP_FILE).each do |line|
|
38
57
|
matches = CONTROL_GROUP_RE.match(line)
|
58
|
+
next if matches.nil?
|
39
59
|
# multiples controls, same hierarchy
|
40
60
|
controllers = matches[1].split(CONTROLLER_SEPARATOR_RE)
|
41
|
-
controllers.
|
61
|
+
controllers.each do |controller|
|
62
|
+
case controller
|
63
|
+
when CONTROLLER_CPU_LABEL
|
64
|
+
response[controller] = CpuResource.new(matches[2])
|
65
|
+
when CONTROLLER_CPUACCT_LABEL
|
66
|
+
response[controller] = CpuAcctResource.new(matches[2])
|
67
|
+
else
|
68
|
+
response[controller] = UnimplementedResource.new(controller, matches[2])
|
69
|
+
end
|
70
|
+
end
|
42
71
|
end
|
43
|
-
|
44
72
|
response
|
45
73
|
end
|
74
|
+
end
|
46
75
|
|
47
|
-
|
48
|
-
|
76
|
+
module ControllerResource
|
77
|
+
attr_reader :base_path, :override, :offset_path
|
78
|
+
def implemented?
|
79
|
+
true
|
49
80
|
end
|
50
|
-
|
51
|
-
def
|
52
|
-
|
81
|
+
private
|
82
|
+
def common_initialize(base, override_key, original_path)
|
83
|
+
@base_path = base
|
84
|
+
# override is needed here for the logging statements
|
85
|
+
@override = Override.new(override_key)
|
86
|
+
@offset_path = @override.override(original_path)
|
87
|
+
@procs = {}
|
88
|
+
@procs[:read_int] = lambda {|path| IO.readlines(path).first.to_i }
|
89
|
+
@procs[:read_lines] = lambda {|path| IO.readlines(path) }
|
53
90
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
91
|
+
def call_if_file_exists(call_key, file, not_found_value)
|
92
|
+
path = ::File.join(@base_path, @offset_path, file)
|
93
|
+
if ::File.exist?(path)
|
94
|
+
@procs[call_key].call(path)
|
95
|
+
else
|
96
|
+
message = "File #{path} cannot be found, "
|
97
|
+
if override.nil?
|
98
|
+
message.concat("try providing an override '#{override.key}' in the Logstash JAVA_OPTS environment variable")
|
99
|
+
else
|
100
|
+
message.concat("even though the '#{override.key}' override is: '#{override.value}'")
|
101
|
+
end
|
102
|
+
logger.debug(message)
|
103
|
+
not_found_value
|
104
|
+
end
|
57
105
|
end
|
106
|
+
end
|
58
107
|
|
59
|
-
|
60
|
-
|
108
|
+
class CpuAcctResource
|
109
|
+
include LogStash::Util::Loggable
|
110
|
+
include ControllerResource
|
111
|
+
def initialize(original_path)
|
112
|
+
common_initialize(CPUACCT_DIR, "ls.cgroup.cpuacct.path.override", original_path)
|
61
113
|
end
|
62
|
-
|
63
|
-
|
64
|
-
IO.readlines(PROC_SELF_CGROUP_FILE)
|
114
|
+
def to_hash
|
115
|
+
{:control_group => offset_path, :usage_nanos => cpuacct_usage}
|
65
116
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
def initialize(number_of_elapsed_periods, number_of_times_throttled, time_throttled_nanos)
|
71
|
-
@number_of_elapsed_periods = number_of_elapsed_periods
|
72
|
-
@number_of_times_throttled = number_of_times_throttled
|
73
|
-
@time_throttled_nanos = time_throttled_nanos
|
74
|
-
end
|
117
|
+
private
|
118
|
+
def cpuacct_usage
|
119
|
+
call_if_file_exists(:read_int, "cpuacct.usage", -1)
|
75
120
|
end
|
121
|
+
end
|
76
122
|
|
77
|
-
|
78
|
-
|
123
|
+
class CpuResource
|
124
|
+
include LogStash::Util::Loggable
|
125
|
+
include ControllerResource
|
126
|
+
def initialize(original_path)
|
127
|
+
common_initialize(CPU_DIR, "ls.cgroup.cpu.path.override", original_path)
|
79
128
|
end
|
129
|
+
def to_hash
|
130
|
+
{
|
131
|
+
:control_group => offset_path,
|
132
|
+
:cfs_period_micros => cfs_period_us,
|
133
|
+
:cfs_quota_micros => cfs_quota_us,
|
134
|
+
:stat => build_cpu_stats_hash
|
135
|
+
}
|
136
|
+
end
|
137
|
+
private
|
138
|
+
def cfs_period_us
|
139
|
+
call_if_file_exists(:read_int, "cpu.cfs_period_us", -1)
|
140
|
+
end
|
141
|
+
def cfs_quota_us
|
142
|
+
call_if_file_exists(:read_int, "cpu.cfs_quota_us", -1)
|
143
|
+
end
|
144
|
+
def build_cpu_stats_hash
|
145
|
+
stats = CpuStats.new
|
146
|
+
lines = call_if_file_exists(:read_lines, "cpu.stat", [])
|
147
|
+
stats.update(lines)
|
148
|
+
stats.to_hash
|
149
|
+
end
|
150
|
+
end
|
80
151
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
152
|
+
class UnimplementedResource
|
153
|
+
attr_reader :controller, :original_path
|
154
|
+
def initialize(controller, original_path)
|
155
|
+
@controller, @original_path = controller, original_path
|
156
|
+
end
|
157
|
+
def implemented?
|
158
|
+
false
|
159
|
+
end
|
160
|
+
end
|
87
161
|
|
162
|
+
class CpuStats
|
163
|
+
def initialize
|
164
|
+
@number_of_elapsed_periods = -1
|
165
|
+
@number_of_times_throttled = -1
|
166
|
+
@time_throttled_nanos = -1
|
167
|
+
end
|
168
|
+
def update(lines)
|
88
169
|
lines.each do |line|
|
89
170
|
fields = line.split(/\s+/)
|
171
|
+
next unless fields.size > 1
|
90
172
|
case fields.first
|
91
|
-
when "nr_periods" then number_of_elapsed_periods = fields[1].to_i
|
92
|
-
when "nr_throttled" then number_of_times_throttled= fields[1].to_i
|
93
|
-
when "throttled_time" then time_throttled_nanos = fields[1].to_i
|
173
|
+
when "nr_periods" then @number_of_elapsed_periods = fields[1].to_i
|
174
|
+
when "nr_throttled" then @number_of_times_throttled = fields[1].to_i
|
175
|
+
when "throttled_time" then @time_throttled_nanos = fields[1].to_i
|
94
176
|
end
|
95
177
|
end
|
96
|
-
|
97
|
-
CpuStats.new(number_of_elapsed_periods, number_of_times_throttled, time_throttled_nanos)
|
98
178
|
end
|
179
|
+
def to_hash
|
180
|
+
{
|
181
|
+
:number_of_elapsed_periods => @number_of_elapsed_periods,
|
182
|
+
:number_of_times_throttled => @number_of_times_throttled,
|
183
|
+
:time_throttled_nanos => @time_throttled_nanos
|
184
|
+
}
|
185
|
+
end
|
186
|
+
end
|
99
187
|
|
100
|
-
|
101
|
-
groups = control_groups
|
102
|
-
return if groups.empty?
|
103
|
-
|
104
|
-
cgroups_stats = {
|
105
|
-
:cpuacct => {},
|
106
|
-
:cpu => {}
|
107
|
-
}
|
108
|
-
|
109
|
-
cpuacct_group = groups[GROUP_CPUACCT]
|
110
|
-
cgroups_stats[:cpuacct][:control_group] = cpuacct_group
|
111
|
-
cgroups_stats[:cpuacct][:usage_nanos] = cgroup_cpuacct_usage_nanos(cpuacct_group)
|
188
|
+
CGROUP_RESOURCES = CGroupResources.new
|
112
189
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
190
|
+
class << self
|
191
|
+
def get_all
|
192
|
+
unless CGROUP_RESOURCES.cgroup_available?
|
193
|
+
logger.debug("One or more required cgroup files or directories not found: #{CRITICAL_PATHS.join(', ')}")
|
194
|
+
return
|
195
|
+
end
|
117
196
|
|
118
|
-
|
197
|
+
groups = CGROUP_RESOURCES.controller_groups
|
119
198
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
}
|
199
|
+
if groups.empty?
|
200
|
+
logger.debug("The main cgroup file did not have any controllers: #{CGROUP_FILE}")
|
201
|
+
return
|
202
|
+
end
|
125
203
|
|
126
|
-
|
204
|
+
cgroups_stats = {}
|
205
|
+
groups.each do |name, controller|
|
206
|
+
next unless controller.implemented?
|
207
|
+
cgroups_stats[name.to_sym] = controller.to_hash
|
208
|
+
end
|
209
|
+
cgroups_stats
|
127
210
|
rescue => e
|
128
|
-
logger.debug("Error, cannot retrieve cgroups information", :exception => e.class.name, :message => e.message) if logger.debug?
|
211
|
+
logger.debug("Error, cannot retrieve cgroups information", :exception => e.class.name, :message => e.message, :backtrace => e.backtrace.take(4)) if logger.debug?
|
129
212
|
nil
|
130
213
|
end
|
131
214
|
|
132
215
|
def get
|
133
|
-
|
216
|
+
get_all
|
134
217
|
end
|
135
218
|
end
|
136
219
|
end
|
@@ -2,127 +2,258 @@
|
|
2
2
|
require "logstash/instrument/periodic_poller/cgroup"
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
|
6
|
-
subject { described_class }
|
5
|
+
LogStash::Logging::Logger::configure_logging("DEBUG")
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
module LogStash module Instrument module PeriodicPoller
|
8
|
+
describe "cgroup stats" do
|
9
|
+
let(:relative_path) { "/docker/a1f61" }
|
10
|
+
let(:proc_self_cgroup_content) do
|
11
|
+
%W(14:name=systemd,holaunlimited:#{relative_path}
|
12
|
+
13:pids:#{relative_path}
|
13
|
+
12:hugetlb:#{relative_path}
|
14
|
+
11:net_prio:#{relative_path}
|
15
|
+
10:perf_event:#{relative_path}
|
16
|
+
9:net_cls:#{relative_path}
|
17
|
+
8:freezer:#{relative_path}
|
18
|
+
7:devices:#{relative_path}
|
19
|
+
6:memory:#{relative_path}
|
20
|
+
5:blkio:#{relative_path}
|
21
|
+
4:cpuacct:#{relative_path}
|
22
|
+
3:cpu:#{relative_path}
|
23
|
+
2:cpuset:#{relative_path}
|
24
|
+
1:name=openrc:/docker
|
25
|
+
0::/docker)
|
26
|
+
end
|
27
|
+
describe Cgroup::CGroupResources do
|
28
|
+
subject(:cgroup_resources) { described_class.new }
|
29
|
+
context "method: cgroup_available?" do
|
30
|
+
context "resources exist" do
|
31
|
+
before do
|
32
|
+
allow(::File).to receive(:exist?).and_return(true)
|
33
|
+
end
|
34
|
+
it "returns true" do
|
35
|
+
expect(cgroup_resources.cgroup_available?).to be_truthy
|
36
|
+
end
|
37
|
+
end
|
38
|
+
context "resources do not exist" do
|
39
|
+
subject { described_class.new }
|
40
|
+
before do
|
41
|
+
allow(::File).to receive(:exist?).and_return(true)
|
42
|
+
allow(::File).to receive(:exist?).with("/proc/self/cgroup").and_return(false)
|
43
|
+
end
|
44
|
+
it "returns false" do
|
45
|
+
expect(cgroup_resources.cgroup_available?).to be_falsey
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "method: controller_groups" do
|
10
51
|
before do
|
11
|
-
allow(
|
12
|
-
allow(::Dir).to receive(:exist?).with(subject::PROC_CGROUP_CPU_DIR).and_return(true)
|
13
|
-
allow(::Dir).to receive(:exist?).with(subject::PROC_CGROUP_CPUACCT_DIR).and_return(true)
|
52
|
+
allow(IO).to receive(:readlines).with("/proc/self/cgroup").and_return(proc_self_cgroup_content)
|
14
53
|
end
|
15
54
|
|
16
|
-
it "returns
|
17
|
-
|
55
|
+
it "returns the control groups" do
|
56
|
+
controllers = cgroup_resources.controller_groups
|
57
|
+
|
58
|
+
controller = controllers["cpuacct"]
|
59
|
+
expect(controller).to be_a(Cgroup::CpuAcctResource)
|
60
|
+
expect(controller.base_path).to eq("/sys/fs/cgroup/cpuacct")
|
61
|
+
expect(controller.offset_path).to eq(relative_path)
|
62
|
+
expect(controller.override).to be_a(Cgroup::Override)
|
63
|
+
expect(controller.override.nil?).to be_truthy
|
64
|
+
|
65
|
+
controller = controllers["cpu"]
|
66
|
+
expect(controller).to be_a(Cgroup::CpuResource)
|
67
|
+
expect(controller.base_path).to eq("/sys/fs/cgroup/cpu")
|
68
|
+
expect(controller.offset_path).to eq(relative_path)
|
69
|
+
expect(controller.override).to be_a(Cgroup::Override)
|
70
|
+
expect(controller.override.nil?).to be_truthy
|
71
|
+
|
72
|
+
controller = controllers["name=systemd"]
|
73
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
74
|
+
expect(controller.controller).to eq("name=systemd")
|
75
|
+
expect(controller.original_path).to eq(relative_path)
|
76
|
+
|
77
|
+
controller = controllers["holaunlimited"]
|
78
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
79
|
+
expect(controller.controller).to eq("holaunlimited")
|
80
|
+
expect(controller.original_path).to eq(relative_path)
|
81
|
+
|
82
|
+
controller = controllers["pids"]
|
83
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
84
|
+
expect(controller.controller).to eq("pids")
|
85
|
+
expect(controller.original_path).to eq(relative_path)
|
86
|
+
|
87
|
+
controller = controllers["hugetlb"]
|
88
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
89
|
+
expect(controller.controller).to eq("hugetlb")
|
90
|
+
expect(controller.original_path).to eq(relative_path)
|
91
|
+
|
92
|
+
controller = controllers["net_prio"]
|
93
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
94
|
+
expect(controller.controller).to eq("net_prio")
|
95
|
+
expect(controller.original_path).to eq(relative_path)
|
96
|
+
|
97
|
+
controller = controllers["perf_event"]
|
98
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
99
|
+
expect(controller.controller).to eq("perf_event")
|
100
|
+
expect(controller.original_path).to eq(relative_path)
|
101
|
+
|
102
|
+
controller = controllers["net_cls"]
|
103
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
104
|
+
expect(controller.controller).to eq("net_cls")
|
105
|
+
expect(controller.original_path).to eq(relative_path)
|
106
|
+
|
107
|
+
controller = controllers["freezer"]
|
108
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
109
|
+
expect(controller.controller).to eq("freezer")
|
110
|
+
expect(controller.original_path).to eq(relative_path)
|
111
|
+
|
112
|
+
controller = controllers["devices"]
|
113
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
114
|
+
expect(controller.controller).to eq("devices")
|
115
|
+
expect(controller.original_path).to eq(relative_path)
|
116
|
+
|
117
|
+
controller = controllers["memory"]
|
118
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
119
|
+
expect(controller.controller).to eq("memory")
|
120
|
+
expect(controller.original_path).to eq(relative_path)
|
121
|
+
|
122
|
+
controller = controllers["blkio"]
|
123
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
124
|
+
expect(controller.controller).to eq("blkio")
|
125
|
+
expect(controller.original_path).to eq(relative_path)
|
126
|
+
|
127
|
+
controller = controllers["cpuset"]
|
128
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
129
|
+
expect(controller.controller).to eq("cpuset")
|
130
|
+
expect(controller.original_path).to eq(relative_path)
|
131
|
+
|
132
|
+
controller = controllers["name=openrc"]
|
133
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
134
|
+
expect(controller.controller).to eq("name=openrc")
|
135
|
+
expect(controller.original_path).to eq("/docker")
|
18
136
|
end
|
19
137
|
end
|
20
138
|
|
21
|
-
context "
|
139
|
+
context "method: controller_groups with override" do
|
22
140
|
before do
|
23
|
-
|
24
|
-
|
25
|
-
allow(
|
141
|
+
java.lang.System.setProperty("ls.cgroup.cpu.path.override", "/foo")
|
142
|
+
java.lang.System.setProperty("ls.cgroup.cpuacct.path.override", "/bar")
|
143
|
+
allow(IO).to receive(:readlines).with("/proc/self/cgroup").and_return(proc_self_cgroup_content)
|
26
144
|
end
|
145
|
+
after do
|
146
|
+
java.lang.System.clearProperty("ls.cgroup.cpu.path.override")
|
147
|
+
java.lang.System.clearProperty("ls.cgroup.cpuacct.path.override")
|
148
|
+
end
|
149
|
+
it "returns overridden control groups" do
|
150
|
+
controllers = cgroup_resources.controller_groups
|
151
|
+
controller = controllers["cpuacct"]
|
152
|
+
expect(controller).to be_a(Cgroup::CpuAcctResource)
|
153
|
+
expect(controller.override.nil?).to be_falsey
|
154
|
+
expect(controller.base_path).to eq("/sys/fs/cgroup/cpuacct")
|
155
|
+
expect(controller.offset_path).to eq("/bar")
|
156
|
+
expect(controller.override).to be_a(Cgroup::Override)
|
157
|
+
|
158
|
+
controller = controllers["cpu"]
|
159
|
+
expect(controller).to be_a(Cgroup::CpuResource)
|
160
|
+
expect(controller.override.nil?).to be_falsey
|
161
|
+
expect(controller.base_path).to eq("/sys/fs/cgroup/cpu")
|
162
|
+
expect(controller.offset_path).to eq("/foo")
|
163
|
+
expect(controller.override).to be_a(Cgroup::Override)
|
27
164
|
|
28
|
-
|
29
|
-
expect(
|
165
|
+
controller = controllers["cpuset"]
|
166
|
+
expect(controller).to be_a(Cgroup::UnimplementedResource)
|
167
|
+
expect(controller.controller).to eq("cpuset")
|
168
|
+
expect(controller.original_path).to eq(relative_path)
|
30
169
|
end
|
31
170
|
end
|
32
171
|
end
|
33
172
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
173
|
+
describe Cgroup::CpuAcctResource do
|
174
|
+
subject(:cpuacct_resource) { described_class.new("/bar") }
|
175
|
+
describe "method: to_hash, without override" do
|
176
|
+
context "when the files cannot be found" do
|
177
|
+
it "fills in the hash with minus one" do
|
178
|
+
expect(cpuacct_resource.base_path).to eq("/sys/fs/cgroup/cpuacct")
|
179
|
+
expect(cpuacct_resource.offset_path).to eq("/bar")
|
180
|
+
expect(cpuacct_resource.to_hash).to eq({:control_group=>"/bar", :usage_nanos=>-1})
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
describe "method: to_hash, with override" do
|
185
|
+
before do
|
186
|
+
java.lang.System.setProperty("ls.cgroup.cpuacct.path.override", "/quux")
|
187
|
+
end
|
188
|
+
after do
|
189
|
+
java.lang.System.clearProperty("ls.cgroup.cpuacct.path.override")
|
190
|
+
end
|
191
|
+
context "when the files cannot be found" do
|
192
|
+
it "fills in the hash with minus one" do
|
193
|
+
expect(cpuacct_resource.base_path).to eq("/sys/fs/cgroup/cpuacct")
|
194
|
+
expect(cpuacct_resource.offset_path).to eq("/quux")
|
195
|
+
expect(cpuacct_resource.to_hash).to eq({:control_group=>"/quux", :usage_nanos=>-1})
|
196
|
+
end
|
197
|
+
end
|
53
198
|
end
|
199
|
+
end
|
54
200
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
"
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
"
|
69
|
-
|
70
|
-
|
71
|
-
"
|
72
|
-
|
201
|
+
describe Cgroup::CpuResource do
|
202
|
+
subject(:cpu_resource) { described_class.new("/bar") }
|
203
|
+
describe "method: fill, without override" do
|
204
|
+
context "when the files cannot be found" do
|
205
|
+
it "fills in the hash with minus one" do
|
206
|
+
expect(cpu_resource.base_path).to eq("/sys/fs/cgroup/cpu")
|
207
|
+
expect(cpu_resource.offset_path).to eq("/bar")
|
208
|
+
expect(cpu_resource.to_hash).to eq({:cfs_period_micros=>-1, :cfs_quota_micros=>-1, :control_group=>"/bar", :stat=>{:number_of_elapsed_periods=>-1, :number_of_times_throttled=>-1, :time_throttled_nanos=>-1}})
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
describe "method: fill, with override" do
|
213
|
+
before do
|
214
|
+
java.lang.System.setProperty("ls.cgroup.cpu.path.override", "/quux")
|
215
|
+
end
|
216
|
+
after do
|
217
|
+
java.lang.System.clearProperty("ls.cgroup.cpu.path.override")
|
218
|
+
end
|
219
|
+
let(:target) { Hash.new }
|
220
|
+
context "when the files cannot be found" do
|
221
|
+
it "fills in the hash with minus one" do
|
222
|
+
expect(cpu_resource.base_path).to eq("/sys/fs/cgroup/cpu")
|
223
|
+
expect(cpu_resource.offset_path).to eq("/quux")
|
224
|
+
expect(cpu_resource.to_hash).to eq({:cfs_period_micros=>-1, :cfs_quota_micros=>-1, :control_group=>"/quux", :stat=>{:number_of_elapsed_periods=>-1, :number_of_times_throttled=>-1, :time_throttled_nanos=>-1}})
|
225
|
+
end
|
226
|
+
end
|
73
227
|
end
|
74
228
|
end
|
75
229
|
|
76
|
-
|
77
|
-
|
78
|
-
let(:cpuacct_control_group) { "/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61" }
|
230
|
+
describe Cgroup do
|
231
|
+
describe "class method: get_all" do
|
79
232
|
let(:cpuacct_usage) { 1982 }
|
80
|
-
let(:cpu_control_group) { "/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61" }
|
81
233
|
let(:cfs_period_micros) { 500 }
|
82
234
|
let(:cfs_quota_micros) { 98 }
|
83
235
|
let(:cpu_stats_number_of_periods) { 1 }
|
84
236
|
let(:cpu_stats_number_of_time_throttled) { 2 }
|
85
237
|
let(:cpu_stats_time_throttled_nanos) { 3 }
|
86
|
-
let(:
|
87
|
-
|
88
|
-
|
89
|
-
12:hugetlb:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
90
|
-
11:net_prio:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
91
|
-
10:perf_event:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
92
|
-
9:net_cls:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
93
|
-
8:freezer:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
94
|
-
7:devices:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
95
|
-
6:memory:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
96
|
-
5:blkio:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
97
|
-
4:cpuacct:#{cpuacct_control_group}
|
98
|
-
3:cpu:#{cpu_control_group}
|
99
|
-
2:cpuset:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
100
|
-
1:name=openrc:/docker) }
|
101
|
-
let(:cpu_stat_file_content) {
|
102
|
-
[
|
103
|
-
"nr_periods #{cpu_stats_number_of_periods}",
|
104
|
-
"nr_throttled #{cpu_stats_number_of_time_throttled}",
|
105
|
-
"throttled_time #{cpu_stats_time_throttled_nanos}"
|
106
|
-
]
|
107
|
-
}
|
108
|
-
|
238
|
+
let(:cpu_stat_file_content) do
|
239
|
+
["nr_periods #{cpu_stats_number_of_periods}", "nr_throttled #{cpu_stats_number_of_time_throttled}", "throttled_time #{cpu_stats_time_throttled_nanos}"]
|
240
|
+
end
|
109
241
|
before do
|
110
|
-
allow(
|
111
|
-
allow(
|
112
|
-
|
113
|
-
allow(
|
114
|
-
allow(
|
115
|
-
allow(
|
242
|
+
allow(::File).to receive(:exist?).and_return(true)
|
243
|
+
allow(IO).to receive(:readlines).with("/sys/fs/cgroup/cpuacct#{relative_path}/cpuacct.usage").and_return([cpuacct_usage])
|
244
|
+
allow(IO).to receive(:readlines).with("/sys/fs/cgroup/cpu#{relative_path}/cpu.cfs_period_us").and_return([cfs_period_micros])
|
245
|
+
allow(IO).to receive(:readlines).with("/sys/fs/cgroup/cpu#{relative_path}/cpu.cfs_quota_us").and_return([cfs_quota_micros])
|
246
|
+
allow(IO).to receive(:readlines).with("/sys/fs/cgroup/cpu#{relative_path}/cpu.stat").and_return(cpu_stat_file_content)
|
247
|
+
allow(IO).to receive(:readlines).with("/proc/self/cgroup").and_return(proc_self_cgroup_content)
|
116
248
|
end
|
117
|
-
|
118
249
|
it "returns all the stats" do
|
119
|
-
expect(
|
250
|
+
expect(described_class.get_all).to match(
|
120
251
|
:cpuacct => {
|
121
|
-
:control_group =>
|
252
|
+
:control_group => relative_path,
|
122
253
|
:usage_nanos => cpuacct_usage,
|
123
254
|
},
|
124
255
|
:cpu => {
|
125
|
-
:control_group =>
|
256
|
+
:control_group => relative_path,
|
126
257
|
:cfs_period_micros => cfs_period_micros,
|
127
258
|
:cfs_quota_micros => cfs_quota_micros,
|
128
259
|
:stat => {
|
@@ -137,12 +268,14 @@ describe LogStash::Instrument::PeriodicPoller::Cgroup do
|
|
137
268
|
|
138
269
|
context "when an exception is raised" do
|
139
270
|
before do
|
140
|
-
allow(
|
271
|
+
allow(::File).to receive(:exist?).and_return(true)
|
272
|
+
allow(Cgroup::CGROUP_RESOURCES).to receive(:controller_groups).and_raise("Something went wrong")
|
141
273
|
end
|
142
274
|
|
143
|
-
it "returns nil" do
|
144
|
-
expect(
|
275
|
+
it "method: get_all returns nil" do
|
276
|
+
expect(described_class.get_all).to be_nil
|
145
277
|
end
|
146
278
|
end
|
147
279
|
end
|
148
280
|
end
|
281
|
+
end end end
|
@@ -12,46 +12,43 @@ describe LogStash::Instrument::PeriodicPoller::Os do
|
|
12
12
|
let(:snapshot_store) { metric.collector.snapshot_metric.metric_store }
|
13
13
|
let(:os_metrics) { snapshot_store.get_shallow(:os) }
|
14
14
|
|
15
|
-
let(:
|
15
|
+
let(:relative_path) { "/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61" }
|
16
|
+
let(:proc_self_cgroup_content) do
|
17
|
+
%W(14:name=systemd,holaunlimited:#{relative_path}
|
18
|
+
13:pids:#{relative_path}
|
19
|
+
12:hugetlb:#{relative_path}
|
20
|
+
11:net_prio:#{relative_path}
|
21
|
+
10:perf_event:#{relative_path}
|
22
|
+
9:net_cls:#{relative_path}
|
23
|
+
8:freezer:#{relative_path}
|
24
|
+
7:devices:#{relative_path}
|
25
|
+
6:memory:#{relative_path}
|
26
|
+
5:blkio:#{relative_path}
|
27
|
+
4:cpuacct:#{relative_path}
|
28
|
+
3:cpu:#{relative_path}
|
29
|
+
2:cpuset:#{relative_path}
|
30
|
+
1:name=openrc:/docker
|
31
|
+
0::/docker)
|
32
|
+
end
|
33
|
+
|
16
34
|
let(:cpuacct_usage) { 1982 }
|
17
|
-
let(:cpu_control_group) { "/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61" }
|
18
35
|
let(:cpu_period_micros) { 500 }
|
19
36
|
let(:cpu_quota_micros) { 98 }
|
20
37
|
let(:cpu_stats_number_of_periods) { 1 }
|
21
38
|
let(:cpu_stats_number_of_time_throttled) { 2 }
|
22
39
|
let(:cpu_stats_time_throttled_nanos) { 3 }
|
23
|
-
let(:proc_self_cgroup_content) {
|
24
|
-
%W(14:name=systemd,holaunlimited:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
25
|
-
13:pids:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
26
|
-
12:hugetlb:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
27
|
-
11:net_prio:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
28
|
-
10:perf_event:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
29
|
-
9:net_cls:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
30
|
-
8:freezer:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
31
|
-
7:devices:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
32
|
-
6:memory:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
33
|
-
5:blkio:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
34
|
-
4:cpuacct:#{cpuacct_control_group}
|
35
|
-
3:cpu:#{cpu_control_group}
|
36
|
-
2:cpuset:/docker/a10687343f90e97bbb1f7181bd065a42de96c40c4aa91764a9d526ea30475f61
|
37
|
-
1:name=openrc:/docker) }
|
38
|
-
let(:cpu_stat_file_content) {
|
39
|
-
[
|
40
|
-
"nr_periods #{cpu_stats_number_of_periods}",
|
41
|
-
"nr_throttled #{cpu_stats_number_of_time_throttled}",
|
42
|
-
"throttled_time #{cpu_stats_time_throttled_nanos}"
|
43
|
-
]
|
44
|
-
}
|
45
|
-
|
46
|
-
before do
|
47
|
-
allow(LogStash::Instrument::PeriodicPoller::Cgroup).to receive(:are_cgroup_available?).and_return(true)
|
48
40
|
|
49
|
-
|
50
|
-
|
41
|
+
let(:cpu_stat_file_content) do
|
42
|
+
["nr_periods #{cpu_stats_number_of_periods}", "nr_throttled #{cpu_stats_number_of_time_throttled}", "throttled_time #{cpu_stats_time_throttled_nanos}"]
|
43
|
+
end
|
51
44
|
|
52
|
-
|
53
|
-
allow(
|
54
|
-
allow(
|
45
|
+
before do
|
46
|
+
allow(::File).to receive(:exist?).and_return(true)
|
47
|
+
allow(IO).to receive(:readlines).with("/sys/fs/cgroup/cpuacct#{relative_path}/cpuacct.usage").and_return([cpuacct_usage])
|
48
|
+
allow(IO).to receive(:readlines).with("/sys/fs/cgroup/cpu#{relative_path}/cpu.cfs_period_us").and_return([cpu_period_micros])
|
49
|
+
allow(IO).to receive(:readlines).with("/sys/fs/cgroup/cpu#{relative_path}/cpu.cfs_quota_us").and_return([cpu_quota_micros])
|
50
|
+
allow(IO).to receive(:readlines).with("/sys/fs/cgroup/cpu#{relative_path}/cpu.stat").and_return(cpu_stat_file_content)
|
51
|
+
allow(IO).to receive(:readlines).with("/proc/self/cgroup").and_return(proc_self_cgroup_content)
|
55
52
|
|
56
53
|
subject.collect
|
57
54
|
end
|
data/versions-gem-copy.yml
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.6.
|
4
|
+
version: 5.6.13
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|