Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой записной книжке показано, как анализировать данные журнала с помощью пользовательской библиотеки с Apache Spark в HDInsight. Используемая пользовательская библиотека — это библиотека Python с именем iislogparser.py.
Предпосылки
Кластер Apache Spark в HDInsight. Для получения инструкций см. Создание кластеров Apache Spark в Azure HDInsight.
Сохранение необработанных данных в виде RDD
В этом разделе мы используем Jupyter Notebook, связанный с кластером Apache Spark в HDInsight, для выполнения заданий, обрабатывающих необработанные образцы данных и сохраняем их в виде таблицы Hive. Пример данных — это файл .csv (hvac.csv), доступный во всех кластерах по умолчанию.
После сохранения данных в качестве таблицы Apache Hive в следующем разделе мы подключимся к таблице Hive с помощью таких средств бизнес-аналитики, как Power BI и Tableau.
В веб-браузере перейдите на страницу
https://CLUSTERNAME.azurehdinsight.net/jupyter
, гдеCLUSTERNAME
— это имя вашего кластера.Создайте новую записную книжку. Выберите "Создать", а затем PySpark.
Notebook" border="true":::
Будет создана и открыта записная книжка с именем Untitled.pynb. Выберите название блокнота в верхней части и введите понятное имя.
Так как вы создали записную книжку с помощью ядра PySpark, вам не нужно явно создавать контексты. Контексты Spark и Hive автоматически создаются при запуске первой ячейки кода. Сначала можно импортировать типы, необходимые для этого сценария. Вставьте следующий фрагмент кода в пустую ячейку и нажмите клавиши SHIFT+ВВОД.
from pyspark.sql import Row from pyspark.sql.types import *
Создайте RDD с помощью примеров данных журнала, уже доступных в кластере. Вы можете получить доступ к данным в учетной записи хранения по умолчанию, связанной с кластером
\HdiSamples\HdiSamples\WebsiteLogSampleData\SampleLog\909f2b.log
. Выполните следующий код:logs = sc.textFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/SampleLog/909f2b.log')
Извлеките образец журнала, чтобы убедиться, что предыдущий шаг выполнен успешно.
logs.take(5)
Должен отобразиться результат, аналогичный приведенному ниже:
[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']
Анализ данных журнала с помощью пользовательской библиотеки Python
В выводе выше первые строки включают сведения о заголовке, а каждая из оставшихся строк соответствует схеме, описанной в этом заголовке. Анализ таких журналов может быть сложным. Поэтому мы используем пользовательскую библиотеку Python (iislogparser.py), что упрощает анализ таких журналов. По умолчанию эта библиотека включена в кластер Spark в HDInsight
/HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py
.Однако этой библиотеки нет в
PYTHONPATH
, поэтому мы не можем использовать ее с помощью инструкции импорта, напримерimport iislogparser
. Чтобы использовать эту библиотеку, необходимо распространить ее на все рабочие узлы. Выполните следующий фрагмент кода.sc.addPyFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py')
iislogparser
предоставляет функциюparse_log_line
, возвращающуюNone
, если строка журнала является строкой заголовкаLogLine
, и возвращает экземпляр класса, если он встречает строку журнала.LogLine
Используйте класс для извлечения только строк журнала из 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()
Получите пару извлеченных строк журнала, чтобы убедиться, что шаг выполнен успешно.
logLines.take(2)
Выходные данные должны быть похожи на следующий текст:
[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]
Класс
LogLine
, в свою очередь, имеет некоторые полезные методы, напримерis_error()
, которые возвращают, имеет ли запись журнала код ошибки. Этот класс позволяет вычислить количество ошибок в извлеченных строках журнала, а затем записать все ошибки в другой файл.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')
Выходные данные должны содержать состояние
There are 30 errors and 646 log entries
.Вы также можете использовать Matplotlib для создания визуализации данных. Например, если вы хотите изолировать причину запросов, выполняющихся в течение длительного времени, может потребоваться найти файлы, которые занимают больше всего времени на обработку в среднем. Приведенный ниже фрагмент извлекает первые 25 ресурсов, которые заняли больше всего времени для обслуживания запроса.
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])
Выходные данные должны отображаться следующим образом:
[(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)]
Эти сведения также можно представить в виде графика. На первом шаге к созданию графика давайте сначала создадим временную таблицу AverageTime. Таблица группирует журналы по времени, чтобы узнать, были ли какие-либо необычные пики задержки в любое время.
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')
Затем можно запустить следующий SQL-запрос, чтобы получить все записи в таблице AverageTime .
%%sql -o averagetime SELECT * FROM AverageTime
Магия
%%sql
, которая идет за-o averagetime
, гарантирует, что выходные данные запроса сохраняются локально на сервере Jupyter (обычно это головной узел кластера). Выходные данные сохраняются в виде кадра данных Pandas с заданным названием averagetime.Вы должны увидеть выходные данные, как показано на следующем рисунке:
yter sql query output" border="true":::
Для получения дополнительной информации о
%%sql
магии см. Параметры, поддерживаемые магией %%sql.Теперь можно использовать Matplotlib, библиотеку, используемую для создания визуализации данных, для создания диаграммы. Поскольку диаграмма должна быть создана из локально сохраненного кадра данных averagetime, фрагмент кода должен начинаться с магической команды
%%local
. Это гарантирует, что код выполняется локально на сервере 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)')
Вы должны увидеть выходные данные, как показано на следующем рисунке:
График анализа журналов eb" border="true":::
После завершения работы приложения необходимо завершить работу записной книжки, чтобы освободить ресурсы. Для этого в меню File (Файл) записной книжки выберите пункт Close and Halt (Закрыть и остановить). Это действие завершит работу и закроет записную книжку.
Дальнейшие действия
Ознакомьтесь со следующими статьями: