0Pricing
DevOps Bootcamp · 강의

로그 스트림에서 지표 및 히스토그램 계산

스트리밍 로그 데이터에서 직접 요청률, 백분위수 및 상위 N개 보고서를 집계합니다.

로그 스트림에서 지표 및 히스토그램 계산은(는) CoddyKit의 무료 DevOps Bootcamp 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 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로 파이프하고 시스템 시계(systime())를 사용하여 N초마다 카운터를 재설정하는 것입니다.

이 예제는 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

awk로 p50, p95 및 p99 계산하기

지연 시간 값을 정렬한 후에는 산술 계산으로 백분위수를 선택합니다. 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 상태 코드는 서비스의 상태를 알려 줍니다. 로그 줄을 상태 코드별로 그룹화하고 개수를 세면 errors가 드문지 아니면 시스템 전반의 문제인지 알 수 있습니다.

아래 스크립트는 모든 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

awk로 ASCII 히스토그램 만들기

텍스트 히스토그램을 사용하면 터미널이나 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를 통한 메트릭 스트리밍

관찰 가능성 파이프라인에서는 로그 스트림을 분기해야 하는 경우가 많습니다. 원시 줄을 디스크에 기록하는 동시에 메트릭을 계산하는 방식입니다. 명명된 파이프(mkfifo)와 tee를 사용하면 전체 스트림을 메모리에 버퍼링하지 않고도 이를 수행할 수 있습니다.

  • 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"

정렬된 N개 지연 시간 값 배열에서 p95 백분위수를 올바르게 계산하는 awk 기법은 무엇입니까?

N개의 정렬된 지연 시간 값을 awk 배열 v[1..N]에 불러왔습니다. p95 백분위수를 올바르게 가져오는 표현식은 무엇입니까?

강의 요약: 로그 스트림의 메트릭과 히스토그램

이 강의에서는 Bash에서 직접 완전한 메트릭 파이프라인을 구축했습니다.

  • 요청률: awk로 타임스탬프에서 분 단위 구간을 추출하고 발생 횟수를 계산합니다. tail -f와 systime()을 함께 사용하면 실시간 슬라이딩 윈도우 요청률을 얻을 수 있습니다.
  • 지연 시간 백분위수: 지연 시간 열을 추출하고 sort -n으로 정렬한 다음, awk에서 int(N * p + 0.9999)를 사용해 ceil(p/100 * N) 위치의 행을 선택합니다.
  • 상위 N개 보고서: 일반적인 awk | sort | uniq -c | sort -rn | head -N 파이프라인은 범주형 필드(경로, IP, 상태 코드)에 모두 사용할 수 있습니다.
  • ASCII 히스토그램: 값을 구간으로 나누고 각 구간의 개수를 센 다음, 한눈에 분포를 확인할 수 있도록 최대 구간 개수에 맞춰 막대 길이를 조정합니다.
  • 이름 있는 파이프를 사용한 팬아웃: mkfifo와 tee를 사용하면 스트림을 메모리에 적재하지 않고 원시 로그를 보관하는 동시에 메트릭 소비자에게 전달할 수 있습니다.

이처럼 조합 가능한 기본 요소를 사용하면 장애 상황에서 외부 도구가 필요하지 않으며, Bash가 실행되는 어디에서나 작동하는 경량 관측성 스크립트의 기반을 마련할 수 있습니다.

자주 묻는 질문

“로그 스트림에서 지표 및 히스토그램 계산” 강의는 무료인가요?

네 — “로그 스트림에서 지표 및 히스토그램 계산” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 DevOps Bootcamp 강의 전체를 잠금 해제할 수 있습니다. DevOps Bootcamp 강의에는 총 4개의 강의가 포함되어 있습니다.

“로그 스트림에서 지표 및 히스토그램 계산”에서 뭘 배우나요?

스트리밍 로그 데이터에서 직접 요청률, 백분위수 및 상위 N개 보고서를 집계합니다. 브라우저에서 직접 실행하는 실습 코드로 DevOps Bootcamp을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

DevOps Bootcamp을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 DevOps Bootcamp은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“로그 스트림에서 지표 및 히스토그램 계산” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 DevOps Bootcamp 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 DevOps Bootcamp 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 대규모 웹 및 애플리케이션 로그 분석
  2. 실시간 로그 추적 및 스트리밍 알림
  3. 스크립트에서 journalctl로 journald 조회
  4. 로그 스트림에서 지표 및 히스토그램 계산
← DevOps Bootcamp(으)로 돌아가기