Skip to content

Report a startup event to trace, off the main thread and with an opt-out - #218

Merged
dmccoystephenson merged 1 commit into
mainfrom
usage-reporting-via-trace
Sep 12, 2026
Merged

Report a startup event to trace, off the main thread and with an opt-out#218
dmccoystephenson merged 1 commit into
mainfrom
usage-reporting-via-trace

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

Summary

Usage reporting via the trace service is added to Viron. On start-up, once the Spring context is ready (ApplicationReadyEvent), one startup event is sent; the client is closed when the context shuts down. The change is entirely additive: no existing class, property or behaviour is altered.

  • TraceClient.java (trace-client-java 0.1.0, MIT) is vendored as a single file under preponderous.viron.trace, unmodified apart from the package line, together with its test. No dependency is added.
  • UsageReporter (@Component) builds the client from usage-reporting.* properties, sends the event, and closes the client in @PreDestroy.
  • The version tag is filled in from the Maven project version at build time (usage-reporting.version=@project.version@, resource-filtered by the Spring Boot parent), with the jar's Implementation-Version as the fallback.

Guarantees

The client returns immediately (the HTTP call runs on a single daemon thread), never throws (a server that is down, slow or rejecting the key is a dropped report logged at debug level), and is bounded (at most 256 reports are queued; beyond that new ones are dropped). A blank key or a malformed endpoint yields a disabled client rather than a failed start-up, so the report can never be the reason the service does not come up or a request waits.

What is sent, and what is not

Sent, once per start-up: application: "viron", name: "startup", tags version (the project version) and service: "true" (so hosted services can be hidden from the fleet view on the operator page). Nothing is sent per request, and no usernames, hostnames, IPs, paths, or any data the service holds are ever included.

Opt-out

Configured in application.properties with environment overrides, following the file's existing ${VAR:default} convention:

Property Environment variable Default
usage-reporting.enabled USAGE_REPORTING_ENABLED true
usage-reporting.endpoint USAGE_REPORTING_ENDPOINT https://trace.danielstephenson.dev
usage-reporting.key USAGE_REPORTING_KEY the bundled program key

USAGE_REPORTING_ENABLED=false turns it off. The README, sample.env and compose.yml are updated to say so. No first-run notice is needed since the service is operator-hosted; an INFO line at start-up states whether reporting is on and how to turn it off.

Test plan

  • ./mvnw test -B on JDK 21 (the CI toolchain): 454 → 472 tests, 0 failures (18 added: 10 vendored client tests, 7 UsageReporterTest unit tests, 1 UsageReporterStartupEventTest).
  • src/test/resources/application.properties sets usage-reporting.enabled=false, so no context start-up in the suite contacts the real service; the one Spring test that turns it on points the endpoint at a loopback JDK HttpServer via @DynamicPropertySource and asserts on the event that arrives.
  • Built jar checked with unzip -l: BOOT-INF/classes/preponderous/viron/trace/TraceClient.class and UsageReporter.class are present, and the packaged application.properties carries usage-reporting.version=0.7.0-SNAPSHOT-8-8-2026.
  • Local stub proof: the real jar was run (java -jar target/viron-0.7.0-SNAPSHOT-8-8-2026.jar --server.port=0 with USAGE_REPORTING_ENDPOINT=http://127.0.0.1:47311) against a 10-line Python http.server handler. Exactly one request arrived, POST /api/metrics, Authorization: Bearer <the bundled key>, body:
    {"application":"viron","name":"startup","tags":{"service":"true","version":"0.7.0-SNAPSHOT-8-8-2026"}}
  • Opt-out proof: the same run with USAGE_REPORTING_ENABLED=false logged Usage reporting is off. and the stub received nothing.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WYoD9SsaRz8PjakTSHhmn6


drafted by Claude on behalf of Daniel Stephenson

…n opt-out

The trace client (trace-client-java 0.1.0, MIT) is vendored as one file
under preponderous.viron.trace, unmodified apart from the package line,
together with its test. A UsageReporter component sends a single
"startup" event once the context is ready (ApplicationReadyEvent),
tagged with the project version (filled in from the Maven version at
build time, the jar's Implementation-Version as a fallback) and
service=true, and closes the client on context shutdown. Nothing is sent
per request, and nothing about users, hosts, addresses or data.

The client returns immediately, never throws, and queues at most 256
reports, so an unreachable trace server is a dropped report rather than
a slow start-up. Reporting is configured through usage-reporting.*
properties with environment overrides; USAGE_REPORTING_ENABLED=false
turns it off. A blank key or a malformed endpoint yields a disabled
client rather than a failed start-up.

Tests keep reporting off (src/test/resources/application.properties) so
no context start-up contacts the real service; one Spring test points
it at a loopback stub and checks the event that arrives.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYoD9SsaRz8PjakTSHhmn6
@dmccoystephenson
dmccoystephenson merged commit 614d06b into main Sep 12, 2026
3 checks passed
@dmccoystephenson
dmccoystephenson deleted the usage-reporting-via-trace branch September 12, 2026 04:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant