CloudWatch Logs Insights
Logs Insights memberi bahasa kueri untuk log CloudWatch. Digabung dengan log terstruktur, ia mengubah investigasi dari menit jadi detik.
Intisari
- Kueri disusun dari perintah yang dirangkai dengan
|:fields,filter,stats,sort,limit. - Log berformat JSON di-parse otomatis — field-nya langsung bisa dikueri.
- Ini alasan konkret memakai log terstruktur, bukan
print(). - Bisa mengueri banyak log group sekaligus — berguna untuk menelusuri satu permintaan lintas Lambda.
- Ditagih berdasarkan jumlah data yang dipindai; persempit rentang waktu sebelum menjalankan.
Log terstruktur dulu
import json
import logging
log = logging.getLogger()
log.setLevel("INFO")
def catat(peristiwa: str, **field):
log.info(json.dumps({"peristiwa": peristiwa, **field}, ensure_ascii=False))
catat("bedrock_selesai",
request_id=context.aws_request_id,
model=MODEL_ID,
token_masuk=resp["usage"]["inputTokens"],
token_keluar=resp["usage"]["outputTokens"],
latensi_ms=resp["metrics"]["latencyMs"],
potongan=len(potongan),
guardrail=diblokir)
Inilah imbalan konkret dari log terstruktur. Baris log berbentuk JSON di-parse otomatis, sehingga
token_keluar langsung jadi field yang bisa difilter dan diagregasi. Log berupa kalimat bebas
seperti print(f"selesai, {n} token") tidak bisa dikueri tanpa regex yang rapuh.
Kueri yang langsung terpakai
-- Biaya token per model, satu jam terakhir
fields @timestamp, model, token_masuk, token_keluar
| filter peristiwa = "bedrock_selesai"
| stats sum(token_masuk) as masuk,
sum(token_keluar) as keluar,
count(*) as permintaan
by model
-- Permintaan paling lambat
fields @timestamp, request_id, latensi_ms, token_keluar
| filter peristiwa = "bedrock_selesai"
| sort latensi_ms desc
| limit 20
-- Persentil latensi per 5 menit
filter peristiwa = "bedrock_selesai"
| stats pct(latensi_ms, 50) as p50,
pct(latensi_ms, 99) as p99
by bin(5m)
-- Menelusuri satu permintaan lintas seluruh komponen
fields @timestamp, @log, @message
| filter request_id = "abc-123-def"
| sort @timestamp asc
Perintah yang perlu dihafal
| Perintah | Gunanya |
|---|---|
fields | Memilih dan menghitung field |
filter | Menyaring baris |
stats … by … | Agregasi: sum, avg, count, pct |
bin(5m) | Mengelompokkan per rentang waktu |
parse | Mengambil bagian dari teks yang tidak terstruktur |
sort, limit | Mengurutkan dan memotong |
@log | Log group asal — penting saat mengueri banyak group |
Biaya
Logs Insights ditagih berdasarkan jumlah data yang dipindai. Kueri tanpa filter atas rentang
tujuh hari bisa mahal. Tiga kebiasaan yang menekan biayanya:
- Persempit rentang waktu sebelum menjalankan, bukan sesudah.
- Taruh
filtersedini mungkin di rangkaian. - Simpan kueri yang sering dipakai supaya tidak diketik ulang dengan rentang yang terlalu lebar.
Dari kueri jadi metrik
Kalau sebuah kueri kamu jalankan berulang-ulang, ubah jadi metric filter. Ia mengubah pola di log jadi metrik CloudWatch yang bisa dipasangi alarm — sehingga kamu berhenti memeriksa manual.
log_group.add_metric_filter(
"GuardrailIntervensi",
filter_pattern=logs.FilterPattern.string_value("$.guardrail", "=", "true"),
metric_namespace="AsistenHR",
metric_name="GuardrailIntervensi",
)
Latihan: ubah seluruh print() di aplikasimu jadi log JSON terstruktur, lalu tulis tiga
kueri: biaya token per model, p99 latensi per 5 menit, dan jumlah intervensi guardrail per jam. Simpan
ketiganya, dan ubah yang ketiga jadi metric filter beserta alarmnya.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.