o2o-negosium-original/backend/run_local_pgwatch.sh
민헌 23cb8291bc chore(backend): 로컬 실행/부하테스트 스크립트 추가
- run_local_server.sh / run_local_locust.sh / run_local_pgwatch.sh (대화형, 메뉴 선택 방식)
- loadtest: self-register 방식 locustfile (가상 유저가 on_start 에서 계정 생성 → login/me/refresh)
- locust 스크립트가 부하용 공급사 보장·이전 부하계정/토큰 정리·LOAD_SUPPLIER_ID 주입을 자동 처리

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:17:37 +09:00

63 lines
2.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
#
# PostgreSQL 커넥션 모니터 (로그 방식). negosium_db 커넥션을 한 줄씩 쌓아가며 본다.
# 부하테스트(run_local_locust.sh) 중 별도 터미널에서 띄워 풀 사용량 추세를 관찰한다.
# (화면을 덮어쓰지 않으므로 스크롤로 이력을 그대로 볼 수 있다)
#
set -uo pipefail
cd "$(dirname "$0")" # backend/
# DB 접속 (local 기본값, 환경변수로 override 가능)
PGHOST="${PGHOST:-127.0.0.1}"
PGPORT="${PGPORT:-5432}"
PGUSER="${PGUSER:-postgres}"
PGDATABASE="${PGDATABASE:-negosium_db}"
q() { psql -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" -d "$PGDATABASE" "$@"; }
# 접속 확인
if ! q -tAc "SELECT 1" >/dev/null 2>&1; then
echo "[error] DB 접속 실패: $PGUSER@$PGHOST:$PGPORT/$PGDATABASE"
exit 1
fi
MAXCONN="$(q -tAc "SHOW max_connections;" 2>/dev/null | tr -d '[:space:]')"
MAXCONN="${MAXCONN:-0}"
read -rp "갱신 간격(초) [1]: " ITV; ITV="${ITV:-1}"
read -rp "로그 파일로도 저장 (경로, 비우면 화면만): " LOGF
echo "DB=$PGDATABASE max_connections=$MAXCONN (Ctrl+C 로 종료)"
echo " - total: 전체 커넥션 / active: 실행 중 / idle: 풀 유휴 / idle_tx: 트랜잭션 유휴(누수 의심)"
HEADER="시각 total active idle idle_tx"
echo "$HEADER"
[[ -n "$LOGF" ]] && { echo "# $HEADER" >>"$LOGF"; }
emit() { # 화면 + (옵션)파일
echo "$1"
[[ -n "$LOGF" ]] && echo "$1" >>"$LOGF"
}
# 우리 앱 풀 산식(참고): USER/PARTNER × R/W = 엔진 4벌 × (pool_size+max_overflow) = 최대 120 / 워커
while true; do
TS="$(date '+%H:%M:%S')"
# 상태별 카운트를 한 쿼리로(모니터 자신은 제외). 출력: "total active idle idle_tx"
ROW="$(q -tAF' ' -c "SELECT count(*),
count(*) FILTER (WHERE state='active'),
count(*) FILTER (WHERE state='idle'),
count(*) FILTER (WHERE state='idle in transaction')
FROM pg_stat_activity
WHERE datname='$PGDATABASE' AND pid <> pg_backend_pid();" 2>/dev/null)"
read -r TOTAL ACTIVE IDLE IDLETX <<<"${ROW:-0 0 0 0}"
TOTAL="${TOTAL:-0}"; ACTIVE="${ACTIVE:-0}"; IDLE="${IDLE:-0}"; IDLETX="${IDLETX:-0}"
PCT=0
if [[ "$MAXCONN" =~ ^[0-9]+$ && "$MAXCONN" -gt 0 ]]; then PCT=$(( TOTAL * 100 / MAXCONN )); fi
WARN=""
if (( PCT >= 80 )); then WARN=" <- max 임박!"; fi
emit "$(printf '%s %3s/%s (%3s%%) %5s %4s %4s%s' \
"$TS" "$TOTAL" "$MAXCONN" "$PCT" "$ACTIVE" "$IDLE" "$IDLETX" "$WARN")"
sleep "$ITV"
done