fix: declare plugin interval so stale data waits two full intervals
The server inferred each plugin's collection interval from the gap between the last two received PLG samples, then expired data at interval * 3. After an outage this guess was wrong: the request_update re-send of collect-once InfoPlugins produced two close samples, yielding a tiny inferred interval that purged permanent info data minutes after recovery. Clients now declare each plugin's interval in the PLG message (_interval). The server uses it directly (from the first post-recovery sample), expiring at interval * 3 so live data survives at least two full intervals; interval 0 marks collect-once InfoPlugins that never go stale. Legacy clients omit the field and fall back to the previous inferred-gap behavior. Adds _interval to all three clients: hbc, hbc_mini.py, hbc_mini.c. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+11
-4
@@ -667,6 +667,7 @@ static void plugin_os_info(conn_t *c, const config_t *cfg) {
|
||||
if (osver[0]) kv_set(&d, "distro_version_id", osver);
|
||||
}
|
||||
#endif
|
||||
kv_set_int(&d, "_interval", 0); /* InfoPlugin: collect-once, never stale */
|
||||
conn_send(c, "PLG", &d);
|
||||
LOGI("sent os_info");
|
||||
}
|
||||
@@ -781,6 +782,7 @@ static void plugin_cpu_monitor(conn_t *c, const config_t *cfg) {
|
||||
}
|
||||
read_cpu_extras(&d);
|
||||
kv_set_dbl(&d, "_timestamp", now_ts());
|
||||
kv_set_int(&d, "_interval", cfg->cpu_interval);
|
||||
conn_send(c, "PLG", &d);
|
||||
LOGD("sent cpu_monitor");
|
||||
}
|
||||
@@ -796,7 +798,7 @@ static void plugin_cpu_monitor(conn_t *c, const config_t *cfg) {
|
||||
static void mem_send(conn_t *c,
|
||||
long long tot, long long used, long long av, long long fr,
|
||||
long long act, long long ina, long long cac, long long buf,
|
||||
long long stot, long long sused) {
|
||||
long long stot, long long sused, int interval) {
|
||||
kvdict_t d; kv_clear(&d);
|
||||
kv_set(&d, "plugin", "memory_monitor");
|
||||
kv_set_ull(&d, "memory_total", (unsigned long long)tot);
|
||||
@@ -819,6 +821,7 @@ static void mem_send(conn_t *c,
|
||||
kv_set(&d, "swap_percent", pct);
|
||||
}
|
||||
kv_set_dbl(&d, "_timestamp", now_ts());
|
||||
kv_set_int(&d, "_interval", interval);
|
||||
conn_send(c, "PLG", &d);
|
||||
LOGD("sent memory_monitor");
|
||||
}
|
||||
@@ -863,7 +866,7 @@ static void plugin_memory_monitor(conn_t *c, const config_t *cfg) {
|
||||
/* values from /proc/meminfo are in kB */
|
||||
mem_send(c, tot*1024, used*1024, av*1024, fr*1024,
|
||||
act*1024, ina*1024, cac*1024, buf*1024,
|
||||
stot*1024, (stot-sfr)*1024);
|
||||
stot*1024, (stot-sfr)*1024, cfg->mem_interval);
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
@@ -889,7 +892,7 @@ static void plugin_memory_monitor(conn_t *c, const config_t *cfg) {
|
||||
long long cac = (long long)v_cache * ps;
|
||||
long long av = fr + ina + cac; if (av > tot) av = tot;
|
||||
long long used = tot - av;
|
||||
mem_send(c, tot, used, av, fr, act, ina, cac, 0, 0, 0);
|
||||
mem_send(c, tot, used, av, fr, act, ina, cac, 0, 0, 0, cfg->mem_interval);
|
||||
}
|
||||
|
||||
#elif defined(__NetBSD__)
|
||||
@@ -910,7 +913,7 @@ static void plugin_memory_monitor(conn_t *c, const config_t *cfg) {
|
||||
long long used = tot - av;
|
||||
long long stot = (long long)uvm.swpages * ps;
|
||||
long long sinuse = (long long)uvm.swpginuse * ps;
|
||||
mem_send(c, tot, used, av, fr, act, ina, 0, 0, stot, sinuse);
|
||||
mem_send(c, tot, used, av, fr, act, ina, 0, 0, stot, sinuse, cfg->mem_interval);
|
||||
}
|
||||
|
||||
#endif /* platform memory */
|
||||
@@ -962,6 +965,7 @@ static void plugin_disk_monitor(conn_t *c, const config_t *cfg) {
|
||||
char *jval = malloc(MAX_VAL + 1);
|
||||
if (jval) { snprintf(jval, MAX_VAL, "@%s", json); kv_set(&d, "partitions", jval); free(jval); }
|
||||
kv_set_dbl(&d, "_timestamp", now_ts());
|
||||
kv_set_int(&d, "_interval", cfg->disk_interval);
|
||||
conn_send(c, "PLG", &d);
|
||||
free(json);
|
||||
LOGD("sent disk_monitor");
|
||||
@@ -1067,6 +1071,7 @@ static void plugin_network_monitor(conn_t *c, const config_t *cfg) {
|
||||
char *jval = malloc(MAX_VAL + 1);
|
||||
if (jval) { snprintf(jval, MAX_VAL, "@%s", json); kv_set(&d, "interfaces", jval); free(jval); }
|
||||
kv_set_dbl(&d, "_timestamp", now_ts());
|
||||
kv_set_int(&d, "_interval", cfg->net_interval);
|
||||
conn_send(c, "PLG", &d);
|
||||
free(json);
|
||||
LOGD("sent network_monitor");
|
||||
@@ -1125,6 +1130,7 @@ static void plugin_ping_monitor(conn_t *c, const config_t *cfg) {
|
||||
}
|
||||
}
|
||||
kv_set_dbl(&d, "_timestamp", now_ts());
|
||||
kv_set_int(&d, "_interval", cfg->ping_interval);
|
||||
conn_send(c, "PLG", &d);
|
||||
LOGD("sent ping_monitor");
|
||||
}
|
||||
@@ -1194,6 +1200,7 @@ static void plugin_nagios_runner(conn_t *c, const config_t *cfg) {
|
||||
parse_perfdata(output, &d, name);
|
||||
}
|
||||
kv_set_dbl(&d, "_timestamp", now_ts());
|
||||
kv_set_int(&d, "_interval", cfg->nagios_interval);
|
||||
conn_send(c, "PLG", &d);
|
||||
LOGD("sent nagios_runner");
|
||||
}
|
||||
|
||||
+2
-2
@@ -955,7 +955,7 @@ async def _run_info_plugins(conn: AsyncConnection, plugins: List[Plugin]):
|
||||
try:
|
||||
data = await plugin.collect()
|
||||
if data:
|
||||
await conn.sendto({"plugin": plugin.name, **data}, "PLG")
|
||||
await conn.sendto({"plugin": plugin.name, **data, "_interval": plugin.interval}, "PLG")
|
||||
log.info("sent %s", plugin.name)
|
||||
except Exception as e:
|
||||
log.error("%s collect: %s", plugin.name, e)
|
||||
@@ -968,7 +968,7 @@ async def _run_monitor_group(conn: AsyncConnection, plugins: List[Plugin], inter
|
||||
try:
|
||||
data = await plugin.collect()
|
||||
if data:
|
||||
await conn.sendto({"plugin": plugin.name, **data}, "PLG")
|
||||
await conn.sendto({"plugin": plugin.name, **data, "_interval": plugin.interval}, "PLG")
|
||||
log.debug("sent %s", plugin.name)
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user