B4: probe task store, panel API, heartbeat ingestion, agent prober
- probe package: probe_ping_task/probe_ping_node tables; task CRUD with hub save semantics (id high-water, base-diff assignment, 64-per-agent crowding refusal, auto_join cap); filing with assignment-gated insert; PingHistory weighted-median chart read over minute+hour tiers; auto-join on first Record (ensureRows). - controller: /panel/api/agent/probe-tasks* management endpoints (node id space, hub validation chain verbatim); series=ping now serves real rows from probe.PingHistory; heartbeat ingests probeResults (missing latency skipped, batch capped); config response carries probe_tasks (always present, empty = clear). - agent: per-task probe loops (immediate first probe, ticker, 900ms resolve/dial budgets, <=3 addresses, resolve overrun = no sample), result buffer drained on heartbeat and requeued on failure; task set applied before the config-hash early return.
This commit is contained in:
@@ -136,3 +136,103 @@ func DeleteAgentData(agentID int64) {
|
||||
logger.Warningf("probe: delete agent %d data: %v", agentID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// ---- B4: probe tasks, results and the latency read ----
|
||||
|
||||
// PingTasks lists every probe task with its assignments. With no
|
||||
// store the list is empty.
|
||||
func PingTasks() ([]PingTask, error) {
|
||||
st := Default()
|
||||
if st == nil {
|
||||
return []PingTask{}, nil
|
||||
}
|
||||
return st.PingTasks()
|
||||
}
|
||||
|
||||
// SavePingTask creates or replaces one probe task (see Store).
|
||||
func SavePingTask(t PingTask, base *[]int64) (int64, error) {
|
||||
st := Default()
|
||||
if st == nil {
|
||||
return 0, nil
|
||||
}
|
||||
return st.SavePingTask(t, base)
|
||||
}
|
||||
|
||||
// DeletePingTask removes one probe task and its filed history.
|
||||
func DeletePingTask(id int64) error {
|
||||
st := Default()
|
||||
if st == nil {
|
||||
return nil
|
||||
}
|
||||
return st.DeletePingTask(id)
|
||||
}
|
||||
|
||||
// SetNodePingTasks applies one agent's assignment difference.
|
||||
func SetNodePingTasks(agentID int64, tasks, base []int64) error {
|
||||
st := Default()
|
||||
if st == nil {
|
||||
return nil
|
||||
}
|
||||
return st.SetNodePingTasks(agentID, tasks, base)
|
||||
}
|
||||
|
||||
// ReorderPingTasks rewrites the panel order of the task list.
|
||||
func ReorderPingTasks(ids []int64) error {
|
||||
st := Default()
|
||||
if st == nil {
|
||||
return nil
|
||||
}
|
||||
return st.ReorderPingTasks(ids)
|
||||
}
|
||||
|
||||
// PingTasksFor reads the task list pushed to one agent on its config
|
||||
// poll. Best-effort like the rest of the ingest side: a store failure
|
||||
// reads as "no tasks" and is logged, so a broken probe.db never
|
||||
// breaks config delivery — the agent keeps its current list until a
|
||||
// poll succeeds.
|
||||
func PingTasksFor(agentID int64) []PingTaskRef {
|
||||
st := Default()
|
||||
if st == nil {
|
||||
return []PingTaskRef{}
|
||||
}
|
||||
refs, err := st.PingTasksFor(agentID)
|
||||
if err != nil {
|
||||
logger.Warningf("probe: ping tasks for agent %d: %v", agentID, err)
|
||||
return []PingTaskRef{}
|
||||
}
|
||||
return refs
|
||||
}
|
||||
|
||||
// PingTaskNames reads one agent's probe chart labels.
|
||||
func PingTaskNames(agentID int64) (map[string]string, error) {
|
||||
st := Default()
|
||||
if st == nil {
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
return st.PingTaskNames(agentID)
|
||||
}
|
||||
|
||||
// InsertPings files one agent's probe results at the arrival stamp.
|
||||
// Best-effort (heartbeat path): failures are logged and swallowed.
|
||||
func InsertPings(agentID int64, results []PingResult) {
|
||||
if len(results) == 0 {
|
||||
return
|
||||
}
|
||||
st := Default()
|
||||
if st == nil {
|
||||
return
|
||||
}
|
||||
if err := st.InsertPings(agentID, results, time.Now().Unix()); err != nil {
|
||||
logger.Warningf("probe: insert pings agent %d: %v", agentID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// PingHistory is the B4 read port for one agent's latency window.
|
||||
// With no store the window is simply empty.
|
||||
func PingHistory(agentID int64, sp Span) ([]PingRow, map[string]float64, error) {
|
||||
st := Default()
|
||||
if st == nil {
|
||||
return []PingRow{}, map[string]float64{}, nil
|
||||
}
|
||||
return st.PingHistory(agentID, sp)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user