fix(cost): wire MeteringService lifecycle for persistent cost tracking (#3310)#3315
Merged
Conversation
#3310) - Call metering.load() at startup to restore persisted records - Add initial JSONL replay at startup to backfill metering data for sessions that already have JSONL files (watcher only fires on changes) - Add metering.save() to graceful shutdown handler - Add periodic metering.save() every 5 minutes (same cadence as metrics) Root cause: MeteringService was instantiated but load()/save() were never called, and the JSONL watcher only processes file changes β not existing content. This meant cost data was always zero on every server restart.
Contributor
There was a problem hiding this comment.
β Approved β code review complete, pending CI.
Review summary:
- Lifecycle wiring for MeteringService:
load()at startup,save()on shutdown + periodic (5min) - JSONL backfill for sessions with
monitorOffset > 0β correct, only replays sessions with existing data - Error handling consistent: all load/save/backfill failures are non-critical (logged or silently caught)
- Follows existing metrics save pattern (same interval, same shutdown handler approach)
- No secrets, no security concerns
- Targets
developβ
Minor note: No dedicated tests for the server.ts wiring, but this is lifecycle glue β the MeteringService itself has tests. Acceptable for this scope.
Will merge once CI goes green.
OneStepAt4time
pushed a commit
that referenced
this pull request
May 16, 2026
Adds entries Hermes missed for: --json-logs (#3519), CLI shortcuts (#3521), ag run timeout (#3518/#3498), auto MCP wiring (#3501), Windows workDir (#3502), cost tracking fixes (#3311), metering lifecycle (#3315), preflight auth (#3314), project-local config (#3313), /send non-blocking (#3437), ACP notifications wired (#3463), design tokens system-wide (#3456), auth persistence (#3386), protobufjs CVE (#3218), and 16 more.
aegis-gh-agent Bot
pushed a commit
that referenced
this pull request
May 16, 2026
* chore(release): bump version to 0.6.7 (#3495) - package.json: 0.6.7-preview.1 β 0.6.7 - .release-please-manifest.json: 0.6.7-preview.1 β 0.6.7 - Helm charts: version + appVersion aligned - CHANGELOG.md: Unreleased β 0.6.7 release header - Docs: version references updated Key fixes in this release: - #3479: sendPrompt uses request() with 5s ack timeout - #3484: proactive keys.json reload + orphan auth-token detection - Zero-config first run (ag run, ag init) - ACP cutover complete (tmux removed) - 150+ PRs since v0.6.6 * docs(changelog): add 93 missing entries for PRs #3250-#3517 Covers all merged PRs since the last changelog update (#3254): - 11 Added (cost tracking, runner, CLI subcommands, dashboard features) - 4 Changed (auth refactor, design tokens, route cleanup) - 49 Fixed (ACP, CLI, API, dashboard, deploy, security, CI) - 26 Documentation (RBAC, competitive, guides, README, ADR) - 2 Dependencies (dashboard deps, OTel) Requested by Scribe after review identified ~80+ missing entries. * docs(changelog): editorial follow-up β 36 remaining PRs from Scribe pass Adds entries Hermes missed for: --json-logs (#3519), CLI shortcuts (#3521), ag run timeout (#3518/#3498), auto MCP wiring (#3501), Windows workDir (#3502), cost tracking fixes (#3311), metering lifecycle (#3315), preflight auth (#3314), project-local config (#3313), /send non-blocking (#3437), ACP notifications wired (#3463), design tokens system-wide (#3456), auth persistence (#3386), protobufjs CVE (#3218), and 16 more. * docs(changelog): comprehensive 0.6.7 changelog β all 141 PRs, Boss's categories Complete rewrite of the 0.6.7 section: - 150 commits, 141 unique PRs β every single one listed - Organized by Boss's requested categories: Security (21), Features (19), Bug Fixes β ACP (14), Bug Fixes β CLI (13), Bug Fixes β API (12), Bug Fixes β Dashboard (14), Bug Fixes β Other (8), Documentation (42), Dependencies & Chore (6) - No summarization β each PR gets its own bullet - All PR references verified against git log Co-authored-by: Scribe <scribe@openclaw.ai> --------- Co-authored-by: Argus <argus@openclaw.ai> Co-authored-by: Hephaestus <hep@aegis.dev> Co-authored-by: Scribe <scribe@openclaw.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #3310
The
MeteringServicewas instantiated but itsload()/save()lifecycle methods were never called, and theJsonlWatcheronly processes file changes β not existing content. This meant cost data was always zero after every server restart.Changes
metering.load()after instantiation to restore persisted records from previous runsmonitorOffset > 0). This backfills metering for sessions completed before the current server startmetering.save()to the graceful shutdown handler (alongside existingmetrics.save())meteringSaveInterval(5-minute cadence, same as metrics) to persist data periodicallyVerification
Notes
monitorOffset > 0to avoid re-processing sessions where no data has been read yet (those will be picked up by the watcher naturally)