Analýza webových protokolů pomocí vlastní knihovny Pythonu s clusterem Apache Spark ve službě HDInsight
Tento poznámkový blok ukazuje, jak analyzovat data protokolů pomocí vlastní knihovny s Apache Sparkem ve službě HDInsight. Vlastní knihovna, která používáme, je knihovna Pythonu s názvem iislogparser.py.
Požadavky
Cluster Apache Spark ve službě HDInsight. Pokyny najdete v tématu Vytváření clusterů Apache Spark ve službě Azure HDInsight.
Uložení nezpracovaných dat jako sady RDD
V této části použijeme poznámkový blok Jupyter přidružený ke clusteru Apache Spark ve službě HDInsight ke spouštění úloh, které zpracovávají nezpracovaná ukázková data, a uložíme je jako tabulku Hive. Ukázková data jsou soubor .csv (hvac.csv) dostupný ve výchozím nastavení ve všech clusterech.
Po uložení dat jako tabulky Apache Hive se v další části připojíme k tabulce Hive pomocí nástrojů BI, jako jsou Power BI a Tableau.
Ve webovém prohlížeči přejděte do
https://CLUSTERNAME.azurehdinsight.net/jupyter
umístění , kdeCLUSTERNAME
je název vašeho clusteru.Vytvořte nový poznámkový blok. Vyberte Nový a pak PySpark.
Notebook" border="true":::
Nový poznámkový blok se vytvoří a otevře s názvem Untitled.pynb. Vyberte název poznámkového bloku v horní části a zadejte popisný název.
Protože jste vytvořili poznámkový blok pomocí jádra PySpark, nemusíte explicitně vytvářet žádné kontexty. Kontexty Spark a Hive se automaticky vytvoří za vás při spuštění první buňky kódu. Můžete začít importem typů požadovaných pro tento scénář. Vložte následující fragment kódu do prázdné buňky a stiskněte Shift +Enter.
from pyspark.sql import Row from pyspark.sql.types import *
Vytvořte sadu RDD pomocí ukázkových dat protokolu, která jsou už v clusteru k dispozici. K datům můžete přistupovat ve výchozím účtu úložiště přidruženém ke clusteru na adrese
\HdiSamples\HdiSamples\WebsiteLogSampleData\SampleLog\909f2b.log
. Spusťte následující kód:logs = sc.textFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/SampleLog/909f2b.log')
Načtení ukázkové sady protokolů pro ověření úspěšného dokončení předchozího kroku
logs.take(5)
Měl by se zobrazit výstup podobný následujícímu textu:
[u'#Software: Microsoft Internet Information Services 8.0', u'#Fields: date time s-sitename cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Cookie) cs(Referer) cs-host sc-status sc-substatus sc-win32-status sc-bytes cs-bytes time-taken', u'2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step2.png X-ARR-LOG-ID=2ec4b8ad-3cf0-4442-93ab-837317ece6a1 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 53175 871 46', u'2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step3.png X-ARR-LOG-ID=9eace870-2f49-4efd-b204-0d170da46b4a 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 51237 871 32', u'2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step4.png X-ARR-LOG-ID=4bea5b3d-8ac9-46c9-9b8c-ec3e9500cbea 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 72177 871 47']
Analýza dat protokolu pomocí vlastní knihovny Pythonu
Ve výstupu výše obsahují první pár řádků informace o záhlaví a každý zbývající řádek odpovídá schématu popsanému v této hlavičce. Analýza takových protokolů může být složitá. Proto používáme vlastní knihovnu Pythonu (iislogparser.py), která usnadňuje analýzu takových protokolů. Ve výchozím nastavení je tato knihovna součástí vašeho clusteru Spark ve službě HDInsight na adrese
/HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py
.Tato knihovna ale není v této
PYTHONPATH
knihovně, takže ji nemůžeme použít pomocí příkazu importu, jako jeimport iislogparser
. Abychom mohli tuto knihovnu použít, musíme ji distribuovat do všech pracovních uzlů. Spusťte následující fragment kódu.sc.addPyFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py')
iislogparser
poskytuje funkciparse_log_line
, která vrátíNone
, pokud řádek protokolu je řádek záhlaví, a vrátí instanciLogLine
třídy, pokud narazí na řádek protokolu.LogLine
Pomocí třídy extrahujte pouze řádky protokolu ze sady RDD:def parse_line(l): import iislogparser return iislogparser.parse_log_line(l) logLines = logs.map(parse_line).filter(lambda p: p is not None).cache()
Načtěte několik extrahovaných řádků protokolu, abyste ověřili, že se krok úspěšně dokončil.
logLines.take(2)
Výstup by měl být podobný následujícímu textu:
[2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step2.png X-ARR-LOG-ID=2ec4b8ad-3cf0-4442-93ab-837317ece6a1 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 53175 871 46, 2014-01-01 02:01:09 SAMPLEWEBSITE GET /blogposts/mvc4/step3.png X-ARR-LOG-ID=9eace870-2f49-4efd-b204-0d170da46b4a 80 - 1.54.23.196 Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/31.0.1650.63+Safari/537.36 - http://weblogs.asp.net/sample/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx www.sample.com 200 0 0 51237 871 32]
Třída
LogLine
má zase několik užitečných metod, jako jeis_error()
například , která vrací, zda položka protokolu má kód chyby. Pomocí této třídy můžete vypočítat počet chyb v extrahovaných řádcích protokolu a potom za protokolovat všechny chyby do jiného souboru.errors = logLines.filter(lambda p: p.is_error()) numLines = logLines.count() numErrors = errors.count() print 'There are', numErrors, 'errors and', numLines, 'log entries' errors.map(lambda p: str(p)).saveAsTextFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/SampleLog/909f2b-2.log')
Výstup by měl být ve stavu
There are 30 errors and 646 log entries
.Pomocí knihovny Matplotlib můžete také vytvořit vizualizaci dat. Pokud například chcete izolovat příčinu požadavků, které běží dlouhou dobu, můžete chtít najít soubory, které v průměru zabírají nejvíce času. Následující fragment kódu načte prvních 25 prostředků, které trvaly většinu času na zpracování požadavku.
def avgTimeTakenByKey(rdd): return rdd.combineByKey(lambda line: (line.time_taken, 1), lambda x, line: (x[0] + line.time_taken, x[1] + 1), lambda x, y: (x[0] + y[0], x[1] + y[1]))\ .map(lambda x: (x[0], float(x[1][0]) / float(x[1][1]))) avgTimeTakenByKey(logLines.map(lambda p: (p.cs_uri_stem, p))).top(25, lambda x: x[1])
Měl by se zobrazit výstup podobný následujícímu textu:
[(u'/blogposts/mvc4/step13.png', 197.5), (u'/blogposts/mvc2/step10.jpg', 179.5), (u'/blogposts/extractusercontrol/step5.png', 170.0), (u'/blogposts/mvc4/step8.png', 159.0), (u'/blogposts/mvcrouting/step22.jpg', 155.0), (u'/blogposts/mvcrouting/step3.jpg', 152.0), (u'/blogposts/linqsproc1/step16.jpg', 138.75), (u'/blogposts/linqsproc1/step26.jpg', 137.33333333333334), (u'/blogposts/vs2008javascript/step10.jpg', 127.0), (u'/blogposts/nested/step2.jpg', 126.0), (u'/blogposts/adminpack/step1.png', 124.0), (u'/BlogPosts/datalistpaging/step2.png', 118.0), (u'/blogposts/mvc4/step35.png', 117.0), (u'/blogposts/mvcrouting/step2.jpg', 116.5), (u'/blogposts/aboutme/basketball.jpg', 109.0), (u'/blogposts/anonymoustypes/step11.jpg', 109.0), (u'/blogposts/mvc4/step12.png', 106.0), (u'/blogposts/linq8/step0.jpg', 105.5), (u'/blogposts/mvc2/step18.jpg', 104.0), (u'/blogposts/mvc2/step11.jpg', 104.0), (u'/blogposts/mvcrouting/step1.jpg', 104.0), (u'/blogposts/extractusercontrol/step1.png', 103.0), (u'/blogposts/sqlvideos/sqlvideos.jpg', 102.0), (u'/blogposts/mvcrouting/step21.jpg', 101.0), (u'/blogposts/mvc4/step1.png', 98.0)]
Tyto informace můžete prezentovat také ve formě vykreslení. Jako první krok k vytvoření grafu si nejprve vytvoříme dočasnou tabulku AverageTime. Tabulka seskupí protokoly podle času, aby se zjistilo, jestli v určitém okamžiku nedošlo k neobvyklým špičkám latence.
avgTimeTakenByMinute = avgTimeTakenByKey(logLines.map(lambda p: (p.datetime.minute, p))).sortByKey() schema = StructType([StructField('Minutes', IntegerType(), True), StructField('Time', FloatType(), True)]) avgTimeTakenByMinuteDF = sqlContext.createDataFrame(avgTimeTakenByMinute, schema) avgTimeTakenByMinuteDF.registerTempTable('AverageTime')
Potom můžete spustit následující dotaz SQL a získat všechny záznamy v tabulce AverageTime .
%%sql -o averagetime SELECT * FROM AverageTime
Magie
%%sql
následovaná-o averagetime
zajišťuje, že se výstup dotazu zachová místně na serveru Jupyter (obvykle hlavní uzel clusteru). Výstup je trvalý jako datový rámec Pandas se zadaným názvem averagetime.Měl by se zobrazit výstup podobný následujícímu obrázku:
yter sql query output" border="true":::
Další informace o magii
%%sql
najdete v tématu Parametry podporované pomocí magic %%sql.K vytvoření grafu teď můžete použít Knihovnu Matplotlib, která se používá k vytvoření vizualizace dat. Vzhledem k tomu, že vykreslení musí být vytvořeno z místně trvalého datového rámce averagetime , musí fragment kódu začínat magií
%%local
. Tím se zajistí, že se kód spustí místně na serveru Jupyter.%%local %matplotlib inline import matplotlib.pyplot as plt plt.plot(averagetime['Minutes'], averagetime['Time'], marker='o', linestyle='--') plt.xlabel('Time (min)') plt.ylabel('Average time taken for request (ms)')
Měl by se zobrazit výstup podobný následujícímu obrázku:
eb log analysis plot" border="true":::
Po dokončení spuštění aplikace byste měli poznámkový blok vypnout a uvolnit prostředky. Provedete to tak, že v nabídce Soubor poznámkového bloku vyberete Zavřít a zastavit. Tato akce vypne a zavře poznámkový blok.
Další kroky
Projděte si následující články: