\chapter{M\'er\'esi k\"ornyezet ismertet\'ese}

\section{Topol\'ogia}
A mérési infrastruktúra kialakításánál a fő szempont a potenciális szűk keresztmetszetek elkerülése volt, ennek okán a méréseket három nagy teljesítményű szerveren végeztem. A Kubernetes klaszter egy Masterből és egy Workerből állt, a harmadik számítógépen pedig a mérőeszközök futottak. A klaszter fizikai fel\'ep\'it\'ese \aref{fig:phys-cluster} \'abr\'an l\'athat\'o. Az így kialakított mérési klaszter előnye, hogy az egyik gépen futó, nagy erőforrás igényű folyamatok nem vesznek el egy másik gépen futó folyamattól erőforrást. Több Kubernetes Worker használatára volt lehetőség, de mivel egyszerre egy mérés futott, valamint a Workerek közötti elosztást nem volt cél vizsgálni, egyet is elégségesnek ítéltem. 

\begin{figure}[!ht]
\centering
\includegraphics[width=120mm, keepaspectratio]{figures/physical_cluster.png}
\caption{A m\'er\'esekhez haszn\'alt fizikai klaszter fel\'ep\'it\'ese}
\label{fig:phys-cluster}
\end{figure}

A számítógépek két tíz gigabites hálózati interfészen keresztül is össze vannak kötve. Egyiken keresztül csatlakoznak az internetre, ezen az interfészen publikus IP címmel rendelkeznek. A másikon csak egymást érik el, itt privát IP címük volt. Mindkét interfészen egy Layer 2-es szórási tartományban voltak. Szakdolgozatom elkészítése során több klaszterrel is dolgoztam, melyek fizikailag nem feltétlen voltak egy switchre bekötve, viszont ez legrosszabb esetben is csak minimálisan befolyásolhatja a méréseket.

\section{Mérési környezet automatizált telepítése}
\subsection{Kubernetes telep\'it\'ese}
Egy Kubernetes klaszter létrehozásához szükség van egy Master és legalább egy Worker telepítésére. A mérésekhez használt szerverek úgy kerültek telepítésre, hogy a root felhasználó a klaszter bármely másik számítógépét eléri ssh-n a magán hálózaton keresztül, jelszó nélkül. Az automatizmus elkészítéséhez ezt felhasználtam. További megkötés, hogy a telepítő programot a létrehozni kívánt Master-en kell futtatni, a Worker-ek IP címének, vagy hosztnevének listáját pedig egy tömbben kell megadni. A méréseket az Ubuntu operációs 18.04-es verzióján végeztem, ez is fontos megkötés, ugyanis a Linux disztribúciókon elérhető csomagkezelő, valamint egyéb eszközök eltérhetnek. 

A Kubernetes szoftver előtt telepítésre kell kerüljön a Docker a klaszter minden számítógépére. Ezt az Ubuntuban elérhető apt csomagkezelővel lehet telepíteni. Bár az alapértelmezett csomaggyűjteményben benne van a Docker egy verziója, ez a mérések megkezdésekor egy már nem támogatott verzió volt, ezért szükség volt a Docker fejlesztői által fenntartott csomaggyűjtemény telepítésére. Ezeket a lépéseket bash szkriptnyelven írt program segítségével lehet automatizálni. A majdani Masterre a telepítést parancsok szekvenciális végrehajtásával lehet, a Workerekre pedig ugyanezen parancsok ssh sztenderd bemenetére irányítva lehet végrehajtani. 

A Kubernetes telepítése előtt az operációs rendszer lapozófájlját ki kell kapcsolni, ugyanis a Kubernetes csak akkor működik, ha a hostgépen nincs swap. Ezt egy paranccsal, valamint a swap a bekapcsoláskor betöltött partíciók közüli eltávolításával lehet elérni. 

A Docker telepítése után a Kubernetes rendszert kezelő csomagok telepítése szükséges hasonló módon. A klaszter létrehozásához a kubeadm-et választottam, ugyanis az a referencia implementációja a Kubernetesnek. Az ebben a lépésben szükséges csomagok nem elérhetőek az alapértelmezett csomaggyűjteményben, így mindenképpen szükség van a Kubernetes fejlesztői által fenntartott csomaggyűjtemény telepítésére. Fontos, hogy mivel a Docker legújabb verziója került telepítésre, meg kell adni a kubeadm-nek, hogy ne ellenőrizze a telepített Docker verzióját. Ez nem jelent problémát, ugyanis a Docker API Kubernetes által használt része nem változott a legfrissebb, valamint a Kubernetes által ellenőrzött legfrissebb verzió között. Szintén fontos, hogy pontosan az 1.15.4-es verzió került telepítésre, ugyanis a mérések kezdetekor kiadott legfrissebb verzió -1.16- annyira új, hogy sem a Knative, sem a Kubeless nem támogatják, nem is működtek, ha 1.16-os verziójú klaszterbe próbáltam őket telepíteni. 

A Master node telepítése során a kubeadm futtatásán, valamint a klaszter eléréséhez szükséges fájlok a felhasználó könyvtárába másolásán kívül egyéb teendő nincs, ugyanis Weavenet hálózati modul kerül később telepítésre. Miután a Master node sikeresen települt, a kubeadm eszköz segítségével ki kell nyerni a Workerek csatlakozásához szükséges tokent, valamint az openssl eszköz segítségével a Master nyilvános kulcsának hashét. 

A Worker node telepítése során a két kinyert értéket, valamint a Master IP címét meg kell adni a kubeadm-nek. 

Miután a klaszter minden tagja telepítésre került a további lépéseket a kubectl eszközzel lehet végre hajtani, ami a Masterre került telepítésre. Ahhoz, hogy a klaszterben lévő Podok kommunikálni tudjanak, szükség van egy hálózati beépülő modulra. Több ilyen létezik, szakdolgozatom során a Weavenetet választottam egyszerűsége miatt. Telepítése egy YAML leíró állomány applikálásával lehetséges.

\subsection{Kubeless telep\'it\'ese}
A Kubeless telepítése négy lépésből áll. Először a metrics-server nevű komponens telepítésére kerül sor. Erre a Kubeless által használt Horizontal Pod Autoscaler miatt van szükség, ugyanis ez a komponens gyűjti számára a metrikákat a Podokról. Ennek telepítése nem csak a fejlesztők által elkészített YAML állomány applikálásából áll, ugyanis a metrics-server alapértelmezés szerint mutual TLS protokollal titkosítja a kommunikációját a Kubernetes klaszterrel. Erre nincs szükség ebben a klaszterben, ezért ki lehet kapcsolni ezt a viselkedést, amit egy kapcsolóval lehet megtenni. Ez jól automatizálható sed program használatával. A módosított YAML fájlt már applikálni lehet. 

Ez után a második lépés az Nginx Ingress Controller telepítése. Itt nincs választási lehetőség, ugyanis a Kubelessbe ez a függőség erősen be van kötve. E komponens telepítéséhez két YAML állományt kell applikálni. Azért kettőt, mert van lehetőség menedzselt Kubernetesbe, valamint saját klaszterbe is telepíteni az Nginx Ingress Controllert. A két állomány közül az egyik minden Kubernetes környezet használata esetén alkalmazásra kell kerüljön, a másik pedig specifikus a felhasználó által használt Klaszter típusához, például Azure Kubernetes, vagy Google Container Engine és saját Kubernetes klaszterekhez külön-külön YAML állomány tartozik. 

A Kubeless könnyebb kezelése érdekében a harmadik telepítésre kerülő komponens a kubeless parancssori interfész. Ezt a programot már a fejlesztők lefordították, így csupán a megfelelő verzió beszerzése szükséges, annak egy olyan könyvtárba mozgatása, ahol a bash parancssori értelmező keresi a futtatható programokat, például a /usr/local/bin/ könyvtárba. 

Negyedik és utolsó lépésként a Kubeless klaszterbe telepítésére kerül sor. Ehhez létre kell hozni egy új névteret a kubectl segítségével. Ez után lehet applikálni a Kubeless fejlesztői által elkészített YAML állományt. 

Az itt leírt lépések bash szkript segítségével automatizálhatók.

\subsection{Knative telep\'it\'ese}
A Knative telepítése kevesebb komponens feltelepítéséből áll, azok telepítése viszont bonyolultabb. A rendszer telepítése előtt installálni kell az Istiot. Ezt a helm nevű Kuberneteshez készített csomagkezelő rendszer segítségével lehet, viszont a helmet is installálni kell. Ez az Ubuntu rendszerben lévő snap csomagkezelővel telepíthető. A snap abban különbözik az apt-tól, hogy az általa telepített csomagok és a függőségeik a rendszercsomagoktól és a rendszerben jelen lévő osztott könyvtáraktól függetlenek, de hatással lehetnek a rendszerre. 

A helm telepítése után inicializálni kell, amely az úgynevezett Tiller a Kubernetesbe telepítését, valamint információegyeztetést a Tiller és a helm között jelenti. Viszont ahhoz, hogy a Tiller a klaszterben a kívánt módosításokat el tudja végezni meg kell neki adni a megfelelő jogosultságokat. Erre úgy van lehetőség, hogy létre kell hozni egy új, úgynevezett Service Accountot, amely hasonlóan viselkedik a felhasználói fiókokhoz, viszont ezt Podokhoz lehet rendelni. A létrehozott Service Accounthoz pedig a cluster-admin jogosultságot kell rendelni. Ennél lehet kevesebb jogot adni a Tillernek, viszont egyetlen felhasználója lesz a klaszternek, így nincs szükség finomhangolt jogosultságkezelésre. Csak e két lépés után lehet inicializálni a helmet, valamint a Tillert. 

Az Istio telepítésének megkezdése előtt létre kell hozni az általa bevezetett új objektumtípusokat, valamint egy külön névteret, ahova az Istio rendszer saját objektumai kerülhetnek. Ez számos YAML állomány applikálását jelenti. Ez után az Istio rendszert telepítő YAML állományt ki kell generáltatni a helmmel. A generálásnál lehetőség van megadni, az Istio mely komponensei ne települjenek. Nincs szükségünk például monitoring rendszerre, telemetria és jogosultságkezelő rendszerre. Ezeket parancssori paraméterrel lehet megadni. A generálás után létrehozott YAML fájl által leírt módosítások végrehajtását a megszokott módon kell végrehajtani. 

Miután az Istio feltelepült, a Knative által bevezetett objektumtípusok létrehozása következik. Ezt a lépést kétszer kell végrehajtani egy a fejlesztők által ismert hiba miatt. Az első végrehajtás során néhány objektumtípus nem jön létre, másodszorra viszont ezek is létrejönnek, és a már létező objektumtípusok nem módosulnak. Végül a Knative rendszer telepíthető a fejlesztők által elkészített YAML állomány applikálásával hasonlóan a korábbi rendszerekhez.

\section{M\'er\'esi eszk\"oz\"ok kiv\'alaszt\'asa}
Számos http végpontok teljesítményének mérésére szolgáló eszköz létezik. A használt eszközök kiválasztása előtt fontos megnevezni a szempontokat, amik alapján a használt eszközök kiválasztásra kerültek. 

A legfontosabb, hogy a ráta, amivel a kéréseket képes generálni legalább érje el a mérni kívánt http végpont áteresztőképességét. Amennyiben ez nem teljesül, az adott eszközt nem érdemes használni. 

Szintúgy fontos szempont, hogy az eszköz képes legyen minden visszaérkező válaszról információt valamilyen automatikusan feldolgozható formátumban - például csv, vagy xml - menteni. Ez azért fontos, mert a mérések elvégzése és az adatok feldolgozásának automatizálása cél volt, ha ezt egy eszköz nem támogatja, nem használható a mérések során. 

A végső szempont a megfelelő dokumentáció elérhetősége. Hiába felel meg egy eszköz mindkét korábban részletezett szempontnak, amennyiben nem érhető el hozzá dokumentáció, egyrészt a funkcióinak teljes tárháza sem feltétlen megismerhető, működésének elsajátítása pedig aránytalanul nehéz lehet. 

A megfelelő mérési eszköz kiválasztásához számos eszközt megvizsgáltam.

\subsection{Wrk}
A wrk egy C-ben írt, nyílt forráskódú http teljesítménymérő szoftver. Többszálú designjának köszönhetően nagy sebességgel képes generálni a kéréseket. A használt kapcsolat objektumok és szálak száma parancssori kapcsoló segítségével beállítható, valamint működésének bizonyos aspektusai Lua szkriptnyelven testreszabhatók. Egyetlen hátránya, hogy bár a kimeneti formátumot Lua-ban írt szkript segítségével testre lehet szabni, nincs lehetőség minden kérés, vagy bizonyos időközönként átlagolt részeredmény exportálására. Mivel a wrk az általam vizsgált megoldások közül az egyik legrégebb óta fejlesztett, a hozzá elérhető dokumentáció kitér a gyakran előforduló problémákra, valamint a szkriptelést megkönnyítik a fejlesztők által előre elkészített példák. A wrk a mérés végeztével egyszer menti a másodpercenkénti átlagos kérések számát, amire érkezett valamilyen válasz, valamint egyebek mellett az átlagos kérleltetést, amivel a válasz megérkezett. 

Emiatt a wrk nem volt alkalmas a mérések elvégzésére.

\subsection{Hey}
A hey egy Go nyelven írt, nyílt forráskódú http terhelés generáló. Eredetileg az ApacheBench cseréjére hozták létre, emiatt parancssori interfésze igen hasonló. Mivel Go-ban készült, az általa elérhető teljesítmény potenciálisan nagy. A használt kapcsolat objektumokat, valamint esetleges ráta limitet parancssori kapcsolóval meg lehet adni. A megadott limit kapcsolat objektumonként értelmezett. Tehát százas ráta limit esetén két kapcsolat használatával a hey által másodpercenként generált kérések száma kétszáz. Lehetőség van a hosztnév fejléc, valamint a kérés törzsének megadására, szintén parancssori kapcsolóval. 

Alapértelmezés szerint a hey is hasonló összefoglalót generál, mint a wrk, viszont azzal ellentétben a hey képes minden kérésről exportálni többek között, hogy az indítástól kezdve mikor és milyen késleltetéssel ért vissza, valamint a szerver milyen http kóddal válaszolt. Hátránya viszont, hogy egyszerre csak tízmillió választ képes tárolni, amely hosszabb mérések esetén azt jelenti, több rövidebb almérésre kell bontani a mérést. Bár a hozzá elérhető dokumentáció csak az elérhető parancssori kapcsolók, valamint azok paramétereiig terjed ki, belső működése egyszerűsége okán ennél többre nincs szükség a használatához. 

A leírtak miatt úgy döntöttetem, a mérések során a hey-t használom.

\subsection{Loadtest}
A Loadtest egy Javascript nyelven, Node.Js környezetben írt nyílt forráskódú http teljesítménymérő. Lényeges előnye a hey-jel szemben, hogy a kérések kiküldése előtt nem várja meg az adott konkurencia objektum, hogy megérkezzen a válasz. Jelentős hátrány, hogy csak egy szálat használ, így az általa generált másodpercenkénti kérések száma jelentősen alacsonyabb, mint az általam vizsgált többi eszközé. Emellett a Loadtest is csak a mérés végeztével generál egy összefoglaló riportot, nem képes a kérésekről adatok exportálására. A hozzá elérhető dokumentáció alapján használata egyszerű, valamint a belső működés könnyedén megérthető. Ezek miatt a Loadtestet nem találtam alkalmasnak a mérések elvégzésére.

\subsection{Apache Jmeter}
Az Apache Jmeter, vagy Jmeter egy Java 8-as verziójában íródott, nyílt forráskódú, testre szabható webes teljesítménymérő. Fő tulajdonsága, hogy saját mérési tervet lehet segítségével összeállítani, majd végrehajtani azt. A mérési tervet egy grafikus felületen lehet összeállítani. Lehetőség van definiálni több felhasználói csoportot, ahonnan a terhelés érkezik, valamint az egyes felhasználók által küldött paraméterek is testre szabhatók. Egy méréshez legalább egy felhasználói csoportot meg kell adni, valamint http végpont teljesítményének mérése esetén egy HTTP Request objektum definiálása szükséges. Ha az eredményeket látni akarjuk, akkor a megtekintés szerint kívánt formátumú Listenert kell definiálni. Fontos, hogy http fejlécek küldése esetén még hozzá kell adni egy HTTP Header Manager komponenst, amelyben tetszőleges számú fejlécet lehet definiálni kulcs-érték párban. A Jmeter képes grafikonon ábrázolni az érzékelt késleltetés időbeni alakulását, valamint minden kérésről exportálni tudja többek között a kapott http státusz kódot, a mért késleltetést, valamint a kérés küldésének pontos idejét. Mivel egy Javaban írt programról van szó, a teljesítménye jelentősen függ a Java virtuális gép számára elérhető memóriától, valamint a használt Garbage Collector algoritmustól. 

A Jmeter igen elterjedt szoftver, viszont kifejezetten bonyolult, szerencsére a hozzá elérhető dokumentáció az összes általam vizsgált eszköz közül a legrészletesebb. Mivel a Jmeter működése eltér a hey-től, valamint a kritériumoknak megfelel, úgy döntöttem a méréseket mindkét eszközzel elvégzem.

\section{M\'er\'esek automatiz\'al\'asa}
A mérőeszközök kiválasztása után magukat a méréseket dolgoztam ki. Az egyértelmű volt, hogy konstans terhelésű mérést mindenképpen kell végezzek. A Kubeless esetén, mivel skálázása csak a cpu terheléstől függ, a skálázás megfigyelésére az ilyen típusú mérések elégségesek lehetnek. Ezzel szemben a Knative konkurencia alapú skálázásának megfigyelésére a bemeneti oldali konkurens kérések folyamatos növelése az előző típusú mérés mellett érdekesnek bizonyulhat. 

Mivel a méréseket nem egyszerre végeztem, valamint a mérések elvégzéséhez a hey esetében a megfelelő parancssori kapcsolók lánca hosszú, szükségét láttam annak, hogy legalább a hey esetében egy bash szkript segítségével automatizáljam a mérések elvégzését. A Jmeter esetében erre nincs szükség, hála az előre elkészíthető mérési terveknek. 

A bash szkript megírásánál a hey automatizált telepítése is fontos volt, ugyanis a munkám során több klaszteren is dolgoztam. Annak érdekében, hogy a mérések paraméterei testre szabhatók legyenek, a 
\begin{itemize}
 \item mérendő függvények nevét,
 \item használandó connection objektumok számát,
 \item a mérés időbeni hosszát,
 \item másodpercenkénti kérések számára megszabott limitet,
 \item valamint a cél IP címét és port számát külön változókban tároltam.
\end{itemize}

A mérendő függvények nevét egy tömbben tároltam, így egymás után több mérés is elvégezhető ugyanazon paraméterekkel. A mérés típusát egy parancssori kapcsolóval lehet kiválasztani. Annak érdekében, hogy a szkript használatát kényelmessé tegyem, úgy döntöttem, mindkét típusú mérést el lehet végezni egy futtatással. A szkript elkészítésénél igyekeztem figyelni arra, hogy új típusú mérés bevezetéséhez ne legyen szükséges olyan részeket módosítani, amik nem kapcsolódnak közvetlen az új funkcionalitáshoz.

A folyamatos terhel\'est gener\'al\'o m\'er\'es \aref{code:bash-banchmark-for} k\'odr\'eszleten l\'athat\'o. A hey saj\'at\'oss\'agai miatt alkalmaztam azt a megold\'ast, hogy a k\'iv\'ant hossz\'us\'ag\'u fut\'as el\'er\'ese \'erdek\'eben t\"obbsz\"or elind\'itottam az eszk\"ozt. Látható, hogy a Kubeless-be és a Knative-ba telepített függvények meghívása eltér nem csak az alkalmazott http metódusban és a hosztnév sémájában, de a Content-Type fejléc, melynek értékét a –T kapcsolóval lehet megadni, megléte is különbözik. 

Mint az \aref{code:bash-banchmark-climb} kódrészleten látszik, a növekvő terhelésű mérés implementációja igen hasonló az egyenletes terhelésűhöz. A hey működését kihasználva, a –rps kapcsoló segítségével beállított limit nem változik a mérés során, csupán a connection objektumok száma emelkedik.

\section{Null\'ara sk\'al\'az\'as eset\'eben v\'alaszidő m\'er\'ese}
Teljesen m\'ashogy kell m\'erni azt, hogy mik\'ent alakul a v\'alaszideje a f\"uggv\'enynek olyan esetekben, hogy \'eppen null\'ara sk\'al\'azta a Knative rendszer a podj\'at, vagy a k\'er\'es be\'erkez\'esekor m\'ar l\'etezett a Podja. Erre az esetre olyan m\'er\'est alak\'itottam ki, amely elk\"uld egy k\'er\'est a f\"uggv\'eny fele, egy \'allom\'anyba r\"oggz\'iti a v\'alaszidőt, majd k\"ozvetlen ez ut\'an ism\'etelten k\'er\'est k\"uld \'es egy m\'asik \'allom\'anyba r\"ogz\'iti ezt a v\'alaszidőt. Ez ut\'an az \'altalam k\'esz\'itett szkript v\'ar pontosan k\'et percet. Az\'ert ennyi időt, mert tapasztalataim alapj\'an k\"or\"ulbel\"ul m\'asf\'el percig tartott a f\"uggv\'enyek Podjainak termin\'al\'asa, a v\'arakoz\'asnak pedig enn\'el nagyobb időt szerettem volna be\'all\'itani arra az esetre, amikor enn\'el is tov\'abb tart a le\'all\'as. A m\'er\'est egy bash szkript seg\'its\'eg\'evel lehet elk\'esz\'iteni, ami addig fut, am\'ig a felhaszn\'al\'o le nem \'all\'itja. Bőv\'iteni egyszerűen lehet, ugyanis a m\'erendő f\"uggv\'enyek egy list\'aban vannak felsorolva, minden v\'arakoz\'as előtt az ott felsorolt f\"uggv\'enyekre megt\"ort\'enik a v\'alaszidők m\'er\'ese.

\section{M\'er\'esi eredm\'enyek automatiz\'alt elemz\'ese}
Egy mérés eredményeként a mérés típusától függően akár több, nagy méretű csv állomány keletkezik. Ezen fájlok feldolgozása függ attól, hogy azt a Jmeter vagy a hey generálta. A fájlok kézi feldolgozása nyilvánvalóan lehetetlen. Az is előfordulhat, hogy már korábban feldolgozott méréseket egy új szempontból is fel kell dolgozni. Ez elő is fordult, ugyanis a program első verziója még nem volt képes az észlelt késleltetés feldolgozására. Szerencsére a Python programnyelv ilyen feladatok elvégzésére kiváló választás. 

A program célja az volt, hogy az összes összegyűjtött mérésből generáljon diagrammokat, melyeken ábrázolja a függvény által feldolgozott kérések másodpercenkénti számát, valamint később a másodpercenkénti átlagos késleltetés időbeni alakulását a mérés során. Szintén a munka közben merült fel az igény, hogy a Knative Autoscaler komponensének naplófájlja alapján az általa érzékelt konkurencia és a létrehozott Podok számának alakulását is nyomon kövesse a program. 

Mivel egy méréshez több állomány is tartozhat, az egybe tartozó állományok egy mappába kerültek. A mappa neve reflektálja a mérőeszköz nevét, a mért rendszer és függvény nevét. Például a jmeter-knative-hello-scale-1 egy lehetséges mappanév. Az így strukturált adatok feldolgozása nem függ másik méréstől. A program indulása után az adatokat tartalmazó mappákat kigyűjti, majd a jmeter kulcsszót tartalmazó mappák feldolgozását továbbítja a Jmeter kimenetét feldolgozni képes objektumnak. Az összes többi könyvtárat pedig a hey által generált állományok feldolgozásáért felelő objektumnak továbbítja. Mivel a Knative Autoscaler naplófájljainak feldolgozása, mint igény, később jelent meg, a könyvtárak neve nem jelzi, hogy az adott objektum számára tartalmaz-e releváns információt, ezért az minden mappa tartalmát megvizsgálja, tartalmaz-e általa feldolgozandó állományokat. 

Ahogy \aref{code:jmeter-analyze} kódrészleten látszik, hogy a Python eléggé megkönnyíti egy csv fájl feldolgozását. A csv.reader függvény egy generátorral tér vissza, melyen végig iterálva lehet soronként feldolgozni az állományt. Egy sort a Python egy tuple objektumként reprezentál. Az első sorban az oszlopok nevét adja meg a Jmeter, így azt külön tuple objektumba mentve a zip hívással egy dictionary-t kapunk. Ebből a kívánt oszlop nevét megadva lehet kinyerni a keresett mezőt. 

A JmeterAnalyzer objektum létrejöttekor létrehoz egy dictionary objektumot, melyben a beolvasott fájl timeStamp mezője lesz a kulcs, az érték pedig az adott másodpercben érzékelt válaszok körbefordulási ideje. Mivel a Jmeter egy Java-ban írt szoftver, a timeStamp mező egy java.utils.Date objektum szerializálva. Ahhoz, hogy ebből Python datetime objektumot lehessen készíteni, az adott számot el kell osztani ezerrel. Az így kapott datetime már másodperc pontosan fogja tárolni az időt. Az adott másodpercben visszaérkezett válaszok számát pedig az adott másodpercben tárolt késleltetési értékek száma adja meg. 

A feldolgozás végeztével egy-egy listába kigyűjti a másodpercenként összegyűjtött adatokat tartalmazó listák hosszát, valamint az értékek átlagát. 

Amint \aref{code:hey-analyze} hey esetében máshogy kell csinálni, ugyanis itt a mérés több fájlra bomlik, amelyekben viszont nem lehet feltételezni, hogy pontosan harminc másodpercnyi, vagy egyéb konstans időtartamnyi mérés adatát tartalmazza egy-egy fájl, ugyanis a munka során ez változott. Emiatt egy fájl feldolgozása után gyűjti ki két listába az összegyűjtött adatokat tartalmazó lista hosszát és a késleltetések átlagát. 

Miután a Knative Autoscaler naplóállománya analizálásának igénye felmerült, a méréseket automatizáló bash szkript módosítva lett úgy, hogy minden mérés kezdetének és végeztének másodpercre pontos dátumát egy külön fájlba menti. Ez által a naplófájl bejegyzéseit lehet szűrni a két dátum köztire. 

A Knative Autoscaler a naplóbejegyzéseket json objektumként menti, melyből a Python képes dictionary objektumot készíteni. Amennyiben az adott bejegyzés ts mezője a mérés kezdési és befejezési ideje közé esik, akkor az msg mezőben lévő üzenet feldolgozásra kerül. Az üzenetben kulcs-érték párok vannak szóközzel elválasztva egymástól. A kulcs és az érték között egyenlőségjel van. Ezt egy reguláris kifejezéssel listává lehet konvertálni. Sajnos a Python reguláris kifejezés API-jában nincs arra lehetőség, hogy ilyen esetben dictionary objektumot adjon vissza, így azt kézzel kell konvertálni kihasználva azt, hogy az értékek mindig egy kulcs után következnek. Ezután a Podok száma, valamint a megfigyelt stabil konkurencia érték letárolható. Ennek folyamat\'at \aref{sec:log-analyze} f\"uggel\'ekben l\'atni.

A feldolgozott adatokból a matplotlib Python könyvtár segítségével készíthető grafikon úgy, hogy az adatokat tartalmazó listát átadjuk a megfelelő függvény számára. A grafikon mentése egy másik függvényhívással lehetséges. Szintén külön függvényhívással lehet a grafikon címét, valamint a tengelyek feliratát elhelyezni a grafikonon.

A méréseket elvégző szkript kis módosításával elértem, hogy a mérési eredmények egy általam üzemeltett számítógépre töltődjenek fel archiválásra és az itt részletezett program által feldolgozásra. A feltöltés után a szkript meghívott egy ugyanezen a szerveren futó REST-es végpontot, amely hatására elindult az adatok feldolgozása. Maga a program egy Docker konténerben futott. A kód verziókövetésére Git-et használtam, amelynek előnye az volt, hogy minden alkalommal, mikor egy állapotát mentettem a kódnak, abból a Travis szolgáltatás automatikusan elkészítette a Docker Image-et, valamint feltöltötte a Docker Hub-ra. Így a fejlesztéstől a mérésig teljesen automatizált munkafolyamatot dolgoztam ki. Felmerült ötletként, hogy ezt a Knative rendszerbe telepítsem, viszont szerettem volna, ha a méréseket feldolgozó folyamat független a mért rendszertől és a lehető leglazábban kapcsolódik hozzá. Ez által a két rendszerben történő folyamatok, esetleges hibák nem hatnak ki a másik működésére. 

Miután a késleltetést is grafikonon akartam ábrázolni, számos mérési eredményt újra fel kellett dolgozni, ami az adatok nagy mennyisége miatt sok időt vett igénybe. Viszont felismerve, hogy a mérések között nincs függőség, minden könyvtár feldolgozását külön process-ekre bontottam. Kimondottan nem szálakat használtam, ugyanis a Pythonban közismert probléma a Global Interpreter Lock, ami miatt a Python egyszerre csak egy szál éppen futó kódját értelmezi. Amennyiben az adott feladat számára teljesen önálló process indul, annak saját GIL-je lesz, ezzel megoldva ezt a problémát. Ez által a feldolgozási idő kevesebb, mint felére csökkent.
