Pertanyaan umum dan solusi untuk melakukan kueri serta analisis log berformat JSON di Simple Log Service, termasuk konfigurasi indeks, fungsi JSON, dan penanganan array JSON.
Contoh log
Contoh dalam topik ini menggunakan log JSON dari sistem pemrosesan pesanan.
-
Bidang request berisi informasi permintaan pesanan dalam format JSON. Satu permintaan dapat mencakup beberapa pesanan untuk satu pengguna, masing-masing dengan produk yang dibeli dan total pembayaran.
-
Bidang response berisi hasil pemrosesan pesanan.
-
Jika permintaan berhasil, nilai bidang response adalah SUCCESS.
-
Jika permintaan gagal, nilai bidang response berada dalam format JSON dan berisi informasi `errcode` dan `msg`.
-
Anda dapat menggunakan Logtail untuk Mengumpulkan log dalam mode JSON ke Simple Log Service untuk kueri dan analisis.
Cara mengonfigurasi indeks
Anda harus mengonfigurasi indeks sebelum melakukan kueri atau analisis data log. Saat mengonfigurasi indeks untuk log JSON, pertimbangkan poin-poin berikut.
Cara memilih jenis indeks
Simple Log Service mendukung indeks teks penuh dan indeks bidang. Pilih jenis indeks berdasarkan kriteria berikut. Buat indeks.
-
Untuk melakukan kueri pada semua bidang, buat indeks teks penuh. Untuk melakukan kueri hanya pada bidang tertentu, buat indeks bidang untuk bidang target guna mengurangi biaya.
-
Untuk melakukan analisis SQL pada suatu bidang, buat indeks untuk bidang tersebut dan aktifkan statistik.
Saat indeks teks penuh dan indeks bidang dikonfigurasi secara bersamaan, indeks bidang akan diprioritaskan untuk bidang yang memiliki indeks tersebut.
Sebagai contoh, untuk menganalisis bidang request dan response, Anda dapat membuat indeks bidang untuk keduanya dan mengaktifkan statistik.
Cara memilih tipe data untuk suatu bidang dalam konfigurasi indeks
Saat mengonfigurasi indeks, Anda dapat mengatur tipe data suatu bidang menjadi text, long, double, atau JSON. Tipe data.
Pertimbangkan hal berikut saat menetapkan tipe data untuk bidang JSON.
-
Jika nilai bidang tidak dalam format JSON standar tetapi berisi konten JSON, atur tipe datanya menjadi text. Jika nilainya dalam format JSON standar, atur tipe datanya menjadi JSON.
CatatanUntuk log JSON yang tidak sepenuhnya valid, Simple Log Service dapat mengurai bagian yang valid.
-
Setelah mengatur tipe data menjadi JSON, Anda dapat membuat indeks untuk node daun (leaf node) di dalam objek JSON guna mempercepat kueri. Hal ini menimbulkan biaya indeks tambahan.
-
Simple Log Service mendukung indeks untuk node daun dalam objek JSON, tetapi tidak untuk node anak yang berisi node daun.
-
Simple Log Service tidak mendukung indeks untuk bidang yang nilainya berupa array JSON, atau untuk bidang di dalam array JSON.
Berdasarkan contoh log, Anda dapat membuat indeks berikut.
-
Bidang request
-
request: Nilainya dalam format JSON. Atur tipe data menjadi JSON dan aktifkan statistik.
-
request.clientIp: Bidang ini sering dianalisis. Buat indeks terpisah untuknya, atur tipe data menjadi text, dan aktifkan statistik.
-
request.http.path: Bidang ini jarang dianalisis. Jangan buat indeks terpisah untuknya. Saat perlu menganalisisnya, Anda dapat menguraikannya langsung menggunakan fungsi JSON.
-
request.param: Bidang ini merupakan node anak yang berisi node daun. Anda tidak dapat membuat indeks untuknya.
-
request.param.userId: Bidang ini sering dianalisis. Buat indeks terpisah untuknya, atur tipe data menjadi text, dan aktifkan statistik.
-
request.param.orders: Nilainya berupa array JSON. Anda tidak dapat membuat indeks untuk bidang ini.
-
-
Bidang response
Nilai bidang response tidak selalu dalam format JSON. Atur tipe datanya menjadi text dan aktifkan statistik.

