Coverage Summary for Class: KermitSyncTelemetry (com.georgeci.moneysurfer.sync.internal.telemetry)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| KermitSyncTelemetry |
100%
(6/6)
|
|
100%
(12/12)
|
100%
(88/88)
|
| KermitSyncTelemetry$Companion |
|
| Total |
100%
(6/6)
|
|
100%
(12/12)
|
100%
(88/88)
|
package com.georgeci.moneysurfer.sync.internal.telemetry
import co.touchlab.kermit.Logger
import com.georgeci.moneysurfer.sync.api.SyncError
import com.georgeci.moneysurfer.sync.api.SyncReason
import com.georgeci.moneysurfer.sync.api.SyncRequestId
import com.georgeci.moneysurfer.sync.api.SyncScope
import com.georgeci.moneysurfer.sync.api.SyncStep
import com.georgeci.moneysurfer.sync.api.SyncSummary
import com.georgeci.moneysurfer.sync.telemetry.SyncTelemetry
import org.koin.core.annotation.Single
import kotlin.time.Duration
/**
* Structured logging via Kermit. Tag `SyncTelemetry`, prefix
* `[req=…]` so a single sync run can be grep'd across noisy logs.
*
* Step-level events go to debug; lifecycle (started / completed / failed /
* cancelled) goes to info. Failure carries the typed [SyncError] for grepping
* by class.
*/
@Single(binds = [SyncTelemetry::class])
class KermitSyncTelemetry : SyncTelemetry {
private val log = Logger.withTag(TAG)
override fun onSyncStarted(
requestId: SyncRequestId,
reasons: Set<SyncReason>,
scope: SyncScope,
) {
log.i { "[req=${requestId.value}] started reasons=$reasons scope=$scope" }
}
override fun onStepEntered(requestId: SyncRequestId, step: SyncStep) {
log.d { "[req=${requestId.value}] step=${step::class.simpleName}" }
}
override fun onSyncCompleted(
requestId: SyncRequestId,
summary: SyncSummary,
duration: Duration,
) {
log.i {
"[req=${requestId.value}] completed in $duration " +
"uploaded=${summary.uploadedCount} downloaded=${summary.downloadedCount} " +
"conflicts=${summary.conflictCount} recalculated=${summary.recalculatedCount}"
}
}
override fun onSyncFailed(requestId: SyncRequestId, error: SyncError, duration: Duration) {
log.w {
"[req=${requestId.value}] failed in $duration " +
"error=${error::class.simpleName} retryable=${error.isRetryable}"
}
}
override fun onSyncCancelled(requestId: SyncRequestId, duration: Duration) {
log.i { "[req=${requestId.value}] cancelled after $duration" }
}
private companion object {
const val TAG = "SyncTelemetry"
}
}