Bagikan melalui


Analisis log telemetri Application Insights dengan Apache Spark di Microsoft Azure HDInsight

Pelajari cara menggunakan Apache Spark di Microsoft Azure HDInsight untuk menganalisis data telemetri Wawasan Aplikasi.

Visual Studio Application Insights adalah layanan analitik yang memantau aplikasi web Anda. Data telemetri yang dihasilkan oleh Application Insights dapat diekspor ke Azure Storage. Setelah data berada di Azure Storage, Microsoft Azure HDInsight dapat digunakan untuk menganalisisnya.

Prasyarat

  • Aplikasi yang dikonfigurasi untuk menggunakan Application Insights.

  • Keakraban dengan membuat klaster Microsoft Azure HDInsight berbasis Linux. Untuk informasi selengkapnya, lihat Buat Apache Spark di Microsoft Azure HDInsight.

  • Browser web.

Sumber daya berikut digunakan dalam mengembangkan dan menguji dokumen ini:

Arsitektur dan perencanaan

Diagram berikut mengilustrasikan arsitektur layanan dari contoh ini:

Data flowing from Application Insights to blob storage, then Spark.

Azure Storage

Application Insights dapat dikonfigurasi untuk terus mengekspor informasi telemetri ke blob. Microsoft Azure HDInsight kemudian dapat membaca data yang disimpan dalam blob. Namun, ada beberapa persyaratan yang harus Anda ikuti:

  • Lokasi:Jika Akun Penyimpanan dan Microsoft Azure HDInsight berada di lokasi yang berbeda, itu dapat meningkatkan latensi. Ini juga meningkatkan biaya, karena biaya keluar diterapkan pada data yang berpindah antar wilayah.

    Peringatan

    Penggunaan akun penyimpanan di lokasi yang berbeda dari kluster Microsoft Azure HDInsight tidak didukung.

  • Jenis blob:Microsoft Azure HDInsight hanya mendukung blob blok. Application Insights default untuk menggunakan blob blok, jadi harus bekerja secara default dengan Microsoft Azure HDInsight.

Untuk informasi tentang penambahan penyimpanan ke kluster yang sudah ada, lihat dokumen penambahan akun penyimpanan tambahan.

Skema data

Application Insights menyediakan informasi model data ekspor untuk format data telemetri yang diekspor ke blob. Langkah-langkah dalam dokumen ini menggunakan Spark SQL untuk bekerja dengan data. Spark SQL dapat secara otomatis menghasilkan skema untuk struktur data JSON yang dicatat oleh Application Insights.

Ekspor data telemetri

Ikuti langkah-langkah dalam konfigurasikan Ekspor Berkelanjutan untuk mengonfigurasi Application Insights Anda untuk mengekspor informasi telemetri ke blob Azure Storage.

Konfigurasikan Microsoft Azure HDInsight untuk mengakses data

Jika Anda membuat kluster Microsoft Azure HDInsight, tambahkan akun penyimpanan selama pembuatan kluster.

Untuk menambahkan Akun Azure Storage ke kluster yang sudah ada, gunakan informasi di Tambahkan dokumen Tambahkan Akun Penyimpanan.

