Application Insights, Jekyll i continuous deployment

W trakcie zabaw mających docelowo zmienić hosting bloga oraz nauczyć mnie paru nowych rzeczy przyszedł do mnie taki o to mail. Powiadomienie z Visual Studio Application Insights

Jak widać z dużego nagłówka w mailu powiadomienie pochodzi z Visual Studio Application Insights. Application Insights czy też w skrócie AppInsights to usługa w Microsoft Azure pozwalająca na monitoring aplikacji od strony klienckiej (web, mobile czy też desktop) i serwerowej. Wspiera ona całkiem sporo języków i platform. Tutaj cała lista.

Ja na swoim blogu używam dwóch funkcji AppInsights: testów dostępności oraz monitoringu od strony klienckiej. Monitoring od strony klienckiej w przypadku aplikacji webowej to nic innego jak kawałek skryptu JS, który z przeglądarki monitoruje co się dzieje ze stroną.

W ramach usługi dostajemy z pudełka predefiniowane widoki, które pokazują co dzieje się z naszą aplikacją. Jeśli jeszcze dodatkowo mamy w naszej aplikacji wrzucony monitoring od strony server-side (w aplikacji lub np. w IIS) to nasze logi będą korelowane ze sobą, co bardzo ułatwia potem analizę problów.

Domyślne statystyki Client-Side w Application Insights

Jako alternatywę można stworzyć własne widoki/zapytania w narzędziu analytics.applicationinsights.io (otwiera się je z poziomu Azure). Sam język zapytania podobny jest do Power Query/F#. To już daje nam naprawdę bardzo zaawansowany sposób analizy i brak uwiązania do konkretnych wizualizacji jakie na starcie daje nam usługa.

Jako przykład poniższe zapytanie, które z danych z AppInsights wybierze ze wszystkich pageViews 10 stron z czasem ładowania powyżej 2000 ms i grupowaniem po nazwie strony i regionie/kraju użytkownika.

pageViews 
| summarize count(), avg(duration)
  by operation_Name, client_CountryOrRegion
 | sort by count_  desc 
 | where avg_duration > 2000
 | take 10

Przykładowe zapytanie w analytics.applicationinsights.io

Oprócz widoku tabeli można prezentować dane w postaci wykresów.

Przykładowe zapytanie w analytics.applicationinsights.io

Dodatkowo możemy wrzucać własne zdarzenia i metryki z aplikacji po stronie klienckiej jak i serwerowej, które potem można analizować(tutaj bardziej szczegółowy opis).

Uruchomienie samego monitoringu client-side jest banalnie proste i polega na wrzuceniu kodu JavaScript na stronę, który wygląda tak jak poniżej. Jedyne co należy zmienić to wartość instrumentationKey na Instrumentation Key z naszego AppInsights.

<script type="text/javascript">
  var appInsights=window.appInsights||function(config){
    function r(config){t[config]=function(){var i=arguments;t.queue.push(function(){t[config].apply(t,i)})}}var t={config:config},u=document,e=window,o="script",s=u.createElement(o),i,f;s.src=config.url||"//az416426.vo.msecnd.net/scripts/a/ai.0.js";u.getElementsByTagName(o)[0].parentNode.appendChild(s);try{t.cookie=u.cookie}catch(h){}for(t.queue=[],i=["Event","Exception","Metric","PageView","Trace","Dependency"];i.length;)r("track"+i.pop());return r("setAuthenticatedUserContext"),r("clearAuthenticatedUserContext"),config.disableExceptionTracking||(i="onerror",r(""+i),f=e[i],e[i]=function(config,r,u,e,o){var s=f&&f(config,r,u,e,o);return s!==!0&&t[""+i](config,r,u,e,o),s}),t
    }({
        instrumentationKey:”Twój instrumentationKey”
    });
    window.appInsights=appInsights;
    appInsights.trackPageView();
</script>

appInsights aktualnie istnieje już w postaci gotowych wtyczek do różnych rozwiązań na przykład do WordPress.

Inną opcją jest monitoring dostępności webowej aplikacji. Mamy dostępne dwa typy testów:

Jak widać poniżej konfiguracja URL ping test jest szybka i wygodna. Możemy wybrać z jakich lokalizacji mają być wykonywane testy, jak mają być obsługiwanie alerty i powiadomienia dla nich (mail oraz wywołanie webhook). Kryteria sukcesu wraz z kodem http i szukaniem konkretnej treści w odpowiedzi serwera.

