{"id":31014,"date":"2019-10-31T21:38:54","date_gmt":"2019-10-31T18:38:54","guid":{"rendered":"https:\/\/prohoster.info\/blog\/trassirovka-servisov-opentracing-i-jaeger\/"},"modified":"2019-10-31T21:38:54","modified_gmt":"2019-10-31T18:38:54","slug":"trassirovka-servisov-opentracing-i-jaeger","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/trassirovka-servisov-opentracing-i-jaeger","title":{"rendered":"\u015aledzenie us\u0142ug, OpenTracing i Jaeger","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"\u015aledzenie us\u0142ug, OpenTracing i Jaeger\" src=\"\/wp-content\/uploads\/2019\/04\/045800f00c8da9702f62cf3de53df7b6.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nW naszych projektach stosujemy architektur\u0119 mikroserwisow\u0105. W przypadku wyst\u0105pienia w\u0105skich garde\u0142 w wydajno\u015bci sp\u0119dzamy du\u017co czasu na monitorowaniu i analizie log\u00f3w. Gdy rejestrujemy czasy poszczeg\u00f3lnych operacji w pliku log\u00f3w, zazwyczaj trudno jest zrozumie\u0107, co spowodowa\u0142o wywo\u0142anie tych operacji, \u015bledzi\u0107 sekwencj\u0119 dzia\u0142a\u0144 lub przesuni\u0119cie czasowe jednej operacji w stosunku do drugiej w r\u00f3\u017cnych serwisach. <\/p>\n<p>Aby zminimalizowa\u0107 r\u0119czn\u0105 prac\u0119, postanowili\u015bmy skorzysta\u0107 z jednego z narz\u0119dzi do \u015bledzenia. W tym artykule opowiemy, jak i do czego wykorzysta\u0107 \u015bledzenie oraz jak to zrobili\u015bmy. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Jakie problemy mo\u017cna rozwi\u0105za\u0107 za pomoc\u0105 \u015bledzenia.<\/h3>\n<p><\/p>\n<ol>\n<li>Zidentyfikowa\u0107 w\u0105skie gard\u0142a w wydajno\u015bci zar\u00f3wno w obr\u0119bie jednego serwisu, jak i w ca\u0142ym drzewie wykonania mi\u0119dzy wszystkimi zaanga\u017cowanymi serwisami. Na przyk\u0142ad:\n<ul>\n<li>Wiele kr\u00f3tkich, kolejnych wywo\u0142a\u0144 mi\u0119dzy serwisami, takich jak geokodowanie lub zapytania do bazy danych.<\/li>\n<li>D\u0142ugie oczekiwania na wej\u015bcie\/wyj\u015bcie, na przyk\u0142ad przesy\u0142anie danych przez sie\u0107 czy odczyt z dysku.<\/li>\n<li>D\u0142ugie parsowanie danych.<\/li>\n<li>D\u0142ugie operacje wymagaj\u0105ce CPU.<\/li>\n<li>Fragmenty kodu, kt\u00f3re nie s\u0105 potrzebne do uzyskania ko\u0144cowego wyniku i mo\u017cna je usun\u0105\u0107 lub uruchomi\u0107 z op\u00f3\u017anieniem.<\/li>\n<\/ul>\n<\/li>\n<li>Wizualnie zrozumie\u0107, w jakiej kolejno\u015bci co jest wywo\u0142ywane i co si\u0119 dzieje, gdy wykonywana jest operacja.<br \/>\n<img decoding=\"async\" alt=\"\u015aledzenie us\u0142ug, OpenTracing i Jaeger\" src=\"\/wp-content\/uploads\/2019\/04\/f22f14599568bff5573fe59eeeaea753.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nWida\u0107, \u017ce na przyk\u0142ad zapytanie trafi\u0142o do serwisu WS -&gt; serwis WS uzupe\u0142ni\u0142 dane przez serwis R -&gt; nast\u0119pnie wys\u0142a\u0142 zapytanie do serwisu V -&gt; serwis V za\u0142adowa\u0142 du\u017co danych z serwisu R -&gt; poszed\u0142 do serwisu P -&gt; serwis P jeszcze raz zapyta\u0142 serwis R -&gt; serwis V zignorowa\u0142 wynik i przeszed\u0142 do serwisu J -&gt; i dopiero potem zwr\u00f3ci\u0142 odpowied\u017a do serwisu WS, w mi\u0119dzyczasie kontynuuj\u0105c obliczenia w tle.<br \/>\nBez takiego \u015bladu lub szczeg\u00f3\u0142owej dokumentacji ca\u0142ego procesu bardzo trudno jest zrozumie\u0107, co si\u0119 dzieje, widz\u0105c kod po raz pierwszy, a kod jest rozproszony po r\u00f3\u017cnych serwisach i ukryty za wieloma binami i interfejsami.\n<\/li>\n<li>Zbieranie informacji o drzewie wykonania do p\u00f3\u017aniejszej analizy. Na ka\u017cdym etapie wykonania mo\u017cna do \u015bladu doda\u0107 informacje, kt\u00f3re s\u0105 dost\u0119pne na danym etapie, a nast\u0119pnie zrozumie\u0107, jakie dane wej\u015bciowe doprowadzi\u0142y do takiego scenariusza. Na przyk\u0142ad:\n<ul>\n<li>ID u\u017cytkownika<\/li>\n<li>Uprawnienia<\/li>\n<li>Typ wybranej metody<\/li>\n<li>Log lub b\u0142\u0105d wykonania<\/li>\n<\/ul>\n<\/li>\n<li>Przekszta\u0142cenie trace'\u00f3w w podzbi\u00f3r metryk, a nast\u0119pnie analiza w postaci metryk.<\/li>\n<\/ol>\n<h3>Co potrafi logowa\u0107 \u015bledzenie. Span<\/h3>\n<p>W \u015bledzeniu istnieje poj\u0119cie spanu, kt\u00f3re jest odpowiednikiem jednego logu w konsoli. Span ma:<\/p>\n<ul>\n<li>Nazwa, zazwyczaj to nazwa metody, kt\u00f3ra by\u0142a wykonywana<\/li>\n<li>Nazwa us\u0142ugi, w kt\u00f3rej zosta\u0142 wygenerowany span<\/li>\n<li>W\u0142asny unikalny ID<\/li>\n<li>Jak\u0105\u015b metainformacj\u0119 w postaci key\/value, kt\u00f3r\u0105 zalogowano. Na przyk\u0142ad, parametry metody lub informacja, czy metoda zako\u0144czy\u0142a si\u0119 b\u0142\u0119dem, czy nie<\/li>\n<li>Czas rozpocz\u0119cia i zako\u0144czenia wykonania tego spanu<\/li>\n<li>ID parent span<\/li>\n<\/ul>\n<p>\nKa\u017cdy span jest wysy\u0142any do kolektora span\u00f3w, aby zosta\u0142 zapisany w bazie w celu p\u00f3\u017aniejszego przegl\u0105dania, gdy tylko zako\u0144czy swoje wykonanie. Mo\u017cna p\u00f3\u017aniej zbudowa\u0107 drzewo wszystkich span\u00f3w, \u0142\u0105cz\u0105c je po ID rodzica. Podczas analizy mo\u017cna znale\u017a\u0107 na przyk\u0142ad wszystkie spany w danej us\u0142udze, kt\u00f3re zajmowa\u0142y wi\u0119cej ni\u017c okre\u015blony czas. Nast\u0119pnie, przechodz\u0105c do konkretnego spanu, mo\u017cna zobaczy\u0107 ca\u0142e drzewo powy\u017cej i poni\u017cej tego spanu.<\/p>\n<p><img decoding=\"async\" alt=\"\u015aledzenie us\u0142ug, OpenTracing i Jaeger\" src=\"\/wp-content\/uploads\/2019\/04\/9cc97f1278af60f0efd5e393cd183c5c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Opentrace, Jaeger i jak zrealizowali\u015bmy to w naszych projektach<\/h3>\n<p>\nIstnieje og\u00f3lny standard <noindex><a rel=\"nofollow\" href=\"https:\/\/opentracing.io\/docs\/overview\/\">Opentrace<\/a><\/noindex>, kt\u00f3ry opisuje, jak i co powinno by\u0107 zbierane, nie wi\u0105\u017c\u0105c \u015bledzenia z konkretn\u0105 implementacj\u0105 w jakimkolwiek j\u0119zyku. Na przyk\u0142ad w Javie ca\u0142a praca z trace'ami jest realizowana za po\u015brednictwem wsp\u00f3lnego API Opentrace, a pod nim mo\u017ce si\u0119 kry\u0107 na przyk\u0142ad Jaeger lub pusta domy\u015blna implementacja, kt\u00f3ra nic nie robi.<br \/>\nU nas u\u017cywa si\u0119 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jaegertracing.io\/\">Jaeger<\/a><\/noindex> jako implementacji Opentrace. Sk\u0142ada si\u0119 z kilku komponent\u00f3w:<\/p>\n<p><img decoding=\"async\" alt=\"\u015aledzenie us\u0142ug, OpenTracing i Jaeger\" src=\"\/wp-content\/uploads\/2019\/04\/1fd4ae8563569271b067861c81101d71.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Jaeger-agent \u2014 lokalny agent, kt\u00f3ry zazwyczaj znajduje si\u0119 na ka\u017cdej maszynie i do kt\u00f3rego loguj\u0105 us\u0142ugi na lokalny domy\u015blny port. Je\u015bli agenta brakuje, to trace'y wszystkich us\u0142ug na tej maszynie s\u0105 zazwyczaj wy\u0142\u0105czone<\/li>\n<li>Jaeger-collector \u2014 do niego wszyscy agenci wysy\u0142aj\u0105 zebrane trace'y, a on zapisuje je w wybranej bazie danych<\/li>\n<li>Baza danych \u2014 preferowan\u0105 baz\u0105 danych jest Cassandra, ale u nas u\u017cywa si\u0119 Elasticsearch, istniej\u0105 implementacje tak\u017ce dla kilku innych baz danych oraz realizacja w pami\u0119ci, kt\u00f3ra nic nie zapisuje na dysku<\/li>\n<li>Jaeger-query \u2014 to us\u0142uga, kt\u00f3ra przeszukuje baz\u0119 danych i zwraca ju\u017c zebrane trace'y do analizy<\/li>\n<li>Jaeger-ui \u2014 to interfejs webowy do wyszukiwania i przegl\u0105dania trace'\u00f3w, kt\u00f3ry \u0142\u0105czy si\u0119 z jaeger-query<\/li>\n<\/ul>\n<p><img decoding=\"async\" alt=\"\u015aledzenie us\u0142ug, OpenTracing i Jaeger\" src=\"\/wp-content\/uploads\/2019\/04\/afc415cb5d4f19e7ba18394c2c1a9dd5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOdseparowanym komponentem mo\u017cna nazwa\u0107 implementacj\u0119 Opentrace Jaeger pod konkretne j\u0119zyki, przez kt\u00f3r\u0105 spany s\u0105 wysy\u0142ane do jaeger-agent.<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jaegertracing\/jaeger-client-java\">Pod\u0142\u0105czenie Jaegera w Javie<\/a><\/noindex> Polega na zaimplementowaniu interfejsu io.opentracing.Tracer, po czym wszystkie \u015blady b\u0119d\u0105 przesy\u0142ane przez niego do rzeczywistego agenta.<\/p>\n<p><img decoding=\"async\" alt=\"\u015aledzenie us\u0142ug, OpenTracing i Jaeger\" src=\"\/wp-content\/uploads\/2019\/04\/5ce4bdfc06def7e4645bd58163e99dab.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMo\u017cna r\u00f3wnie\u017c pod\u0142\u0105czy\u0107 do komponent\u00f3w Springa <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opentracing-contrib\/java-spring-cloud\">opentracing-spring-cloud-starter<\/a><\/noindex> oraz implementacj\u0119 od Jaeger <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opentracing-contrib\/java-spring-jaeger\">opentracing-spring-jaeger-cloud-starter<\/a><\/noindex> kt\u00f3ra automatycznie skonfiguruje \u015bledzenie wszystkiego, co przechodzi przez te komponenty, na przyk\u0142ad zapytania http w kontrolerach, zapytania do bazy danych przez jdbc itd.<\/p>\n<h3>Logowanie \u015blad\u00f3w w Javie<\/h3>\n<p>\nNa najwy\u017cszym poziomie powinien by\u0107 utworzony pierwszy Span, co mo\u017ce by\u0107 zrobione automatycznie, na przyk\u0142ad przez kontroler Springa w momencie otrzymania \u017c\u0105dania, lub r\u0119cznie, je\u015bli takiego nie ma. Nast\u0119pnie jest on przekazywany przez Scope ni\u017cej. Je\u015bli jaki\u015b metod ni\u017cej chce doda\u0107 Span, pobiera aktualny activeSpan z Scope, tworzy nowy Span i informuje, \u017ce jego rodzicem jest otrzymany activeSpan, oraz ustawia nowy Span jako aktywny. Przy wywo\u0142aniach zewn\u0119trznych serwis\u00f3w przekazywany jest im aktualny aktywny span, a te serwisy tworz\u0105 nowe spany zwi\u0105zane z tym spanem.<br \/>\nCa\u0142a praca przebiega przez instancj\u0119 Tracera, kt\u00f3rej mo\u017cna uzyska\u0107 przez mechanizm DI lub GlobalTracer.get() jako zmienn\u0105 globaln\u0105, je\u015bli mechanizm DI nie dzia\u0142a. Domy\u015blnie, je\u015bli tracer nie zosta\u0142 zainicjalizowany, zostanie zwr\u00f3cony NoopTracer, kt\u00f3ry nic nie robi.<br \/>\nNast\u0119pnie z tracera przez ScopeManager pobierany jest aktualny scope, tworzony jest nowy scope z aktualnym powi\u0105zanym nowym spanem, a p\u00f3\u017aniej zamykany jest utworzony scope, kt\u00f3ry zamyka utworzony span i przywraca poprzedni scope do aktywnego stanu. Scope jest powi\u0105zane z w\u0105tkiem, dlatego w programowaniu wielow\u0105tkowym nale\u017cy pami\u0119ta\u0107 o przekazywaniu aktywnego spanu do innego w\u0105tku, aby nast\u0119pnie aktywowa\u0107 scope w inny w\u0105tku z powi\u0105zaniem z tym spanem.<\/p>\n<pre><code class=\"java\">io.opentracing.Tracer tracer = ...; \/\/ GlobalTracer.get()\n\nvoid DoSmth () {\n   try (Scope scope = tracer.buildSpan(\"DoSmth\").startActive(true)) {\n      ...\n   }\n}\nvoid DoOther () {\n    Span span = tracer.buildSpan(\"someWork\").start();\n    try (Scope scope = tracer.scopeManager().activate(span, false)) {\n        \/\/ Wykonaj rzeczy.\n    } catch(Exception ex) {\n        Tags.ERROR.set(span, true);\n        span.log(Map.of(Fields.EVENT, \"error\", Fields.ERROR_OBJECT, ex, Fields.MESSAGE, ex.getMessage()));\n    } finally {\n        span.finish();\n    }\n}\n\nvoid DoAsync () {\n    try (Scope scope = tracer.buildSpan(\"ServiceHandlerSpan\").startActive(false)) {\n        ...\n        final Span span = scope.span();\n        doAsyncWork(() -&gt; {\n            \/\/ KROK 2 POWY\u017bEJ: reaktywuj Span w wywo\u0142aniu zwrotnym, przekazuj\u0105c true do\n            \/\/ startActive(), je\u015bli\/kiedy Span ma zosta\u0107 zako\u0144czony.\n            try (Scope scope = tracer.scopeManager().activate(span, false)) {\n                ...\n            }\n        });\n    }\n}<\/code><\/pre>\n<p>Dla programowania wielow\u0105tkowego istnieje r\u00f3wnie\u017c TracedExecutorService i podobne opakowania, kt\u00f3re automatycznie przekazuj\u0105 bie\u017c\u0105cy span do w\u0105tku przy uruchamianiu asynchronicznych zada\u0144:<\/p>\n<pre><code class=\"java\">private ExecutorService executor = new TracedExecutorService(\n    Executors.newFixedThreadPool(10), GlobalTracer.get()\n);<\/code><\/pre>\n<p>Do zewn\u0119trznych zapyta\u0144 HTTP dost\u0119pny jest <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opentracing-contrib\/java-apache-httpclient\">TracingHttpClient<\/a><\/noindex><\/p>\n<pre><code class=\"java\">HttpClient httpClient = new TracingHttpClientBuilder().build();<\/code><\/pre>\n<h3>Problemy, z kt\u00f3rymi si\u0119 spotkali\u015bmy<\/h3>\n<p><\/p>\n<ul>\n<li>Biny i DI nie zawsze dzia\u0142aj\u0105, je\u015bli tracer nie jest u\u017cywany w serwisie lub komponencie, wtedy <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/autowired\/\" class=\"user_link\">@Autowired<\/a><\/noindex> Tracer mo\u017ce nie dzia\u0142a\u0107 i trzeba b\u0119dzie u\u017cy\u0107 GlobalTracer.get().<\/li>\n<li>Adnotacje nie dzia\u0142aj\u0105, je\u015bli nie jest to komponent lub serwis, lub je\u015bli wywo\u0142anie metody odbywa si\u0119 z s\u0105siedniej metody tej samej klasy. Nale\u017cy by\u0107 ostro\u017cnym, sprawdzi\u0107, co dzia\u0142a i korzysta\u0107 z r\u0119cznego tworzenia trace'a, je\u015bli @Traced nie dzia\u0142a. Mo\u017cna r\u00f3wnie\u017c doda\u0107 dodatkowy kompilator dla adnotacji java, wtedy powinny dzia\u0142a\u0107 wsz\u0119dzie.<\/li>\n<li>W starszym springu i spring boot nie dzia\u0142a automatyczna konfiguracja opentracing spring cloud z powodu b\u0142\u0119d\u00f3w w DI, wi\u0119c je\u015bli chcemy, aby trace'y w komponentach springa dzia\u0142a\u0142y automatycznie, mo\u017cemy to zrobi\u0107 na podobie\u0144stwo <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opentracing-contrib\/java-spring-jaeger\/blob\/master\/opentracing-spring-jaeger-starter\/src\/main\/java\/io\/opentracing\/contrib\/java\/spring\/jaeger\/starter\/JaegerAutoConfiguration.java\">github.com\/opentracing-contrib\/java-spring-jaeger\/blob\/master\/opentracing-spring-jaeger-starter\/src\/main\/java\/io\/opentracing\/contrib\/java\/spring\/jaeger\/starter\/JaegerAutoConfiguration.java<\/a><\/noindex><\/li>\n<li>W groovy nie dzia\u0142a try with resources, trzeba koniecznie u\u017cy\u0107 try finally.<\/li>\n<li>Ka\u017cdy serwis powinien mie\u0107 swoj\u0105 spring.application.name, pod kt\u00f3r\u0105 b\u0119d\u0105 logowane trace'y. Nale\u017cy r\u00f3wnie\u017c wprowadzi\u0107 osobn\u0105 nazw\u0119 dla \u015brodowiska produkcyjnego i testowego, aby si\u0119 nie miesza\u0142y.<\/li>\n<li>Je\u015bli u\u017cywasz GlobalTracer i tomcata, to wszystkie serwisy uruchomione w tym tomcat maj\u0105 jeden GlobalTracer, wi\u0119c wszystkie b\u0119d\u0105 mia\u0142y t\u0119 sam\u0105 nazw\u0119 serwisu.<\/li>\n<li>Dodaj\u0105c trace'y do metody, nale\u017cy upewni\u0107 si\u0119, \u017ce nie jest ona wywo\u0142ywana w p\u0119tli wiele razy. Nale\u017cy doda\u0107 jeden wsp\u00f3lny trace do wszystkich wywo\u0142a\u0144, kt\u00f3ry zaloguje \u0142\u0105czne czasy wykonania. W przeciwnym razie b\u0119dzie generowana zb\u0119dna obci\u0105\u017cenie.<\/li>\n<li>Raz w jaeger-ui zrobili\u015bmy zbyt du\u017ce zapytania o du\u017c\u0105 liczb\u0119 trace'\u00f3w i poniewa\u017c nie czekali\u015bmy na odpowied\u017a, wykonali\u015bmy je ponownie. W rezultacie jaeger-query zacz\u0105\u0142 zu\u017cywa\u0107 du\u017co pami\u0119ci i spowalnia\u0142 elastika. Pom\u00f3g\u0142 restart jaeger-query.<\/li>\n<\/ul>\n<h3>Pr\u00f3bkowanie, przechowywanie i przegl\u0105danie trace'\u00f3w<\/h3>\n<p>\nS\u0105 trzy typy <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jaegertracing.io\/docs\/1.9\/sampling\/\">pr\u00f3bkowania trace'\u00f3w<\/a><\/noindex>:<\/p>\n<ol>\n<li>Const, kt\u00f3ry wysy\u0142a i zapisuje wszystkie trace'y.<\/li>\n<li>Probabilistic, kt\u00f3ry filtruje trace'y z okre\u015blon\u0105 prawdopodobie\u0144stwem.<\/li>\n<li>Ratelimiting, kt\u00f3ry ogranicza liczb\u0119 \u015blad\u00f3w na sekund\u0119. Mo\u017cna skonfigurowa\u0107 te parametry na kliencie, albo na jaeger-agent, albo w kolektorze. Obecnie w naszym stosie walidator\u00f3w u\u017cywamy const 1, poniewa\u017c nie ma zbyt wielu zapyta\u0144, ale zajmuj\u0105 one du\u017co czasu. W przysz\u0142o\u015bci, je\u015bli to b\u0119dzie wywiera\u0107 zbyt du\u017c\u0105 presj\u0119 na system, mo\u017cna to ograniczy\u0107.<\/li>\n<\/ol>\n<p>\nJe\u015bli u\u017cywasz Cassandry, domy\u015blnie przechowuje ona \u015blady tylko przez dwa dni. U nas u\u017cywana jest <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jaegertracing\/jaeger\/tree\/master\/plugin\/storage\/es\">elasticsearch<\/a><\/noindex> i \u015blady s\u0105 przechowywane przez ca\u0142y czas i nie s\u0105 usuwane. Tworzony jest osobny indeks na ka\u017cdy dzie\u0144, na przyk\u0142ad jaeger-service-2019-03-04. W przysz\u0142o\u015bci nale\u017cy skonfigurowa\u0107 automatyczne czyszczenie starych \u015blad\u00f3w.<\/p>\n<p>Aby zobaczy\u0107 \u015blady, nale\u017cy:<\/p>\n<ul>\n<li>Wybra\u0107 us\u0142ug\u0119, wed\u0142ug kt\u00f3rej chcesz filtrowa\u0107 \u015blady, na przyk\u0142ad tomcat7-default dla us\u0142ugi, kt\u00f3ra dzia\u0142a w Tomcat i nie mo\u017ce mie\u0107 swojej nazwy.<\/li>\n<li>Nast\u0119pnie wybierz operacj\u0119, okres czasu i minimalny czas trwania operacji, na przyk\u0142ad od 10 sekund, aby wzi\u0105\u0107 tylko d\u0142ugie wykonania.<br \/>\n<img decoding=\"async\" alt=\"\u015aledzenie us\u0142ug, OpenTracing i Jaeger\" src=\"\/wp-content\/uploads\/2019\/04\/bc712d4aabfe9c2ae961d3b8f9396a42.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>Przejd\u017a do jednego ze \u015blad\u00f3w i zobacz, co tam op\u00f3\u017ania\u0142o.<br \/>\n<img decoding=\"async\" alt=\"\u015aledzenie us\u0142ug, OpenTracing i Jaeger\" src=\"\/wp-content\/uploads\/2019\/04\/16e9dd11903358f5498fe11034bbf848.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ul>\n<p>\nJe\u015bli znany jest jaki\u015b id zapytania, mo\u017cna znale\u017a\u0107 \u015blad po tym id za pomoc\u0105 wyszukiwania po tagach, je\u015bli ten id jest logowany w \u015bladzie.<\/p>\n<h3>Dokumentacja<\/h3>\n<p><\/p>\n<ul>\n<li>Dokumentacja opentracing <noindex><a rel=\"nofollow\" href=\"https:\/\/opentracing.io\/docs\/overview\/what-is-tracing\/\">opentracing.io\/docs\/overview\/what-is-tracing<\/a><\/noindex><\/li>\n<li>Dokumentacja jaeger <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jaegertracing.io\/docs\/1.10\/\">www.jaegertracing.io\/docs\/1.10<\/a><\/noindex><\/li>\n<li>Pod\u0142\u0105czenie jaeger java <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jaegertracing\/jaeger-client-java\">github.com\/jaegertracing\/jaeger-client-java<\/a><\/noindex><\/li>\n<li>Pod\u0142\u0105czenie spring opentracing<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jaegertracing\/jaeger-client-java\">github.com\/jaegertracing\/jaeger-client-java<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opentracing-contrib\/java-spring-cloud\">github.com\/opentracing-contrib\/java-spring-cloud<\/a><\/noindex><\/li>\n<\/ul>\n<h3>Artyku\u0142y<\/h3>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/carprice\/blog\/340946\/\">habr.com\/ru\/company\/carprice\/blog\/340946<\/a><\/noindex> Jaeger Opentracing i Mikrous\u0142ugi w rzeczywistym projekcie na PHP i Golang<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/eng.uber.com\/distributed-tracing\/\">eng.uber.com\/distributed-tracing<\/a><\/noindex> Evolving Distributed Tracing at Uber Engineering<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/opentracing.io\/guides\/java\/\">opentracing.io\/guides\/java<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/jaegertracing\/running-jaeger-agent-on-bare-metal-d1fc47d31fab\">medium.com\/jaegertracing\/running-jaeger-agent-on-bare-metal-d1fc47d31fab<\/a><\/noindex> Uruchamianie Jaeger Agent na go\u0142ej maszynie<\/li>\n<\/ul>\n<h3>Wideo<\/h3>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=qg0ENOdP1Lo\">www.youtube.com\/watch?v=qg0ENOdP1Lo<\/a><\/noindex> Jak u\u017cyli\u015bmy Jaeger i Prometheus do b\u0142yskawicznych zapyta\u0144 u\u017cytkownik\u00f3w \u2014 Bryan Boreham<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=WRntQsUajow\">www.youtube.com\/watch?v=WRntQsUajow<\/a><\/noindex> Wprowadzenie: Jaeger \u2014 Yuri Shkuro, Uber &amp; Pavol Loffay, Red Hat<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=fsHb0qK37bc\">www.youtube.com\/watch?v=fsHb0qK37bc<\/a><\/noindex> Serghei Iakovlev, \"Ma\u0142a historia wielkiego zwyci\u0119stwa: OpenTracing, AWS i Jaeger\"<\/li>\n<\/ul>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/srg\/blog\/446752\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443. \u041f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u0443\u0437\u043a\u0438\u0445 \u043c\u0435\u0441\u0442 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0442\u0440\u0430\u0442\u0438\u0442\u0441\u044f \u043d\u0430 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0438 \u0440\u0430\u0437\u0431\u043e\u0440 \u043b\u043e\u0433\u043e\u0432. \u041f\u0440\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0442\u0430\u0439\u043c\u0438\u043d\u0433\u043e\u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0432 \u043b\u043e\u0433-\u0444\u0430\u0439\u043b, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u043b\u043e \u043a \u0432\u044b\u0437\u043e\u0432\u0443 \u044d\u0442\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0438\u043b\u0438 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u0434\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445. \u0414\u043b\u044f \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":22990,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-31014","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0443\u044e.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/trassirovka-servisov-opentracing-i-jaeger\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0422\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, OpenTracing \u0438 Jaeger | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0443\u044e.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/trassirovka-servisov-opentracing-i-jaeger\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:38:54+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:38:54+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47\u015aledzenie us\u0142ug, OpenTracing i Jaeger | ProHoster","description":"W naszych projektach u\u017cywamy architektury mikroserwisowej.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/trassirovka-servisov-opentracing-i-jaeger","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0422\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, OpenTracing \u0438 Jaeger | ProHoster","og:description":"\u0412 \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0443\u044e.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/trassirovka-servisov-opentracing-i-jaeger","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:38:54+00:00","article:modified_time":"2019-10-31T18:38:54+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"31014","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 04:06:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:26:04","updated":"2026-01-21 04:06:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/31014","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=31014"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/31014\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/22990"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=31014"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=31014"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=31014"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}