Czym jest profiling?
Profiling to technika obserwowalności, która pokazuje, jak aplikacja wykorzystuje zasoby obliczeniowe, przede wszystkim CPU i pamięć z dokładnością do konkretnej funkcji, a nawet linii kodu źródłowego. Zamiast wiedzieć jedynie, że "serwis X zużywa dużo CPU", profiling odpowiada na pytanie “dlaczego”. Odpowiedzią może być na przykład funkcja parseJSON(), która w module płatności wykonuje niepotrzebne alokacje pamięci przy każdym żądaniu.
Profilowanie kodu samo w sobie nie jest nowością. Programiści od dekad używają profilerów do poprawiania wydajności lokalnie (debuggowania), na własnym komputerze. Problem w tym, że taki tradycyjny profiling jest reaktywny: trzeba ręcznie uruchomić profiler w momencie, gdy problem występuje, co w praktyce oznacza, że przerywane, trudne do odtworzenia problemy wydajnościowe w produkcji często umykają.
Continuous profiling - profilowanie ciągłe
Odpowiedzią na te ograniczenia jest continuous profiling, czyli profilowanie ciągłe. Zamiast uruchamiać profiler doraźnie, system profiluje aplikację cały czas, w tle, na produkcji, przy minimalnym narzucie wydajnościowym, zwykle poniżej 2-3% dodatkowego zużycia CPU. Dzięki próbkowaniu (sampling) o niskim obciążeniu dane są zbierane nieprzerwanie i zapisywane w dedykowanej bazie danych do późniejszej analizy.
Dzięki temu profiling przestaje być narzędziem "na żądanie", a staje się częścią stałego monitoringu, dokładnie tak jak metryki czy logi. Gdy w środę o 3 w nocy wystąpi nagły skok zużycia pamięci, nie trzeba go złapać "na żywo", wystarczy cofnąć się w czasie i przejrzeć zebrane profile z tego okresu.
Profile w continuous profilingu są dodatkowo wzbogacane o dwa istotne wymiary:
- czas - dane są zbierane nieprzerwanie, więc można odpytywać wydajność aplikacji z dowolnego punktu w przeszłości,
- metadane kontekstowe (np. nazwa usługi, wersja, region) - pozwalają filtrować i porównywać profile między wdrożeniami, środowiskami czy instancjami.

Źródło: Grafana
Jak profiling uzupełnia pozostałe filary?
W skrócie, możemy powiedzieć, że:
- Metryki - mówią, że "coś" jest nie tak (np. wysokie CPU)
- Logi - co się wydarzyło w danym momencie
- Tracing - który serwis/request jest wąskim gardłem
- Profiling - która funkcja/linia kodu zużywa zasoby
Każdy z tych filarów odpowiada na inne pytanie. Aby zobaczyć, jak współpracują ze sobą w praktyce, wyobraźmy sobie problem na linii produkcyjnej w fabryce.
Metryki
Na pulpicie kierownika pojawia się alert: pobór energii elektrycznej na linii nr 2 spadł o 25%. Wiadomo, że coś jest nie tak.
Logi
W dzienniku zdarzeń widać, że o 10:17 fragment linii odpowiedzialnej za składanie opakowań zgłosił błąd i przeszedł w tryb awaryjny.
Tracing
Śledzisz drogę jednej sztuki przez kolejne stanowiska i widzisz, że największe opóźnienie powstaje na stanowisku nr 7.
Profiling
Analizujesz pracę robota na stanowisku nr 7 i odkrywasz, że trzykrotna kontrola wagi każdego opakowania zajmuje większość czasu pracy stanowiska. To właśnie ona jest bezpośrednią przyczyną spowolnienia.
Jak działa Pyroscope?
Grafana Pyroscope to otwartoźródłowy system do agregacji danych profilowania ciągłego. Powstał z połączenia dwóch projektów: Pyroscope (założonego w 2020 roku przez Ryana Perry'ego i Dmitry'ego Filimonova) oraz Phlare, projektu rozwijanego przez Grafana Labs, które w 2023 roku przejęły Pyroscope i połączyły oba narzędzia pod jedną nazwą.
Kluczowe cechy architektoniczne:
- Jeden binarny plik - Pyroscope można uruchomić jako pojedynczy proces bez dodatkowych zależności, co ułatwia start.
- Skalowalność pozioma - architektura rozproszona pozwala skalować Pyroscope wraz ze wzrostem liczby profilowanych usług.
- Trwałe, długoterminowe przechowywanie danych profilowania, umożliwiające analizę trendów w czasie.
- Zgodność z OpenTelemetry Protocol, co wpisuje się w ogólny trend standaryzacji w observability.
Warto tu wspomnieć o dużej zmianie architektonicznej z Pyroscope 2.0 (wydanie z kwietnia 2026). W wersji 1.x każdy profil był replikowany trzykrotnie na ścieżce zapisu, co przy profilach ważących nierzadko dziesiątki megabajtów generowało spory narzut kosztowy. Pyroscope 2.0 eliminuje tę replikację całkowicie. Każdy profil zapisywany jest dokładnie raz, bezpośrednio do object storage, które staje się jedynym źródłem prawdy dla wdrożeń rozproszonych. Odciążono też ścieżkę zapytań - przetwarzanie zapytań stało się bezstanowe, co pozwala elastycznie skalować moc obliczeniową zamiast rezerwować ją "na zapas" pod szczytowe obciążenia.

