Zbieranie i analiza metryk requestów HTTP.
import rip.nerd.kitsunenet.metrics.KNETMetrics
val metrics = KNETMetrics()
val client = KNETClient.builder()
.addInterceptor(metrics.interceptor())
.build()
// Po wykonaniu requestów
val stats = metrics.getStats()
println("Total requests: ${stats.totalRequests}")
println("Success: ${stats.successCount}")
println("Errors: ${stats.errorCount}")
println("Success rate: ${stats.successRate}%")
println("Avg latency: ${stats.averageLatencyMs}ms")
println("P50 latency: ${stats.p50LatencyMs}ms")
println("P95 latency: ${stats.p95LatencyMs}ms")
println("P99 latency: ${stats.p99LatencyMs}ms")
val endpointStats = metrics.getStatsByEndpoint()
endpointStats.forEach { (endpoint, stats) ->
println("$endpoint:")
println(" Requests: ${stats.totalRequests}")
println(" Avg: ${stats.averageLatencyMs}ms")
println(" Errors: ${stats.errorRate}%")
}
import rip.nerd.kitsunenet.metrics.KNETConnectionQuality
val connectionQuality = KNETConnectionQuality.Builder(context)
.pingUrl("https://api.example.com/ping")
.checkInterval(30_000) // Co 30s
.build()
// Start monitorowania
connectionQuality.start()
// Pobierz aktualną jakość
val quality = connectionQuality.currentQuality
println("Level: ${quality.level}") // EXCELLENT, GOOD, FAIR, POOR
println("Latency: ${quality.latencyMs}ms")
println("Type: ${quality.connectionType}") // WIFI, CELLULAR, NONE
// Nasłuchuj zmian
connectionQuality.observe { newQuality ->
when (newQuality.level) {
ConnectionLevel.POOR -> showSlowConnectionWarning()
ConnectionLevel.OFFLINE -> showOfflineMessage()
else -> hideWarnings()
}
}
val metrics = KNETMetrics()
// Nasłuchuj każdego requestu
metrics.onRequest { request, response, durationMs, error ->
// Loguj do analytics
analytics.log("api_request", mapOf(
"url" to request.url,
"method" to request.method,
"status" to (response?.statusCode ?: 0),
"duration_ms" to durationMs,
"success" to (error == null)
))
// Alert przy slow requests
if (durationMs > 5000) {
alertSlowRequest(request, durationMs)
}
// Alert przy errors
if (error != null) {
reportError(request, error)
}
}
// JSON
val json = metrics.exportToJson()
// Prometheus format
val prometheus = metrics.exportToPrometheus()
// Custom format
val report = metrics.generateReport { stats ->
buildString {
appendLine("=== API Metrics Report ===")
appendLine("Period: ${stats.periodStart} - ${stats.periodEnd}")
appendLine("Total: ${stats.totalRequests}")
appendLine("Success rate: ${stats.successRate}%")
appendLine("Avg latency: ${stats.averageLatencyMs}ms")
}
}
@Composable
fun MetricsDashboard(metrics: KNETMetrics) {
val stats by metrics.statsFlow.collectAsState()
Column {
Text("API Metrics", style = MaterialTheme.typography.h6)
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
MetricCard("Requests", stats.totalRequests.toString())
MetricCard("Success", "${stats.successRate.toInt()}%")
MetricCard("Avg", "${stats.averageLatencyMs}ms")
}
// Error rate chart
if (stats.errorRate > 5) {
Text("⚠️ High error rate!", color = Color.Red)
}
}
}
@Composable
fun MetricCard(label: String, value: String) {
Card(Modifier.padding(8.dp)) {
Column(Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally) {
Text(value, style = MaterialTheme.typography.h4)
Text(label, style = MaterialTheme.typography.caption)
}
}
}