Tracing to metoda obserwacji przepływu żądań przez system rozproszony, w której każdy krok przetwarzania jest rejestrowany jako osobne zdarzenie z znacznikiem czasu. Według danych OpenTelemetry, 2025, trace łączy pełną ścieżkę żądania od punktu wejścia do ostatecznej odpowiedzi, przechodząc przez wszystkie mikrousługi i wywołania zewnętrzne. Pozwala to programistom identyfikować wąskie gardła, opóźnienia i awarie w złożonych architekturach backendów mobilnych.
Najważniejsze
Tracing to metoda rozproszonej obserwacji, w której każde przychodzące żądanie jest śledzone przez wszystkie usługi i komponenty systemu. W przeciwieństwie do metryk, które pokazują zagregowane wartości (średni czas odpowiedzi, liczbę błędów), tracing zachowuje pełny kontekst jednego konkretnego żądania.
Każdy krok przetwarzania — wywołanie bazy danych, żądanie HTTP do innej mikrousługi, wykonanie zadania w tle — jest rejestrowany jako osobna jednostka z znacznikiem czasu, statusem i atrybutami. Według danych Google Dapper (oryginalna publikacja z 2010 roku), tracing pozwala zlokalizować opóźnienia w systemach rozproszonych z dokładnością do jednego wywołania.
Tracing jest szczególnie ważny dla aplikacji mobilnych, gdzie backend składa się z dziesiątków mikrousług. Akcja użytkownika — na przykład logowanie do konta — może przejść przez API Gateway, usługę uwierzytelniania, bazę danych i serwis Push. Bez trace praktycznie niemożliwe jest określenie, który komponent spowalnia odpowiedź.
Podstawową jednostką trace jest span. Każdy span reprezentuje jedną logiczną operację: żądanie HTTP, zapytanie SQL, wywołanie gRPC, serializację JSON. Span zawiera unikalny identyfikator, identyfikator rodzica, nazwę operacji, czas rozpoczęcia, czas trwania, status i zestaw atrybutów.
Wszystkie spany dotyczące jednego żądania źródłowego łączą się w trace. Span główny (root span) reprezentuje punkt wejścia — żądanie HTTP od klienta mobilnego do API. Spany potomne tworzą drzewo, w którym każdy span odwołuje się do rodzica przez pole parent_span_id.
Czas trwania trace jest równy sumie czasów trwania unikalnych odcinków czasowych wszystkich spanów. Jeśli dwa spany potomne wykonują się równolegle, ich czas nie jest sumowany — jest to krytyczne dla prawidłowej analizy opóźnień spowodowanych równoległymi wywołaniami mikrousług.
Każdy span może zawierać atrybuty — pary klucz-wartość z metainformacjami: URL żądania, ID użytkownika, wersja API, nazwa hosta. Atrybuty są używane do filtrowania i grupowania trace. Oprócz atrybutów, span obsługuje zdarzenia — znaczniki czasu z opisem tekstowym, na przykład „chybienie pamięci podręcznej” lub „ponowna próba połączenia”.
Distributed tracing rozwiązuje problem łączenia spanów, które są tworzone w różnych procesach i na różnych maszynach. Mechanizm opiera się na przekazywaniu kontekstu: podczas wywołania usługi B z usługi A do wychodzącego żądania dodawany jest nagłówek z identyfikatorem bieżącego trace i rodzica span.
Standardowe protokoły przekazywania kontekstu — W3C Trace Context (nagłówki traceparent i tracestate) oraz Zipkin B3 (nagłówki X-B3-TraceId, X-B3-SpanId). W3C Trace Context został przyjęty jako standard przez konsorcjum W3C w 2021 roku i jest obsługiwany przez wszystkich głównych dostawców telemetrii.
Po otrzymaniu żądania usługa B wyodrębnia trace_id z nagłówka i tworzy span potomny z tym trace_id. W ten sposób po zakończeniu żądania wszystkie spany z różnych usług łączą się w jeden trace po stronie kolektora. Wymaga to, aby każda usługa była instrumentowana tą samą biblioteką trace.
W programowaniu mobilnym przekazywanie kontekstu obejmuje nie tylko backend, ale także interakcję klient-serwer. Aplikacja mobilna może wysyłać trace_id w nagłówku każdego żądania API, pozwalając powiązać działanie klienta z przetwarzaniem po stronie serwera. OpenTelemetry SDK dla iOS i Android obsługuje automatyczne tworzenie i przesyłanie kontekstu trace przez klienty HTTP.
import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context
class TracingInterceptor : Interceptor {
private val tracer: Tracer = OpenTelemetry.getTracer("mobile-app")
override fun intercept(chain: Interceptor.Chain): Response {
val span = tracer.spanBuilder("HTTP POST /api/login")
.setParent(Context.current())
.startSpan()
return chain.proceed(chain.request())
.also { span.end() }
}
}
Przedstawiony interceptor w Kotlinie tworzy span dla każdego żądania HTTP do serwera. Kontekst rodzica jest przekazywany z kodu wywołującego przez Context.current(), co pozwala powiązać trace po stronie klienta z trace po stronie serwera.
OpenTelemetry — standard de facto do zbierania danych trace. Zapewnia ujednolicone API do generowania spanów, automatyczną instrumentację popularnych bibliotek i elastyczny mechanizm eksportu danych do różnych backendów: Jaeger, Zipkin, Grafana Tempo, Datadog, New Relic.
OpenTelemetry obsługuje automatyczne tworzenie spanów dla popularnych frameworków: Spring Boot, Ktor, Flask, Express, gRPC. Programista musi tylko dodać zależność do projektu, a biblioteka samodzielnie przechwytuje przychodzące i wychodzące żądania. Auto-instrumentation dla Javy wykorzystuje javaagent, który modyfikuje bytecode w locie bez zmiany źródła.
Dla platform mobilnych OpenTelemetry udostępnia Swift SDK i Kotlin SDK. Automatycznie tworzą one spany dla żądań sieciowych (URLSession, OkHttp), pracy z bazą danych (CoreData, Room) i zadań w tle. Programista może dodawać niestandardowe spany dla logiki biznesowej.
Zebrane spany są wysyłane do kolektora przez protokół OTLP (OpenTelemetry Protocol). Kolektor może buforować, filtrować i przekierowywać dane do jednego lub kilku systemów przechowywania. Według dokumentacji OpenTelemetry, typowe opóźnienie od wygenerowania spanu do wyświetlenia go na dashboardzie wynosi 2–5 sekund przy użyciu eksportu gRPC.
import OpenTelemetryApi
import OpenTelemetrySdk
import URLSessionInstrumentation
let instrumentation = URLSessionInstrumentation()
instrumentation.enable()
let tracer = OpenTelemetry.instance.tracerFactory
.get("mobile-monitoring")
let span = tracer.spanBuilder("fetch-user-profile")
.setAttribute(key: "user.id", value: userId)
.startSpan()
span.end()
Kod w Swift aktywuje automatyczną instrumentację warstwy sieciowej i tworzy niestandardowy span dla operacji pobierania profilu użytkownika. Atrybut user.id pozwala później filtrować trace według konkretnego użytkownika.
W systemach o wysokim obciążeniu niemożliwe jest trace każdego żądania — powodowałoby to niedopuszczalne obciążenie pamięci masowej i sieci. Próbkowanie rozwiązuje ten problem, zapisując tylko część trace. Wybór strategii bezpośrednio wpływa na kompletność danych i koszt infrastruktury.
Decyzja o zapisaniu trace jest podejmowana w momencie jego utworzenia — w spanu głównym. Najprostsze i najczęściej stosowane podejście: stały procent żądań (np. 5%) jest zapisywany, pozostałe są odrzucane. Wadą jest brak gwarancji, że rzadkie błędy zostaną przechwycone. Probability sampler w OpenTelemetry obsługuje ustawienie prawdopodobieństwa od 0.0 do 1.0.
Decyzja jest odkładana do zakończenia wszystkich spanów trace. Analizator ocenia, czy trace zawiera błędy, przekroczenie czasu lub interesujące atrybuty, i dopiero wtedy go zapisuje. To podejście wymaga buforowania wszystkich spanów w kolektorze, co zwiększa zużycie pamięci. Według danych Grafana Labs, tail-based sampling jest o 40–60% bardziej efektywny pod względem stosunku „cena za użyteczne dane” w systemach z rzadkimi, ale krytycznymi błędami.
| Strategia | Zalety | Wady |
|---|---|---|
| Fixed probability | Prostota, przewidywalne obciążenie | Pomija rzadkie zdarzenia |
| Rate limiting | Gwarantowana objętość danych | Nierównomierne pokrycie |
| Tail-based | Przechwytywanie wszystkich błędów | Wysokie zużycie pamięci |
| Adaptive | Równowaga kosztów i pokrycia | Złożoność konfiguracji |
Logowanie rejestruje pojedyncze zdarzenia z poziomem ważności (info, warn, error), ale nie łączy ich w kontekst jednego żądania. Tracing przeciwnie, tworzy strukturyzowane drzewo operacji należących do jednego żądania end-to-end. W praktyce te dwa podejścia nie wykluczają się, lecz uzupełniają.
Logi są skuteczne do szczegółowej analizy konkretnego błędu: programista widzi dokładną wiadomość, stos wywołań, wartości zmiennych. Tracing odpowiada na pytanie „dlaczego żądanie wykonuje się 5 sekund” — pokazuje, która mikrousługa lub które wywołanie zajęło najwięcej czasu. Według danych Honeycomb (2024), zespoły używające trace razem z logowaniem znajdują źródło incydentów 2,3 razy szybciej.
Nowoczesne podejście — observability — łączy trace, metryki i logi w jeden system. OpenTelemetry obsługuje korelację między tymi trzema sygnałami: każdy span może zawierać odnośniki do powiązanych logów, a metryki mogą być oznaczane za pomocą trace_id w celu przejścia do konkretnych trace.
Często zadawane pytania
Monitorowanie pokazuje zagregowane metryki systemu — średni czas odpowiedzi, liczbę błędów na minutę, obciążenie CPU. Tracing pokazuje ścieżkę jednego konkretnego żądania przez wszystkie komponenty. Monitorowanie odpowiada na pytanie „co się dzieje”, tracing — „dlaczego to się dzieje”.
Dla systemów produkcyjnych wystarczy 1–5% żądań przy head-based sampling. Jeśli system rzadko generuje błędy, zaleca się tail-based sampling z skupieniem na przechwytywaniu wszystkich błędnych trace. Dla środowiska staging dopuszczalne jest trace 100% żądań bez ograniczeń.
Główne narzędzia: Jaeger (rozwiązanie od Uber, open source), Grafana Tempo (skalowalne przechowywanie trace), Datadog APM, New Relic Distributed Tracing, AWS X-Ray i Honeycomb. Wszystkie obsługują standard OpenTelemetry do odbierania danych.
Tak, lokalny tracing działa wewnątrz jednego procesu. OpenTelemetry SDK dla iOS i Android tworzy spany dla lokalnych operacji: odczyt z bazy danych, przetwarzanie obrazów, żądania sieciowe. Takie trace nie są rozproszone, ale są przydatne do diagnostyki wydajności strony klienckiej.
Nowoczesne biblioteki trace dodają mniej niż 1% narzutu przy head-based sampling. OpenTelemetry używa asynchronicznego eksportu danych, który nie blokuje głównego wątku. Dla urządzeń mobilnych zaleca się ograniczenie częstotliwości tworzenia spanów i stosowanie strategii adaptacyjnego próbkowania.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również