All Products
Search
Document Center

Simple Log Service:Referensi umum

Last Updated:Mar 14, 2026

Topik ini menjelaskan cara menggunakan Structured Process Language (SPL) dalam berbagai skenario.

Pengoptimalan pernyataan SPL

Anda sering dapat menulis pernyataan SPL dengan beberapa cara untuk mencapai hasil pemrosesan data yang sama. Pernyataan SPL yang ringkas dan efisien menyederhanakan pemeliharaan serta meningkatkan performa. Tabel berikut memberikan beberapa saran.

Saran

Sebelum pengoptimalan

Setelah pengoptimalan

Gabungkan klausa where yang berurutan menjadi satu.

*
| where request_method = 'POST'
| where cast(status as integer) >= 500
*
| where request_method = 'POST' and cast(status as integer) >= 500

Gabungkan klausa extend yang berurutan menjadi satu.

*
| extend k1 = 'v1'
| extend k2 = 'v2'
| extend k3 = 'v3'
*
| extend k1 = 'v1', k2 = 'v2', k3 = 'v3'

Ganti extend + project-away dengan project-rename.

*
| extend method = request_method
| project-away request_method
*
| project-rename method = request_method

Ubah nilai field secara langsung alih-alih menggunakan extend untuk membuat field baru, kecuali jika diperlukan.

*
| extend newContent = json_extract(content, 'abc \d+')
| project-away content
*
| extend content = json_extract(content, 'abc \d+')

Menangani field khusus

Bidang waktu

Selama eksekusi SPL, tipe data field waktu pada log Simple Log Service selalu berupa INTEGER atau BIGINT. Field-field ini mencakup field waktu data __time__ dan bagian nanodetik dari field waktu data __time_ns_part__.

Untuk memperbarui waktu data, gunakan instruksi extend dan pastikan nilai barunya berupa INTEGER atau BIGINT. Instruksi lain tidak dapat mengoperasikan field waktu. Perilaku mereka adalah sebagai berikut:

  • project, project-away, dan project-rename: Instruksi-instruksi ini secara default mempertahankan field waktu. Anda tidak dapat mengganti nama atau menimpanya.

  • parse-regexp dan parse-json: Jika hasil ekstraksi mencakup field waktu, field tersebut diabaikan.

Contoh

Ekstrak nilai field waktu dari string waktu yang sudah ada.

  • Pernyataan SPL

    * 
    | parse-regexp time, '([\d\-\s:]+)\.(\d+)' as ts, ms
    | extend ts=date_parse(ts, '%Y-%m-%d %H:%i:%S')
    | extend __time__=cast(to_unixtime(ts) as INTEGER)
    | extend __time_ns_part__=cast(ms as INTEGER) * 1000000
    | project-away ts, ms
  • Data input

    time: '2023-11-11 01:23:45.678'
  • Hasil output

    __time__: 1699637025
    __time_ns_part__: 678000000
    time: '2023-11-11 01:23:45.678'

Nama field yang mengandung karakter khusus

