PromQL จากศูนย์
PromQL (Prometheus Query Language) คือภาษาที่ใช้ถามข้อมูลจาก Prometheus มันดูแปลกตาตอนแรก แต่พอเข้าใจ 4-5 concept ก็ใช้ได้ 90% ของงานจริง บทนี้ปูจากศูนย์
ทุก query ในบทนี้ลองพิมพ์เล่นได้ที่ Prometheus UI (
http://localhost:9090) หลังทำ lab-metrics-01 หรือใน Grafana Explore — เรียน PromQL ต้องลองพิมพ์เอง
4 ชนิดของค่าที่ query คืนมา
- Instant vector — ค่า ณ เวลาปัจจุบัน 1 ค่าต่อ series (พบบ่อยสุด)
- Range vector — ค่าในช่วงเวลา เช่น 5 นาทีย้อนหลัง (ใช้กับ
rate()) เขียนด้วย[5m] - Scalar — เลขตัวเดียว
- String — ไม่ค่อยใช้
ระดับ 1: เลือก series (selector)
# ทุก series ของ metric นี้
http_requests_total
# filter ด้วย label (= ตรงตัว)
http_requests_total{status="500"}
# หลาย label + regex (=~ คือ match regex, != คือไม่เท่า)
http_requests_total{status=~"5..", method="POST"}
# range vector: ข้อมูล 5 นาทีย้อนหลัง
http_requests_total[5m]
| ตัวดำเนินการ | ความหมาย |
|---|---|
= |
เท่ากับพอดี |
!= |
ไม่เท่ากับ |
=~ |
match regex |
!~ |
ไม่ match regex |
ระดับ 2: rate() — หัวใจของ counter
จำจากบทที่ 13: ค่าดิบของ counter ไม่มีความหมาย เราต้องการ อัตราการเพิ่ม → ใช้ rate()
# request ต่อวินาที เฉลี่ยในช่วง 5 นาที
rate(http_requests_total[5m])
rate() คำนวณ "เพิ่มขึ้นกี่หน่วยต่อวินาที" โดยเฉลี่ยในหน้าต่างเวลาที่ให้ และฉลาดพอที่จะจัดการตอน counter reset (แอป restart) ให้ด้วย
rate()vsirate():rate()เฉลี่ยทั้งช่วง (กราฟเนียน เหมาะทำ dashboard/alert) ·irate()ใช้แค่ 2 จุดล่าสุด (ไวต่อการเปลี่ยนแปลง เหมาะดู spike แต่กราฟกระตุก) — ใช้rate()เป็นหลัก
หน้าต่างใน
[5m]ต้องกว้างกว่า scrape interval อย่างน้อย ~4 เท่า (เช่น scrape 15s → ใช้[1m]ขึ้นไป) ไม่งั้นข้อมูลในหน้าต่างน้อยเกินจนคำนวณเพี้ยน
ระดับ 3: aggregation — ยุบหลาย series เป็นภาพรวม
ปกติ metric มีหลาย series (แยกตาม instance, path, ...) เรามักอยากรวม:
# รวม request rate ของทุก series เป็นตัวเลขเดียว
sum(rate(http_requests_total[5m]))
# รวมแล้วแยกตาม status (เก็บ label status ไว้ ยุบตัวอื่น)
sum by (status) (rate(http_requests_total[5m]))
# ยุบทุกอย่างยกเว้น instance
sum without (path, method) (rate(http_requests_total[5m]))
operator รวมกลุ่มที่ใช้บ่อย: sum, avg, max, min, count
by (...)= "เก็บ label พวกนี้ไว้ ยุบที่เหลือ" ·without (...)= "ยุบ label พวกนี้ เก็บที่เหลือ" — สองคำนี้คือกุญแจของ PromQL ที่คนใหม่งงบ่อยสุด
ระดับ 4: คำนวณ error rate (RED ในชีวิตจริง)
รวมทุกอย่างข้างบนเป็น query ที่ใช้จริงบ่อยที่สุด — สัดส่วน error:
# error rate = (5xx ต่อวิ) / (ทั้งหมดต่อวิ)
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
ผลลัพธ์ 0.01 = error 1% ตรงกับ SLO ในบทที่ 12 เป๊ะ
ระดับ 5: percentile จาก histogram
จำ histogram_quantile() จากบทที่ 13 — นี่คือวิธีได้ p95/p99 latency:
# p95 latency (วินาที)
histogram_quantile(
0.95,
sum by (le) (rate(http_request_duration_seconds_bucket[5m]))
)
leคือ label ของ histogram bucket ("less than or equal") — ต้องเก็บleไว้ตอน sum เสมอ- เปลี่ยน
0.95เป็น0.5(p50),0.99(p99) ได้
Recording Rules — precompute query หนัก
query ซับซ้อนที่ dashboard/alert เรียกบ่อย ควรคำนวณไว้ล่วงหน้าเป็น metric ใหม่ ด้วย recording rule — ช่วยให้ dashboard เร็วขึ้นมาก:
groups:
- name: api-aggregations
interval: 30s
rules:
- record: job:http_error_rate:ratio5m
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))
หลังจากนี้ใน dashboard เรียกแค่ job:http_error_rate:ratio5m (มี convention ตั้งชื่อ level:metric:operation)
Cheat sheet ที่ใช้จริง 90%
| อยากได้ | query |
|---|---|
| request/วิ รวม | sum(rate(http_requests_total[5m])) |
| error rate % | sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) |
| p99 latency | histogram_quantile(0.99, sum by(le)(rate(http_request_duration_seconds_bucket[5m]))) |
| CPU ใช้ต่อ instance | 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) |
| memory ใช้ % | (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 |
| target ที่ down | up == 0 |
สรุป
- ค่าที่คืนมามี instant vector (ตอนนี้) และ range vector (
[5m], ใช้กับ rate) rate(counter[5m])= อัตราต่อวินาที — ใช้เสมอกับ counter, อย่าดูค่าดิบsum by (label)= รวม series แล้วเก็บ label ที่ต้องการ- error rate =
sum(rate(5xx)) / sum(rate(total)) - p99 =
histogram_quantile(0.99, sum by(le)(rate(..._bucket[5m]))) - recording rules precompute query หนักให้ dashboard เร็ว
บทหน้า: จะได้ metric มา query ต้องมี exporters & instrumentation — แหล่งที่มาของ metric ทั้งหมด