0Pricing
DevOps Bootcamp · บทเรียน

การคำนวณตัวชี้วัดและฮิสโตแกรมจากกระแสบันทึก

รวมอัตราคำขอ ค่าเปอร์เซ็นไทล์ และรายงานอันดับต้น ๆ โดยตรงจากข้อมูลบันทึกแบบสตรีม

การคำนวณตัวชี้วัดและฮิสโตแกรมจากกระแสบันทึก เป็นบทเรียน DevOps Bootcamp ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน DevOps Bootcamp และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงคำนวณเมตริกจากบันทึกดิบ

ระบบที่ใช้งานจริงสร้างบันทึกหลายพันบรรทัดต่อวินาที แทนที่จะส่งบันทึกดิบไปยังแพลตฟอร์มวิเคราะห์ข้อมูลราคาแพง คุณสามารถคำนวณ อัตราคำขอ ค่าเปอร์เซ็นไทล์ และรายงานอันดับสูงสุด N รายการ ได้โดยตรงในเชลล์ด้วยต้นทุนเกือบเป็นศูนย์

  • อัตราคำขอ: บริการของคุณรองรับคำขอกี่รายการต่อวินาทีหรือต่อนาที
  • ค่าเปอร์เซ็นไทล์ของเวลาแฝง: เวลาตอบสนอง p50/p95/p99 เป็นเท่าใด
  • รายงานอันดับสูงสุด N รายการ: จุดปลายทาง IP หรือรหัสข้อผิดพลาดใดปรากฏบ่อยที่สุด

เครื่องมือเชลล์อย่าง awk, sort, uniq และ bc ทำงานร่วมกันเป็นกระบวนการประมวลผลที่ทรงพลังและประกอบต่อกันได้ ซึ่งตอบคำถามเหล่านี้ได้จากกระแสบันทึกแบบสดหรือไฟล์ย้อนหลังโดยไม่ต้องออกจากเทอร์มินัล

โครงสร้างของบันทึกการเข้าถึงทั่วไป

เว็บเซิร์ฟเวอร์ส่วนใหญ่เขียนบันทึกในรูปแบบ Combined Log Format การทำความเข้าใจฟิลด์ต่าง ๆ เป็นพื้นฐานของกระบวนการประมวลผลเมตริกทุกชนิด:

127.0.0.1 - frank [10/Oct/2024:13:55:36 -0700] "GET /api/users HTTP/1.1" 200 2326 0.042
  • ฟิลด์ 1: IP ของไคลเอ็นต์
  • ฟิลด์ 4 (ในวงเล็บ): การประทับเวลา
  • ฟิลด์ 7 (ในเครื่องหมายอัญประกาศ): เมธอด HTTP + เส้นทาง
  • ฟิลด์ 9: รหัสสถานะ
  • ฟิลด์ 10: ไบต์ของการตอบกลับ
  • ฟิลด์ 11: เวลาตอบกลับเป็นวินาที (ฟิลด์กำหนดเอง ซึ่งอาจไม่มีเสมอไป)

ใช้ awk เพื่ออ้างอิงฟิลด์ตามตำแหน่ง ($1, $9 เป็นต้น) ฟิลด์ภายในเครื่องหมายอัญประกาศจะนับเป็นโทเค็นเดียวก็ต่อเมื่อแยกข้อมูลอย่างระมัดระวัง ให้ครอบบรรทัดบันทึกด้วย awk -F'"' หรือใช้การประมวลผลหลายรอบ

การนับอัตราคำขอต่อนาที

