API 로그에 사용자/테넌트 정보 및 그룹핑 기능 추가
- LogApiRequest 미들웨어에서 app('api_user'), app('tenant_id') 사용
- 5초 TTL 캐시 기반 group_id 생성으로 연관 API 호출 그룹핑
- group_id 컬럼 추가 마이그레이션
This commit is contained in:
@@ -77,6 +77,15 @@ protected function logRequest(Request $request, Response $response, float $start
|
||||
try {
|
||||
$durationMs = (int) ((microtime(true) - $startTime) * 1000);
|
||||
|
||||
// 사용자/테넌트 정보 가져오기 (ApiKeyMiddleware에서 설정된 값 우선)
|
||||
$apiUser = app()->bound('api_user') ? app('api_user') : null;
|
||||
$tenantId = app()->bound('tenant_id') ? app('tenant_id') : null;
|
||||
$userId = $apiUser?->id ?? $request->user()?->id;
|
||||
$tenantId = $tenantId ?? $request->user()?->current_tenant_id;
|
||||
|
||||
// 그룹 ID 생성 (동일 tenant+user의 연속 요청 묶기)
|
||||
$groupId = $this->getOrCreateGroupId($tenantId, $userId);
|
||||
|
||||
$logData = [
|
||||
'method' => $request->method(),
|
||||
'url' => $request->fullUrl(),
|
||||
@@ -89,8 +98,9 @@ protected function logRequest(Request $request, Response $response, float $start
|
||||
'duration_ms' => $durationMs,
|
||||
'ip_address' => $request->ip(),
|
||||
'user_agent' => $request->userAgent(),
|
||||
'user_id' => $request->user()?->id,
|
||||
'tenant_id' => $request->user()?->current_tenant_id ?? null,
|
||||
'user_id' => $userId,
|
||||
'tenant_id' => $tenantId,
|
||||
'group_id' => $groupId,
|
||||
];
|
||||
|
||||
// DB 저장
|
||||
@@ -163,4 +173,29 @@ protected function writeToLogFile(array $logData): void
|
||||
'response_status' => $logData['response_status'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 그룹 ID 생성 또는 기존 그룹 ID 반환
|
||||
* 동일 tenant+user의 5초 내 요청은 같은 그룹으로 묶음
|
||||
*/
|
||||
protected function getOrCreateGroupId(?int $tenantId, ?int $userId): string
|
||||
{
|
||||
$cacheKey = "api_log_group:{$tenantId}:{$userId}";
|
||||
$groupTtl = 5; // 5초 내 요청은 같은 그룹
|
||||
|
||||
// 캐시에서 기존 그룹 ID 확인
|
||||
$existingGroupId = cache()->get($cacheKey);
|
||||
|
||||
if ($existingGroupId) {
|
||||
// TTL 갱신 (연속 요청 시 그룹 유지)
|
||||
cache()->put($cacheKey, $existingGroupId, $groupTtl);
|
||||
return $existingGroupId;
|
||||
}
|
||||
|
||||
// 새 그룹 ID 생성
|
||||
$newGroupId = now()->format('Ymd_His_') . substr(md5(uniqid((string) mt_rand(), true)), 0, 8);
|
||||
cache()->put($cacheKey, $newGroupId, $groupTtl);
|
||||
|
||||
return $newGroupId;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
* @property string|null $user_agent
|
||||
* @property int|null $user_id
|
||||
* @property int|null $tenant_id
|
||||
* @property string|null $group_id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
*/
|
||||
class ApiRequestLog extends Model
|
||||
@@ -41,6 +42,7 @@ class ApiRequestLog extends Model
|
||||
'user_agent',
|
||||
'user_id',
|
||||
'tenant_id',
|
||||
'group_id',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('api_request_logs', function (Blueprint $table) {
|
||||
$table->string('group_id', 50)->nullable()->after('tenant_id')->comment('요청 그룹 ID (연관 API 묶음)');
|
||||
$table->index('group_id');
|
||||
$table->index(['tenant_id', 'user_id', 'created_at']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('api_request_logs', function (Blueprint $table) {
|
||||
$table->dropIndex(['group_id']);
|
||||
$table->dropIndex(['tenant_id', 'user_id', 'created_at']);
|
||||
$table->dropColumn('group_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user