const std = @import("std"); const Self = @This(); const RawStats = struct { user: u32, nice: u32, system: u32, idle: u32, iowait: u32, irq: u32, softirq: u32, steal: u32, guest: u32, guest_nice: u32, }; pub const Stats = struct { all: u32, all_idle: u32, all_active: u32, pub fn active_ratio(self: Stats) f32 { return @as(f32, @floatFromInt(self.all_active)) / @as(f32, @floatFromInt(self.all)); } pub fn active_perc(self: Stats) u8 { return @intCast(100 * self.all_active / self.all); } }; fh: std.fs.File, buf: []u8, pub fn init(alloc: std.mem.Allocator) !Self { const fh = try std.fs.openFileAbsolute("/proc/stat", .{ .mode = .read_only }); errdefer fh.close(); const buf = try alloc.alloc(u8, 512); errdefer alloc.free(buf); return .{ .fh = fh, .buf = buf }; } pub fn deinit(self: Self, alloc: std.mem.Allocator) void { self.fh.close(); alloc.free(self.buf); } pub fn get(self: Self) !Stats { try self.fh.seekTo(0); const line = try self.fh.reader().readUntilDelimiter(self.buf, '\n'); var tokens = std.mem.tokenizeScalar(u8, line, ' '); _ = tokens.next(); // skip "cpu" var raw: RawStats = undefined; inline for (std.meta.fields(RawStats)) |f| { const token = tokens.next() orelse return error.MissingStat; @field(raw, f.name) = try std.fmt.parseInt(f.type, token, 10); } const idle = raw.idle + raw.iowait; const active = raw.user + raw.nice + raw.system + raw.irq + raw.softirq + raw.steal; return .{ .all = idle + active, .all_idle = idle, .all_active = active }; } pub fn get_delta(self: Self, prev: *Stats) !Stats { const next = try self.get(); const delta: Stats = .{ .all = next.all - prev.all, .all_idle = next.all_idle - prev.all_idle, .all_active = next.all_active - prev.all_active, }; prev.* = next; return delta; } pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const alloc = gpa.allocator(); const monitor = try Self.init(alloc); defer monitor.deinit(alloc); var stats = try monitor.get(); std.time.sleep(std.time.ns_per_s); const delta = try monitor.get_delta(&stats); std.debug.print("{any}\n", .{delta}); std.debug.print("{d:.6} {d}\n", .{ delta.active_ratio(), delta.active_perc() }); }