Menganalisis log situs web menggunakan pustaka Python kustom dengan klaster Apache Spark pada HDInsight

Notebook ini menunjukkan cara menganalisis data log menggunakan pustaka kustom dengan Apache Spark pada 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 klaster Apache Spark di HDInsight untuk menjalankan pekerjaan yang memproses data sampel mentah Anda dan menyimpannya sebagai tabel Hive. Data sampel adalah file .csv (hvac.csv) yang tersedia pada semua klaster secara default.

Setelah data Anda disimpan sebagai tabel Apache Hive, di bagian berikutnya kita akan terhubung ke tabel 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 notebook baru. Pilih Baru, lalu PySpark.

    Create a new Apache Jupyter Notebook. Notebook" border="true":::

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

    Provide a name for the notebook.

  4. Karena Anda membuat notebook menggunakan kernel PySpark, Anda tidak perlu membuat konteks apa pun secara eksplisit. Konteks Spark dan Apache Hive secara otomatis dibuat saat Anda menjalankan sel kode pertama. Anda bisa 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 pada klaster. Anda dapat mengakses data di akun penyimpanan default yang terkait dengan klaster di \HdiSamples\HdiSamples\WebsiteLogSampleData\SampleLog\909f2b.log. Jalankan kode berikut:

    logs = sc.textFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/SampleLog/909f2b.log')
    
  6. Ambil set log sampel 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. Penguraian 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 klaster Spark Anda pada HDInsight di /HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py.

    Akan tetapi, 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 node pekerja. Jalankan cuplikan berikut.

    sc.addPyFile('wasbs:///HdiSamples/HdiSamples/WebsiteLogSampleData/iislogparser.py')
    
  2. iislogparser menyediakan fungsi parse_log_line yang menampilkan None jika baris log adalah baris header, dan menampilkan instans kelas LogLine jika menemukan baris log. Gunakan kelas LogLine untuk mengekstrak baris log dari RDD saja:

    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 seharusnya sama 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, sebaliknya, memiliki beberapa metode yang berguna, seperti is_error(), yang menampilkan apakah entri log memiliki kode eror. Gunakan kelas ini untuk menghitung jumlah eror dalam baris log yang diekstrak, lalu catat semua eror ke file lain.

    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. Contohnya, jika Anda ingin mengisolasi penyebab permintaan yang berjalan untuk waktu yang lama, Anda mungkin ingin menemukan file yang menghabiskan waktu paling lama untuk layanan rata-rata. Cuplikan di bawah ini mengambil 25 sumber daya teratas yang menghabiskan 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 contoh di bawah ini:

    [(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 menghadirkan informasi ini dalam bentuk plot. Sebagai langkah pertama untuk membuat plot, mari kita terlebih dahulu membuat tabel AverageTime sementara. Tabel mengelompokkan log berdasarkan 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 ini untuk mendapatkan semua rekaman dalam tabel AverageTime.

    %%sql -o averagetime
    SELECT * FROM AverageTime
    

    %%sql Sihir diikuti dengan -o averagetime memastikan bahwa output kueri ditempelkan secara lokal di server Jupyter (biasanya headnode kluster). Outputnya dipertahankan sebagai kerangka data Pandas dengan nama yang ditentukan adalah averagetime.

    Anda akan melihat output seperti contoh di bawah ini:

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

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

  8. Anda sekarang dapat menggunakan Matplotlib, pustaka yang digunakan untuk membangun visualisasi data, untuk membuat plot. Karena plot harus dibuat dari kerangka data averagetime yang dipertahankan secara lokal, cuplikan kode harus dimulai dengan keajaiban %%local. Ini untuk memastikan kode dijalankan secara lokal pada 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 contoh di bawah ini:

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

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

Langkah berikutnya

Jelajahi artikel berikut: