Skip to content

Commit

Permalink
metrics: collect disk usage from internal metrics
Browse files Browse the repository at this point in the history
use `mount.total` and `mount.used` from internal metrics
instead of parsing `df` output.
  • Loading branch information
tomasmatus committed Oct 1, 2024
1 parent ab36148 commit ad6a56d
Showing 1 changed file with 16 additions and 49 deletions.
65 changes: 16 additions & 49 deletions pkg/metrics/metrics.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ const CURRENT_METRICS = [
{ name: "cpu.core.nice", derive: "rate" },
{ name: "disk.dev.read", units: "bytes", derive: "rate" },
{ name: "disk.dev.written", units: "bytes", derive: "rate" },
{ name: "mount.total", units: "bytes" },
{ name: "mount.used", units: "bytes" },
];

const CPU_TEMPERATURE_METRICS = [
Expand Down Expand Up @@ -282,15 +284,11 @@ class CurrentMetrics extends React.Component {
this.onMetricsUpdate = this.onMetricsUpdate.bind(this);
this.onTemperatureUpdate = this.onTemperatureUpdate.bind(this);
this.onPrivilegedMetricsUpdate = this.onPrivilegedMetricsUpdate.bind(this);
this.updateMounts = this.updateMounts.bind(this);
this.updateLoad = this.updateLoad.bind(this);

cockpit.addEventListener("visibilitychange", this.onVisibilityChange);
this.onVisibilityChange();

// regularly update info about filesystems
this.updateMounts();

// there is no internal metrics channel for load yet; see https://github.com/cockpit-project/cockpit/pull/14510
this.updateLoad();
}
Expand Down Expand Up @@ -359,51 +357,6 @@ class CurrentMetrics extends React.Component {
return result;
}

updateMounts() {
Promise.all([
/* df often exits with non-zero if it encounters any filesystem it can't read;
but that's fine, get info about all the others */
cockpit.script("df --local --exclude-type=tmpfs --exclude-type=devtmpfs --block-size=1 --output=target,size,avail,pcent || true",
{ err: "message" }),
cockpit.file("/proc/mounts").read()
])
.then(([df_out, mounts_out]) => {
const hide = this.hideMounts(mounts_out);

// skip first line with the headings
const mounts = [];
df_out.trim()
.split("\n")
.slice(1)
.forEach(s => {
const fields = s.split(/ +/);
if (fields.length != 4) {
console.warn("Invalid line in df:", s);
return;
}

if (hide.has(fields[0]))
return;
mounts.push({
target: fields[0],
size: Number(fields[1]),
avail: Number(fields[2]),
use: Number(fields[3].slice(0, -1)), /* strip off '%' */
});
});

debug("df parsing done:", JSON.stringify(mounts));
this.setState({ mounts });

// update it again regularly
window.setTimeout(this.updateMounts, 10000);
})
.catch(ex => {
console.warn("Failed to run df or read /proc/mounts:", ex.toString());
this.setState({ mounts: [] });
});
}

updateLoad() {
cockpit.file("/proc/loadavg").read()
.then(content => {
Expand Down Expand Up @@ -465,6 +418,8 @@ class CurrentMetrics extends React.Component {
this.cgroupMemoryNames = data.metrics[10].instances.slice();
console.assert(data.metrics[14].name === 'disk.dev.read');
this.disksNames = data.metrics[14].instances.slice();
console.assert(data.metrics[16].name === 'mount.total');
this.mountPoints = data.metrics[16].instances.slice();
debug("metrics message was meta, new net instance names", JSON.stringify(this.netInterfacesNames));
return;
}
Expand Down Expand Up @@ -548,6 +503,18 @@ class CurrentMetrics extends React.Component {
if (notMappedContainers.length !== 0) {
this.update_podman_name_mapping(notMappedContainers);
}

const mountsTotal = this.samples[16];
const mountsUsed = this.samples[17];
newState.mounts = mountsTotal.map((mountTotal, i) => {
return {
target: this.mountPoints[i],
size: mountTotal,
avail: mountTotal - mountsUsed[i],
use: Math.round(mountsUsed[i] / mountTotal * 100),
};
});

this.setState(newState);
}

Expand Down

0 comments on commit ad6a56d

Please sign in to comment.