Konfiguracja URL ping test w appInsights

Bardzo przydatną opcją jest Parse dependent requests. Parametr ten odpowiada w trakcie testu za pobranie wszystkich dodatkowych zasobów takich jak pliki css, js czy obrazy.

W trakcie sprawdzania bloga właśnie ta dodatkowa opcja wskazała, że coś zepsułem. Dokładnie to gdzieś wcięło plik css.

Aktualnie mój blog działa na Azure WebApps z wykorzystaniem statycznych stron generowanych za pomocą Jekyll. Jekyll to taki fajny kawałek softu do generowania statycznych stron z plików markdown oraz szablów stworzonych z wykorzystaniem Liquid itp. Wordpressa porzuciłem ze względu na potrzebę utrzymywania(aktualizowania), bardzo wolne darmowe ClearDB oferowane w Azure (nie wszystkie pluginy działały wtedy z SQL Database). Po za tym sposób obsługi Jekyll dla mojej geekowskiej natury jest fajniejszy (kochane cmd).

Sam Jekyll jest napisany w Ruby i działa jako generator statycznych plików HTML, czyli po napisaniu nowego posta trzeba wygenerować za pomocą polecenia(jekyll build) nowe pliki strony i wgrać je na serwer/usługę.

Oczywiście z wrodzonego lenistwa proces publikacji u mnie został uproszczony ;-).

Projekt z blogiem trzymam w repozytorium GIT na Bitbucket (ma za darmo prywatne repozytoria w porównaniu do GitHub).

Sam proces continuous deployment wygląda tak:

Proces continuous deployment  z Jekyll na Azure WebApp

Dodając coś do bloga piszę lokalnie i wprowadzam zmiany w lokalnym repo, a następnie wypycham zmiany do repozytorium Bitbucket. Kiedy Bitbucket otrzymuję nowy push do repo to za pomocą webhook uruchamia WebJob w Azure. WebJob to skrypt, który pobiera ostatnią wersję strony z repozytorium i za pomocą Jekyll buduję nową wersję stronę, a następnie publikuje ją w Azure WebApp poprzez skopiowanie plików.

W ramach nauki i zmniejszenia zużycia mojej prywatnej subskrypcji Azure (WebApp do małej strony nie jest opłacalny ;-)) postanowiłem przerzucić blog na AWS. Dokładnie na storage S3, który wspiera hostowanie statycznych stron oraz CDN CloudFront, który daję parę benefitów o których napiszę innym razem. Cały koszt takiego utrzymania w AWS to aż 1,3 USD miesięcznie :-D.

Nowy proces CD wygląda tak:

Proces continuous deployment (CD) z Jekyll na Azure WebApp

Jak widać zamiast Webjob jest tutaj wercker. Wercker to narzędzie SaaS do automatycznego budowania aplikacji i publikowania z wykorzystaniem kontenerów. W Wercker mam opisane trzy-krokowe zadanie, które w czystym kontenerze ze środowiskiem Ruby instaluje i konfiguruje Jekyll, w następnym korku generuje nową stronę i na koniec publikuje ją w S3 za pomocą s3cmd.

Wszystko fajnie i automatycznie się robi, ale po skonfigurowaniu procesu generowanie strony w wercker wywalało mi błędy spowodowane rzekomo złym kodowaniem i tym sposobem kompilowanie sass do css wyłożyło się. Oczywiście z rozpędu od razu korzystałem z tego samego branchu w repo co dla Azure. Przy każdej wprowadzonej zmianie, żeby rozwiązać problem z nowym hostingiem na Azure budowała się i publikowała wersja bez CSS.

Po poprawieniu błędu z sass szczęśliwie Application Insights poinformował mnie, że już wszystko ok ;-)

Powiadomienie o rozwiązanym alercie z Visual Studio Application Insights

Patrząc na trendy i kierunek w którym faktycznie idzie rynek to monitoring aplikacji, a nie tylko infrastruktury, kontenery, automatyzacja wdrażania, procesy CI i CD, narzędzia, które były uznawane za czysto deweloperskie będą codziennością IT Pro w najbliższych latach i warto rozwijać się w tym kierunku. Ostatnio na LinkiedIn widać coraz więcej ofert pracy w takim zakresie (DevOps) nie tylko dla zagranicznych firm :-)