Setelah membuat indeks, log yang baru dikumpulkan akan muncul dalam format seperti di bawah ini.
Cara mengatur alias
Jika jalur (path) node daun JSON panjang, Anda dapat mengatur alias untuknya. Alias kolom.
-
Nama bidang dan alias harus unik di seluruh bidang dalam konfigurasi indeks.
-
Untuk bidang bertipe JSON, keunikan nama node daun ditentukan oleh jalur lengkapnya. Misalnya, jika Anda mengatur alias bidang response menjadi clientIp, sistem tidak menganggap alias ini sebagai duplikat dari nama bidang request.clientIp.
Cara melakukan kueri dan analisis pada bidang JSON yang telah diindeks
Pernyataan kueri dan analisis menggunakan format pernyataan kueri|pernyataan analitik. Dalam pernyataan analitik, sertakan nama bidang dalam tanda kutip ganda ("") dan string dalam tanda kutip tunggal (''). Tentukan jalur lengkap untuk bidang target, seperti Key1.Key2.Key3. Contoh: request.clientIp dan request.param.userId. Kueri dan analisis log JSON.
Sebagai contoh, untuk menemukan alamat IP klien untuk pengguna 186499, eksekusi pernyataan berikut.
*
and request.param.userId: 186499 |
SELECT
distinct("request.clientIp")
Hasil kueri dan analisis ditampilkan di bawah ini.
Kapan menggunakan fungsi JSON
Untuk set data besar dengan struktur JSON kompleks namun tetap yang memerlukan performa tinggi, buat indeks bidang untuk node daun JSON. Untuk set data kecil, gunakan fungsi JSON tanpa indeks bidang guna menghemat biaya. Fungsi JSON memungkinkan pemrosesan dan analisis dinamis terhadap log JSON. Dalam beberapa kasus, hanya fungsi JSON yang dapat digunakan untuk kueri dan analisis.
-
Nilai bidang tidak selalu dalam format JSON atau memerlukan pra-pemrosesan.
Sebagai contoh, bidang response berisi JSON dengan bidang errcode hanya ketika permintaan gagal. Untuk menganalisis distribusi errcode, filter log permintaan gagal terlebih dahulu, lalu gunakan fungsi JSON untuk mengekstrak errcode.
* not response :SUCCESS | SELECT json_extract_scalar(response, '$.errcode') AS errcodeHasil kueri dan analisis ditampilkan di bawah ini.

-
Untuk node JSON yang tidak mendukung pengindeksan, Anda hanya dapat menggunakan fungsi JSON untuk analisis real-time. Contohnya adalah bidang request.param dan request.param.orders.
Cara memilih antara fungsi json_extract dan json_extract_scalar
Kedua fungsi `json_extract` dan `json_extract_scalar` mengekstrak konten dari objek atau array JSON. Perbedaan utamanya:
-
`json_extract` mengembalikan tipe JSON; `json_extract_scalar` mengembalikan tipe varchar.
CatatanIni mengacu pada tipe data SQL (varchar, bigint, boolean, JSON, array, date), yang berbeda dari tipe data indeks SLS. Gunakan fungsi `typeof` untuk melihat tipe data objek SQL. Fungsi typeof.
-
`json_extract` dapat mengurai sub-struktur apa pun dari objek JSON. `json_extract_scalar` hanya mengurai node daun skalar (string, Boolean, atau angka) dan mengembalikan string yang sesuai.
Untuk mengekstrak bidang clientIp dari bidang request, Anda dapat menggunakan salah satu fungsi tersebut.
-
Gunakan `json_extract` untuk mengekstrak data.
* | SELECT json_extract(request, '$.clientIp')Hasil kueri dan analisis ditampilkan di bawah ini.

-
Gunakan `json_extract_scalar` untuk mengekstrak data.
* | SELECT json_extract_scalar(request, '$.clientIp')Hasil kueri dan analisis ditampilkan di bawah ini.