Źródło: Grafana
Proces zbierania danych
W praktyce działanie Pyroscope wygląda następująco:
- Instrumentacja aplikacji. Do aplikacji (lub jej środowiska uruchomieniowego) dołączany jest agent profilujący. Może to być biblioteka wbudowana w kod (SDK dla Go, Java, Python, Ruby, .NET itd.) albo profiler oparty o eBPF, działający na poziomie systemu operacyjnego i nie wymagający zmian w kodzie aplikacji.
- Próbkowanie (sampling). Agent okresowo (np. 97 razy na sekundę) "robi zdjęcie" stosu wywołań (call stack) każdego wątku aplikacji. Sprawdza, jaka funkcja jest aktualnie wykonywana i jaki jest jej pełny łańcuch wywołań.
- Agregacja próbek. Zebrane próbki są agregowane lokalnie i okresowo wysyłane do serwera Pyroscope (lub Grafana Cloud Profiles jako usługi zarządzanej).
- Zapis w bazie profilowania. Serwer Pyroscope zapisuje dane w wyspecjalizowanej bazie zoptymalizowanej pod dane profilowe, czyli duże, gęste struktury reprezentujące stosy wywołań w czasie.
- Wizualizacja i zapytania. Dane można przeglądać w Grafanie. Do eksploracji służy m.in. Grafana Profiles Drilldown, a zapytania do danych profilowych obsługuje dedykowany język zapytań (FlameQL).
Jedną z największych zalet Pyroscope jest możliwość połączenia profili z trace'ami z Tempo - funkcja nazywana span profiles. Dzięki niej, patrząc na wolny span w tracingu rozproszonym, można od razu zobaczyć profil dokładnie tego fragmentu żądania i zejść na poziom linii kodu odpowiedzialnej za opóźnienie, zamiast zgadywać na podstawie samego czasu trwania spanu.

Źródło: Grafana
Po co to wszystko?
Continuous profiling rozszerza możliwości observability o analizę na poziomie kodu. Dzięki temu zespoły mogą nie tylko wykrywać problemy z wydajnością, ale także dokładniej identyfikować ich źródło. Zamiast dorzucać kolejne instancje serwerów, gdy rośnie zużycie CPU, zespoły mogą wskazać dokładnie tę linię kodu, która odpowiada za problem, i naprawić przyczynę, a nie objaw. W praktyce przekłada się to na:
- niższe koszty infrastruktury, dzięki eliminacji nieefektywności w kodzie zamiast skalowania sprzętu,
- niższe opóźnienia, bo precyzyjna lokalizacja wąskich gardeł pozwala je szybciej usunąć,
- krótszy czas rozwiązywania incydentów (MTTR), bo zamiast szukać przyczyny "po omacku", inżynierowie od razu widzą, która funkcja odpowiada za skok zużycia zasobów.
Podsumowanie
Profiling domyka obraz observability. Dzięki podejściu continuous profiling, realizowanemu przez narzędzia takie jak Grafana Pyroscope, można nieprzerwanie obserwować, jak aplikacja zużywa CPU i pamięć, z dokładnością do konkretnej linii kodu, i cofać się w czasie, by zbadać incydenty, które wystąpiły, zanim ktokolwiek zdążył ręcznie uruchomić profiler. To właśnie czyni profiling pełnoprawnym, czwartym filarem nowoczesnego observability.
