Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
183 commits
Select commit Hold shift + click to select a range
3254ce1
fix : Update the minimum required Linux kernel version (#221)
Vperiodt Jun 16, 2025
88f42d8
Merge pull request #147 from nudgebee/prod
mayankpande88 Jun 19, 2025
bcbb471
fix cgroup handling for Incus containers (#224)
def Jun 19, 2025
85208c9
metrics: enhance the `instance` label uniqueness to avoid collisions
apetruhin Jun 25, 2025
0f55c4a
Merge pull request #228 from coroot/metrics-enhance-instance-label-un…
apetruhin Jun 25, 2025
36d7f25
containers: add support for ZFS filesystem (coroot/coroot#371)
apetruhin Jun 26, 2025
6b15ef1
Merge pull request #229 from coroot/containers-zfs
apetruhin Jun 26, 2025
41c2ef3
fix: fix for external domain resolution (#148)
mayankpande88 Jul 2, 2025
6d9279e
Update netDeviceFilterRe to allow enP4p65s0 and enP2p33s0 (#232)
tsndqst Jul 8, 2025
f7a2da8
Add support for monitoring eMMC drives (#233)
tsndqst Jul 8, 2025
a0f10d4
add FoundationDB application type
def Aug 12, 2025
eb43dc0
Merge pull request #235 from coroot/foundationdb_app_type
def Aug 12, 2025
b349fee
add support for Oracle Cloud metadata
def Aug 13, 2025
7937399
Merge pull request #236 from coroot/oracle_cloud_support
def Aug 13, 2025
0099b5f
add support for disabling log monitoring via container ENV variable
def Aug 20, 2025
ee83bcd
Merge pull request #237 from coroot/disable_log_monitoring
def Aug 20, 2025
d29d9ed
cgroup v1: use hierarchical total_* counters for accurate RSS/memory …
def Aug 21, 2025
94fcaf7
Merge pull request #238 from coroot/cgroup_v1_mem
def Aug 21, 2025
4fe3e12
FoundationDB support
def Aug 29, 2025
73630f0
Merge pull request #239 from coroot/fdb_support
def Sep 1, 2025
3888932
ebpf traces: allow disabling traces per container with COROOT_EBPF_TR…
def Sep 1, 2025
c7d5d32
ebpf traces: add sampling support
def Sep 1, 2025
c71a416
Merge pull request #240 from coroot/ebpf_traces_improvements
def Sep 1, 2025
6a27da6
build(deps): bump github.com/ulikunitz/xz from 0.5.12 to 0.5.14 (#152)
dependabot[bot] Sep 4, 2025
29da74f
build(deps): bump github.com/docker/docker (#151)
dependabot[bot] Sep 4, 2025
da8b5a4
grpc: get grpc-status from payload if possible
def Sep 11, 2025
2e9d8aa
Merge pull request #243 from coroot/grpc_status
def Sep 11, 2025
aa169a6
add `container_nodejs_event_loop_blocked_time_seconds_total`
def Sep 19, 2025
aa81b30
Merge pull request #245 from coroot/nodejs_event_loop_monitoring
def Sep 19, 2025
611166e
read python stats directly from the ebpf map
def Sep 19, 2025
d7c8349
Merge pull request #246 from coroot/python_ebpf_map
def Sep 19, 2025
3a7cbbd
add per-container Pressure Stall Information (PSI) metrics
def Sep 22, 2025
f331454
Merge pull request #247 from coroot/psi_metrics
def Sep 22, 2025
1f394c0
feat: fix response parsing and llm request tracking
mayankpande88 Sep 23, 2025
3ea3fcd
fix: fix for compilation
mayankpande88 Sep 23, 2025
ce80ecf
feat: response fragement parsing improvement
mayankpande88 Sep 24, 2025
ebe3fd4
fix: fix for compilation
mayankpande88 Sep 24, 2025
3629737
fix: fix for verflow
mayankpande88 Sep 24, 2025
e085c22
fix: fix for failure
mayankpande88 Sep 24, 2025
64413f5
fix: fix for failure
mayankpande88 Sep 24, 2025
f3d4ce8
feat: complete LLM observability with DNS resolution fixes
mayankpande88 Sep 24, 2025
a7874ba
Merge upstream main branch preserving LLM observability features
mayankpande88 Sep 24, 2025
9ed44a0
fix: fix for compile
mayankpande88 Sep 24, 2025
7462b2a
fix: fix for failure
mayankpande88 Sep 24, 2025
59bdf8b
fix: fix for compile
mayankpande88 Sep 24, 2025
0e677ae
fix: fix for failure
mayankpande88 Sep 24, 2025
495de92
fix: fix for lint
mayankpande88 Sep 24, 2025
ffa1786
fix: fix for compile
mayankpande88 Sep 24, 2025
b4e1012
fix: removed http fragement handling
mayankpande88 Sep 24, 2025
4cab2ea
fix: fix for failure
mayankpande88 Sep 24, 2025
c12d20e
fix: fix for failure
mayankpande88 Sep 24, 2025
e4215d1
fix: fix for lint
mayankpande88 Sep 24, 2025
dee4379
fix: fix for failure
mayankpande88 Sep 24, 2025
a97b39a
fix: fix for failure
mayankpande88 Sep 24, 2025
3757b42
fix: fix for panic
mayankpande88 Sep 24, 2025
b253f1b
fix: fix for failure
mayankpande88 Sep 24, 2025
9a1447b
fix: fix for dns resolution
mayankpande88 Sep 24, 2025
9d3025a
fix: fix for parsing
mayankpande88 Sep 24, 2025
1470a07
fix: fix for http2 parsing and cpu
mayankpande88 Sep 24, 2025
72bd889
fix: fix for failure
mayankpande88 Sep 24, 2025
aad70bd
fix: fix for cache init
mayankpande88 Sep 24, 2025
4a90e3d
fix: fix for http
mayankpande88 Sep 24, 2025
5aa9da9
fix: fix for https traffic handling
mayankpande88 Sep 24, 2025
aa960de
fix: fix for ssl lib
mayankpande88 Sep 24, 2025
f5d546c
fix: fix for failure
mayankpande88 Sep 25, 2025
f1568f4
fix: fix for tls handling
mayankpande88 Sep 25, 2025
4bd85b3
fix: fix for garbage request and response
mayankpande88 Sep 25, 2025
cf92e0e
fix: fix for request and response handling
mayankpande88 Sep 25, 2025
8e83596
fix: removed test file
mayankpande88 Sep 25, 2025
491d7ca
fix: fix for request and response handling
mayankpande88 Sep 25, 2025
683feff
fix: fix removed unwantd files
mayankpande88 Sep 25, 2025
070805e
fix: fix for test and dns mapping
mayankpande88 Sep 25, 2025
2cbd7db
fix: fix for dns mapping
mayankpande88 Sep 25, 2025
39e716a
fix: fix for external destination name
mayankpande88 Sep 25, 2025
19970ac
fix: fix for trace collection failure and logging fixes
mayankpande88 Sep 25, 2025
727f832
fix: fix for compile
mayankpande88 Sep 25, 2025
911fd8b
fix: fix for orphan code and compilation
mayankpande88 Sep 25, 2025
5981326
fix: fix for formatting
mayankpande88 Sep 25, 2025
b8c2b8b
fix: fix for invalid utf8 data
mayankpande88 Sep 25, 2025
12ea241
fix: fix for parsing
mayankpande88 Sep 25, 2025
9e29c13
fix: fix for sanitize http utf
mayankpande88 Sep 25, 2025
767e775
fix: fix for actual destination pod name
mayankpande88 Sep 25, 2025
2bceae7
fix: fix for pod owner mapping
mayankpande88 Sep 25, 2025
bd38f78
fix: fix for invalid utf8
mayankpande88 Sep 26, 2025
2b6dd62
perf: optimize eBPF binary parsing with buffer pool
mayankpande88 Sep 26, 2025
43c265b
debug: enhance HTTP parsing error logging
mayankpande88 Sep 26, 2025
c874e55
Revert "perf: optimize eBPF binary parsing with buffer pool"
mayankpande88 Sep 26, 2025
3cf0864
perf: optimize eBPF binary parsing with bytes.NewReader
mayankpande88 Sep 26, 2025
ca33eda
Revert "perf: optimize eBPF binary parsing with bytes.NewReader"
mayankpande88 Sep 26, 2025
3ec5ef0
fix: clean up inconsistent error messages in eBPF tracer
mayankpande88 Sep 26, 2025
558e799
fix: add UTF-8 validation to HTTP parsing pipeline
mayankpande88 Sep 27, 2025
b41e7c8
fix: fix for metrics duplication
mayankpande88 Sep 27, 2025
9e2fc2a
fix: remove unused variable in registry.go
mayankpande88 Sep 27, 2025
531f9eb
fix: resolve eBPF verifier back-edge error in binary detection loop
mayankpande88 Sep 27, 2025
e1c0668
fix: resolve remaining eBPF verifier back-edge errors in HTTP validation
mayankpande88 Sep 27, 2025
df3130b
fix: fix for failire
mayankpande88 Sep 27, 2025
ee94917
fix: fix for failure
mayankpande88 Sep 27, 2025
d2f936f
fix: fix for utf8 failure
mayankpande88 Sep 27, 2025
fae3110
debug: add logging to see what binary data passes eBPF as HTTP response
mayankpande88 Sep 27, 2025
6f7fc62
fix: prevent binary data being parsed as HTTP headers
mayankpande88 Sep 29, 2025
3739eb6
feat: implement complete HTTP data capture with process_vm_readv
mayankpande88 Sep 29, 2025
c22030c
fix: add minimal HTTPRequestProcessor for backward compatibility
mayankpande88 Sep 29, 2025
2b2ee1f
fix: add missing methods to HTTPRequestContext for LLM detection
mayankpande88 Sep 29, 2025
9d0afcf
fix: fix for failure
mayankpande88 Sep 29, 2025
7e4b01f
enhance: complete HTTP request processing with proper header-body sep…
mayankpande88 Sep 29, 2025
7118e40
fix: fix for go routine leaks
mayankpande88 Oct 1, 2025
02b63a5
fix: prevent duplicate container metrics registration and fix tracing…
mayankpande88 Oct 1, 2025
350dd35
fix: prevent duplicate metrics by centralizing eBPF stats update
mayankpande88 Oct 1, 2025
c4778e4
temp: stage current changes before reverting process_vm_readv
mayankpande88 Oct 1, 2025
7c76305
Revert "feat: implement complete HTTP data capture with process_vm_re…
mayankpande88 Oct 1, 2025
4a53758
fix: redesign L7Stats architecture to eliminate duplicate metrics issue
mayankpande88 Oct 1, 2025
a6e45c2
fix: resolve compilation errors after L7Stats architecture change
mayankpande88 Oct 1, 2025
7d01db6
fix: fix for label duplication and registry
mayankpande88 Oct 1, 2025
4e42957
fix: resolve eBPF l7_event structure mismatch causing EOF errors
mayankpande88 Oct 1, 2025
4a19ea1
fix: resolve label cardinality mismatch in L7Stats observe method
mayankpande88 Oct 1, 2025
76cdb3b
fix: resolve duplicate network metrics by moving updateStatsFromEbpfM…
mayankpande88 Oct 1, 2025
fd574f1
chore: fix Go code formatting
mayankpande88 Oct 1, 2025
806f298
enhance: improve DNS mapping and hostname resolution in traces
mayankpande88 Oct 1, 2025
945fbf2
fix: fix path high cardanility
mayankpande88 Oct 1, 2025
3d76787
fix: removed trace id from metrics
mayankpande88 Oct 1, 2025
242d9a1
fix: enhance HTTP path normalization to prevent cardinality explosion
mayankpande88 Oct 1, 2025
e9325b7
fix: prevent RabbitMQ traffic misclassification as ClickHouse
mayankpande88 Oct 1, 2025
e8eb7b4
fix: resolve RabbitMQ label cardinality mismatch
mayankpande88 Oct 1, 2025
5a27ca5
fix: fix for request and headers seperation
mayankpande88 Oct 1, 2025
18f2d9a
fix: fix for dns lookup
mayankpande88 Oct 1, 2025
0614245
fix: fix for http detection
mayankpande88 Oct 1, 2025
16f2420
fix: resolve duplicate network metrics by adding region/zone labels
mayankpande88 Oct 2, 2025
cb9d98a
fix: fix for invalid utf
mayankpande88 Oct 2, 2025
4c55161
fix: fix for metrics duplication
mayankpande88 Oct 2, 2025
6e9fcf7
fix: fix for missing metric
mayankpande88 Oct 3, 2025
b728f8b
chore: fix Go code formatting
mayankpande88 Oct 3, 2025
0a8a698
fix: fix for invalid utf and clickhouse query detection
mayankpande88 Oct 3, 2025
2cfe3be
fix: fix for failure
mayankpande88 Oct 3, 2025
aa6a9ee
fix: fix for failire
mayankpande88 Oct 3, 2025
c8aec92
fix: fix for failure
mayankpande88 Oct 3, 2025
a790750
fix: resolve eBPF verifier error and add psycopg2 SSL library support
mayankpande88 Oct 3, 2025
de146ab
fix: fix for failure
mayankpande88 Oct 3, 2025
5deab87
fix: resolve eBPF verifier errors by disabling complex iovec processing
mayankpande88 Oct 3, 2025
5be3f2c
fix: fix for failure
mayankpande88 Oct 3, 2025
d77075b
fix: fix for failure
mayankpande88 Oct 3, 2025
6908794
fix: fix for args mismatch
mayankpande88 Oct 3, 2025
469cee7
fix: fix for http detection
mayankpande88 Oct 3, 2025
6701701
fix: refactor L7 metrics to prevent duplicate collection errors
mayankpande88 Oct 3, 2025
db62176
Revert "fix: refactor L7 metrics to prevent duplicate collection errors"
mayankpande88 Oct 3, 2025
e96324d
fix: implement protocol-level L7 metrics to prevent duplicate collection
mayankpande88 Oct 3, 2025
a312e81
debug: add comprehensive logging to track duplicate metrics collection
mayankpande88 Oct 3, 2025
5fc0d04
fix: prevent duplicate metrics by unregistering containers during ID …
mayankpande88 Oct 3, 2025
ff2e2cf
fix: completely replace containers during ID conflicts to prevent dup…
mayankpande88 Oct 3, 2025
a0f0f7d
fix: resolve duplicate metrics and optimize memory usage
mayankpande88 Oct 3, 2025
cacdf97
style: apply gofmt formatting
mayankpande88 Oct 3, 2025
aa4d7c0
fix: restore controller resolution in MinimalPod optimization
mayankpande88 Oct 3, 2025
a70bffc
feat: implement comprehensive memory optimization to prevent OOM
mayankpande88 Oct 4, 2025
0ef6773
feat: make HTTP path normalization configurable and generic
mayankpande88 Oct 4, 2025
de9fb60
style: apply gofmt formatting
mayankpande88 Oct 4, 2025
ee63fa1
feat: enhance memory optimization with payload size reduction and opt…
mayankpande88 Oct 4, 2025
f78a1ca
feat: optimize eBPF memory usage with reduced L7 request tracking
mayankpande88 Oct 4, 2025
b4244af
perf: remove frequent debug loggers to reduce memory usage
mayankpande88 Oct 4, 2025
a9b45bb
fix: fix for http detection
mayankpande88 Oct 4, 2025
bb61dc0
fix: fix for failure
mayankpande88 Oct 4, 2025
a42b4e9
fix: fix for http protocol detection
mayankpande88 Oct 4, 2025
9a3ac8f
fix: resolve HTTP parsing logic error causing missing traces and CPU …
mayankpande88 Oct 4, 2025
c41e590
fix: resolve duplicate TCP metrics causing Prometheus target failures
mayankpande88 Oct 4, 2025
4569b1a
fix: ensure service workloads inherit location data from backing pods
mayankpande88 Oct 4, 2025
9461bb8
feat: enhance eBPF L7 protocol detection capabilities
mayankpande88 Oct 4, 2025
f7fc559
fix: improve L7 protocol detection to prevent RabbitMQ misclassificat…
mayankpande88 Oct 4, 2025
aaf2997
feat: comprehensive memory optimization and protocol detection improv…
mayankpande88 Oct 5, 2025
264a1db
fix: remove excessive DEBUG logging from container collection
mayankpande88 Oct 5, 2025
93e6a33
feat: add comprehensive cardinality analysis and memory protection
mayankpande88 Oct 6, 2025
0b35c31
fix: resolve compilation errors in debug_metrics.go
mayankpande88 Oct 6, 2025
bfcc252
fix: remove path and method labels from HTTP histogram metrics to red…
mayankpande88 Oct 6, 2025
fd7de5d
feat: add grouped status codes for histogram metrics to further reduc…
mayankpande88 Oct 6, 2025
fd8db30
fix: release container lock early to eliminate severe lock contention
mayankpande88 Oct 11, 2025
e8d25e3
style: fix Go formatting issues
mayankpande88 Oct 11, 2025
9d4f275
feat: add comprehensive lock contention debugging and remove debug ov…
mayankpande88 Oct 12, 2025
c0562c3
perf: optimize metrics collection and reduce overhead
mayankpande88 Oct 12, 2025
41c6c3d
fix: remove unused encoding/json import
mayankpande88 Oct 12, 2025
00836a6
Add comprehensive timing logs to Container.Collect() method
mayankpande88 Oct 13, 2025
3c5d9b1
perf: optimize collection throttling with atomic operations
mayankpande88 Oct 13, 2025
44de62e
style: fix formatting with gofmt
mayankpande88 Oct 13, 2025
0fd5884
feat: fix response parsing and llm request tracking (#154)
mayankpande88 Oct 13, 2025
21def7d
Merge remote-tracking branch 'origin/test' into test-main-backmerge
mayankpande88 Oct 29, 2025
692d744
Merge pull request #156 from nudgebee/test-main-backmerge
mayankpande88 Oct 29, 2025
b3f3c6d
Merge pull request #155 from nudgebee/main
mayankpande88 Oct 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dev-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Build and Push Agent Image
uses: docker/build-push-action@v3
with:
platforms: linux/amd64,linux/arm64
platforms: linux/amd64
context: .
file: 'Dockerfile'
push: true
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Below are some basic guidelines.


## Requirements
* Linux ≥v4.16 (amd64, arm64)
* Linux ≥v5.1 (amd64, arm64)
* Go v1.23


Expand Down
11 changes: 5 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
FROM golang:1.23.10-bullseye AS builder

RUN apt-get update \
&& apt-get install -y --no-install-recommends libsystemd-dev \
&& rm -rf /var/lib/apt/lists/*

FROM golang:1.24.7-trixie AS builder
RUN apt update && apt install -y libsystemd-dev
WORKDIR /tmp/src
COPY go.mod .
COPY go.sum .
Expand All @@ -16,6 +12,9 @@ FROM registry.access.redhat.com/ubi9/ubi-minimal AS runtime

ARG VERSION=unknown

# Install SSL/TLS libraries for HTTPS LLM API tracing
RUN microdnf install -y openssl-libs

COPY --from=builder /tmp/src/coroot-node-agent /usr/bin/coroot-node-agent

ENTRYPOINT ["coroot-node-agent"]
5 changes: 4 additions & 1 deletion Dockerfile.alpine
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ RUN CGO_ENABLED=1 go build -mod=readonly -ldflags "-extldflags='-Wl,-z,lazy' -X
# Runtime stage
FROM alpine:3.22 AS release-stage

# Install SSL/TLS libraries for HTTPS LLM API tracing
RUN apk add --no-cache openssl libssl3 ca-certificates

WORKDIR /app

# Copy the statically linked binary
COPY --from=builder /app/coroot-node-agent /usr/bin/coroot-node-agent

# Ensure its executable
# Ensure it's executable
RUN chmod +x /usr/bin/coroot-node-agent

# Run it
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

The agent gathers metrics related to a node and the containers running on it, and it exposes them in the Prometheus format.

It uses eBPF to track container related events such as TCP connects, so the minimum supported Linux kernel version is 4.16.
It uses eBPF to track container related events such as TCP connects, so the minimum supported Linux kernel version is 5.1.

<img src="https://coroot.com/static/img/blog/ebpf.svg" width="800" />

Expand Down
56 changes: 34 additions & 22 deletions cgroup/cgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var (
lxcIdRegexp = regexp.MustCompile(`/lxc/([^/]+)`)
systemSliceIdRegexp = regexp.MustCompile(`(/(system|runtime|reserved)\.slice/([^/]+))`)
talosIdRegexp = regexp.MustCompile(`/(system|podruntime)/([^/]+)`)
lxcPayloadRegexp = regexp.MustCompile(`/lxc\.payload\.([^/]+)`)
)

type ContainerType uint8
Expand Down Expand Up @@ -129,7 +130,14 @@ func NewFromProcessCgroupFile(filePath string) (*Cgroup, error) {
continue
}
for _, cgType := range strings.Split(parts[1], ",") {
p := path.Join(baseCgroupPath, parts[2])
cgPath := parts[2]
if strings.HasPrefix(parts[2], "/lxc.payload.") {
pp := strings.Split(cgPath, "/")
if len(parts) > 2 {
cgPath = "/" + pp[1]
}
Comment on lines +136 to +138

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The condition if len(parts) > 2 is confusing. parts is the result of strings.SplitN(line, ":", 3), and the code has already ensured len(parts) is 3, so this check is always true. It seems to be a typo and was likely intended to be if len(pp) > 1 to ensure the path has at least one component after splitting. This change would make the code clearer and more robust.

Suggested change
if len(parts) > 2 {
cgPath = "/" + pp[1]
}
if len(pp) > 1 {
cgPath = "/" + pp[1]
}

}
p := path.Join(baseCgroupPath, cgPath)
switch p {
case "/", "/init.scope":
continue
Expand All @@ -147,27 +155,25 @@ func NewFromProcessCgroupFile(filePath string) (*Cgroup, error) {

func containerByCgroup(cgroupPath string) (ContainerType, string, error) {
parts := strings.Split(strings.TrimLeft(cgroupPath, "/"), "/")
if cgroupPath == "/init" {
return ContainerTypeTalosRuntime, "/talos/init", nil
}
if len(parts) < 2 {
if len(parts) == 0 {
return ContainerTypeStandaloneProcess, "", nil
}
if *flags.DisableKubeProbe && parts[1] == "kubelet.service" {
if *flags.DisableKubeProbe && len(parts) > 1 && parts[1] == "kubelet.service" {
return ContainerTypeStandaloneProcess, "", nil
}
prefix := parts[0]
if prefix == "user.slice" || prefix == "init.scope" {
switch {
case cgroupPath == "/init":
return ContainerTypeTalosRuntime, "/talos/init", nil
case prefix == "user.slice" || prefix == "init.scope":
return ContainerTypeStandaloneProcess, "", nil
}
if prefix == "docker" || (prefix == "system.slice" && strings.HasPrefix(parts[1], "docker-")) {
case prefix == "docker" || (prefix == "system.slice" && len(parts) > 1 && strings.HasPrefix(parts[1], "docker-")):
matches := dockerIdRegexp.FindStringSubmatch(cgroupPath)
if matches == nil {
return ContainerTypeUnknown, "", fmt.Errorf("invalid docker cgroup %s", cgroupPath)
}
return ContainerTypeDocker, matches[1], nil
}
if strings.Contains(cgroupPath, "kubepods") {
case strings.Contains(cgroupPath, "kubepods"):
crioMatches := crioIdRegexp.FindStringSubmatch(cgroupPath)
if crioMatches != nil {
return ContainerTypeCrio, crioMatches[1], nil
Expand All @@ -184,27 +190,33 @@ func containerByCgroup(cgroupPath string) (ContainerType, string, error) {
return ContainerTypeSandbox, "", nil
}
return ContainerTypeDocker, matches[1], nil
}
if prefix == "lxc" {
matches := lxcIdRegexp.FindStringSubmatch(cgroupPath)
if matches == nil {
return ContainerTypeUnknown, "", fmt.Errorf("invalid lxc cgroup %s", cgroupPath)
}
return ContainerTypeLxc, matches[1], nil
}
if prefix == "system" || prefix == "podruntime" {
case prefix == "system" || prefix == "podruntime":
matches := talosIdRegexp.FindStringSubmatch(cgroupPath)
if matches == nil {
return ContainerTypeUnknown, "", fmt.Errorf("invalid talos runtime cgroup %s", cgroupPath)
}
return ContainerTypeTalosRuntime, path.Join("/talos/", matches[2]), nil
}
if prefix == "system.slice" || prefix == "runtime.slice" || prefix == "reserved.slice" {
case prefix == "system.slice" || prefix == "runtime.slice" || prefix == "reserved.slice":
matches := systemSliceIdRegexp.FindStringSubmatch(cgroupPath)
if matches == nil {
return ContainerTypeUnknown, "", fmt.Errorf("invalid systemd cgroup %s", cgroupPath)
}
return ContainerTypeSystemdService, strings.Replace(matches[1], "\\x2d", "-", -1), nil
case prefix == "lxc":
matches := lxcIdRegexp.FindStringSubmatch(cgroupPath)
if matches == nil {
return ContainerTypeUnknown, "", fmt.Errorf("invalid lxc cgroup %s", cgroupPath)
}
return ContainerTypeLxc, matches[1], nil
case strings.HasPrefix(prefix, "lxc.payload."):
matches := lxcPayloadRegexp.FindStringSubmatch(cgroupPath)
if matches == nil {
return ContainerTypeUnknown, "", fmt.Errorf("invalid lxc payload cgroup %s", cgroupPath)
}
return ContainerTypeLxc, "/lxc/" + matches[1], nil
case len(parts) < 2:
return ContainerTypeStandaloneProcess, "", nil
}

return ContainerTypeUnknown, "", fmt.Errorf("unknown container: %s", cgroupPath)
}
17 changes: 17 additions & 0 deletions cgroup/cgroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNewFromProcessCgroupFile(t *testing.T) {
Expand Down Expand Up @@ -75,6 +76,12 @@ func TestNewFromProcessCgroupFile(t *testing.T) {
assert.Equal(t, "95cbe853416f52d927dec41f1406dd75015ea131244a1ca875a7cd4ebe927ac8", cg.ContainerId)
assert.Equal(t, ContainerTypeDocker, cg.ContainerType)

cg, err = NewFromProcessCgroupFile(path.Join("fixtures/proc/3000/cgroup"))
require.Nil(t, err)
assert.Equal(t, "/lxc.payload.first", cg.Id)
assert.Equal(t, "/lxc/first", cg.ContainerId)
assert.Equal(t, ContainerTypeLxc, cg.ContainerType)

baseCgroupPath = "/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-podc83d0428_58af_41eb_8dba_b9e6eddffe7b.slice/docker-0e612005fd07e7f47e2cd07df99a2b4e909446814d71d0b5e4efc7159dd51252.scope"
defer func() {
baseCgroupPath = ""
Expand Down Expand Up @@ -178,4 +185,14 @@ func TestContainerByCgroup(t *testing.T) {
as.Equal(typ, ContainerTypeTalosRuntime)
as.Equal("/talos/init", id)
as.Nil(err)

typ, id, err = containerByCgroup("/lxc.payload.first")
as.Equal(typ, ContainerTypeLxc)
as.Equal("/lxc/first", id)
as.Nil(err)

typ, id, err = containerByCgroup("/lxc.monitor.first")
as.Equal(ContainerTypeStandaloneProcess, typ)
as.Equal("", id)
as.Nil(err)
}
6 changes: 3 additions & 3 deletions cgroup/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type CPUStat struct {
LimitCores float64
}

func (cg Cgroup) CpuStat() *CPUStat {
func (cg *Cgroup) CpuStat() *CPUStat {
cpu, cpuacct := cg.subsystems["cpu"], cg.subsystems["cpuacct"]
if cpu == "" || cpuacct == "" {
st, _ := cg.cpuStatV2()
Expand All @@ -26,7 +26,7 @@ func (cg Cgroup) CpuStat() *CPUStat {
return st
}

func (cg Cgroup) cpuStatV1() (*CPUStat, error) {
func (cg *Cgroup) cpuStatV1() (*CPUStat, error) {
if cg.subsystems["cpu"] == "" || cg.subsystems["cpuacct"] == "" {
return nil, nil
}
Expand Down Expand Up @@ -56,7 +56,7 @@ func (cg Cgroup) cpuStatV1() (*CPUStat, error) {
return res, nil
}

func (cg Cgroup) cpuStatV2() (*CPUStat, error) {
func (cg *Cgroup) cpuStatV2() (*CPUStat, error) {
if cg.subsystems[""] == "" {
return nil, nil
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
some avg10=0.00 avg60=0.00 avg300=0.00 total=465907442
full avg10=0.00 avg60=0.00 avg300=0.00 total=463529433
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
some avg10=0.00 avg60=0.00 avg300=0.05 total=17657662684
full avg10=0.00 avg60=0.00 avg300=0.05 total=17636951020
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
some avg10=0.00 avg60=0.00 avg300=0.00 total=6937313991
full avg10=0.00 avg60=0.00 avg300=0.00 total=6934649214
1 change: 1 addition & 0 deletions cgroup/fixtures/proc/3000/cgroup
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0::/lxc.payload.first/system.slice/systemd-logind.service
4 changes: 2 additions & 2 deletions cgroup/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ func (cg *Cgroup) memoryStatV1() (*MemoryStat, error) {
// mapped_file is accounted only when the memory cgroup is owner of page
// cache.)
return &MemoryStat{
RSS: vars["rss"] + vars["mapped_file"],
Cache: vars["cache"],
RSS: vars["total_rss"] + vars["total_mapped_file"],
Cache: vars["total_cache"],
Limit: limit,
}, nil
}
Expand Down
85 changes: 85 additions & 0 deletions cgroup/psi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package cgroup

import (
"os"
"path"
"strconv"
"strings"

"github.com/coroot/coroot-node-agent/common"
"k8s.io/klog/v2"
)

type PSIStats struct {
CPUSecondsSome float64
CPUSecondsFull float64
MemorySecondsSome float64
MemorySecondsFull float64
IOSecondsSome float64
IOSecondsFull float64
}

type PressureTotals struct {
SomeSecondsTotal float64
FullSecondsTotal float64
}

func (cg *Cgroup) PSI() *PSIStats {
if cg.subsystems[""] == "" {
return nil
}
stats := &PSIStats{}
for _, controller := range []string{"cpu", "memory", "io"} {
p, err := cg.readPressure(controller)
if err != nil {
if !common.IsNotExist(err) {
klog.Warningln(err)
}
return nil
}
switch controller {
case "cpu":
stats.CPUSecondsSome = p.SomeSecondsTotal
stats.CPUSecondsFull = p.FullSecondsTotal
case "memory":
stats.MemorySecondsSome = p.SomeSecondsTotal
stats.MemorySecondsFull = p.FullSecondsTotal
case "io":
stats.IOSecondsSome = p.SomeSecondsTotal
stats.IOSecondsFull = p.FullSecondsTotal
}
}
return stats
}

func (cg *Cgroup) readPressure(controller string) (*PressureTotals, error) {
data, err := os.ReadFile(path.Join(cg2Root, cg.subsystems[""], controller+".pressure"))
if err != nil {
return nil, err
}
pressure := &PressureTotals{}
for _, line := range strings.Split(strings.TrimSpace(string(data)), "\n") {
parts := strings.Fields(line)
if len(parts) == 0 {
continue
}
kind := parts[0]
for _, p := range parts[1:] {
if strings.HasPrefix(p, "total=") {
vStr := strings.TrimPrefix(p, "total=")
v, err := strconv.ParseUint(vStr, 10, 64)
if err != nil {
return nil, err
}
switch kind {
case "some":
pressure.SomeSecondsTotal = float64(v) / 1e6 // microseconds to seconds
case "full":
pressure.FullSecondsTotal = float64(v) / 1e6
}
break
}
}
}
return pressure, nil
}
27 changes: 27 additions & 0 deletions cgroup/psi_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cgroup

import (
"path"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestCgroupPSI(t *testing.T) {
cgRoot = "fixtures/cgroup"
cg2Root = "fixtures/cgroup"

cg, _ := NewFromProcessCgroupFile(path.Join("fixtures/proc/400/cgroup"))
stat := cg.PSI()
require.NotNil(t, stat)
assert.Equal(t, float64(465907442)/1e6, stat.CPUSecondsSome)
assert.Equal(t, float64(463529433)/1e6, stat.CPUSecondsFull)
assert.Equal(t, float64(6937313991)/1e6, stat.MemorySecondsSome)
assert.Equal(t, float64(6934649214)/1e6, stat.MemorySecondsFull)
assert.Equal(t, float64(17657662684)/1e6, stat.IOSecondsSome)
assert.Equal(t, float64(17636951020)/1e6, stat.IOSecondsFull)

cg, _ = NewFromProcessCgroupFile(path.Join("fixtures/proc/100/cgroup"))
assert.Nil(t, cg.PSI())
}
Loading
Loading