Repository navigation
Description
Blocker: yes. #28 and #29 send their data through this.
Part of the monitoring agent (contract v0.2.1). Order: #26 → #27 → #28 → #29 → #30, with #9.
Defect
- The contract requires that the agent keeps unsent samples and events on disk (sections 4 and 6).
- The CLI has no store for this.
Cost
- Without this store, a network failure or a restart loses samples. The charts then have gaps.
- The contract requires the same event id for each resend. Without a store, a resend gets a new id.
Benefit of the fix
- An outage of up to 24 hours loses no data.
- A resend is safe. The control plane keeps one sample for each minute, and applies each event id one time.
Fix
-
Keep two queues in the state folder: samples and events. Write each change to a temporary file, sync it, then rename it.
-
Samples: keep at most 1440 (24 hours). When the queue is full, drop the oldest sample first.
-
Set
recorded_atwhen the agent measures. Do not change it on a resend. -
Events: make the ULID when the event goes into the queue. Keep the id with the event. Use the same id for each resend.
-
Before a value goes into a queue, compare it with the ranges of the contract. Cut
data.errorto 2000 characters. Reason: one bad value makes a400, and a400drops the full request. -
Send at most 240 samples and at most 100 events in one request. Send the oldest first. Send one request at a time (the limit is 30 requests each minute for each token).
-
In each cycle, do these steps in this order: send the events, send the samples with the status, then poll for commands (enhancement: Run
agent.updateandagent.restartone time only #29). Events first closes finished commands before the poll. -
Apply the rules of the contract for each reply:
Reply Samples Events 200drop the samples that were sent, also the rejected ones drop 400drop, and write a log line drop, and write a log line 401keep, and try again each 5 minutes keep, and try again each 5 minutes 422drop — 429keep, and wait for Retry-Afterkeep, and wait for Retry-After5xx, or no replykeep, and wait longer after each failure keep, and wait longer after each failure -
Continue to measure while the sender waits.
-
At each start, put
agent.startedwith the version in the event queue.
Decision necessary
- How does the agent keep its queues on disk?
- Recommendation: plain JSON files in the state folder, written as step 1 tells. The largest queue is 1440 samples, about 300 KB. No new dependency.
- Other option:
go.etcd.io/bbolt, a small embedded database. It adds a dependency and a file format.
- Where do the event ids (ULIDs) come from?
- Recommendation:
github.com/oklog/ulid/v2. It is small and well known. - Other option: about 30 lines of our own code.
- Recommendation:
Completion checks
- The queues are the same after an agent restart and after a server reboot.
- After a
503, the samples stay in the queue. After a400, they go, and a log line shows why. - Sample 1441 drops the oldest sample.
- 1000 samples go in 5 requests of at most 240.
- A resent event has the same id.
- After a
429, the agent waits for the time inRetry-After. - A
kill -9during a write leaves a queue file that the agent can read.
Activity
feat(agent): keep samples and events on disk until the control plane …
[-]Keep the agent's samples and events on disk until the control plane accepts them[/-][+]enhancement: Keep the agent's samples and events on disk until the control plane accepts them[/+]