Na początku był chaos…

…i problemy produkcyjne

Z aplikacją na produkcji może być wiele problemów. Wycieki pamięci, rzucane wyjątki, zamulająca baza danych – to tylko kilka przykładów z czym borykamy się wdrażając naszą aplikację na serwer produkcyjny. Niestety zwykle (a raczej nigdy) nie ma tam pod ręką Visual Studio aby zdiagnozować takie problematyczne sytuacje. Musimy sobie radzić inaczej. Jeśli masz czasami taki problemy – zapraszam do lektury

Jak sobie radzić?

 

Opisywałem już kiedyś, że w takich sytuacjach możemy poradzić sobie korzystając z narzędzi,  mniejszych i lżejszych, niż Visual Studio. Są to: remote debugging, mDbg oraz WinDbg. Możemy także wykonać zrzut pamięci procesu (TaskManager, Process Explorer lub podobne) i starać się z niego wyciągnąć informacje o tym jak radzi sobie nasza aplikacji (choć w tym przypadku dostaniemy informację tylko o tym jak sobie radzi zarządzając pamięcią). Dziś pokażę jak możemy okiełznać produkcyjny pożar gdy wcześniejsze techniki i narzędzia to luksus. Okazuje się, że już na poziomie Windowsa mamy wbudowany mechanizm, który dostarcza nam mnóstwa informacji. Mechanizmem tym są Performance Countery.

Czym są Performance Countery?

 

Są to metryki zaszyte w system operacyjny, które dostarczają informacji o tym jak radzi on sobie w danym momencie czasu. Monitorowanych parametrów jest sporo: CPU, pamięć, procesy, wątki – to tylko niektóre z nich. W zasadzie możemy dowiedzieć się wszystkiego. Mechanizm jest rozszerzalny, i wiele programów z niego korzysta, więc tak na prawdę możliwości informacyjne są nieograniczone.

Interesujące wskaźniki dla programisty

 

Jak już wspomniałem – wskaźników jest sporo. Rzekłbym, że nawet za dużo. Warto dobrze się zastanowić nad tymi, które chcemy logować z tego względu, że od nadmiaru zalogowanych danych może nam się odechcieć ich analizy. Z drugiej strony warto mieć w zanadrzu jakieś dodatkowe miary aby nimi podeprzeć nasze wnioski. Do najważniejszych (moim zdaniem) wskaźników z punktu widzenia programisty .NET są:
  • .NET Exceptions
  • .NET CLR Loading
  • .NET CLR Memory
  • ASP.NET v 4.0.xxxx/ASP.NET v 2.0.xxxx
  • ASP.NET Apps
  • ASP.NET Applications
  • SQL Server (o ile zainstalowany)
  • Process

Oczywiście w zależności od kontekstu mogą przydać nam się inne mierniki – ale powyższe chyba stanowią takie minimum od którego zawsze zaczynam.

Gdzie ich szukać i jak logować

Wystarczy uruchomić perfmon.exe lub wybrać je z Narzędzi Administracyjnych. Pokaże się nam okno jak poniżej gdzie klikając na element Performance Monitor będziemy mogli na żywo obserwować wybrane przez nas mierniki.

Po przejściu na element Performance Monitor, za pomocą dodatkowego przycisku (zielony plus) będziemy mogli dodać mierniki.

Z listy możemy wybrać na początku interesującą nas grupę. Jeśli jej nie rozwiniemy i nie zmienimy domyślnego wyboru, zostaną zaznaczone wszystkie dostępne w niej mierniki w danej. Po wyborze grupy możemy, jeśli taka opcja jest dostępna dla danego miernika, wybór instancji danego wskaźnika. Zwykle możemy się zadowolić wyborem _Total lub . Przy bardziej dokładnej analizie warto zdecydować się na wybór poszczególnych elementów, aby nie mieć zbyt dużego zbioru do analizy.

Po tym możemy już oglądać pomiar na ekranie. Jednakże takie podejście jest mało optymalne. Bo co w momencie gdy potrzebujemy obserwować pomiar przez dłuższy czas lub też zrobić go w określonych godzinach? Siedzenie do późna w nocy aby sprawdzić responsywność serwera także przedstawia się mało ciekawie. Na szczęście jest na to rozwiązanie.

Wystarczy przejść do elementu Data Collector Sets. Są tam już gotowe szablony dostarczone z systemem, ale my utworzymy własny. Klikamy na element User Defined i z menu kontekstowego wybieramy New a następnie Data Collector Set. Otworzy nam się kreator tworzenia nowego zbioru. W pierwszym kroku nadajemy mu nazwę i wybieramy czy chcemy skorzystać z predefiniowanych szablonów czy też określić wszystko samodzielnie. W większości wypadków można skorzystać z gotowców a jak będziemy potrzebować większej kontroli można użyć rozwiązania zaawansowanego. W kroku drugim wybieramy szablon