Untuk mengekstrak bagian pertama dari nilai clientIp, pertama-tama gunakan `json_extract_scalar` untuk mengekstrak clientIp, lalu gunakan `split_part` untuk mengekstrak angka pertama. Anda tidak dapat menggunakan `json_extract` di sini karena `split_part` memerlukan input bertipe varchar.
* |
SELECT
split_part(
json_extract_scalar(request, '$.clientIp'),
'.',
1
) AS segment
Hasil kueri dan analisis ditampilkan di bawah ini.
Dalam kebanyakan kasus, gunakan `json_extract_scalar` — tipe pengembaliannya (varchar) mudah digabungkan dengan fungsi lain. Gunakan `json_extract` saat menganalisis struktur JSON itu sendiri. Sebagai contoh, untuk menghitung jumlah pesanan dalam satu permintaan (panjang array JSON request.param.orders):
* |
SELECT
json_array_length((json_extract(request, '$.param.orders')))
Hasil kueri dan analisis ditampilkan di bawah ini.
`json_extract_scalar` mengembalikan tipe varchar. Sebagai contoh, angka 2 dalam hasil sebelumnya bertipe varchar. Untuk melakukan perhitungan seperti penjumlahan, pertama-tama gunakan `cast` untuk mengonversinya menjadi bigint. Fungsi konversi tipe.
Cara mengatur json_path
Saat menggunakan fungsi seperti `json_extract`, tentukan `json_path` untuk menunjukkan bagian mana dari objek JSON yang akan diekstrak. Formatnya adalah $.a.b, di mana `$` merepresentasikan node root dan tanda titik (.) merujuk ke node anak.
Jika nama bidang JSON mengandung karakter khusus (seperti http.path, http path, atau http-path), gunakan tanda kurung siku `[]` menggantikan titik dan sertakan nama bidang dalam tanda kutip ganda. Contoh: * |SELECT json_extract_scalar(request, '$["http.path"]').
Saat melakukan kueri melalui SDK, escape tanda kutip ganda tersebut. Contoh: * | select json_extract_scalar(request, '$[\"http.path\"]').
Untuk mengekstrak elemen dari array JSON, gunakan tanda kurung siku `[]` dengan indeks berbasis nol. Contoh:
-
Lihat pembayaran untuk pesanan pertama pengguna.
* | SELECT json_extract_scalar(request, '$.param.orders[0].payment')Hasil kueri dan analisis ditampilkan di bawah ini.

-
Lihat produk kedua yang dibeli dalam pesanan pertama pengguna.
* | SELECT json_extract_scalar(request, '$.param.orders[0].commodity[1]')Hasil kueri dan analisis ditampilkan di bawah ini.

Cara menganalisis array JSON
Untuk menganalisis array JSON, gabungkan `cast` dengan klausa `UNNEST` untuk memperluas array, lalu agregasi hasilnya.
Contoh 1
Untuk menghitung total pembayaran untuk semua pesanan yang berhasil:
-
Filter permintaan yang berhasil dan ekstrak bidang orders menggunakan `json_extract`.
* and response: SUCCESS | SELECT json_extract(request, '$.param.orders')Hasil kueri dan analisis ditampilkan di bawah ini.

-
Konversi array JSON menjadi tipe array.
* and response: SUCCESS | SELECT cast( json_extract(request, '$.param.orders') AS array(json) )Hasil kueri dan analisis ditampilkan di bawah ini.

-
Gunakan `UNNEST` untuk memperluas array.
* and response: SUCCESS | SELECT orderinfo FROM log, unnest( cast( json_extract(request, '$.param.orders') AS array(json) ) ) AS t(orderinfo)Hasil kueri dan analisis ditampilkan di bawah ini.

-
Ekstrak nilai payment menggunakan `json_extract_scalar`, konversi ke bigint, lalu jumlahkan.
* and response: SUCCESS | SELECT sum( cast( json_extract_scalar(orderinfo, '$.payment') AS bigint ) ) FROM log, unnest( cast( json_extract(request, '$.param.orders') AS array(json) ) ) AS t(orderinfo)Hasil kueri dan analisis ditampilkan di bawah ini.

Contoh 2
Untuk menghitung jumlah setiap produk dalam semua permintaan yang berhasil: ekstrak bidang orders, konversi ke `array(json)`, lalu perluas dengan `UNNEST`. Setiap baris merepresentasikan satu pesanan. Kemudian ekstrak bidang commodity, konversi dan perluas lagi. Setiap baris merepresentasikan satu produk. Terakhir, kelompokkan dan hitung.
*
and response: SUCCESS |
SELECT
item,
count(1) AS cnt
FROM (
SELECT
orderinfo
FROM log,
unnest(
cast(
json_extract(request, '$.param.orders') AS array(json)
)
) AS t(orderinfo)
),
unnest(
cast(
json_extract(orderinfo, '$.commodity') AS array(json)
)
) AS t(item)
GROUP BY
item
ORDER BY
cnt DESC
Hasil kueri dan analisis ditampilkan di bawah ini.
