OpenTelemetry obok Elastic i Grafany: jak go wdrożyć
OpenTelemetry to otwarty standard zbierania metryk, logów i śladów. Opisujemy architekturę z kolektorem i wysyłkę danych do Elastic oraz Grafany.
OpenTelemetry (OTel) to otwarty standard i zestaw narzędzi do wytwarzania, zbierania i wysyłania danych telemetrycznych: śladów, metryk i logów. Nie jest systemem do przechowywania ani wizualizacji danych. Te role zostawia backendom, takim jak Elastic, Grafana, Prometheus czy rozwiązania komercyjne. Dzięki temu aplikację instrumentujesz raz, a miejsce docelowe danych możesz zmienić bez przepisywania kodu. Poniżej opisujemy, jak to ułożyć w praktyce.
Z czego składa się OpenTelemetry
- Sygnały. Ślady (traces) pokazują drogę pojedynczego żądania przez usługi, metryki to liczby opisujące stan systemu w czasie, a logi to zdarzenia z aplikacji i infrastruktury. Wspólne identyfikatory śladu i spanu pozwalają połączyć log z żądaniem, które go wywołało.
- SDK i instrumentacja. Biblioteki dla języków takich jak Java, .NET, Python, Node.js czy Go. Instrumentacja automatyczna dodaje ślady do popularnych bibliotek bez zmian w kodzie, a ręczna pozwala opisać własną logikę biznesową.
- OTLP. Protokół OpenTelemetry (OpenTelemetry Protocol), którym dane przechodzą między aplikacją, kolektorem i backendem. Działa przez gRPC (domyślnie port 4317) i HTTP (port 4318).
- Konwencje semantyczne. Ustalone nazwy atrybutów, na przykład dla żądań HTTP, baz danych czy hostów. To dzięki nim te same dane wyglądają tak samo w każdym narzędziu.
- Collector. Osobny proces, który odbiera dane, przetwarza je i wysyła dalej. To najważniejszy element wdrożenia.
OpenTelemetry jest projektem Cloud Native Computing Foundation, powstał z połączenia OpenTracing i OpenCensus i nie jest związany z jednym dostawcą.
Dlaczego kolektor, a nie wysyłka prosto z aplikacji
Aplikacje potrafią wysyłać dane bezpośrednio do backendu, ale w środowisku firmowym kolektor między nimi daje kilka konkretnych korzyści:
- Jedno miejsce konfiguracji. Adres backendu, dane uwierzytelniające i filtry zmieniasz w kolektorze, a nie w kilkudziesięciu aplikacjach.
- Buforowanie i ponawianie. Gdy backend jest chwilowo niedostępny, kolektor przechowuje dane i ponawia wysyłkę, więc aplikacja nie traci czasu na czekanie.
- Przetwarzanie przed wysyłką. Kolektor może dodać atrybuty (nazwa środowiska, region), usunąć dane wrażliwe, odrzucić szum i spróbkować ślady.
- Wysyłka do wielu miejsc. Ten sam strumień może trafić jednocześnie do Elastic i do Grafany, na przykład podczas migracji z jednego narzędzia na drugie.
Kolektor składa się z odbiorników (receivers), procesorów (processors) i eksporterów (exporters) łączonych w potoki osobno dla każdego sygnału. Zwykle uruchamia się go w dwóch rolach: jako agenta na każdym hoście lub w klastrze Kubernetes (zbiera dane lokalnie) i jako bramę (gateway), czyli małą grupę instancji, które przyjmują dane od agentów i wysyłają je do backendów.
Przykład konfiguracji kolektora
Poniższy szkic odbiera dane OTLP, zabezpiecza kolektor przed przeciążeniem pamięci, grupuje dane w paczki i wysyła je w dwa miejsca. Adresy i dane uwierzytelniające są przykładowe.
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 75
spike_limit_percentage: 20
resourcedetection:
detectors: [system]
batch: {}
exporters:
otlp/elastic:
endpoint: apm.example.com:443
headers:
Authorization: "Bearer ${env:ELASTIC_SECRET_TOKEN}"
otlphttp/grafana:
endpoint: https://otlp.example.com
headers:
Authorization: "Basic ${env:GRAFANA_OTLP_TOKEN}"
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, resourcedetection, batch]
exporters: [otlp/elastic, otlphttp/grafana]
metrics:
receivers: [otlp]
processors: [memory_limiter, resourcedetection, batch]
exporters: [otlp/elastic, otlphttp/grafana]
logs:
receivers: [otlp]
processors: [memory_limiter, resourcedetection, batch]
exporters: [otlp/elastic, otlphttp/grafana]
Procesor memory_limiter stoi w potoku pierwszy, a batch ostatni. Sekrety przekazuj przez zmienne środowiskowe, nie wpisuj ich do pliku. Wysyłkę do dwóch backendów zostaw tylko na czas porównania albo migracji, bo podwaja ruch i koszt przechowywania.
OpenTelemetry i Elastic
Elastic przyjmuje dane OTLP, więc aplikacja zinstrumentowana przez OpenTelemetry może wysyłać ślady i metryki do Elastic Observability. Możliwe są trzy drogi:
- dane OTLP z kolektora (lub wprost z SDK) trafiają do APM Server, który przyjmuje OTLP i zapisuje dane w Elasticsearch;
- ta sama ścieżka, ale z użyciem Elastic Distribution of OpenTelemetry (EDOT), czyli dystrybucji kolektora i SDK dla wybranych języków, którą rozwija Elastic;
- istniejące agenty Elastic APM, które mogą pracować z API OpenTelemetry.
Dla nowych wdrożeń zaczynamy od standardowych SDK OpenTelemetry i kolektora, bo to nie wiąże aplikacji z jednym dostawcą. Warto sprawdzić, które wersje i funkcje obsługuje wybrana wersja Elastic, bo zakres wsparcia dla OTel w Elastic szybko rośnie.
OpenTelemetry i Grafana
Stos Grafany też przyjmuje OTLP: Tempo przechowuje ślady, Loki logi, a Mimir i Prometheus metryki. Do zbierania danych Grafana oferuje Grafana Alloy, czyli własną dystrybucję kolektora OpenTelemetry z wbudowanymi potokami Prometheus. Alloy może więc pełnić rolę kolektora z przykładu powyżej.
Jak wdrażać krok po kroku
- Zacznij od jednej usługi. Wybierz aplikację ważną dla biznesu, ale nie najbardziej krytyczną. Włącz instrumentację automatyczną i sprawdź, jakie ślady powstają.
- Ustal konwencje. Nazwy usług, środowisk i wersji muszą być jednolite we wszystkich zespołach. Bez tego dashboardy i alerty będą nieczytelne.
- Postaw kolektor. Najpierw jako bramę, potem agenty na hostach. Monitoruj sam kolektor: ma własne metryki (zużycie pamięci, długość kolejek, odrzucone dane).
- Dodaj logi z powiązaniem ze śladem. Wpisywanie identyfikatora śladu do logów aplikacji to najtańszy sposób, żeby z błędu w logu przejść do całego żądania.
- Ogranicz koszt. Próbkowanie śladów, filtrowanie metryk o wysokiej kardynalności i krótszy czas przechowywania zwykle obniżają rachunek o więcej niż jakakolwiek optymalizacja backendu.
- Rozszerzaj stopniowo. Dopiero po ustabilizowaniu pierwszej usługi dodawaj kolejne.
Na co uważać
Instrumentacja automatyczna zwiększa zużycie procesora i pamięci aplikacji, więc po włączeniu zmierz to na środowisku testowym. Atrybuty ze śladów mogą zawierać dane osobowe, na przykład adresy e-mail w adresach URL, więc przed wysyłką filtruj je w kolektorze. Wreszcie: różne języki mają różny stopień dojrzałości poszczególnych sygnałów, dlatego sprawdź dokumentację OpenTelemetry dla swojego języka, zanim obiecasz sobie logi lub metryki z danej biblioteki.
Gdy będziesz porównywać wydajność klastra przyjmującego te dane, przyda się nasz tekst o benchmarku Elasticsearch narzędziem Rally. Architekturę z kolektorem, od wyboru po utrzymanie, wdrażamy w ramach monitoringu aplikacji.