Bagikan melalui


Menganalisis log situs web menggunakan pustaka Python kustom dengan kluster Apache Spark di HDInsight

Notebook ini menunjukkan cara menganalisis data log menggunakan pustaka kustom dengan Apache Spark di HDInsight. Pustaka kustom yang kami gunakan adalah pustaka Python yang disebut iislogparser.py.

Prasyarat

Klaster Apache Spark pada HDInsight. Untuk petunjuk selengkapnya, lihat Membuat kluster Apache Spark di Microsoft Azure HDInsight.

Menyimpan data mentah sebagai RDD

Di bagian ini, kami menggunakan Jupyter Notebook yang terkait dengan kluster Apache Spark di HDInsight untuk menjalankan pekerjaan yang memproses data sampel mentah Anda dan menyimpannya sebagai tabel Apache Hive. Data sampel adalah file .csv (hvac.csv) yang tersedia di semua kluster secara default.

Setelah data Anda disimpan sebagai tabel Apache Hive, di bagian berikutnya kita akan menyambungkan ke tabel Apache Hive menggunakan alat BI seperti Power BI dan Tableau.

  1. Dari browser web, arahkan ke https://CLUSTERNAME.azurehdinsight.net/jupyter, di mana CLUSTERNAME merupakan nama kluster Anda.

  2. Buat buku catatan baru. Pilih Baru, lalu PySpark.

    Buat Notebook Apache Jupyter baru. Notebook" border="true":::

  3. Notebook baru dibuat dan dibuka dengan nama Untitled.pynb. Pilih nama notebook di bagian atas, dan masukkan nama yang bersahabat.

    Berikan nama untuk buku catatan.

  4. Karena Anda membuat buku catatan menggunakan kernel PySpark, Anda tidak perlu membuat konteks apa pun secara eksplisit. Konteks Spark dan Apache Hive akan dibuat secara otomatis untuk Anda saat Anda menjalankan sel kode pertama. Anda dapat memulai dengan mengimpor jenis yang diperlukan untuk skenario ini. Tempelkan cuplikan berikut dalam sel kosong, lalu tekan Shift + Enter.

    from pyspark.sql import Row
    from pyspark.sql.types import *
    
  5. Buat RDD menggunakan data log sampel yang sudah tersedia di kluster. Anda dapat mengakses data di akun penyimpanan default yang terkait dengan kluster di \HdiSamples\HdiSamples\WebsiteLogSampleData\SampleLog\909f2b.log. Jalankan kode berikut:

    logs = sc.textFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/SampleLog/909f2b.log')
    
  6. Ambil sampel kumpulan log untuk memverifikasi bahwa langkah sebelumnya berhasil diselesaikan.

    logs.take(5)
    

    Anda akan melihat output yang mirip dengan yang berikut:

    [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']
    

Menganalisis data log menggunakan pustaka Python kustom

  1. Dalam output di atas, beberapa baris pertama menyertakan informasi header dan setiap baris yang tersisa cocok dengan skema yang dijelaskan di header tersebut. Mengurai log tersebut bisa rumit. Jadi, kami menggunakan pustaka Python kustom (iislogparser.py) yang membuat penguraian log tersebut jauh lebih mudah. Secara default, pustaka ini disertakan dengan kluster Spark Anda di HDInsight di /HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py.

    Namun, pustaka ini tidak ada di PYTHONPATH sehingga kami tidak dapat menggunakannya dengan menggunakan pernyataan impor seperti import iislogparser. Untuk menggunakan pustaka ini, kita harus mendistribusikannya ke semua simpul pekerja. Jalankan cuplikan berikut.

    sc.addPyFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py')
    
  2. iislogparser menyediakan fungsi parse_log_line yang mengembalikan None jika baris log adalah baris header, dan mengembalikan instans LogLine kelas jika menemukan baris log. LogLine Gunakan kelas untuk mengekstrak hanya baris log dari 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()
    
  3. Ambil beberapa baris log yang diekstrak untuk memverifikasi bahwa langkah berhasil diselesaikan.

    logLines.take(2)
    

    Output harus mirip dengan teks berikut:

    [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]
    
  4. Kelas LogLine , pada gilirannya, memiliki beberapa metode yang berguna, seperti is_error(), yang mengembalikan apakah entri log memiliki kode kesalahan. Gunakan kelas ini untuk menghitung jumlah kesalahan dalam baris log yang diekstrak, lalu catat semua kesalahan ke file yang berbeda.

    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')
    

    Output harus menyatakan There are 30 errors and 646 log entries.

  5. Anda juga dapat menggunakan Matplotlib untuk membangun visualisasi data. Misalnya, jika Anda ingin mengisolasi penyebab permintaan yang berjalan untuk waktu yang lama, Anda mungkin ingin menemukan file yang membutuhkan waktu paling lama untuk dilayani rata-rata. Cuplikan di bawah ini mengambil 25 sumber daya teratas yang membutuhkan waktu paling lama untuk melayani permintaan.

    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])
    

    Anda akan melihat output seperti teks berikut:

    [(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)]
    
  6. Anda juga dapat menyajikan informasi ini dalam bentuk plot. Sebagai langkah pertama untuk membuat plot, mari kita terlebih dahulu membuat tabel sementara AverageTime. Tabel mengelompokkan log menurut waktu untuk melihat apakah ada lonjakan latensi yang tidak biasa pada waktu tertentu.

    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')
    
  7. Anda kemudian bisa menjalankan kueri SQL berikut untuk mendapatkan semua rekaman dalam tabel AverageTime .

    %%sql -o averagetime
    SELECT * FROM AverageTime
    

    Pengolahan ajaib %%sql diikuti dengan -o averagetime memastikan bahwa output kueri disimpan secara lokal di server Jupyter (biasanya simpul utama dari klaster). Output disimpan sebagai kerangka data Pandas dengan nama yang ditentukan averagetime.

    Anda akan melihat output seperti gambar berikut:

    output kueri hdinsight jupyter sql. yter sql query output" border="true":::

    Untuk informasi selengkapnya tentang %%sql sihir, lihat Parameter yang didukung dengan sihir %%sql.

  8. Anda sekarang dapat menggunakan Matplotlib, pustaka yang digunakan untuk membangun visualisasi data, untuk membuat plot. Karena plot harus dibuat dari dataframe averagetime yang tersimpan secara lokal, cuplikan kode harus dimulai dengan perintah magic %%local. Ini memastikan bahwa kode dijalankan secara lokal di server 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)')
    

    Anda akan melihat output seperti gambar berikut:

    apache spark web log analysis plot. eb log analysis plot" border="true":::

  9. Setelah selesai menjalankan aplikasi, Anda harus mematikan buku catatan untuk merilis sumber daya. Untuk melakukannya, dari menu File pada notebook, pilih Tutup dan Hentikan. Tindakan ini akan mematikan dan menutup buku catatan.

Langkah berikutnya

Jelajahi artikel berikut: