LogQL adalah bahasa query Loki untuk memilih, memfilter, dan mengagregasi log. Episode ini membahas stream selector dan label matcher, line filter, parser json dan logfmt, metrik log seperti rate dan count_over_time, serta teknik optimasi performa query.

Loki menyimpan log, dan untuk membacanya kalian butuh bahasa query: LogQL. Berbeda dari bahasa query pada umumnya, LogQL bekerja dalam dua lapisan — memilih aliran log berdasarkan label, lalu memfilter dan memparsing isi baris di dalam aliran tersebut.
Episode ini membangun kemampuan LogQL dari nol: stream selector, line filter, parser expression, metrik log, sampai teknik optimasi. Dengan LogQL, kalian bisa mengubah kumpulan log mentah menjadi jawaban — berapa error dalam satu jam, atau berapa latency rata-rata per service.
Setiap query LogQL dimulai dengan memilih aliran log menggunakan label:
{job="checkout"}
{service="payment", level="error"}
{job=~"checkout|cart"}Notasi {job="checkout"} sama konsepnya dengan selector label Prometheus — gabungan matcher =, !=, =~, dan !~ untuk label.
Setelah memilih aliran, kalian bisa memfilter baris berdasarkan isinya:
{job="checkout"} |= "error"
{job="checkout"} |~ "timeout|refused"
{job="checkout"} != "debug"Operator |=, |~, !=, dan !~ memfilter baris tanpa parsing. {job="checkout"} |= "error" mengembalikan hanya baris yang mengandung kata error.
Untuk membaca field dari log terstruktur, gunakan parser:
{job="checkout"} |= "error" | json
{job="checkout"} | json level="lvl" | lvl="error"
{job="checkout"} | logfmtParser json mengekstrak semua field JSON menjadi label query sementara. Bisa juga dipetakan ulang seperti json level="lvl" agar nama field konsisten.
Untuk log semi-terstruktur, gunakan parser pattern:
{job="api"} | pattern "<method> <path> <status> <duration>"Parser pattern memakai template posisi untuk mengekstrak field. Pola ini sangat efisien untuk log akses server.
LogQL memiliki dua hasil:
{job="checkout"} |= "error".Fungsi metrik log yang paling sering dipakai:
count_over_time({job="checkout"} |= "error" [5m])
rate({job="checkout"} |= "error" [5m])
bytes_over_time({job="checkout"} [5m])Query count_over_time({job="checkout"} |= "error" [5m]) menghitung jumlah baris error dalam 5 menit — persis seperti pola RED errors.
Untuk menghitung nilai numerik dari field log, gunakan unwrap:
avg_over_time({job="api"} | json | unwrap duration [5m])
sum(rate({job="api"} | json | unwrap duration [5m]))Kombinasi | json | unwrap duration mengekstrak field duration lalu menghitung statistiknya — mirip histogram dari data log.
LogQL bisa menulis ulang label dengan label_format dan menggabungkan dua query dengan operator binary:
{job="checkout"} | label_format env=service_name
sum(rate({service="payment"} [5m])) / sum(rate({service="orders"} [5m]))Hasil binary operation bisa digabungkan dengan variabel templating Grafana untuk dashboard dinamis.
Beberapa kebiasaan agar query LogQL tetap cepat:
|= "error" lebih murah daripada parse lalu filter.Tip
Saat mendebug query di Grafana Explore, mulai dari stream selector yang sempit lalu perluas bertahap. Tambahkan filter baris dulu, baru parser — pola ini menghemat waktu evaluasi di sisi Loki.
Di episode 10 ini kalian menguasai LogQL: memilih aliran dengan stream selector, memfilter baris dengan operator filter, mengekstrak field dengan parser json, logfmt, dan pattern, menghitung metrik dari log, serta menerapkan teknik optimasi performa.
Inti yang harus dibawa pulang:
Di episode 11 selanjutnya kita akan membahas mengumpulkan log dengan Grafana Alloy — pengganti Grafana Agent, arsitektur komponen berbasis River, metode koleksi dari file dan Docker, proses parsing dan enrichment, hingga pengiriman log ke Loki dengan remote write. Query LogQL kalian akan segera punya sumber data yang terus mengalir.