Telemetry (install id, node types, errors) only posted from the server-only
PlatformLogger, so app launches on desktop / Android / iOS were invisible. Ben
wanted launch tracking on every non-WASM platform, plus platform and hostName
in the telemetry payload.
No shared telemetry path existed. The poster, the endpoint constant, and the CIO
client all lived in server/. The KrillLog model also carried no platform or
host identification.
platform: Platform and base64 hostName: String to
shared/.../telemetry/KrillLog.kt.shared/.../telemetry/TelemetryReporter (commonMain) with pure, tested
seams — shouldReport (WASM excluded), encodeHost (base64), buildLaunchLog,
a post(log, client) that swallows every Throwable and closes the client, and
a fire-and-forget reportAppLaunch().internal expect fun buildTelemetryHttpClient()
— CIO (jvm/android), Darwin (ios), throwing stub (wasmJs, never reached). It uses
default system trust, deliberately NOT the app’s peer-trust httpClient,
because the telemetry endpoint is a public-CA host the peer-trust manager would
reject.launch { runCatching { … } } in
composeApp/commonMain/.../App.kt’s existing LaunchedEffect(Unit), so it runs
concurrently with nodeManager.init and never blocks the ready flip. WASM is a
runtime no-op via the reporter guard.PlatformLogger.postLogs now builds the richer log with the two new
fields and delegates the POST to TelemetryReporter.post, dropping its own
endpoint constant.httpClient — that client’s ReloadableX509TrustManager only trusts peer
certs from the Krill trust dir and will fail TLS against a public CA. Build a
fresh client with default system trust.commonMain needs an explicit per-target engine factory —
Ktor’s no-arg HttpClient() engine auto-discovery does not work on iOS-native or
JS, so it cannot be relied on in KMP common code.LaunchedEffect must be
launch-ed (not awaited inline) and double-guarded (runCatching at the call
site + a try/catch inside the suspend fn) so nothing can bubble into the
composition or stall startup.