#OpenTelemetry #Observability #Alloy #Distributed Tracing #Kubernetes
“Czyli ten taki element, który wszyscy traktują: eee tam, pitu pitu, a okazuje się, że jest jednym z najbardziej krytycznych.” 🎯 Szymon przyniósł 16 stron notatek o OpenTelemetry Collector. Każda strona to osobny sposób na zgubienie telemetrii.
Budujemy topologię kolektorów od zera. Collector per namespace, DaemonSet na wypadek aplikacji, która nie wstała, i agenci na VM-kach zamiast otwierania sieci dla Prometheusa. Nad tym OTel Gateway, który ma być “głupi jak budowa cepa”, a nie kolejnym ESB. Do tego Kafka przed Lokim i gRPC, które za load balancerem po cichu sabotuje skalowanie.
Potem ciche awarie. Błąd w konfiguracji? Kolektory “zrobią rollback do poprzedniej wersji, Ty się o tym nie dowiesz”. Unauthorized nie jest retry’owany, więc dane lecą do kosza. ⚠️ Recepta Szymona: “metryki, metryki, metryki”.
Na deser tail sampling, który według Szymona “niewyobrażalnie komplikuje architekturę całego rozwiązania”. Chyba że masz terabajty trace’ów w trzy dni. Czy Grafana Alloy to obowiązek, czy kolejna warstwa, na której się wywalisz?
Linki i ciekawe znaleziska
Transkrypcja
Szymon Warda: Czyli ten taki element, który wszyscy traktują: eee tam, pitu pitu, a okazuje się, że jest jednym z najbardziej krytycznych. Kolektor nie jest obowiązkowy, ale jest wysoce wskazany. Kolektory działają tak, że jeżeli masz błąd konfiguracji, to one powiedzą: hmm nie, nie, zrobią rollback do poprzedniej wersji. Ty się o tym nie dowiesz. Tu też jest ta wartość tego całego kolektora. Mianowicie ona pokazuje, że stajesz się niezależny od konkretnego dostawcy. Wdrożenie kolektora bez całego stosu do observability, bez prawidłowego wdrożenia spowoduje, że dane będziecie bardziej gubili…
Łukasz Kałużny: Cześć, słuchajcie Patoarchitektów. Prowadzi Łukasz Kałużny…
Szymon Warda: I Szymon Warda dla odmiany.
Łukasz Kałużny: Dobra Szymon, bo Ty dzisiaj się wymądrzałeś i stwierdziłeś, że zrobisz temat na odcinek i notatkę i zrobiłeś 16 stron, czyli więcej niż ja.
Szymon Warda: O jedną może i miałeś 18. Dobrze.
Łukasz Kałużny: Dobra, o czym chcesz nam dzisiaj poopowiadać?
Szymon Warda: Dziś temat znowu observability, temat mianowicie o kolektorach.
Chłopaki z Baraków: Obserwuję Was jak gówienny sęp.
Szymon Warda: Czyli ten taki element, który wszyscy traktują: eee tam, pitu pitu, a okazuje się, że jest jednym z najbardziej krytycznych.
Łukasz Kałużny: Wiesz co, dobra, to może powiedzmy sobie, bo w ogóle zanim przejdziemy czym jest kolektor, bo to jest problem taki, że ok, teraz mówisz observability znowu. Odsyłamy, jest parę takich starszych odcinków, tutaj znajdzie się sobie teraz na ekranie albo poniżej w notatce. Dobra Szymon, ale jak wygląda ten cały stos? Bo wszyscy znamy to z dwóch stron. Albo jest aplikacja, albo dashboard w Kibanie bądź w Grafanie. Dobra i jakbyś powiedział jak to sobie przelatuje?
Szymon Warda: Dobra, to teraz zacznijmy przede wszystkim od jednej podstawowej rzeczy. Kolektor nie jest obowiązkowy, ale jest wysoce wskazany. Jaka jest rola kolektora? Kolektor to jest takie sobie powiedzmy anti corruption layer trochę, coś, co ma zbierać te sygnały, procesować, buforować, przerabiać, adnotować i robić to wszystko, żeby to, co wychodzi z aplikacji, trafiało do naszych danych, gdzie przechowujemy to wszystko w formie dobrej, ładnej, ułożonej i odpowiedniej.
Łukasz Kałużny: Dobra, to teraz cofniemy się, bo użyłeś za dużo rzeczy. Dobra, OpenTelemetry to jest standard w jaki sposób… No właśnie, czym jest OpenTelemetry jako worek? Jakąś krótką definicję OpenTelemetry.
Szymon Warda: OpenTelemetry kiedyś to był standard do tego jak instrumentować aplikację. Czyli powstało to po to, żebyśmy na przykład jak robimy aplikację, nie integrujemy się z jakimś stosem do observability, z jakimś stosem do observability tego wszystkiego, na przykład mamy Datadoga, to załóżmy klient ma New Relica, to żeby nie przepisywać wszystkiego na nowo. Okej, dobra. Czym się observability stało teraz? To jest kilka rzeczy. Po pierwsze, to są jak instrumentować aplikacje. Po drugie, to jest generalnie jak to wszystko zbierać. Po trzecie, to jest formaty i jak to właściwie wysyłać, procesować, co można robić, semantykę nazewnictwa, całość właściwie, czyli jak podejść do observability całości.
Łukasz Kałużny: Czyli jest jako całość, dobra. I teraz powiedziałaś takie słowo klucz, które będziesz musiał rozszyfrować, bo nazwałeś coś, co się ładnie nazywa sygnały. I są 4 składowe, dobrze pamiętam?
Szymon Warda: Formalnie są trzy. Ja upieram się, że są cztery.
Łukasz Kałużny: Dobra, to zacznijmy od tej najprostszej, którą wszyscy znają.
Szymon Warda: Logi, które wcale nie są takie proste jak się okazuje generalnie. Ale do tego dojdziemy przy architekturze. Logi. Metryki, czyli liczby. Trace’y, czyli to się nazywa ślady po polsku ładnie, niech będzie. I profile, czyli to właściwie co samplujemy na poziomie bardzo niskim, bo kernela praktycznie.
Łukasz Kałużny: To są trace’y z eBPF-ów.
Szymon Warda: I tak i nie. To jest generalnie, to mówi o tej wydajności, czyli mówi o tym, co się dzieje nawet w tym czasie powiedzmy tych 100 milisekund, gdzie już tracing ma mały sens, wewnątrz aplikacji. Czyli te wszystkie ładne flamegraphy, które pewnie widzieliście nie raz, dokładnie.
Łukasz Kałużny: Dobra i to powiedz teraz, dobra, czyli powiedziałeś, czyli co, można podsumować, że ten kolektor, o którym chcesz dzisiaj porozmawiać o kolektorach i podejściu tego, że kolektor to jest takie międzymordzie, nie używając słowa interfejs, pomiędzy aplikacją a naszym stosem observability, do którego te sygnały, czyli logi, metryki, trace’y trafiają?
Szymon Warda: I tak i nie. Bo tak, to jest coś pomiędzy, ale nie, bo to nie jest jeden element. Jak porozmawiamy sobie o topologii kolektorów, to zobaczymy, że ich tam jest dość sporawo i czemu, który do czego służy, bo to nie jest wcale takie proste.
Łukasz Kałużny: No dobra, to słuchaj, to wytłumacz w takim razie tą architekturę kolektorów. W ogóle po co, dlaczego i co, gdzie siedzi?
Szymon Warda: Dobrze, do tego jeszcze będzie rysunek, sobie rzucimy, jak to wygląda? Zacznijmy od takiego najprostszego. Czyli zakładamy sobie taką opcję, że mamy sobie powiedzmy Kubernetesa. I teraz zakładamy, że mamy sobie OpenTelemetry, aplikacje są instrumentowane, czyli po OpenTelemetry Protocol wysyłają sobie gdzieś nasze sygnały ogólnie mówiąc. No i tak, mogłyby wysyłać właśnie do samego endpointu. Ale wtedy problem mamy taki, że w aplikacji trzymamy hasła, trzymamy endpointy, co jak robimy, nie możemy samplować i tak dalej i tak dalej. Więc stawiamy sobie kolektor i aplikacje piszą do naszego OpenTelemetry Collectora i on tam zajmuje się, wysyła dalej. No i teraz jaka jest rola tego OpenTelemetry Collectora w tej sytuacji? On ma odbierać sygnały po OpenTelemetry Protocol, ma się ładnie skalować i tak dalej, i tak dalej. Proste, ładne, logiczne. Dobra, ale teraz znowu problem mamy sobie taki, że w tym momencie potencjalnie na przykład w każdym namespacie albo każdym obszarze byśmy trzymali taką bestię. Więc teraz co robimy? Dorzucamy sobie z reguły coś, co ja nazywam OpenTelemetry Gateway, który zajmuje się zbieraniem telemetrii w ogóle z całego klastra, albo nawet z wielu klastrów i wysyła dalej i on trzyma wszystkie sekrety, on jest zarządzane przez Platformę jako taką i dzieje się dalej. Teraz możesz powiedzieć: ale po co tą hopkę robić? A no bo mamy teraz taki kolejny element, że doskonale wiesz, że fajnie byłoby, gdyby aplikacje wysyłały sobie np. logi i wszystkie inne rzeczy po OpenTelemetry Protocol. Ale jak aplikacja nie może wstać, to tych logów nie wyśle. Więc co trzeba zrobić? Dorzucamy sobie DaemonSeta, który pochodzi na każdym nodzie i scrapuje te logi, które się tam pojawiły z aplikacji. No i teraz znowu właśnie i teraz wchodzi ten sens tego Gateway’a. W tym momencie Collector i DaemonSet piszą nam do Gateway’a, on jest naszym jedynym punktem wyjścia. No to pomyślisz: dobra, to w sumie właściwie byłoby wszystko. No nie, bo teraz co nam dochodzi dalej? Pewnie mamy tam jakąś wirtualkę. No to co teraz robimy? No to możemy powiedzieć teraz: to spoko, otwieram sobie sieć i teraz mój Prometheusz może scrapować wszystkie wirtualki w tej sieci.
The Office: No, God, please no, no, no.
Szymon Warda: Brzmi to tragicznie i strasznie. Więc co robimy? Instalujemy sobie kolektora na VM-ce, on może zbierać logi z tej VM-ki, może aplikacja z nim pisze lokalnie, zbiera wszystkie metryki z VM-ki, z aplikacji i tak dalej i nam ładnie wysyła gdzie? Do naszego Gateway’a znowu. Czyli mamy jeden punkt wyjścia, wszystko fajnie śmiga.
Łukasz Kałużny: Dobra, czyli teraz tak, czyli jeżeli sobie popatrzymy, OpenTelemetry, można to też Szymon tak podsumować, jest tak, że Gateway jest proxy i zamienia wersje w wielu miejscach z pull na push schemat, czyli przyjmuje. Jeżeli mówimy o aplikacji na prostszych przypadkach, czyli Kubernetes, mamy dwie ścieżki. Aplikacja działa, to wysyła sama swoje logi i metryki. Nie działa albo jest ten moment wstawiania logów technicznych, które idą na stdout czy do plików, to DaemonSet z każdego miejsca to powinien ściągnąć.
Szymon Warda: Ja bym chciał, żeby tak było, bo teraz wchodzi problem w aplikacji, który się dzieje i to jest takie trochę…
Łukasz Kałużny: Poczekaj, podsumujmy jeszcze, pozwól, zanim przejdziemy do tego problemu. Druga sprawa, na VM-kach mamy po prostu agenta, który też pushuje i eksportera tego i w tym miejscu też model, mimo że piszemy w formacie prometeuszowym, przygotowujemy metryki i podejście do nich, tu się nic nie zmienia, to jest to pushbase, nie pullbase.
Szymon Warda: Tak.
Łukasz Kałużny: A powinno… Może inaczej, powinno być.
Szymon Warda: W tym będzie dualne, bo na przykład z podów jako takich będziesz niektóre zbierał metryki jako pullując. Od tego też jest ten Alloy, który umie scrapować. Znowu aplikacyjne metryki powinniśmy wysyłać, wszystkie powinniśmy mu wysyłać, ale to nie zawsze tak fajnie działa. Tym bardziej, że powiedzmy z naszego kodu aplikacyjnego wyślesz, ale na przykład załóżmy z innych systemów musisz scrapować. Więc znowu te elementy tam muszą być. I ok, one nam pogarszają SLO, SLA, SLI i tak dalej. Ale gdzie jeszcze jest wartość? Bo Ty mówisz, że aplikacje wysyłają. Tak, wysyłają, o ile wysyłają zgodne, czyli są zgodne w standardzie. I teraz dlatego właśnie mamy tego OpenTelemetry, tak się często robi właśnie, że mamy OpenTelemetry Collectora per namespace, gdzie tam zespół powiedzmy jak jest niezgodny, to może sobie zrobić swój, ten cały anti corruption layer może dorzucić i transformaty po to, żeby móc puszczać do Getwaya. A jak są już zgodni ze standardem, to pushują od razu tego natywnego kolektora, który nie jest ich środowiskowy. Czyli mamy tę opcję, że nagle nasz… Bo problem jest też taki, że łatwo jest zrobić taką sytuację, że Gateway stanie się takim ESB, czyli tam będziemy mieli wszystkie transformaty i tak dalej. Nie, Gateway ma być głupi jak budowa cepa i to co on przyjmuje, daje…
Łukasz Kałużny: Powinien przepychać tylko.
Szymon Warda: Przepychać, dodawać odpowiednie transformaty dla wszystkich takie same i pchać dalej, trzymać secrety i tak dalej. Więc mamy ładny podział. Alloye i wszystkie kolektory, które są w namespace’ach, to odpowiedzialność zespołów, a cała reszta to odpowiedzialność platformy. Śmiga ładnie i jest fajnie. Powiedziałeś o jednej rzeczy. Powiedziałeś, że aplikacja wypisze stdout.
Łukasz Kałużny: Powinna.
Szymon Warda: Powinna. Problem jaki jest, niestety, to jest taki, że OpenTelemetry Protocol i instrumentacje aplikacyjne, jak działają, to push jest asynchroniczny. Czyli jak pushujesz to nie wiesz czy push się udał, czyli nie wiesz czy kolektor jest aktualny. Czyli tak naprawdę ciężko zrobić ten fallback i tam trzeba się trochę nagimnastykować. To się zmienia obecnie i wchodzą supporty jeżeli chodzi do aplikacji (…), żeby stdout był jako fallbackiem. To są całe problemy jakie się dzieją, kiedy zaczyna się OpenTelemetry realnie wykorzystywać. No tak że to nie jest taki prosty temat, jakby się mogło wydawać.
Łukasz Kałużny: Ale słuchaj, to jakbyś, bo teraz powiedzieliśmy, a co tak naprawdę dają te kolektory i tak skomplikowana infra pod to?
Szymon Warda: Dają kilka rzeczy. Przede wszystkim idąc od tyłu, czyli do naszego Gateway’a, co on daje? Gateway jest tym jedynym elementem, który jest persystentny. On ma kolejkę persystentną, co kolektory wspierają już teraz. Czyli generalnie załóżmy co Ci to daje? Że możesz sobie zrobić restart twojego Loki, Mimira, Elastica, czegokolwiek i danych nie stracisz. Możesz buforować, możesz te wszystkie rzeczy, możesz przygotować, możesz batchować to wszystko, zarządzać tym. Teraz co dzieje się wcześniej? To jest to, że jak na przykład te OpenTelemetry Collectory, które występują, możesz skalować niezależnie. One mogą znowu też batchować, buforować, robić adnotacje, wszystko, co potrzebujesz, żeby to działało ładnie.
Łukasz Kałużny: Dobra, to może… Mam takie pytanie, ono było przy logach, czy tam gdzieś jest Kafka?
Szymon Warda: Tam jest często Kafka właśnie. I to zależy, bym tak powiedział.
Łukasz Kałużny: Właśnie od czego? Bo powiedziałeś o buforowaniu, wyłączaniu. No właśnie, bo teraz, jak powiedziałeś mi o buforowaniu, o asyncach, powrocie, skalowaniu, to mam pytanie, gdzie jest budowany bufor?
Szymon Warda: No właśnie buforów jest kilka. Idziemy. Masz bufor, powiedzieliśmy, że masz bufor persystnenty w Gateway’u. Spoko. Cofamy się. Teraz, generalnie teraz tak, co jest z DaemonSetem? DaemonSet, jak się nie wyrabia, no to co? Podbierze, najwyżej wyśle te logi wielokrotnie, nie ma tragedii. Patrzymy na OpenTelemetry Collector, czyli ten element, który jest, do którego aplikacje wysyłają, on ma swój bufor pamięciowy. Tam z reguły robimy memory limiter, żeby nam klastra nie zabił i on ma retry’e. Teraz idziemy znowu krok wcześniej. Dochodzimy do aplikacji. Aplikacja, instrumentacje aplikacji z reguły też mają swoje retry’e, tylko wiadomo, że coraz mniejsze. Więc one umieją to wysyłać. Czy to Ci daje pewność, że danych nie stracisz? Nie. Są przypadki, kiedy sam protokół nie zadziała odpowiednio i niestety są pewne rzeczy, to wszysko trzeba monitorować. O tym sobie jeszcze powiemy, jak to w ogóle monitorować, bo tego jest sposobów na robienie tego. Więc tak, tu masz całą architekturę i ponowienia.
Łukasz Kałużny: Czyli jest, dobrze. Czyli podsumowując lecimy tak, że weźmy Lokiego na przykład do logów, czyli pomiędzy Lokim a infrastrukturą kolektorów, Alloyów jest Kafka. Może być.
Szymon Warda: Loki już w nowej wersji w ogóle wspiera oficjalnie Kafkę. Ta wersja była ogłoszona przed wakacjami, ale jeszcze nie jest wydana. Więc często przed samym Loki daje się Kafkę, żeby właśnie dać to buforowanie.
Łukasz Kałużny: Okej, czyli w tym. Potem podsumowując dalej są sobie bufory na samym Alloyu. Czy on ma jakąś prezystencję na dysk?
Szymon Warda: No właśnie ten Gateway ma persystencję na dysk, dlatego się to stawia z reguły jako z PVC, więc jesteśmy bezpieczni.
Łukasz Kałużny: Ale wtedy, i też trzeba powiedzieć, wtedy zakładamy, że load balancujemy i mamy, to jest jakiś Deployment, StatefulSet i to nie jest jedna instancja, tylko stoją za jakimś load balancerem, serwisem w Kubernetesie, whatever, żeby jakoś to zloadbalansce’ować.
Szymon Warda: Dokładnie tak.
Łukasz Kałużny: Pomóż nam z algorytmem tutaj na YouTubie. Wiesz, tam na dole jest taka funkcja hype czy tam podbij. Weź kliknij, zostaw wszystkie dostępne punkty, jak już tutaj słuchasz.
Szymon Warda: Jak już powiemy o load balancerze, to teraz musimy dotknąć jeszcze innego tematu. Pamiętasz pewnie o tym, że z reguły OpenTelemetry Protocol śmiga po gRPC. I mówiliśmy w odcinku, chyba 2 odcinki temu odnośnie load balancera, jak mamy gRPC plus load balancer, czyli aplikacja łączy się po gRPC do swojego kolektora, to loadbalance’ujemy połączenie. Czyli w tym momencie skalowanie naszego kolektora staje się bardzo trudne, bo co? Mamy problemy wydajnościowe w kolektorze, skalujemy się, a w tym momencie nic nie podejdzie. I znowu wchodzimy do takich małych szczegółów, że aplikację trzeba odpowiednio postawić, żeby właśnie aplikacja kliencka loadbalance’owała się między wszystkimi dostępnymi kolektorami. Mała rzecz, a okaże się, że Ci…
Łukasz Kałużny: Tak, tylko dobra, jak pójdziemy sobie na jakieś nowsze, to też nie jest aż taka tragiczna, w tych nowych implementacjach, nie powinna być.
Szymon Warda: Nie powinna być, ale w aplikacji często po prostu ludzie podają adres load balancera i myślą, że: a, jest super, będzie.
Łukasz Kałużny: Słuchaj, dobra, to teraz tak, czyli jest to, wysyłamy sobie. To teraz jeszcze jedna rzecz, która mi się trafia, kto pilnuje monitoringu? Klasyczny problem kto kogo pilnuje? Jak to się monitoruje?
Szymon Warda: Dobra, to teraz omówmy sobie, żeby powiedzieć w ogóle po co monitorować, bo wszyscy mówią, że: to powinno działać. Scenariusze, kiedy to może się nie udać? Robisz taki prosty myk. Robisz sobie, powiedzmy robisz sobie wdrożenie kolektora Helmem, ładnie, rolling update, udało się, wszystko w porządku. Tylko że kolektory działają tak, że jeżeli masz błąd w konfiguracji, to one powiedzą: nie, nie, zrobią rollback do poprzedniej wersji, Ty się o tym nie dowiesz. Jeżeli masz błąd, na przykład masz unauthorized, to jest nieretry’owany błąd, czyli będzie dropowanie powiedzmy. Jeżeli masz literówkę, to kolektor powie: błąd konfiguracji, no trudno, nie będę tego wysyłał.
Cytaty Filmowe: Ja tu jestem kierownikiem tej szatni, nie mamy pańskiego płaszcza. I co pan nam zrobi?
Szymon Warda: Więc teraz jak to wszystko się monitoruje? To jest z reguły, przyjęło się, że jak masz pipeline’y, o czym może powiemy w kolejnym odcinku, to będzie tak, że każdy pipeline dokładnie monitoruje co, gdzie się udało, co przez niego przeszło, poza tym nie wszystkie mają tą konwencję, ale ogólnie monitorujesz kolejki wejściowe, kolejki wyjściowe, ile było retry i tak dalej. Każdego kolektora po drodze i jak to się monitoruje. Czyli metryki, metryki, metryki.
Łukasz Kałużny: Wiecie co, to tak przy okazji dajcie znać w pytanie, bo nie wiem jaka jest teraz ilość słuchających Spotify i telefony, audio versus YouTube. Bo ja się zastanawiam, czy może nie warto byłoby pokazać tego na żywo z jakiegoś komputera, nagrać ekranu i czy chcielibyście zobaczyć to?
Szymon Warda: Albo zrobić live’a i tablicę.
Łukasz Kałużny: Tak, raczej tablicę, w tym wypadku ekran, ekran, ekran. Tablicę, kurde, nie zmieścimy tu już tablicy.
Szymon Warda: Damy radę. Więc tak, monitorowanie jest tu bardzo, bardzo mocno kluczowe. Bo jest bardzo dużo scenariuszy, łącznie z aplikacją, to co powiedziałem, asynchroniczne wysyłanie, błędy w konfiguracji, błędy tokenów i tak dalej, załóżmy takich pierdół. Dopiero niedawno pojawiła się opcja, która wspiera 2 tokeny uwierzytelniające pomiędzy kolektorami.
Łukasz Kałużny: Żeby można było rotować.
Szymon Warda: Dokładnie tak. A błąd w tokenie, nagle gubisz dane.
Łukasz Kałużny: Dobra. I pójdźmy sobie teraz chyba do serii bardzo w tym. Jeszcze jakbyś powiedział, bo nie mam tego na liście materiałów, ale muszę Cię spytać, jak byś wytłumaczył architekturę wewnętrzną kolektora i czym jest pipeline, jakbyś powiedział? Bo to jest chyba istotne, bo użyłeś tego, żeby tak pokrótce wytłumaczyć czym są pipeline’y w kolektorze.
Szymon Warda: Dobra, to czym jest pipeline? Jak znasz, pipeline, jak sama nazwa wskazuje, to jest coś, co przetwarza nam strumienie danych. Bo to są strumienie, mówiąc prosto. I tam mamy kilka rzeczy. Na samym wejściu mamy receiver, czyli coś, co umie odebrać sygnał albo od niego się odpytać. Bo możesz na przykład mieć receiver odnośnie np. prometeuszowego scrapowania, receiver OpenTelemetry, receiver jagerowy, czego właściwie byś tam nie chciał. Tych receiverów jest dużo.
Łukasz Kałużny: Czyli formatów, które wchodzą.
Szymon Warda: Formatów i sposobów. Bo pamiętasz, jeszcze może być odpytywanie jawne. Teraz dalej, masz procesory. Tam masz odnośnie dodawania labelingu, usuwania labeli. Na przykład tam masz procesor odnośnie usuwania danych wrażliwych, peseli, batchowania, dropowania, debugowania, co sobie tylko wymyślisz. Potem dalej masz exporter. I teraz co robi exporter? Exporter jest odwrotnością receivera, czyli on umie wysłać dane zgodnie z jakimś protokołem, gdzieś. Czy to będzie Loki, Mimir, Tempo, Elastic, New Relic, Datadog, cokolwiek właściwie. Tu też jest ta wartość tego całego kolektora. Mianowicie ona pokazuje, że stajesz się niezależny od konkretnego dostawcy. Możesz nawet wysłać do dwóch, trzech, obojętne.
Łukasz Kałużny: Dobra, to tak, ja teraz zanim zadam pytanie, to od razu Szymon skrócę, żebyś nie musiał się też wypowiadać i powtarzać. W zeszłym roku był odcinek 168 i też tutaj jest na ekranie - standaryzacja logów. Nudne rzeczy, które trzeba ustalić. I pytanie brzmi, jak logować z poziomu aplikacji?
Szymon Warda: I tu dochodzimy do tego, że dojrzałość się obecnie bardzo mocno zmienia. To jest ta opcja prosta. Moja rekomendacja, jaka jest, to jest taka, że wysyłasz wszystko po OpenTelemetry Protocol, a jak Ci się nie uda, to walisz na stdouta. Czyli na stdout’cie powinieneś mieć czysto. A jak coś tam się pojawiło..
Łukasz Kałużny: Czy czysto… Dobra, ja teraz…
Szymon Warda: To jest błąd.
Łukasz Kałużny: Dobra i pozwól, to jedna moja opinia, z którą ja się nie zgadzam z OpenTelemetry. Minimum logów administracyjnych na zasadzie fuckupów z aplikacji też powinna zostać na stdout’cie nadal.
Szymon Warda: Ale powiedziałeś fuckupów, czyli błędy krytyczne.
Łukasz Kałużny: Krytyczne błędy, które na zasadzie jestem DevOpsem, administratorem i wchodzę na poda i mogę zobaczyć, że czemu się chrzani. Bo nie tylko nie powinny być nie tylko wysyłane na OTel, ale pozwolicie, to jest trochę dla niektórych piewców observability, przepraszam Szymon, jest to w ogóle zdrada. Przecież jeżeli się wysłało do OTela, to po co to robić?
Szymon Warda: Nie.
Łukasz Kałużny: Ale ja uważam, że takie criticale na zasadzie jako admin wchodzę, patrzę co się dzieje na oncallu i inne rzeczy z apką, nie chciałbym śledzić tego wszystkiego po wszystkich dashboardach i innych rzeczach.
Szymon Warda: Łukasz, criticale się zgodzimy, criticale mogą być. Problem jest taki, że technologicznie jeżeli nie zrobisz tego dobrze, to niestety będziesz miał dublowanie.
Łukasz Kałużny: Tak.
Szymon Warda: I w tym momencie, bo OpenTelemetry używasz z reguły po to, że masz pewien wolumen, który zaczyna Cię kosztować odrobinkę i nagle dublowanie logów ładnych, ułożonych przez OpenTelemetry z logami stdoutowym…
Łukasz Kałużny: Raczej to ten sam… Inaczej, format logów wiesz, że może być ten sam ustrukturyzowany, wyrzucony na ten stdout?
Szymon Warda: Wiesz, że może być. Wiesz, że z reguły też nie jest. I co więcej…
Łukasz Kałużny: Ale koszt zrobienia tego jest zerowy, żeby było taki sam.
Szymon Warda: Sekundę. I co więcej, najgorsze, wiesz, że logi stdouta będą multilinem, czyli wielolinijkowe. I teraz musisz pisać regexy szalone, żeby dowiedzieć się, który się łapie, bo jak nie, to będziesz miał tylko jedną linię z errora bez żadnego constaka ani niczego innego.
Łukasz Kałużny: Tak, to jest wiesz, wiem o czym mówisz, to nie jest… Inaczej, sorry Claude i Chat, jak powiesz zrób dobrze zgodnie z tym i z tym sposobem, to zrobi dobrze. Mówię to teraz złośliwie, ale wiesz o czym, wiesz jak to wygląda w praktyce.
Szymon Warda: Tak, to działa fajnie w aplikacji, które kontrolujesz, ale masz komponenty, które będą same z siebie wyrzucały błędy i tam tego już nie kontrolujesz.
Łukasz Kałużny: Tak, tam nie kontroluję. Mówię… Ale Szymon, podsumujmy, OpenTelemetry jest dla aplikacji, nad którymi masz kontrolę albo dostawca, mądrzy dostawcy, weźmy teraz wszystkie te rzeczy agentowe typu od Anthropica, GitHub Copilota, te agentówki, one wysyłają, tam nikt nic nie wymyślał. Tylko jak wejdziesz w logi to jest po prostu standard Otela, nic więcej. Jest dokładnie nazwy i wszystko ściągnięte. Nikt nie kombinował, wziął standard i go wdrożył.
Szymon Warda: I tak i nie. Bo znowu masz w, to, jak się OpenTelemetry rozrosło, to właśnie o obi i instrumentacji redową, czyli te metryki request, error, duration i o to też OpenTelemetry się rozrosło. Więc możesz monitorować aplikacje zewnętrzne, nad którymi nie masz kontroli. Ok, one będą w innym formacie i tak dalej, i tak dalej, zupełnie inna bajka, ale też właśnie OpenTelemetry to już nie jest tylko standard, to jest też ilość narzędzi, które Ci umożliwiają observability wokół tego. To już nie są tylko aplikacje, które ja rozwijam. Dobra, co tam jeszcze mamy Łukaszu?
Łukasz Kałużny: Słuchaj, to przejdźmy teraz do dwóch mózgotrzepów.
Szymon Warda: No dajesz.
Łukasz Kałużny: Raczej zacznijmy od tego czym jest tail sampling? Bo nie jak robić. Czym w ogóle jest tail sampling?
Szymon Warda: Dobra, to zacznijmy od tego w ogóle po co się robi sampling? Sampling robi się na trace’ach, bo o tym właśnie będziemy mówili. I mamy 2 sposoby samplingu. Head sampling, czyli na samym wejściu mówimy, że ten trace będziemy trace’ować, ten request będziemy trace’ować. I to jest taka loteria, bo nie mamy żadnych danych. I on jest znowu nie za bardzo rozwinięty. Wiadomo, że lepiej byłoby powiedzieć sytuację na samym końcu powiedzieć, że ok, to byśmy chcieli zapisać.
Łukasz Kałużny: W ogóle wytłumacz czym jest sampling. Bo sampling to mówimy, że próbkujemy i bierzemy n requestów sobie, w teorii zostawiamy.
Szymon Warda: Jakieś requesty wybieramy sobie, czy to będą te z błędami, czy te długie, czy mamy jakąś heurystykę bardziej rozbudowaną, tego jest dużo, podejść. Jeżeli chodzi o kolektory od vendorów, sprawdzają się odrobinę lepiej niż te opensource’owe. Więc wybieramy sobie. O to chodzi, żeby wybrać. I teraz jak to działa? Pamiętajmy, że każdy trace z każdej aplikacji idzie osobno, on jest osobno wysyłany. Więc musimy mieć jeden punkt, który te wszystkie trace’y zbierze i zdecyduje: ok, czy ja chcę go dalej zapisywać? Spoko, brzmi fenomenalnie. Tylko pamiętajmy, jak mamy to jedno miejsce, więc te wszystkie trace’y muszą pójść do jednego konkretnego kolektora, bo on to trzyma w pamięci. Więc po pierwsze w pamięci, po drugie musi czekać. Więc brzmi trochę niebezpiecznie. No ale dalej rabialnie, jeżeli mamy bardzo dużą wolumetrię. Spoko. Załóżmy, że to sobie działa. Ustalamy, że faktycznie on po trace id grupuje, moglibyśmy to w Gateway’u robić. Spoko loko. Tylko teraz wchodzimy do drugiego elementu, który to trochę komplikuje. Mamy mianowicie taką opcję, że teraz często wchodzisz do tego, że trace’y są z reguły do odpytywania pojedynczego, nie grupowego. Więc co z reguły robimy? Robimy coś, co nazywa się metrics from traces. Czyli po prostu generujemy metryki na bazie trace’ów, dzięki temu możemy odpytywać się o wolumen, a nie o konkretne trace’y. Spoko, fajnie. Tylko jeżeli teraz połączymy te dwie rzeczy, czyli będziemy mieli próbkowanie i będziemy mieli generowanie metryk, to wchodzimy w taką sytuację, że będziemy generowali metryki z po próbkowaniu. Co nie do końca jest dobrą opcją, bo jeżeli byśmy mieli head sampling, to jest proste, mnożymy razy powiedzmy próbkę, działa. Ale jeżeli mielibyśmy wybieranie bardziej złożone, to w tym momencie nie mamy pojęcia jak to wyglądało, czyli pliki mamy zaburzone kompletnie. Więc teraz co musimy zrobić? To musimy zrobić taki myk, żeby generować metryki z trace’ów zanim spróbkujemy i musimy bardzo mądrze balansować do kolektora, który to wszystko zbiera, którego nie za bardzo możemy potem skalować, bo musi być po tracie grupowany w tej sytuacji, żeby to wszystko trafiło.
Szymon Warda: A teraz wspomnimy jeszcze kolejny, trzeci element. Co jeżeli chcemy zbierać trace’y z wielu systemów? Wtedy musimy je grupować, jeżeli potem chcemy mieć podzielone, a chcemy podzielone, na wiele store’ów, żeby móc robić tam multi tenancy. Czyli dochodzi nam jeszcze jeden kolektor, który jest za Gatewayem, który zbiera z wielu Gatewayi i tam robi wszystko.
Łukasz Kałużny: Szymon, a ja zadam takie naiwne pytanie, bo czasem też się wiesz o tym pojawia. A co jeżeli powiemy, że trace’y trzymamy na przykład 3 dni?
Szymon Warda: To jest moje podejście.
Łukasz Kałużny: I nie samplujemy.
Szymon Warda: Nie ma…
Łukasz Kałużny: I stawiamy, że przykładowo jest sobie kolektor, Kafka, nasze Grafana, Tempo w tym wypadku i retencja na 3 dni.
Szymon Warda: Ja uważam, że trace’y to jest max 7 dni. To zostało obalone w sytuacji jak u innego klienta po samplingu, bardzo poważnym samplingu, w ciągu 3 dni mieli kilka terabajtów.
Kiler: Mają rozmach skurwysyny.
Szymon Warda: Więc tam trzymanie wszystkiego przez kilka dni się nie sprawdzi. Ogólnie rzecz biorąc sampling jako taki brzmi świetnie, niewyobrażalnie komplikuje architekturę całego rozwiązania, tak strasznie, to nie jest tego warte. Jeżeli macie wolumeny terabajtowe w ciągu kilku dni, to bawcie się w to. Ale jeżeli nie, nie dotykajcie tego (…).
Łukasz Kałużny: W szczególności, że chyba storage od Tempo… Inaczej, Kafka, teraz jak Kafka dojdzie teraz do, w tym będzie to wsparcie dla Kafki pomiędzy, jako oficjalny bufor, to naprawdę będzie to, mimo, że nienawidzę Kafki, to uważam, że w tym miejscu przez to, że retencja na tej Kafce jest bardzo krótka, bo ona ma być tylko buforem.
Szymon Warda: Ona ma być buforem, a zapisywanie i tak trzymanie danych jest relatywnie tanie.
Łukasz Kałużny: Tak, bo tam idzie wszystko do blob storage, do object storage.
Szymon Warda: Dokładnie tak.
Łukasz Kałużny: RAM jedynie jest drogi.
Szymon Warda: RAM jest drogi, ale dajemy go na ingesterach i to ogólnie rzecz biorąc śmiga powiedzmy sobie. My lubimy jak się ktoś z nami nie zgadza, więc napisz komentarz, zostaw, odezwiemy się.
Łukasz Kałużny: Dobra, jakaś myśl, którą chciałbyś zakończyć?
Szymon Warda: Moja jedna myśl to jest taka, że uważajcie. Wdrożenie kolektora bez całego stosu do observability, bez prawidłowego wdrożenia spowoduje, że dane będziecie bardziej gubili niż zyskacie. To nie jest takie proste, jakby się wydawało.
Łukasz Kałużny: Jeżeli patrzymy, kolektor jest, jeżeli wdrażacie już… Inaczej, jeżeli bierzecie Prometheusza, bierzecie Mimira, Prometheusza, Lokiego, Tempo, stawiacie na front Grafanę, to wtedy ten Otel jest w postaci na przykład Grafany Alloy jest rzeczą obowiązkową.
Szymon Warda: Tak.
Łukasz Kałużny: Wcześniej…
Szymon Warda: Dla prostych aplikacji pomijajcie kolektora, ale jak już go wdrażacie, to nie jest takie proste, jakby się mogło wydawać. Tam ścieżek, żeby się wywalić jest więcej niż happy pathów.
Blok Ekipa: Dopóki się nie zepsuje, podziała.
Łukasz Kałużny: Dobra, to tym zakończymy, ale wrócimy jeszcze w najbliższych odcinkach do observability, jak do tego teraz podchodzić.
Szymon Warda: Dobrze. Na razie.
Łukasz Kałużny: Na razie.

Wypełnij poniższy formularz, aby być na bieżąco ze wszystkimi
odcinkami Patoarchitektów
i uzyskać dostęp do dodatkowych
materiałów.