Jako, że badamy wydajność naszej aplikacji wybieramy System Performance. W następnym kroku będziemy mieli możliwość ustawienia ścieżki gdzie zostaną zapisane dane z naszych pomiarów. Ostatni krok to pytanie o dalsze działania. Do wyboru mamy: Open properties for this data collector set, Start this data collector set now oraz Save and close. W tym pierwszym przypadku wyświetlone zostaną dodatkowe właściwości dzięki którym jeszcze bardziej możemy dostosować nasz zbiór. Druga opcja to uruchomienie zbierania od razu a ostatnia opcja to zapisanie i zamknięcie bez dalszego działania. Ja zwykle potrzebuję dostosować datę i czas kiedy chcę aby dany zbiór zadziałał więc z reguły zaznaczam pierwszą opcję.

Dane logowane potrafią zająć dość sporo miejsca, dlatego też ustawione są reguły usuwające stare/duże pliki z logami. Jeśli nie chcecie stracić przypadkiem świeżo zalogowanych danych warto zerknąć do DataManager. Można tam ustawić jak i kiedy zalogowane dane powinny być usuwane.

Własne Performance Countery?

 

Zobaczmy teraz jak możemy rozszerzyć dostępne wskaźniki o własne informacje. Przestrzeń nazwa w której się będziemy poruszać to System.Diagnostics.

Pierwsze co zrobimy to sprawdzimy czy nasz miernik istnieje

string name = "Octal Solutions";
if (PerformanceCounterCategory.Exists(name) == false)
{
    var counterData = new CounterCreationDataCollection();
    var instanceCountCounter = new CounterCreationData("Instances", "Instances count", PerformanceCounterType.NumberOfItems32);
    counterData.Add(instanceCountCounter);
    PerformanceCounterCategory.Create(name, "Help", PerformanceCounterCategoryType.SingleInstance, counterData);
}

Kod jest dość prosty więc omówimy go w telegraficznym skrócie. Za pomocą PerformanceCounterCategory.Exists sprawdzamy czy nasza kategoria istnieje, jeśli tak nic dalej nie robimy. W przeciwnym razie przystępujemy do jej utworzenia. Tworzymy nasz miernika podając jego nazwę, opis oraz typ. O typach więcej będzie poniżej. Dodajemy go do kolekcji i tworzymy kategorię podając dodatkowo opis oraz rodzaj. Kategoria może być typu SingleInstance, MultipleInstance oraz Unknown. Parametr ten jest dość oczywisty. Albo nasz miernik będzie zachowywał się jak singleton albo nie. Mając tak przygotowane podwaliny możemy przystąpić do właściwego kodu.
A tego nie będzie wiele..

var performanceCounter = new PerformanceCounter("Octal Solutions", "Instances", false);

Dwa pierwsze argumenty to kategoria oraz nazwa miernika a trzeci określa czy chcemy mieć do niego dostęp tylko-do-odczytu. Gdybyśmy naszą kategorię utworzyli w trybie MultiInstance trzeba wtedy wywołać konstruktor z dodatkowym argumentem określającym nazwę instancji. Mając dostęp do miernika możemy go np. zwiększyć o 1.

static void Main(string[] args)
{
    CreateCounterIfDoesNotExist();
    Console.WriteLine("Demo: Custom Performance Counters");
    var performanceCounter = new PerformanceCounter("Octal Solutions", "Instances", false);
    performanceCounter.Increment();

    Console.WriteLine("Instance created. Press any key to kill it");

    Console.ReadKey();
    performanceCounter.Decrement();
    Console.WriteLine("End");
}

Nasz miernik w działaniu po kilku chwilach..

Teraz trochę o typach mierników. Mamy do wyboru naprawdę pokaźną ich liczbę. Dokładny ich opis można znaleźć na MSDN – PerformanceCounterType. Jeśli zmienimy typ naszego miernika na RateOfCountsPerSecond umożliwi nam to automatycznie analizowanie jak zmienia się nasza miara w czasie. A wykres po krótkim działaniu prezentował o ile zmieniła się wartość naszego wskaźnika w sekundzie czasu. Polecam poeksperymentować z różnymi typami w przypadku tworzenia własnych mierników.

Podsumowanie

Uff – jeśli dotarłeś czytelniku do końca to gratuluję wytrwałości w dążeniu do zdobycia wiedzy. Mam nadzieję, że udało mi się pokazać, że PerfCounter’y mogą stanowić wartościowe źródło informacji o tym co dzieje się w systemie jak i o naszej aplikacji. Biorąc pod uwagę to, że możemy tworzyć własne dajemy sobie jedno centrum zarządzania kryzysowego naszej aplikacji.

Miłego analizowania!

dotnetomaniak.plSpodobał Ci się ten artykuł? Proszę udostępnij go na portalu dotnetomaniak.pl bądź innych portalach społecznościowych.

Founder of Octal Solutions a .NET software house.
Passionate dev, blogger, occasionally speaker, one of the leaders of Wroc.NET user group. Microsoft MVP. Podcaster – Ostrapila.pl