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.
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.
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
Oprócz widoku tabeli można prezentować dane w postaci wykresów.
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:
URL ping test - prosty test polegający na pobraniu wskazanego URL.
Multi-step web test: bardziej wypasiona opcja pozwalająca na stworzenie wielostopniowych testów. Test nagrywa się za pomocą Visual Studio (wymagana wersja Enterprise) i wgrywa się do appInsights.
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.
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:
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:
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 ;-)
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 :-)