Singed, front-end Profilera dla aplikacji Ruby i Rails

May 09 2023
Czy kiedykolwiek chciałeś zrozumieć, dlaczego blok kodu Ruby, określone żądanie sieciowe lub określona akcja kontrolera działała tak wolno? Być może w przeszłości korzystałeś z narzędzi do profilowania, takich jak speedscope, ale okazało się to uciążliwe lub próbowałeś, ale nie udało ci się dowiedzieć, jak z nich korzystać. Przedstawiamy Singed, nową nakładkę do profilowania od Gusto, napisaną przez Josha Nicholsa (alias @technicalpickles).

Czy kiedykolwiek chciałeś zrozumieć, dlaczego blok kodu Ruby, określone żądanie sieciowe lub określona akcja kontrolera działała tak wolno? Być może w przeszłości korzystałeś z narzędzi do profilowania, takich jak speedscope, ale okazało się to uciążliwe lub próbowałeś, ale nie udało ci się dowiedzieć, jak z nich korzystać.

flamegraph: Cokolwiek… i to wszystko!

Przedstawiamy Singed , nową nakładkę do profilowania od Gusto, napisaną przez Josha Nicholsa (alias @technicalpickles) . Singed został zbudowany jako nakładka szwajcarskiego scyzoryka dla kilku narzędzi ( stackprof , rbspy i speedscope ), pomagająca w łatwym przechwytywaniu i przeglądaniu wykresów płomieni, gdzie wcześniej trzeba było napisać kilka szablonów lub tymczasowego kodu, aby zacząć .

Dlaczego kolejne narzędzie do profilowania?

Singed dodaje nową metodę w jądrze, dostępną wszędzie:

flamegraph {
  # your code here
}

Przede wszystkim większość programistów Ruby, którzy chcą przeglądać wykresy płomieni, używa rack-mini-profiler , który jest doskonałym i łatwym w użyciu interfejsem dla stackprof . Po prostu dodaj ?pp=flamegraph na końcu dowolnego adresu URL i świt, masz otwarty wykres płomieni w przeglądarce.

Jednak często chcemy profilować rzeczy, które nie są tylko bieżącym adresem URL na pasku nawigacyjnym naszej przeglądarki.

Na przykład możemy chcieć sprofilować żądanie GraphQL, które jest wysyłane przez bramę taką jak Apollo. Możemy nie być w stanie łatwo znaleźć adresu URL, którego Apollo Gateway używa do wysłania żądania, więc trudno jest powielić i użyć mini-profilera do przechwycenia wykresu płomieni.

Lub możemy chcieć po prostu sprofilować blok kodu Ruby lub zadanie w tle, a nawet test. Możesz napisać własny kod, aby to zrobić i samodzielnie wywołać stackprof, ale przekierowanie danych wyjściowych do pliku to dobre kilkadziesiąt wierszy, a następnie prawdopodobnie nadal będziesz musiał otworzyć go ręcznie w przeglądarce.

Dlaczego warto używać Speedscope, Stackprof i rbspy?

Singed jest zasadniczo opakowaniem trzech różnych narzędzi:

  • Speedscope , wizualizator flamegraphu.
  • stackprof , narzędzie do profilowania próbkowania dla języka Ruby.
  • rbspy , kolejny program do profilowania próbkowania dla języka Ruby, napisany w języku Rust.
Wizualizator Speedscope jest piękny i dość szybki, nawet na dużych profilach.

stackprof to narzędzie do profilowania próbkowania dla języka Ruby. Jest to rozszerzenie C dla maszyny wirtualnej Ruby, co oznacza, że ​​musi być „uruchomione” w tym samym czasie wraz z procesem Ruby. rbspy działa inaczej — w rzeczywistości używa uprawnień sudo do odczytywania pamięci procesu Ruby z zewnątrz. Jako taki, może być dołączony w dowolnym momencie do procesu Ruby, dlatego Singed używa go do profilowania procesów Ruby z CLI.

Profilery próbkowania, takie jak stackprof i rbspy, to świetny wybór, ponieważ dość dobrze skalują się do większych baz kodu. Profilery śledzące, takie jak ruby-prof , zwykle zawodzą w skali Gusto ze względu na ogromną ilość kodu zaangażowanego w uruchamianie naszej aplikacji.

Wreszcie, stackprof i rbspy mają duże wsparcie w społeczności. Nie musimy na przykład samodzielnie aktualizować profilera, aby obsługiwał nowe wersje języka Ruby.

Szybka prezentacja funkcji

Rzućmy okiem na to, co faktycznie potrafi Singed. Jednym z moich ulubionych sposobów korzystania z Singed jest po prostu profilowanie prostego bloku kodu w naszej aplikacji Rails.

Załóżmy na przykład, że chcę sprofilować pracę w tle, MyWorker. Stworzyłbym plik o nazwie myprofile.rb, umieściłbym go w katalogu głównym naszej aplikacji Rails, a następnie dodał:

user = User.first
flamegraph { MyWorker.new.perform(user) }

bin/rails runner myprofile.rb

Inną powszechną rzeczą, z którą spotykam się w przypadku profili, jest to, że czasami dość skomplikowane jest skonfigurowanie stanu wymaganego do profilowania fragmentu kodu. Może po prostu potrzebujesz bardzo określonego stanu bazy danych lub musisz najpierw uruchomić dużo kodu. Często taka konfiguracja istnieje już w naszych testach.

Singed bardzo ułatwia profilowanie testu. Oznacza to, że możesz oczywiście profilować i optymalizować swój zestaw testów, ale tak naprawdę uważam to za bardziej przydatne do profilowania kodu, który wymaga wielu konkretnych ustawień:

require 'singed/rspec'
RSpec.describe YourClass do
  it "is slow :(", flamegraph: true do
    # your code here
  end
end

Innym przypadkiem użycia Singed jest profilowanie żądań. W Gusto mamy bramkę GraphQL (Apollo), która wysyła żądania do naszego backendu Rails. Czasami chcę sprofilować te żądania, ale jest to dość trudne za pomocą rack-mini-profiler, ponieważ nie znam adresu URL i treści żądania, które backend Apollo wysyła do Railsów. Zamiast tego z Singedem robię:

  • Wywołaj żądanie backendu GraphQL z frontendu.
  • W Chrome DevTools kopiuję to żądanie „jako pobrane”. To pozwala mi wkleić go do mojej konsoli JavaScript i wywołać to jedno żądanie GraphQL na żądanie.
  • Zatrzymuję i ponownie uruchamiam serwer zaplecza, tym razem dodając zmienną środowiskową SINGED_MIDDLEWARE_ALWAYS_CAPTURE=1.
  • Ponownie uruchamiam żądanie w mojej konsoli JavaScript.

Możesz także łatwo sprofilować uruchamianie aplikacji Rails:

bundle binstub singed
bin/singed -- bin/rails runner 'true'

Profiler Frontend o wielu zastosowaniach

Mam nadzieję, że przekonałem cię do wypróbowania Singeda. Używam go prawie codziennie tutaj w Gusto.

Jeśli uznałeś to za interesujące, sprawdź to na GitHub .