Трејсинг је метода посматрања тока захтева кроз дистрибуирани систем, при којој сваки корак обраде бива забележен као посебан догађај са временским жигом. Према подацима OpenTelemetry, 2025, trace обједињује пуну путању захтева од тачке уласа до коначног одговора, пролазећи кроз све микросервисе и спољне позиве. Ово омогућава програмерима да открију уска грла, кашњења и отказе у сложеним архитектурама мобилних бекендова.
Главно
Трејсинг је метода дистрибуираног посматрања у којој сваки долазни захтев бива праћен кроз све сервисе и компоненте система. За разлику од метрика, које приказују агрегиране вредности (просечно време одговора, број грешака), трејсинг чува пуни контекст једног одређеног захтева.
Сваки корак обраде — позив базе података, HTTP захтев другом микросервису, извршавање позадинског задатка — бива забележен као посебна јединица са временским жигом, статусом и атрибутима. Према подацима Google Dapper (оригинална публикација из 2010. године), трејсинг омогућава локализацију кашњења у дистрибуираним системима са прецизношћу до једног позива.
Трејсинг је посебно важан за мобилне апликације, где се бекенд састоји од десетина микросервиса. Корисничка акција — на примјер, пријава на налог — може проћи кроз API Gateway, сервис аутентификације, базу података и Push сервис. Без trace-а практично је немогуће одредити која компонента успорава одговор.
Основна јединица трејсинга је span. Сваки span представља једну логичку операцију: HTTP захтев, SQL упит, gRPC позив, JSON серијализацију. Span садржи јединствени идентификатор, идентификатор родитеља, назив операције, време почетка, трајање, статус и скуп атрибута.
Сви spanови који се односе на један коренски захтев спајају се у trace. Коренски span (root span) представља тачку уласа — HTTP захтев од мобилног клијента ка API. Потомствени spanови формирају стабло у којем сваки span упућује на родитеља путем поља parent_span_id.
Трајање trace-а једнако је збиру трајања јединствених временских интервала свих spanова. Ако се два потомствена spanа извршавају паралелно, њихово време се не сабира — ово је критично за правилну анализу кашњења изазваних паралелним позивима микросервиса.
Сваки span може да садржи атрибуте — парове кључ-вредност са метаинформацијама: URL захтева, ID корисника, верзија API-ја, назив хоста. Атрибути се користе за филтрирање и груписање traceова. Поред атрибута, span подржава догађаје — временске жигове са текстуалним описом, на примјер „промашај кеша“ или „поновни покушај повезивања“.
Distributed tracing решава проблем повезивања spanова који се стварају у различитим процесима и на различитим машинама. Механизам се заснива на контекстном преношењу: при позиву сервиса B из сервиса A, у излазни захтев се додаје заглавље са идентификатором тренутног trace-а и родитељског spanа.
Стандардни протоколи преношења контекста — W3C Trace Context (заглавља traceparent и tracestate) и Zipkin B3 (заглавља X-B3-TraceId, X-B3-SpanId). W3C Trace Context је усвојен као стандард од стране W3C конзорцијума 2021. године и га подржавају сви главни пружатељи телеметрије.
При пријему захтева, сервис B извлачи trace_id из заглавља и ствара потомствени span са овим trace_id-ом. На тај начин, након завршетка захтева, сви spanови из различитих сервиса спајају се у један trace на страни колектора. За ово је потребно да сваки сервис буде инструментиран истом библиотеком за трејсинг.
У мобилном развоју, контекстно преношење обухвата не само бекенд, већ и интеракцију клијент-сервер. Мобилна апликација може да шаље trace_id у заглављу сваког API захтева, омогућавајући повезивање акције клијента са серверском обрадом. OpenTelemetry SDK за iOS и Android подржава аутоматско стварање и преношење контекста trace-а кроз 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() }
}
}
Представљени interceptor у Kotlin-у ствара span за сваки HTTP захтев серверу. Родитељски контекст се преноси из кода који позива путем Context.current(), што омогућава повезивање клијентског trace-а са серверским.
OpenTelemetry — де факто стандард за прикупљање података trace-а. Омогућава јединствени API за генерисање spanова, аутоматску инструментацију популарних библиотека и флексибилан механизам извоза података у различите бекендове: Jaeger, Zipkin, Grafana Tempo, Datadog, New Relic.
OpenTelemetry подржава аутоматско стварање spanова за популарне оквире: Spring Boot, Ktor, Flask, Express, gRPC. Програмер само треба да дода зависност у пројекат, а библиотека самостално пресреће долазне и излазне захтеве. Auto-instrumentation за Javu користи javaagent који модификује bytecode у лету без промене изворног кода.
За мобилне платформе, OpenTelemetry пружа Swift SDK и Kotlin SDK. Они аутоматски стварају spanове за мрежне захтеве (URLSession, OkHttp), рад са базом података (CoreData, Room) и позадинске задатке. Програмер може да дода прилагођене spanове за пословну логику.
Прикупљени spanови шаљу се колектору кроз протокол OTLP (OpenTelemetry Protocol). Колектор може да буферише, филтрира и преусмерава податке у један или више система за складиштење. Према документацији OpenTelemetry, типично кашњење од генерисања spanа до његовог приказивања на дашборду износи 2–5 секунди при кориштењу 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()
Код у Swift-у активира аутоматску инструментацију мрежног слоја и ствара прилагођени span за операцију преузимања профила корисника. Атрибут user.id омогућава касније филтрирање traceова по одређеном кориснику.
У системима са високим оптерећењем, трејсирање сваког захтева је немогуће — то би створило неприхватљиво оптерећење за складиште и мрежу. Узорковање решава овај проблем, чувајући само део traceова. Избор стратегије директно утиче на потпуност података и цену инфраструктуре.
Одлука о чувању trace-а доноси се у тренутку његовог стварања — у коренском spanу. Најједноставнији и најраширенији приступ: фиксни проценат захтева (на примјер, 5%) се чува, остали се одбацују. Недостатак — не може се гарантовати да ће ретке грешке бити захваћене. Probability sampler у OpenTelemetry-у подржава подешавање вероватноће од 0.0 до 1.0.
Одлука се одлажа до завршетка свих spanова trace-а. Анализатор процењује да ли трејс садржи грешке, прекораћење времена или занимљиве атрибуте и тек га чува. Овај приступ захтева буферисање свих spanова у колектору, што повећава потрошњу меморије. Према подацима Grafana Labs, tail-based sampling је 40–60% ефикаснији у погледу односа „цена за корисне податке“ у системима са ретким али критичним грешкама.
| Стратегија | Предности | Недостаци |
|---|---|---|
| Fixed probability | Једноставност, предвидиво оптерећење | Пропушта ретке догађаје |
| Rate limiting | Гарантован обим података | Неравномерно покривање |
| Tail-based | Хватање свих грешака | Висока потрошња меморије |
| Adaptive | Баланс цене и покривања | Сложеност подешавања |
Логовање биљежи појединачне догађаје са нивоом важности (info, warn, error), али их не повезује у контекст једног захтева. Трејсинг, напротив, ствара структуирано стабло операција које припадају једном крајне до краја захтеву. У пракси, ова два приступа се не искључују, већ допуњују.
Логови су ефикасни за детаљну анализу одређећене грешке: програмер види тачан поруку, стак позива, вредности промењивих. Tracing одговара на питање „зашто се захтев извршава 5 секунди“ — показује који микросервис или позив је заузео највише времена. Према подацима Honeycomb (2024), тимови који користе трејсинг заједно са логовањем проналазе корени узрок инцидената 2,3 пута брже.
Савремени приступ — observability — обједињује трејсове, метрике и логове у један систем. OpenTelemetry подржава корелацију између ова три сигнала: сваки span може да садржи референце на повезане логове, а метрике могу бити означене trace_id-ом за прелазак на одређећене трејсове.
Често постављана питања
Мониторинг приказује агрегиране метрике система — просечно време одговора, број грешака у минути, оптерећење CPU-а. Tracing приказује путању једног одређећног захтева кроз све компоненте. Мониторинг одговара на питање „шта се догађа“, трејсинг — „зашто се то догађа“.
За производне системе, довољно је 1–5% захтева при head-based sampling. Ако систем ретко даје грешке, препоручује се tail-based sampling са фокусом на хватање свих неисправних трејсова. За staging окружење, допуштиво је трејсирање 100% захтева без ограничења.
Главни алати: Jaeger (решење од Uber-а, отворени код), Grafana Tempo (скалабилно складиште трејсова), Datadog APM, New Relic Distributed Tracing, AWS X-Ray и Honeycomb. Сви подржавају OpenTelemetry стандард за пријем података.
Да, локални трејсинг ради унутар једног процеса. OpenTelemetry SDK за iOS и Android ствара spanове за локалне операције: читање из базе података, обрада слика, мрежни захтеви. Овакви трејсови нису дистрибуирани, али су корисни за дијагностику перформанси клијентског дела.
Савремене библиотеке трејсинга додају мање од 1% повећања оптерећења при head-based sampling. OpenTelemetry користи асинхрони извоз података који не блокира главну нит. За мобилне уређаје, препоручује се ограничење учесталости стварања spanова и кориштење стратегије адаптивног узорковања.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође