Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cgroups-exporter
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ai3
tools
cgroups-exporter
Commits
8a36fb12
Commit
8a36fb12
authored
3 years ago
by
ale
Browse files
Options
Downloads
Patches
Plain Diff
Add PSI metrics
parent
c02894b7
No related branches found
No related tags found
1 merge request
!3
Support cgroups v2
Pipeline
#20614
passed
3 years ago
Stage: build_pkgsrc
Stage: build_pkg
Changes
4
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
cpu_v2.go
+34
-1
34 additions, 1 deletion
cpu_v2.go
io_v2.go
+46
-11
46 additions, 11 deletions
io_v2.go
mem_v2.go
+33
-0
33 additions, 0 deletions
mem_v2.go
util.go
+36
-0
36 additions, 0 deletions
util.go
with
149 additions
and
12 deletions
cpu_v2.go
+
34
−
1
View file @
8a36fb12
...
...
@@ -6,12 +6,29 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
var
usecs
float64
=
1000000
var
(
usecs
float64
=
1000000
cpuV2PressureStalledDesc
=
prometheus
.
NewDesc
(
"cgroup_cpu_pressure_stalled_seconds_total"
,
"PSI stalled CPU seconds."
,
[]
string
{
"slice"
,
"service"
},
nil
,
)
cpuV2PressureWaitingDesc
=
prometheus
.
NewDesc
(
"cgroup_cpu_pressure_waiting_seconds_total"
,
"PSI waiting CPU seconds."
,
[]
string
{
"slice"
,
"service"
},
nil
,
)
)
type
cpuV2Parser
struct
{}
func
(
p
*
cpuV2Parser
)
describe
(
ch
chan
<-
*
prometheus
.
Desc
)
{
ch
<-
cpuV1Desc
ch
<-
cpuV2PressureStalledDesc
ch
<-
cpuV2PressureWaitingDesc
}
func
(
p
*
cpuV2Parser
)
parse
(
path
,
slice
,
unit
string
,
ch
chan
<-
prometheus
.
Metric
)
{
...
...
@@ -33,4 +50,20 @@ func (p *cpuV2Parser) parse(path, slice, unit string, ch chan<- prometheus.Metri
float64
(
usage
[
"system_usec"
])
/
usecs
,
"system"
,
slice
,
unit
,
)
waiting
,
stalled
,
err
:=
parsePressureFile
(
filepath
.
Join
(
cgroupsRootPath
,
path
,
"cpu.pressure"
))
if
err
==
nil
{
ch
<-
prometheus
.
MustNewConstMetric
(
cpuV2PressureWaitingDesc
,
prometheus
.
CounterValue
,
float64
(
waiting
),
slice
,
unit
,
)
ch
<-
prometheus
.
MustNewConstMetric
(
cpuV2PressureStalledDesc
,
prometheus
.
CounterValue
,
float64
(
stalled
),
slice
,
unit
,
)
}
}
This diff is collapsed.
Click to expand it.
io_v2.go
+
46
−
11
View file @
8a36fb12
...
...
@@ -24,6 +24,18 @@ var (
[]
string
{
"mode"
,
"slice"
,
"service"
},
nil
,
)
ioV2PressureStalledDesc
=
prometheus
.
NewDesc
(
"cgroup_blkio_pressure_stalled_seconds_total"
,
"PSI stalled I/O seconds."
,
[]
string
{
"slice"
,
"service"
},
nil
,
)
ioV2PressureWaitingDesc
=
prometheus
.
NewDesc
(
"cgroup_blkio_pressure_waiting_seconds_total"
,
"PSI waiting I/O seconds."
,
[]
string
{
"slice"
,
"service"
},
nil
,
)
)
type
blkioV2Parser
struct
{}
...
...
@@ -44,17 +56,23 @@ func parseDevice(token []byte) (int, int, error) {
return
maj
,
min
,
nil
}
func
parseKVPairs
(
tokens
[][]
byte
,
out
map
[
string
]
int64
)
{
for
_
,
token
:=
range
tokens
{
func
parseKVPair
(
token
[]
byte
)
(
string
,
int64
,
error
)
{
kvp
:=
bytes
.
SplitN
(
token
,
[]
byte
(
"="
),
2
)
if
len
(
kvp
)
!=
2
{
continue
return
""
,
0
,
errors
.
New
(
"not an assignment"
)
}
value
,
err
:=
strconv
.
ParseInt
(
string
(
kvp
[
1
]),
10
,
64
)
if
err
!=
nil
{
continue
return
""
,
0
,
err
}
return
string
(
kvp
[
0
]),
value
,
nil
}
func
parseKVPairs
(
tokens
[][]
byte
,
out
map
[
string
]
int64
)
{
for
_
,
token
:=
range
tokens
{
if
key
,
value
,
err
:=
parseKVPair
(
token
);
err
==
nil
{
out
[
key
]
+=
value
}
out
[
string
(
kvp
[
0
])]
+=
value
}
}
...
...
@@ -65,9 +83,8 @@ func parseIOV2File(path string) (map[string]int64, error) {
}
defer
f
.
Close
()
// Sum I/O counters across devices, but only for mounted
// devices, so we do not count I/O operations twice with
// LVM/MD.
// Sum I/O counters across devices, but only for mounted devices,
// so we do not count I/O operations twice with LVM/MD.
result
:=
make
(
map
[
string
]
int64
)
scanner
:=
bufio
.
NewScanner
(
f
)
for
scanner
.
Scan
()
{
...
...
@@ -92,6 +109,8 @@ func parseIOV2File(path string) (map[string]int64, error) {
func
(
p
*
blkioV2Parser
)
describe
(
ch
chan
<-
*
prometheus
.
Desc
)
{
ch
<-
ioV2BytesDesc
ch
<-
ioV2OpsDesc
ch
<-
ioV2PressureStalledDesc
ch
<-
ioV2PressureWaitingDesc
}
func
(
p
*
blkioV2Parser
)
parse
(
path
,
slice
,
unit
string
,
ch
chan
<-
prometheus
.
Metric
)
{
...
...
@@ -124,4 +143,20 @@ func (p *blkioV2Parser) parse(path, slice, unit string, ch chan<- prometheus.Met
float64
(
counters
[
"rios"
]),
"read"
,
slice
,
unit
,
)
waiting
,
stalled
,
err
:=
parsePressureFile
(
filepath
.
Join
(
cgroupsRootPath
,
path
,
"io.pressure"
))
if
err
==
nil
{
ch
<-
prometheus
.
MustNewConstMetric
(
ioV2PressureWaitingDesc
,
prometheus
.
CounterValue
,
float64
(
waiting
),
slice
,
unit
,
)
ch
<-
prometheus
.
MustNewConstMetric
(
ioV2PressureStalledDesc
,
prometheus
.
CounterValue
,
float64
(
stalled
),
slice
,
unit
,
)
}
}
This diff is collapsed.
Click to expand it.
mem_v2.go
+
33
−
0
View file @
8a36fb12
...
...
@@ -6,10 +6,27 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
var
(
memV2PressureStalledDesc
=
prometheus
.
NewDesc
(
"cgroup_mem_pressure_stalled_seconds_total"
,
"PSI stalled memory seconds."
,
[]
string
{
"slice"
,
"service"
},
nil
,
)
memV2PressureWaitingDesc
=
prometheus
.
NewDesc
(
"cgroup_mem_pressure_waiting_seconds_total"
,
"PSI waiting memory seconds."
,
[]
string
{
"slice"
,
"service"
},
nil
,
)
)
type
memoryV2Parser
struct
{}
func
(
p
*
memoryV2Parser
)
describe
(
ch
chan
<-
*
prometheus
.
Desc
)
{
ch
<-
memV1Desc
ch
<-
memV2PressureStalledDesc
ch
<-
memV2PressureWaitingDesc
}
func
(
p
*
memoryV2Parser
)
parse
(
path
,
slice
,
unit
string
,
ch
chan
<-
prometheus
.
Metric
)
{
...
...
@@ -25,4 +42,20 @@ func (p *memoryV2Parser) parse(path, slice, unit string, ch chan<- prometheus.Me
float64
(
rss
),
slice
,
unit
,
)
waiting
,
stalled
,
err
:=
parsePressureFile
(
filepath
.
Join
(
cgroupsRootPath
,
path
,
"memory.pressure"
))
if
err
==
nil
{
ch
<-
prometheus
.
MustNewConstMetric
(
memV2PressureWaitingDesc
,
prometheus
.
CounterValue
,
float64
(
waiting
),
slice
,
unit
,
)
ch
<-
prometheus
.
MustNewConstMetric
(
memV2PressureStalledDesc
,
prometheus
.
CounterValue
,
float64
(
stalled
),
slice
,
unit
,
)
}
}
This diff is collapsed.
Click to expand it.
util.go
+
36
−
0
View file @
8a36fb12
...
...
@@ -17,6 +17,8 @@ var (
)
func
init
()
{
// Cgroups v1 counters are expressed in 'ticks', so we need to figure
// out the system's HZ value to convert them to seconds.
userHZ
=
100
if
clktck
,
err
:=
sysconf
.
Sysconf
(
sysconf
.
SC_CLK_TCK
);
err
==
nil
{
userHZ
=
float64
(
clktck
)
...
...
@@ -27,6 +29,8 @@ func cgroupV1StatPath(cgroupPath, collector, path string) string {
return
filepath
.
Join
(
"/sys/fs/cgroup"
,
collector
,
cgroupPath
,
path
)
}
// Parse a generic proc-style 'map' file, with space-separated "key value"
// assignments, one per line.
func
parseMapFile
(
path
string
)
(
map
[
string
]
int64
,
error
)
{
f
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
...
...
@@ -51,6 +55,7 @@ func parseMapFile(path string) (map[string]int64, error) {
return
result
,
scanner
.
Err
()
}
// Parse a file containing a single integer value.
func
parseSingleValueFile
(
path
string
)
(
int64
,
error
)
{
data
,
err
:=
ioutil
.
ReadFile
(
path
)
if
err
!=
nil
{
...
...
@@ -62,6 +67,37 @@ func parseSingleValueFile(path string) (int64, error) {
return
strconv
.
ParseInt
(
string
(
data
),
10
,
64
)
}
// Parse a PSI /proc file and return the "some" (waiting), "full" (stalled)
// counters.
func
parsePressureFile
(
path
string
)
(
int64
,
int64
,
error
)
{
f
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
0
,
0
,
err
}
defer
f
.
Close
()
var
waiting
,
stalled
int64
scanner
:=
bufio
.
NewScanner
(
f
)
for
scanner
.
Scan
()
{
line
:=
scanner
.
Bytes
()
parts
:=
bytes
.
Split
(
line
,
[]
byte
(
" "
))
if
len
(
parts
)
!=
5
{
continue
}
_
,
value
,
err
:=
parseKVPair
(
parts
[
4
])
if
err
!=
nil
{
continue
}
switch
{
case
bytes
.
Equal
(
parts
[
0
],
[]
byte
(
"some"
))
:
waiting
=
value
case
bytes
.
Equal
(
parts
[
0
],
[]
byte
(
"full"
))
:
stalled
=
value
}
}
return
waiting
,
stalled
,
scanner
.
Err
()
}
func
splitServiceName
(
path
string
)
(
string
,
string
)
{
slice
,
name
:=
filepath
.
Split
(
path
)
slice
=
strings
.
Trim
(
slice
,
"/"
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment