📊 Metryki

Zbieranie i analiza metryk requestów HTTP.

Metrics Collector

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")

Per-endpoint stats

val endpointStats = metrics.getStatsByEndpoint()

endpointStats.forEach { (endpoint, stats) ->
    println("$endpoint:")
    println("  Requests: ${stats.totalRequests}")
    println("  Avg: ${stats.averageLatencyMs}ms")
    println("  Errors: ${stats.errorRate}%")
}

Connection Quality

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()
    }
}

Real-time monitoring

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)
    }
}

Export metryk

// 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")
    }
}

Dashboard widget

@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)
        }
    }
}

📚 Zobacz też