หากต้องการคำนวณ คำขอต่อนาที ให้แยกส่วนที่เป็นนาทีจากการประทับเวลาของแต่ละรายการแล้วนับจำนวนครั้งที่ปรากฏ รูปแบบ [day/Mon/year:HH:MM จะให้กลุ่มชั่วโมง:นาที

กระบวนการประมวลผลด้านล่างอ่าน access.log และพิมพ์ตาราง นาที → จำนวนคำขอ:

#!/usr/bin/env bash
# Requests per minute from an nginx/apache access log
# Usage: bash req_per_min.sh access.log

LOG="${1:-access.log}"

awk '{
    # Extract [day/Mon/year:HH:MM from field 4
    match($0, /\[([^:]+:[0-9]+:[0-9]+)/, arr)
    minute = arr[1]
    if (minute != "") count[minute]++
} END {
    for (m in count) print count[m], m
}' "$LOG" | sort -k2

อัตราแบบหน้าต่างเลื่อนด้วยกระแสข้อมูลสด

สำหรับการติดตามแบบ สด คุณต้องใช้หน้าต่างเลื่อน เคล็ดลับคือส่งข้อมูลจาก tail -f เข้า awk ซึ่งจะรีเซ็ตตัวนับทุก N วินาทีโดยใช้นาฬิการะบบ (systime())

ตัวอย่างนี้พิมพ์บรรทัดอัตราทุก 10 วินาที:

#!/usr/bin/env bash
# Live request rate — prints lines/10s from a tailed log
# Usage: bash live_rate.sh /var/log/nginx/access.log

LOG="${1:-/var/log/nginx/access.log}"
WINDOW=10

tail -f "$LOG" | awk -v win="$WINDOW" '
BEGIN { start = systime(); count = 0 }
{
    count++
    now = systime()
    if (now - start >= win) {
        printf "[%s] %d req/%ds (%.1f req/s)\n",
               strftime("%H:%M:%S", now), count, win, count/win
        count = 0
        start = now
    }
}'

การแยกค่าความหน่วงเพื่อคำนวณเปอร์เซ็นไทล์

การคำนวณเปอร์เซ็นไทล์จำเป็นต้องเรียงลำดับค่าความหน่วงที่สังเกตได้ทั้งหมด แนวทางมาตรฐานคือ:

  1. แยกคอลัมน์ความหน่วงออกมาเป็นรายการตัวเลขธรรมดา
  2. เรียงลำดับตามตัวเลข
  3. เลือกค่าที่อันดับถูกต้องโดยใช้การคำนวณจำนวนบรรทัด

สคริปต์ด้านล่างจะแยกฟิลด์ 11 (เวลาตอบกลับเป็นวินาที) และบันทึกลงในไฟล์ชั่วคราวเพื่อคำนวณเปอร์เซ็นไทล์ในขั้นตอนถัดไป:

#!/usr/bin/env bash
# Extract latency column from access log (field 11)
# Assumes last field on each line is response time in seconds

LOG="${1:-access.log}"
TMP=$(mktemp /tmp/latency_XXXXXX.txt)

awk '{ if ($NF ~ /^[0-9]+\.?[0-9]*$/) print $NF }' "$LOG" \
    | sort -n > "$TMP"

echo "Extracted $(wc -l < "$TMP") latency samples -> $TMP"
echo "$TMP"   # callers can read this file

การคำนวณ p50, p95 และ p99 ด้วย awk

เมื่อเรียงค่าความหน่วงแล้ว การเลือกเปอร์เซ็นไทล์เป็นการคำนวณทางเลขคณิต โดยเปอร์เซ็นไทล์ลำดับที่ p อยู่ที่แถว ceil(p/100 * N) คุณสามารถใช้ awk ล้วน ๆ ทำงานนี้ได้ในการประมวลผลรอบเดียว หลังโหลดไฟล์ที่เรียงลำดับแล้วลงในอาร์เรย์:

#!/usr/bin/env bash
# Compute p50 / p95 / p99 from a sorted latency file
# Usage: bash percentiles.sh latency_sorted.txt

# Demo: generate 1000 random latencies if no file given
if [[ $# -eq 0 ]]; then
    SORTED=$(mktemp)
    for i in $(seq 1 1000); do
        awk 'BEGIN { srand(); printf "%.4f\n", 0.001 + rand()*0.999 }'
    done | sort -n > "$SORTED"
else
    SORTED="$1"
fi

awk '
{ values[NR] = $1 }
END {
    n = NR
    if (n == 0) { print "No data"; exit }
    p50  = values[int(n * 0.50 + 0.9999)]
    p95  = values[int(n * 0.95 + 0.9999)]
    p99  = values[int(n * 0.99 + 0.9999)]
    printf "p50  = %.4fs\np95  = %.4fs\np99  = %.4fs\nN    = %d\n",
           p50, p95, p99, n
}' "$SORTED"

การสร้างรายงานจุดปลายทางอันดับสูงสุด N รายการ

รายงานอันดับสูงสุด N รายการ ตอบคำถามว่า "เส้นทางใดถูกเรียกใช้บ่อยที่สุด" รูปแบบคำสั่งเชลล์แบบคลาสสิกคือ:

  • awk เพื่อพิมพ์ฟิลด์ที่สนใจ (เช่น เส้นทาง URL)
  • sort เพื่อจัดกลุ่มค่าที่เหมือนกัน
  • uniq -c เพื่อนับค่าซ้ำที่อยู่ติดกัน
  • sort -rn เพื่อจัดอันดับตามจำนวนจากมากไปน้อย
  • head -n N เพื่อเลือก N อันดับแรก
#!/usr/bin/env bash
# Top-10 most requested URL paths from access log
# Usage: bash top_endpoints.sh access.log [N]

LOG="${1:-access.log}"
N="${2:-10}"

echo "=== Top $N endpoints ==="
awk -F'"' '{ print $2 }' "$LOG" \
    | awk '{ print $2 }' \
    | sort \
    | uniq -c \
    | sort -rn \
    | head -n "$N" \
    | awk '{ printf "%6d  %s\n", $1, $2 }'

อันดับสูงสุด N รายการตามรหัสสถานะ: มองเห็นข้อผิดพลาดได้ทันที

รหัสสถานะ HTTP บอกสถานะของบริการ การจัดกลุ่มบรรทัดบันทึกตามรหัสสถานะและนับจำนวนจะเผยให้เห็นว่าข้อผิดพลาดเกิดขึ้นน้อยครั้งหรือเกิดทั่วทั้งระบบ

สคริปต์ด้านล่างสร้างรายละเอียดแยกตามกลุ่ม 2xx/3xx/4xx/5xx ทั้งหมด:

#!/usr/bin/env bash
# Status code frequency breakdown
# Usage: bash status_breakdown.sh access.log

LOG="${1:-access.log}"

echo "=== HTTP Status Code Distribution ==="
awk '{ print $9 }' "$LOG" \
    | grep -E '^[0-9]{3}$' \
    | sort \
    | uniq -c \
    | sort -rn \
    | awk '{ printf "%6d  %s\n", $1, $2 }'

echo
echo "=== 5xx Error Spike Check ==="
awk '$9 ~ /^5/ { print $9, $7 }' "$LOG" \
    | sort | uniq -c | sort -rn | head -20

ฮิสโตแกรม ASCII ด้วย awk

ฮิสโตแกรมแบบข้อความทำให้การกระจายของค่าความหน่วงอ่านเข้าใจได้ทันทีในเทอร์มินัลหรือบันทึก CI แนวทางคือ:

  1. จัดค่าความหน่วงแต่ละค่าเข้าช่วง (เช่น 0-50ms, 50-100ms, …)
  2. นับจำนวนข้อมูลที่สังเกตได้ในแต่ละช่วง
  3. พิมพ์แถบอักขระ # โดยปรับขนาดตามจำนวนสูงสุด

วิธีนี้มีประโยชน์อย่างยิ่งสำหรับตรวจหาการกระจายแบบสองยอดหรือค่าผิดปกติโดยไม่ต้องใช้เครื่องมือสร้างกราฟ

#!/usr/bin/env bash
# ASCII latency histogram from a list of latency values in seconds
# Demo: generates synthetic data if no input file is provided

if [[ $# -eq 0 ]]; then
    # Generate 500 synthetic latencies (ms converted to s)
    python3 -c "
import random, math
for _ in range(500):
    # bimodal: fast cluster ~50ms, slow cluster ~300ms
    if random.random() < 0.75:
        v = max(1, random.gauss(50, 15))
    else:
        v = max(1, random.gauss(300, 80))
    print(f'{v/1000:.4f}')
" | sort -n | awk '
{ values[NR] = $1 * 1000 }  # convert to ms
END {
    buckets = 10; maxVal = 500
    step = maxVal / buckets
    for (i = 0; i < buckets; i++) hist[i] = 0
    for (i = 1; i <= NR; i++) {
        b = int(values[i] / step)
        if (b >= buckets) b = buckets - 1
        hist[b]++
    }
    maxCount = 0
    for (i = 0; i < buckets; i++) if (hist[i] > maxCount) maxCount = hist[i]
    print "Latency (ms)   Count   Distribution"
    print "---------------------------------------"
    for (i = 0; i < buckets; i++) {
        lo = i * step; hi = lo + step
        barLen = int(hist[i] / maxCount * 40)
        bar = ""
        for (j = 0; j < barLen; j++) bar = bar "#"
        printf "%4d-%4dms  %5d  %s\n", lo, hi, hist[i], bar
    }
}'
else
    echo "Usage: pipe a sorted latency file (in seconds) to this pattern"
fi

การรวมเมตริก: รายงานสรุปแบบคำสั่งเดียว

คู่มือปฏิบัติงานของระบบที่ใช้งานจริงมักต้องการคำสั่งเดียวที่แสดง เมตริกสำคัญทั้งหมดพร้อมกัน: อัตรา ค่าเปอร์เซ็นไทล์ของความหน่วง จุดปลายทางอันดับต้น ๆ และอัตราข้อผิดพลาด คุณสามารถประกอบสิ่งที่เรียนรู้มาทั้งหมดเป็นสคริปต์เดียวที่มนุษย์หรือระบบแจ้งเตือนเรียกใช้ได้

#!/usr/bin/env bash
# One-shot log summary report
# Usage: bash log_summary.sh access.log

LOG="${1:-access.log}"
[[ -f "$LOG" ]] || { echo "File not found: $LOG"; exit 1; }

TOTAL=$(wc -l < "$LOG")
ERRORS=$(awk '$9 ~ /^[45]/' "$LOG" | wc -l)
ERR_RATE=$(awk "BEGIN { printf \"%.1f\", ($ERRORS / ($TOTAL || 1)) * 100 }")

echo "====================================="
echo " Log Summary: $LOG"
echo "====================================="
printf " Total requests : %d\n" "$TOTAL"
printf " 4xx/5xx errors : %d (%.1f%%)\n" "$ERRORS" "$ERR_RATE"

echo
echo "--- Top 5 Endpoints ---"
awk -F'"' '{ print $2 }' "$LOG" | awk '{ print $2 }' \
    | sort | uniq -c | sort -rn | head -5 \
    | awk '{ printf "  %6d  %s\n", $1, $2 }'

echo
echo "--- Latency Percentiles ---"
awk '{ if ($NF ~ /^[0-9]+\.?[0-9]*$/) print $NF * 1000 }' "$LOG" \
    | sort -n \
    | awk '
{ v[NR]=$1 }
END {
  if (NR==0) { print "  No latency data"; exit }
  printf "  p50 = %.1fms\n", v[int(NR*0.50+0.9999)]
  printf "  p95 = %.1fms\n", v[int(NR*0.95+0.9999)]
  printf "  p99 = %.1fms\n", v[int(NR*0.99+0.9999)]
}'

การสตรีมเมตริกผ่านไพป์ที่มีชื่อและ tee

ในกระบวนการประมวลผลด้านการสังเกตการณ์ระบบ คุณมักต้องการ แยกกระจายกระแสบันทึก: เขียนบรรทัดดิบลงดิสก์และคำนวณเมตริกไปพร้อมกัน tee ร่วมกับไพป์ที่มีชื่อ (mkfifo) ทำให้ทำเช่นนี้ได้โดยไม่ต้องเก็บกระแสข้อมูลทั้งหมดไว้ในหน่วยความจำ

  • mkfifo /tmp/log_pipe — สร้างไพป์ที่มีชื่อ
  • tee /tmp/log_pipe | metric_consumer & — แยกแขนงหนึ่งไปยังตัวประมวลผลเมตริก
  • แขนงที่เหลือเขียนลงไฟล์จัดเก็บถาวร

รูปแบบนี้ทำให้การเขียนลงดิสก์และการรวมเมตริกแยกจากกัน และช่วยให้แต่ละส่วนเริ่มทำงานใหม่ได้อย่างอิสระ

#!/usr/bin/env bash
# Fan-out: write to archive AND count errors in real time
# Run: bash fanout_pipeline.sh /var/log/nginx/access.log

LOG="${1:-/var/log/nginx/access.log}"
ARCHIVE="/tmp/access_archive.log"
PIPE="/tmp/log_metrics_pipe"

# Clean up on exit
trap 'rm -f "$PIPE"' EXIT

mkfifo "$PIPE"

# Branch 1: count 5xx errors per minute from the pipe
awk '$9 ~ /^5/ {
    match($0, /\[([^:]+:[0-9]+:[0-9]+)/, arr)
    errors[arr[1]]++
} END {
    for (m in errors) printf "5xx errors at %s: %d\n", m, errors[m]
}' "$PIPE" &

# Branch 2: archive to disk + feed Branch 1 via pipe
tail -f "$LOG" | tee "$PIPE" >> "$ARCHIVE"

เทคนิค awk ใดคำนวณเปอร์เซ็นไทล์ p95 จากอาร์เรย์ที่เรียงลำดับของค่าความหน่วงจำนวน N ค่าได้อย่างถูกต้อง

คุณได้โหลดค่าความหน่วงจำนวน N ค่าที่เรียงลำดับแล้วลงในอาร์เรย์ awk v[1..N] นิพจน์ใดดึงค่าเปอร์เซ็นไทล์ p95ได้อย่างถูกต้อง

ทบทวนบทเรียน: เมตริกและฮิสโตแกรมจากกระแสล็อก

ในบทเรียนนี้ คุณได้สร้างไปป์ไลน์เมตริกที่สมบูรณ์โดยตรงใน Bash:

  • อัตราคำขอ: awk แยกช่วงนาทีจากประทับเวลาและนับจำนวนครั้งที่เกิดขึ้น ส่วน tail -f + systime() ให้อัตราในหน้าต่างเลื่อนแบบเรียลไทม์
  • เปอร์เซ็นไทล์ความหน่วง: แยกคอลัมน์ความหน่วง ใช้ sort -n จากนั้นเลือกแถวที่ ceil(p/100 * N) ด้วย int(N * p + 0.9999) ใน awk
  • รายงานอันดับต้น ๆ จำนวน N รายการ: ไปป์ไลน์คลาสสิก awk | sort | uniq -c | sort -rn | head -N ใช้ได้กับฟิลด์แบบหมวดหมู่ใด ๆ (เส้นทาง, IP, รหัสสถานะ)
  • ฮิสโตแกรม ASCII: จัดค่าลงถัง นับจำนวนในแต่ละช่วง และปรับความยาวแท่งตามจำนวนสูงสุดของถัง เพื่อให้เห็นการกระจายได้อย่างรวดเร็ว
  • การกระจายผลลัพธ์ด้วยไปป์ที่มีชื่อ: mkfifo + tee ช่วยให้คุณเก็บล็อกดิบและส่งข้อมูลให้ตัวประมวลผลเมตริกได้พร้อมกัน โดยไม่ต้องโหลดกระแสข้อมูลไว้ในหน่วยความจำ

องค์ประกอบพื้นฐานที่นำมาประกอบกันได้เหล่านี้ช่วยขจัดความจำเป็นในการใช้เครื่องมือภายนอกระหว่างเกิดเหตุขัดข้อง และเป็นแกนหลักของสคริปต์สังเกตการณ์ระบบขนาดเล็กที่ทำงานได้ทุกที่ที่ Bash ทำงาน

คำถามที่พบบ่อย

บทเรียน “การคำนวณตัวชี้วัดและฮิสโตแกรมจากกระแสบันทึก” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การคำนวณตัวชี้วัดและฮิสโตแกรมจากกระแสบันทึก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส DevOps Bootcamp ให้อัปเกรดเป็น CoddyKit PRO คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การคำนวณตัวชี้วัดและฮิสโตแกรมจากกระแสบันทึก”

รวมอัตราคำขอ ค่าเปอร์เซ็นไทล์ และรายงานอันดับต้น ๆ โดยตรงจากข้อมูลบันทึกแบบสตรีม คุณปฏิบัติ DevOps Bootcamp ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน DevOps Bootcamp หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน DevOps Bootcamp บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การคำนวณตัวชี้วัดและฮิสโตแกรมจากกระแสบันทึก” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน DevOps Bootcamp นี้ได้ไหม

ได้ บทเรียน DevOps Bootcamp ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การแยกวิเคราะห์บันทึกเว็บและแอปพลิเคชันในระดับใหญ่
  2. การติดตามบันทึกแบบเรียลไทม์และการแจ้งเตือนแบบสตรีม
  3. การสอบถาม journald ด้วย journalctl ในสคริปต์
  4. การคำนวณตัวชี้วัดและฮิสโตแกรมจากกระแสบันทึก
← กลับไปที่ DevOps Bootcamp