데브포일 홈
DEV MODE - 실서버 영향 없음 📦 배포 관리
고객별 사용량 추적 & 분석
+250 XP
LEVEL 54 QUEST

고객별 사용량 추적 & 분석

usage_logs 테이블 설계, API 호출 로깅 미들웨어, 사용량 집계 쿼리, 초과 알림 및 고객 행동 분석을 구현합니다.

usage_logs 테이블 설계

사용량 로그 데이터 모델

SaaS 서비스에서 고객별 API 사용량을 정확하게 추적하려면 모든 API 호출을 기록하는 로그 테이블이 필요합니다. 성능을 위해 파티셔닝과 인덱스 전략을 함께 설계합니다.

-- usage_logs 테이블 생성 CREATE TABLE usage_logs ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, customer_id INT UNSIGNED NOT NULL, endpoint VARCHAR(255) NOT NULL, method ENUM('GET', 'POST', 'PUT', 'DELETE') NOT NULL, status_code SMALLINT NOT NULL, response_time INT UNSIGNED NOT NULL COMMENT '밀리초', request_size INT UNSIGNED DEFAULT 0, response_size INT UNSIGNED DEFAULT 0, ip_address VARCHAR(45), user_agent VARCHAR(500), api_key_id INT UNSIGNED, called_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX idx_customer_date (customer_id, called_at), INDEX idx_endpoint (endpoint, called_at), INDEX idx_status (status_code, called_at), FOREIGN KEY (customer_id) REFERENCES customers(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 PARTITION BY RANGE (TO_DAYS(called_at)) ( PARTITION p202601 VALUES LESS THAN (TO_DAYS('2026-02-01')), PARTITION p202602 VALUES LESS THAN (TO_DAYS('2026-03-01')), PARTITION p202603 VALUES LESS THAN (TO_DAYS('2026-04-01')), PARTITION p_future VALUES LESS THAN MAXVALUE ); -- 일별 집계 테이블 (빠른 조회용) CREATE TABLE usage_daily_summary ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, customer_id INT UNSIGNED NOT NULL, log_date DATE NOT NULL, total_calls INT UNSIGNED DEFAULT 0, error_calls INT UNSIGNED DEFAULT 0, avg_response DECIMAL(8,2) DEFAULT 0, total_request_bytes BIGINT UNSIGNED DEFAULT 0, total_response_bytes BIGINT UNSIGNED DEFAULT 0, UNIQUE INDEX idx_customer_date (customer_id, log_date) );

API 호출 로깅 미들웨어

// middleware/UsageLogger.php class UsageLogger { private $pdo; private $startTime; public function __construct($pdo) { $this->pdo = $pdo; } /** * 요청 시작 시 호출 - 타이밍 시작 */ public function before($request) { $this->startTime = microtime(true); } /** * 응답 후 호출 - 로그 기록 */ public function after($request, $response) { $responseTime = (microtime(true) - $this->startTime) * 1000; $stmt = $this->pdo->prepare(" INSERT INTO usage_logs (customer_id, endpoint, method, status_code, response_time, request_size, response_size, ip_address, user_agent, api_key_id, called_at) VALUES (:customer_id, :endpoint, :method, :status_code, :response_time, :request_size, :response_size, :ip_address, :user_agent, :api_key_id, NOW()) "); $stmt->execute([ 'customer_id' => $request->getCustomerId(), 'endpoint' => $request->getPath(), 'method' => $request->getMethod(), 'status_code' => $response->getStatusCode(), 'response_time' => (int)$responseTime, 'request_size' => strlen($request->getBody()), 'response_size' => strlen($response->getBody()), 'ip_address' => $request->getClientIp(), 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'api_key_id' => $request->getApiKeyId(), ]); } } // 미들웨어 적용 예시 $logger = new UsageLogger($pdo); $logger->before($request); // ... 비즈니스 로직 처리 ... $logger->after($request, $response);
🔒
여기까지는 미리보기입니다
고객별 사용량 추적 & 분석
무료 가입하면 이어서 볼 수 있고, 강의를 완료할 때마다 XP와 레벨이 쌓입니다.
Google로 3초 만에 시작 →🧵 Threads로 시작무료 공개 강의 둘러보기 (Lv.1~3)