Jika nama field mengandung spasi atau karakter khusus lainnya, sertakan dalam tanda kutip ganda (") saat Anda mereferensikannya. Misalnya, jika sebuah field bernama A B, yang mengandung spasi, Anda dapat mereferensikannya sebagai "A B" dalam pernyataan SPL. Contoh berikut menunjukkan cara melakukannya:

* | where "A B" like '%error%'

Nama field yang tidak peka huruf besar/kecil

Dalam kueri scan SLS, nama field yang direferensikan dalam instruksi SPL bersifat tidak peka huruf besar/kecil. Misalnya, jika sebuah log berisi field bernama Method, Anda dapat mereferensikannya sebagai method atau METHOD dalam instruksi SPL.

Penting

Ini berlaku untuk fitur kueri scan Simple Log Service. Untuk informasi lebih lanjut, lihat Kueri scan.

Contoh

Gunakan nama field yang tidak peka huruf besar/kecil dalam klausa where.

  • Pernyataan SPL

    * | where METHOD like 'Post%'
  • Data input

    Method: 'PostLogstoreLogs'
  • Hasil output

    Method: 'PostLogstoreLogs'

Menangani konflik nama field

Selama pengunggahan log atau eksekusi SPL, pemrosesan yang peka huruf besar/kecil dapat menyebabkan konflik nama field. Misalnya, log mentah mungkin berisi field Method dan method sekaligus. SPL menyelesaikan konflik ini secara berbeda tergantung skenarionya.

Untuk menghindari situasi ini, Anda dapat menstandarkan nama field dalam log mentah Anda.

Konflik dalam data input

Jika log mentah berisi field dengan nama yang sama ketika diabaikan perbedaan huruf besar/kecilnya, seperti Status dan status, SPL secara acak memilih satu field sebagai input dan membuang yang lainnya. Misalnya:

  • Pernyataan SPL

    * | extend status_cast = cast(status as bigint)
  • Data input

    Status: '200'
    status: '404'
  • Hasil pemrosesan

    • Kemungkinan 1: Nilai field Status dipertahankan.

      Status: '200' -- Kolom pertama dipertahankan, kolom kedua dibuang.
      status_cast: '200'
    • Kemungkinan 2: Nilai field status dipertahankan.

      status: '404' -- Kolom kedua dipertahankan, kolom pertama dibuang.
      Status_cast: '404'

Konflik dalam hasil output

Skenario 1: Konflik field data mentah

Selama eksekusi SPL, field dengan nama yang sama ketika diabaikan perbedaan huruf besar/kecilnya mungkin dihasilkan. Dalam kasus ini, SPL secara acak memilih salah satunya untuk output. Misalnya, jika sebuah field log berisi string JSON, penggunaan instruksi parse-json mungkin membuat field dengan nama yang bertentangan. Contohnya:

  • Pernyataan SPL

    * | parse-json content
  • Data input

    content: '{"Method": "PostLogs", "method": "GetLogs", "status": "200"}'
  • Hasil output

    • Kemungkinan 1: Field Method dipertahankan.

      content: '{"Method": "PostLogs", "method": "GetLogs", "status": "200"}'
      Method: 'PostLogs' -- Field Method dipertahankan.
      status: '200'
    • Kemungkinan 2: Field method dipertahankan.

      content: '{"Method": "PostLogs", "method": "GetLogs", "status": "200"}'
      method: 'GetLogs' -- Field method dipertahankan.
      status: '200'

Skenario 2: Konflik dengan field data yang baru dihasilkan

Untuk menghindari ambiguitas, SPL mempertahankan huruf besar/kecil dari nama field baru yang dihasilkan secara eksplisit oleh instruksi. Ini berlaku untuk nama field yang dihasilkan oleh instruksi extend dan nama field yang secara eksplisit ditentukan menggunakan as dalam instruksi parse-regexp dan parse-csv.

Misalnya, jika Anda menggunakan extend untuk membuat field baru Method, nama field yang dihasilkan tetap Method.

  • Pernyataan SPL

    * | extend Method = 'Post'
  • Data input

    Status: '200'
  • Hasil output

    Status: '200'
    Method: 'Post'

Menangani konflik field tercadang SLS

Penting

Ini berlaku untuk fitur konsumsi real-time dan kueri scan Simple Log Service.

Untuk daftar lengkap field tercadang, lihat Field tercadang. SPL membaca data dari struktur LogGroup sebagai input. Untuk informasi lebih lanjut tentang definisi LogGroup, lihat Encoding data. Jika data mentah yang ditulis ke Simple Log Service tidak di-encode dalam format LogGroup standar, beberapa field tercadang mungkin berada di LogContent alih-alih lokasi standarnya. SPL menangani field tercadang ini sebagai berikut:

  • Untuk field __source__, __topic__, __time__, dan __time_ns_part__, SPL membaca nilainya dari struktur LogGroup standar dan mengabaikan field apa pun dengan nama yang sama di LogContent.

  • Untuk field tag dengan awalan __tag__: , SPL pertama-tama mencoba membaca nilainya dari struktur LogGroup standar. Jika nilai tidak ditemukan, SPL membacanya dari LogContent. Misalnya, untuk field __tag__:ip, SPL pertama-tama mencoba membaca field dengan kunci ip dari daftar LogTag. Jika field tersebut tidak ada, SPL kemudian membaca field log dengan kunci __tag__:ip dari field log kustom di LogContent.

Field __line__ untuk pencarian teks penuh

Penting

Ini berlaku untuk fitur kueri scan SLS.

Untuk memfilter log mentah di Konsol atau saat menggunakan operasi API GetLogstoreLogs, Anda dapat menggunakan field __line__.

Contoh

  • Cari kata kunci error dalam log.

    * | where __line__ like '%error%'
  • Jika sebuah log berisi field bernama `__line__`, sertakan nama field dalam backtick untuk mereferensikannya.

    * | where `__line__` ='20'

Kebijakan retensi dan penimpaan nilai

Saat instruksi SPL dieksekusi, jika field output memiliki nama yang sama dengan field yang sudah ada dalam data input, kebijakan untuk menentukan nilai field tersebut adalah sebagai berikut:

Penting

Kebijakan retensi dan penimpaan nilai tidak berlaku untuk instruksi extend. Untuk instruksi extend, jika terjadi konflik nama field, nilai baru selalu digunakan.

Tipe data lama dan baru tidak konsisten

Nilai asli field input dipertahankan.

Contoh

  • Contoh 1: Field yang diganti nama dari instruksi project memiliki nama yang bertentangan.

    • Pernyataan SPL

      * 
      | extend status=cast(status as BIGINT) -- Ubah tipe field status menjadi BIGINT.
      | project code=status -- Tipe nilai baru (BIGINT) berbeda dari tipe nilai lama (VARCHAR), sehingga nilai lama dipertahankan.
    • Data input

      status: '200'
      code: 'Success'
    • Hasil output

      code: 'Success'
  • Contoh 2: Field yang diekstrak dari instruksi parse-json memiliki nama yang bertentangan.

    • Pernyataan SPL

      * 
      | extend status=cast(status as BIGINT) -- Ubah tipe field status menjadi BIGINT.
      | parse-json content -- Tipe lama status adalah BIGINT dan tipe baru adalah VARCHAR. Nilai lama dipertahankan.
    • Data input

      status: '200'
      content: '{"status": "Success", "body": "this is test"}'
    • Hasil output

      content: '{"status": "Success", "body": "this is test"}'
      status: 200
      body: 'this is test'

Tipe data lama dan baru konsisten

Jika nilai input adalah null, nilai baru digunakan. Jika tidak, perilaku ditentukan oleh parameter mode dalam instruksi, sebagaimana didefinisikan dalam tabel berikut.

Penting

Jika parameter mode tidak ditentukan dalam instruksi, nilai default-nya adalah overwrite.

Mode

Deskripsi

overwrite

Menimpa nilai lama dengan nilai baru.

preserve

Mempertahankan nilai lama dan membuang nilai baru.

Contoh

  • Contoh 1: Field yang diganti nama dari instruksi project memiliki nama yang bertentangan dan tipe yang sama. Mode default adalah overwrite.

    • Pernyataan SPL

    * | project code=status -- Tipe lama dan baru dari code sama-sama VARCHAR. Nilai baru digunakan berdasarkan mode overwrite.
    • Data input

      status: '200'
      code: 'Success'
    • Hasil output

      code: '200'
  • Contoh 2: Field yang diekstrak dari instruksi parse-json memiliki nama yang bertentangan dan tipe yang sama. Mode default adalah overwrite.

    • Pernyataan SPL

      * | parse-json content -- Tipe lama dan baru dari status sama-sama VARCHAR. Nilai baru digunakan berdasarkan mode overwrite.
    • Data input

      status: '200'
      content: '{"status": "Success", "body": "this is test"}'
    • Hasil output

      content: '{"status": "Success", "body": "this is test"}'
      status: 'Success'
      body: 'this is test'
  • Contoh 3: Field yang diekstrak dari instruksi parse-json memiliki nama yang bertentangan dan tipe yang sama. Mode diatur ke preserve.

    • Pernyataan SPL

      * | parse-json -mode='preserve' content -- Tipe lama dan baru dari status sama-sama VARCHAR. Nilai lama dipertahankan berdasarkan mode preserve.
    • Data input

      status: '200'
      content: '{"status": "Success", "body": "this is test"}'
    • Hasil output

      content: '{"status": "Success", "body": "this is test"}'
      status: '200'
      body: 'this is test'

Konversi tipe data

Tipe awal

Saat SPL memproses data, tipe data awal semua field input adalah VARCHAR, kecuali field waktu log. Jika logika pemrosesan selanjutnya melibatkan tipe data yang berbeda, Anda harus melakukan konversi tipe data.

Contoh

Untuk memfilter log akses dengan kode status 5xx, Anda harus mengonversi field status ke tipe BIGINT sebelum perbandingan.

* -- Tipe awal field status adalah VARCHAR.
| where cast(status as BIGINT) >= 500 -- Ubah tipe field status menjadi BIGINT, lalu lakukan perbandingan.

Retensi tipe

Selama pemrosesan data SPL, setelah Anda menggunakan instruksi extend untuk mengonversi tipe data suatu field, logika pemrosesan selanjutnya menggunakan tipe data yang telah dikonversi tersebut.

Contoh

* -- Logstore digunakan sebagai data input. Kecuali field waktu, semua field awalnya bertipe VARCHAR.
| where __source__='127.0.0.1' -- Filter berdasarkan field __source__.
| extend status=cast(status as BIGINT) -- Ubah tipe field status menjadi BIGINT.
| project status, content
| where status>=500 -- Tipe field status tetap BIGINT, sehingga dapat langsung dibandingkan dengan angka 500.

Menangani nilai null dalam ekspresi SPL

Menghasilkan nilai null

Selama pemrosesan data SPL, nilai null dihasilkan dalam dua skenario berikut:

  1. Jika field yang digunakan dalam ekspresi SPL tidak ada dalam data input, nilainya dianggap null selama perhitungan.

  2. Jika terjadi exception selama perhitungan ekspresi SPL, hasilnya adalah null. Misalnya, konversi tipe cast gagal atau indeks array di luar batas.

Contoh

  1. Jika field tidak ada, nilainya dianggap null dalam perhitungan.

    • Pernyataan SPL

      * | extend withoutStatus=(status is null)
    • Data input

      # Entri 1
      status: '200'
      code: 'Success'
      
      # Entri 2
      code: 'Success'
    • Hasil output

      # Entri 1
      status: '200'
      code: 'Success'
      withoutStatus: false
      
      # Entri 2
      code: 'Success'
      withoutStatus: true
  2. Jika terjadi exception selama perhitungan, hasilnya adalah null.

    • Pernyataan SPL

      *
      | extend code=cast(code as BIGINT) -- Gagal mengonversi field code ke BIGINT.
      | extend values=json_parse(values)
      | extend values=cast(values as ARRAY(BIGINT))
      | extend last=arr[10] -- Indeks array di luar batas.
    • Data input

      status: '200'
      code: 'Success'
      values: '[1,2,3]'
    • Hasil output

      status: '200'
      code: null
      values: [1, 2, 3]
      last: null

Menghilangkan nilai null

Untuk menghilangkan nilai null selama perhitungan, Anda dapat menggunakan ekspresi COALESCE. Ekspresi ini mengembalikan nilai pertama yang bukan null dari daftar ekspresi. Anda juga dapat menetapkan nilai default yang digunakan jika semua ekspresi bernilai null.

Contoh

Baca elemen terakhir dari array. Jika array kosong, nilai default-nya adalah 0.

  • Pernyataan SPL

    *
    | extend values=json_parse(values)
    | extend values=cast(values as ARRAY(BIGINT))
    | extend last=COALESCE(values[3], values[2], values[1], 0)
  • Data input

    # Entri 1
    values: '[1, 2, 3]'
    
    # Entri 2
    values: '[]'
  • Hasil output

    # Entri 1
    values: [1, 2, 3]
    last: 3
    
    # Entri 2
    values: []
    last: 0

Escape karakter

Tanda kutip tunggal

Tanda kutip tunggal digunakan untuk mengapit literal string. Jika literal string mengandung tanda kutip tunggal, Anda harus menggunakan tanda kutip tunggal tambahan untuk meng-escape-nya.

Contoh

  • Pernyataan SPL

    *
    | extend user = 'Alice'
    | extend phone = 'Alice''s Phone'
  • Hasil output

    user: Alice
    phone: Alice's Phone

Tanda kutip ganda

Tanda kutip ganda digunakan untuk mengapit nama field. Jika nama field mengandung tanda kutip ganda, Anda harus menggunakan tanda kutip ganda tambahan untuk meng-escape-nya.

Contoh

  • Pernyataan SPL

    *
    | extend user_name = 'Alice'
    | extend "user name" = 'Alice'
    | extend "user""name" = 'Alice'
  • Hasil output

    user_name: Alice
    user name: Alice
    user"name: Alice

Karakter khusus lainnya

Contoh 1

Dalam SPL, backslash (\) bukan karakter escape dan karena itu dipertahankan apa adanya.

  • Pernyataan SPL

    *
    | extend a = 'foo\tbar'
    | extend b = 'foo\nbar'
  • Hasil output

    a: foo\tbar
    b: foo\nbar

Contoh 2

Jika string harus menyertakan karakter khusus, seperti karakter tab atau line feed, Anda dapat menggunakan fungsi chr untuk menggabungkan string.

  • Pernyataan SPL

    *
    | extend a = concat('foo', chr(9), 'bar')
    | extend b = concat('foo', chr(10), 'bar')
  • Hasil output

    a: foo	bar
    b: foo
    bar

Penanganan error

Error sintaksis

Error sintaksis terjadi ketika pernyataan SPL tidak valid, seperti nama instruksi salah, kesalahan referensi kata kunci, atau kesalahan spesifikasi tipe. Saat terjadi error sintaksis, SPL tidak memproses data apa pun. Anda harus memperbaiki pernyataan berdasarkan pesan error.

Error data

Error data terjadi ketika fungsi atau konversi gagal selama eksekusi SPL. SPL mengatur field hasil menjadi null. Karena error data dapat terjadi pada baris mana pun, SPL secara acak mengambil sampel dan hanya mengembalikan sebagian pesan error. Anda dapat mengabaikan error ini atau memodifikasi pernyataan SPL berdasarkan konten data.

Error data tidak menghentikan seluruh proses eksekusi. Pernyataan SPL tetap mengembalikan hasil, tetapi nilai field tempat error terjadi adalah null. Anda dapat mengabaikan error ini sesuai kebutuhan.

Timeout eksekusi

Pernyataan SPL berisi berbagai instruksi, dan waktu eksekusinya bervariasi tergantung skenario data. Jika total waktu eksekusi pernyataan SPL melebihi periode timeout default, eksekusi dihentikan dan error timeout dikembalikan. Dalam kasus ini, hasil eksekusi kosong. Periode timeout default dapat berbeda untuk kueri scan, konsumsi real-time, dan pengumpulan Logtail.

Jika Anda mengalami error ini, Anda dapat menyesuaikan pernyataan SPL untuk mengurangi kompleksitasnya, misalnya dengan menyederhanakan ekspresi reguler yang kompleks atau mengurangi jumlah pipeline.

Batas memori terlampaui

Pernyataan SPL berisi berbagai instruksi, dan konsumsi memorinya bervariasi tergantung skenario data. Eksekusi SPL dibatasi oleh kuota memori tertentu. Jika kuota ini terlampaui, eksekusi gagal dan error batas memori terlampaui dikembalikan. Dalam kasus ini, hasil eksekusi kosong. Kuota memori default dapat berbeda untuk kueri scan, konsumsi real-time, dan pengumpulan Logtail.

Jika Anda mengalami error ini, Anda dapat menyesuaikan pernyataan SPL untuk mengurangi kompleksitasnya, mengurangi jumlah pipeline, atau memeriksa apakah ukuran data mentah terlalu besar.