🔗 Request Correlation

KNETRequestCorrelation automatycznie dodaje unikalne ID do każdego requestu, umożliwiając śledzenie przepływu przez cały system.

💡 Kiedy używać?
  • Debugowanie - łatwe znajdowanie logów dla konkretnego requestu
  • Distributed tracing - śledzenie przez microservices
  • Error tracking - powiązanie błędów z requestem
  • Analytics - analiza przepływu użytkownika

📦 Import

import rip.nerd.kitsunenet.util.KNETRequestCorrelation
import rip.nerd.kitsunenet.util.withCorrelationId
import rip.nerd.kitsunenet.util.getCorrelationId

🚀 Szybki start

val correlation = KNETRequestCorrelation.create()

// Jako interceptor
val client = KNETClient.builder()
    .addInterceptor(correlation.interceptor())
    .build()

// Każdy request ma automatyczny header:
// X-Correlation-ID: 550e8400-e29b-41d4-a716-446655440000

val response = client.get("https://api.example.com/users")

// Pobierz ID ostatniego requestu
val lastId = correlation.getLastCorrelationId()
println("Request ID: $lastId")

📊 Tracing

// Pobierz trace dla konkretnego ID
val trace = correlation.getTrace(correlationId)

println("Request: ${trace.request.url}")
println("Response: ${trace.response?.statusCode}")
println("Duration: ${trace.durationMs}ms")
println("Success: ${trace.isSuccess}")

// Pobierz wszystkie traces
val allTraces = correlation.getAllTraces()

// Filtruj po URL
val apiTraces = correlation.getTracesForUrl(Regex("api\\.example\\.com"))

// Pobierz nieudane
val failures = correlation.getFailedTraces()

// Pobierz wolne (> 2s)
val slowRequests = correlation.getSlowTraces(2000)

🔧 Konfiguracja

val correlation = KNETRequestCorrelation.builder()
    // Custom header name
    .headerName("X-Request-ID")

    // Parent ID dla chain requestów
    .parentHeaderName("X-Parent-ID")
    .includeParentId(true)

    // Custom generator
    .idGenerator {
        "req_${System.currentTimeMillis()}_${Random.nextInt(1000)}"
    }

    // Tracing
    .enableTracing(true)
    .maxTraceHistory(500)

    .build()

🌐 Distributed Tracing

// Preset dla distributed tracing
val correlation = KNETRequestCorrelation.forDistributedTracing()
// Używa X-Trace-ID i X-Parent-Trace-ID

// Przekazywanie ID między serwisami
val response = client.get("https://service-a.example.com/data")
val traceId = response.getCorrelationId()

// Użyj tego samego ID w kolejnym requeście
val nextRequest = KNETRequest.get("https://service-b.example.com/process")
    .withCorrelationId(traceId!!)

📝 Metadata

// Dodaj custom metadata do trace
correlation.addMetadata(correlationId, "user_id", userId)
correlation.addMetadata(correlationId, "action", "checkout")

// Pobierz trace z metadata
val trace = correlation.getTrace(correlationId)
val userId = trace?.metadata?.get("user_id")

📊 Statystyki

val stats = correlation.getStats()

println("Total requests: ${stats.totalRequests}")
println("Traced requests: ${stats.tracedRequests}")
println("Success rate: ${stats.successRate}%")
println("Avg duration: ${stats.averageDurationMs}ms")

💡 Praktyczne przykłady

Error reporting z correlation ID

class ErrorReporter(
    private val correlation: KNETRequestCorrelation,
    private val crashlytics: Crashlytics
) {
    fun reportError(error: Throwable) {
        val lastId = correlation.getLastCorrelationId()
        val trace = lastId?.let { correlation.getTrace(it) }

        crashlytics.log("correlation_id", lastId ?: "unknown")
        crashlytics.log("request_url", trace?.request?.url ?: "unknown")
        crashlytics.log("request_duration", trace?.durationMs?.toString() ?: "0")
        crashlytics.recordException(error)
    }
}

Logging middleware

val correlation = KNETRequestCorrelation.create()

val loggingMiddleware = KNETMiddleware.tap(
    onRequest = { request ->
        val id = request.headers["X-Correlation-ID"]
        Log.d("HTTP", "[$id] → ${request.method} ${request.url}")
    },
    onResponse = { request, response ->
        val id = request.headers["X-Correlation-ID"]
        Log.d("HTTP", "[$id] ← ${response.statusCode}")
    }
)

Analiza performance

// Po wykonaniu wielu requestów
val slowTraces = correlation.getSlowTraces(1000)

slowTraces.forEach { trace ->
    analytics.log("slow_request", mapOf(
        "correlation_id" to trace.correlationId,
        "url" to trace.request.url,
        "duration_ms" to trace.durationMs,
        "status" to trace.response?.statusCode
    ))
}

🔗 API Reference

KNETRequestCorrelation

MetodaOpis
interceptor()Tworzy interceptor
generateId()Generuje nowy ID
getLastCorrelationId()Ostatni ID
getTrace(id)Pobiera trace
getAllTraces()Wszystkie traces
getTracesForUrl(pattern)Filtr po URL
getFailedTraces()Nieudane requesty
getSlowTraces(thresholdMs)Wolne requesty
addMetadata(id, key, value)Dodaje metadata
getStats()Statystyki
clear()Czyści historię

📚 Zobacz też