diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-17 19:04:34 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-17 19:04:34 +0200 |
| commit | c521d9eb71c9ca96348598d20eecb5ffd746aabf (patch) | |
| tree | 7ffcc2d0426bfaeb6d6944c9360466daed864876 /lib | |
| parent | 1aa67dbe3e711617895d7b1d6e4dffccc74fa95a (diff) | |
| download | conky-theme-udt-c521d9eb71c9ca96348598d20eecb5ffd746aabf.tar.gz conky-theme-udt-c521d9eb71c9ca96348598d20eecb5ffd746aabf.zip | |
feat: add a byte-rate counter for interface statistics
Mirrors new_cpu_counter: cumulative counters need two samples to yield a
rate, and each direction carries its own previous reading.
Clamps a negative delta to zero rather than letting a 32-bit wrap or an
interface reset produce a spike. One bogus sample sets the shared autoscale
and flattens the entire window.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/data.lua | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/data.lua b/lib/data.lua index 2047ef8..9f20d1f 100644 --- a/lib/data.lua +++ b/lib/data.lua @@ -113,6 +113,43 @@ function M.new_cpu_counter() } end +-- A stateful byte-rate counter, for an interface's rx/tx totals. +-- +-- Same shape as new_cpu_counter and for the same reason: the counters are +-- cumulative, so one reading cannot produce a rate, and each direction needs +-- its own previous sample. +-- +-- `fallback_dt` is the draw interval, used when two samples land in the same +-- clock second. os.time() resolves to whole seconds and the dashboard draws +-- every two, so equal timestamps are ordinary, not exceptional. +function M.new_rate_counter(fallback_dt) + return { + prev_bytes = nil, + prev_time = nil, + -- Returns bytes per second since the previous sample, or nil when there is + -- no usable delta (first call, or a nil reading from a vanished interface). + sample = function(self, bytes, now) + if type(bytes) ~= 'number' then return nil end + now = now or os.time() + local pb, pt = self.prev_bytes, self.prev_time + self.prev_bytes, self.prev_time = bytes, now + if not pb then return nil end + + local dt = now - pt + -- Same second, or a clock that went backwards over an NTP step. + if dt <= 0 then dt = fallback_dt or 2 end + + local db = bytes - pb + -- A negative delta is a 32-bit wrap or an interface reset. Zero, never + -- the huge positive the wrap arithmetic would imply: one bogus sample + -- sets the shared autoscale and flattens the whole window. + if db < 0 then db = 0 end + + return db / dt + end, + } +end + -- Per-core jiffies from /proc/stat, in file order, so entry N is core N. -- -- Separate from cpu_times() rather than a flag on it: the aggregate is a |