Analisis data: PySpark

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

  2. Di sudut kanan atas halaman Jupyter, pilih Baru,lalu PySpark. Tab browser baru yang berisi Jupyter Notebook berbasis Python terbuka.

  3. Di bidang pertama (disebut sel) di halaman, masukkan teks berikut:

    sc._jsc.hadoopConfiguration().set('mapreduce.input.fileinputformat.input.dir.recursive', 'true')
    

    Kode ini mengonfigurasi Spark untuk secara rekursif mengakses struktur direktori untuk data input. Telemetri Application Insights dicatat ke struktur direktori yang mirip dengan /{telemetry type}/YYYY-MM-DD/{##}/.

  4. Gunakan SHIFT+ENTER untuk menjalankan kode. Di sisi kiri sel, ‘*‘ muncul di antara tanda kurung untuk menunjukkan bahwa kode dalam sel ini sedang dijalankan. Setelah selesai, ‘*’ berubah menjadi angka, dan output yang mirip dengan teks berikut ditampilkan di bawah sel:

    Creating SparkContext as 'sc'
    
    ID    YARN Application ID    Kind    State    Spark UI    Driver log    Current session?
    3    application_1468969497124_0001    pyspark    idle    Link    Link    ✔
    
    Creating HiveContext as 'sqlContext'
    SparkContext and HiveContext created. Executing user code ...
    
  5. Sel baru dibuat di bawah sel pertama. Masukkan teks berikut ini di sel baru. Ganti CONTAINER dan STORAGEACCOUNT dengan nama akun Azure Storage dan nama kontainer blob yang berisi data Application Insights.

    %%bash
    hdfs dfs -ls wasbs://CONTAINER@STORAGEACCOUNT.blob.core.windows.net/
    

    Gunakan SHIFT+ENTER untuk menjalankan sel ini. Anda melihat hasil yang mirip dengan teks berikut:

    Found 1 items
    drwxrwxrwx   -          0 1970-01-01 00:00 wasbs://appinsights@contosostore.blob.core.windows.net/contosoappinsights_2bededa61bc741fbdee6b556571a4831
    

    Jalur wasb yang dikembalikan adalah lokasi data telemetri Application Insights. Ubah hdfs dfs -ls baris dalam sel untuk menggunakan jalur wasb yang dikembalikan, lalu gunakan SHIFT+ENTER untuk menjalankan sel lagi. Kali ini, hasilnya harus menampilkan direktori yang berisi data telemetri.

    Catatan

    Untuk sisa langkah-langkah di bagian wasbs://appinsights@contosostore.blob.core.windows.net/contosoappinsights_{ID}/Requests ini, direktori digunakan. Struktur direktori Anda mungkin berbeda.

  6. Di sel berikutnya, masukkan kode berikut: Ganti WASB_PATH dengan jalur dari langkah sebelumnya.

    jsonFiles = sc.textFile('WASB_PATH')
    jsonData = sqlContext.read.json(jsonFiles)
    

    Kode ini membuat dataframe dari file JSON yang diekspor oleh proses ekspor berkelanjutan. Gunakan SHIFT+ENTER untuk menjalankan kode ini.

  7. Di sel berikutnya, masukkan dan jalankan yang berikut ini untuk menampilkan skema yang dibuat Spark untuk file JSON:

    jsonData.printSchema()
    

    Skema untuk setiap jenis telemetri berbeda. Contoh berikut adalah skema yang dihasilkan untuk permintaan web (data yang disimpan dalam Requests subdirektori):

    root
    |-- context: struct (nullable = true)
    |    |-- application: struct (nullable = true)
    |    |    |-- version: string (nullable = true)
    |    |-- custom: struct (nullable = true)
    |    |    |-- dimensions: array (nullable = true)
    |    |    |    |-- element: string (containsNull = true)
    |    |    |-- metrics: array (nullable = true)
    |    |    |    |-- element: string (containsNull = true)
    |    |-- data: struct (nullable = true)
    |    |    |-- eventTime: string (nullable = true)
    |    |    |-- isSynthetic: boolean (nullable = true)
    |    |    |-- samplingRate: double (nullable = true)
    |    |    |-- syntheticSource: string (nullable = true)
    |    |-- device: struct (nullable = true)
    |    |    |-- browser: string (nullable = true)
    |    |    |-- browserVersion: string (nullable = true)
    |    |    |-- deviceModel: string (nullable = true)
    |    |    |-- deviceName: string (nullable = true)
    |    |    |-- id: string (nullable = true)
    |    |    |-- osVersion: string (nullable = true)
    |    |    |-- type: string (nullable = true)
    |    |-- location: struct (nullable = true)
    |    |    |-- city: string (nullable = true)
    |    |    |-- clientip: string (nullable = true)
    |    |    |-- continent: string (nullable = true)
    |    |    |-- country: string (nullable = true)
    |    |    |-- province: string (nullable = true)
    |    |-- operation: struct (nullable = true)
    |    |    |-- name: string (nullable = true)
    |    |-- session: struct (nullable = true)
    |    |    |-- id: string (nullable = true)
    |    |    |-- isFirst: boolean (nullable = true)
    |    |-- user: struct (nullable = true)
    |    |    |-- anonId: string (nullable = true)
    |    |    |-- isAuthenticated: boolean (nullable = true)
    |-- internal: struct (nullable = true)
    |    |-- data: struct (nullable = true)
    |    |    |-- documentVersion: string (nullable = true)
    |    |    |-- id: string (nullable = true)
    |-- request: array (nullable = true)
    |    |-- element: struct (containsNull = true)
    |    |    |-- count: long (nullable = true)
    |    |    |-- durationMetric: struct (nullable = true)
    |    |    |    |-- count: double (nullable = true)
    |    |    |    |-- max: double (nullable = true)
    |    |    |    |-- min: double (nullable = true)
    |    |    |    |-- sampledValue: double (nullable = true)
    |    |    |    |-- stdDev: double (nullable = true)
    |    |    |    |-- value: double (nullable = true)
    |    |    |-- id: string (nullable = true)
    |    |    |-- name: string (nullable = true)
    |    |    |-- responseCode: long (nullable = true)
    |    |    |-- success: boolean (nullable = true)
    |    |    |-- url: string (nullable = true)
    |    |    |-- urlData: struct (nullable = true)
    |    |    |    |-- base: string (nullable = true)
    |    |    |    |-- hashTag: string (nullable = true)
    |    |    |    |-- host: string (nullable = true)
    |    |    |    |-- protocol: string (nullable = true)
    
  8. Gunakan yang berikut ini untuk mendaftarkan dataframe sebagai tabel sementara dan menjalankan kueri terhadap data:

    jsonData.registerTempTable("requests")
    df = sqlContext.sql("select context.location.city from requests where context.location.city is not null")
    df.show()
    

    Kueri ini mengembalikan informasi kota untuk 20 rekaman teratas di mana konteks.lokasi.kota tidak null.

    Catatan

    Struktur konteks hadir di semua telemetri yang dicatat oleh Application Insights. Elemen kota mungkin tidak diisi dalam log Anda. Gunakan skema untuk mengidentifikasi elemen lain yang bisa Anda kueri yang mungkin berisi data untuk log Anda.

    Kueri ini menampilkan informasi yang mirip dengan teks berikut:

    +---------+
    |     city|
    +---------+
    | Bellevue|
    |  Redmond|
    |  Seattle|
    |Charlotte|
    ...
    +---------+
    

Analisis data: Scala

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

  2. Di sudut kanan atas halaman Jupyter, pilih Baru, lalu Scala. Tab browser baru yang berisi Jupyter Notebook berbasis Python terbuka.

  3. Di bidang pertama (disebut sel) di halaman, masukkan teks berikut:

    sc.hadoopConfiguration.set("mapreduce.input.fileinputformat.input.dir.recursive", "true")
    

    Kode ini mengonfigurasi Spark untuk secara rekursif mengakses struktur direktori untuk data input. Telemetri Application Insights dicatat ke struktur direktori yang mirip dengan /{telemetry type}/YYYY-MM-DD/{##}/.

  4. Gunakan SHIFT+ENTER untuk menjalankan kode. Di sisi kiri sel, ‘*‘ muncul di antara tanda kurung untuk menunjukkan bahwa kode dalam sel ini sedang dijalankan. Setelah selesai, ‘*’ berubah menjadi angka, dan output yang mirip dengan teks berikut ditampilkan di bawah sel:

    Creating SparkContext as 'sc'
    
    ID    YARN Application ID    Kind    State    Spark UI    Driver log    Current session?
    3    application_1468969497124_0001    spark    idle    Link    Link    ✔
    
    Creating HiveContext as 'sqlContext'
    SparkContext and HiveContext created. Executing user code ...
    
  5. Sel baru dibuat di bawah sel pertama. Masukkan teks berikut ini di sel baru. Ganti CONTAINER dan STORAGEACCOUNT dengan nama akun Azure Storage dan nama kontainer blob yang berisi data Application Insights.

    %%bash
    hdfs dfs -ls wasbs://CONTAINER@STORAGEACCOUNT.blob.core.windows.net/
    

    Gunakan SHIFT+ENTER untuk menjalankan sel ini. Anda melihat hasil yang mirip dengan teks berikut:

    Found 1 items
    drwxrwxrwx   -          0 1970-01-01 00:00 wasbs://appinsights@contosostore.blob.core.windows.net/contosoappinsights_2bededa61bc741fbdee6b556571a4831
    

    Jalur wasb yang dikembalikan adalah lokasi data telemetri Application Insights. Ubah hdfs dfs -ls baris dalam sel untuk menggunakan jalur wasb yang dikembalikan, lalu gunakan SHIFT+ENTER untuk menjalankan sel lagi. Kali ini, hasilnya harus menampilkan direktori yang berisi data telemetri.

    Catatan

    Untuk sisa langkah-langkah di bagian wasbs://appinsights@contosostore.blob.core.windows.net/contosoappinsights_{ID}/Requests ini, direktori digunakan. Direktori ini mungkin tidak ada kecuali data telemetri Anda adalah untuk aplikasi web.

  6. Di sel berikutnya, masukkan kode berikut: Ganti WASB\_PATH dengan jalur dari langkah sebelumnya.

    var jsonFiles = sc.textFile('WASB_PATH')
    val sqlContext = new org.apache.spark.sql.SQLContext(sc)
    var jsonData = sqlContext.read.json(jsonFiles)
    

    Kode ini membuat dataframe dari file JSON yang diekspor oleh proses ekspor berkelanjutan. Gunakan SHIFT+ENTER untuk menjalankan kode ini.

  7. Di sel berikutnya, masukkan dan jalankan yang berikut ini untuk menampilkan skema yang dibuat Spark untuk file JSON:

    jsonData.printSchema
    

    Skema untuk setiap jenis telemetri berbeda. Contoh berikut adalah skema yang dihasilkan untuk permintaan web (data yang disimpan dalam Requests subdirektori):

    root
    |-- context: struct (nullable = true)
    |    |-- application: struct (nullable = true)
    |    |    |-- version: string (nullable = true)
    |    |-- custom: struct (nullable = true)
    |    |    |-- dimensions: array (nullable = true)
    |    |    |    |-- element: string (containsNull = true)
    |    |    |-- metrics: array (nullable = true)
    |    |    |    |-- element: string (containsNull = true)
    |    |-- data: struct (nullable = true)
    |    |    |-- eventTime: string (nullable = true)
    |    |    |-- isSynthetic: boolean (nullable = true)
    |    |    |-- samplingRate: double (nullable = true)
    |    |    |-- syntheticSource: string (nullable = true)
    |    |-- device: struct (nullable = true)
    |    |    |-- browser: string (nullable = true)
    |    |    |-- browserVersion: string (nullable = true)
    |    |    |-- deviceModel: string (nullable = true)
    |    |    |-- deviceName: string (nullable = true)
    |    |    |-- id: string (nullable = true)
    |    |    |-- osVersion: string (nullable = true)
    |    |    |-- type: string (nullable = true)
    |    |-- location: struct (nullable = true)
    |    |    |-- city: string (nullable = true)
    |    |    |-- clientip: string (nullable = true)
    |    |    |-- continent: string (nullable = true)
    |    |    |-- country: string (nullable = true)
    |    |    |-- province: string (nullable = true)
    |    |-- operation: struct (nullable = true)
    |    |    |-- name: string (nullable = true)
    |    |-- session: struct (nullable = true)
    |    |    |-- id: string (nullable = true)
    |    |    |-- isFirst: boolean (nullable = true)
    |    |-- user: struct (nullable = true)
    |    |    |-- anonId: string (nullable = true)
    |    |    |-- isAuthenticated: boolean (nullable = true)
    |-- internal: struct (nullable = true)
    |    |-- data: struct (nullable = true)
    |    |    |-- documentVersion: string (nullable = true)
    |    |    |-- id: string (nullable = true)
    |-- request: array (nullable = true)
    |    |-- element: struct (containsNull = true)
    |    |    |-- count: long (nullable = true)
    |    |    |-- durationMetric: struct (nullable = true)
    |    |    |    |-- count: double (nullable = true)
    |    |    |    |-- max: double (nullable = true)
    |    |    |    |-- min: double (nullable = true)
    |    |    |    |-- sampledValue: double (nullable = true)
    |    |    |    |-- stdDev: double (nullable = true)
    |    |    |    |-- value: double (nullable = true)
    |    |    |-- id: string (nullable = true)
    |    |    |-- name: string (nullable = true)
    |    |    |-- responseCode: long (nullable = true)
    |    |    |-- success: boolean (nullable = true)
    |    |    |-- url: string (nullable = true)
    |    |    |-- urlData: struct (nullable = true)
    |    |    |    |-- base: string (nullable = true)
    |    |    |    |-- hashTag: string (nullable = true)
    |    |    |    |-- host: string (nullable = true)
    |    |    |    |-- protocol: string (nullable = true)
    
  8. Gunakan yang berikut ini untuk mendaftarkan dataframe sebagai tabel sementara dan menjalankan kueri terhadap data:

    jsonData.registerTempTable("requests")
    var city = sqlContext.sql("select context.location.city from requests where context.location.city isn't null limit 10").show()
    

    Kueri ini mengembalikan informasi kota untuk 20 rekaman teratas di mana konteks.lokasi.kota tidak null.

    Catatan

    Struktur konteks hadir di semua telemetri yang dicatat oleh Application Insights. Elemen kota mungkin tidak diisi dalam log Anda. Gunakan skema untuk mengidentifikasi elemen lain yang bisa Anda kueri yang mungkin berisi data untuk log Anda.

    Kueri ini menampilkan informasi yang mirip dengan teks berikut:

    +---------+
    |     city|
    +---------+
    | Bellevue|
    |  Redmond|
    |  Seattle|
    |Charlotte|
    ...
    +---------+
    

Langkah berikutnya

Untuk contoh selengkapnya menggunakan Apache Spark untuk bekerja dengan data dan layanan di Azure, lihat dokumen berikut ini:

Untuk informasi tentang membuat dan menjalankan aplikasi Spark, lihat dokumen berikut: