- ApiLogController: 로그 목록/상세/삭제 기능 - ApiRequestLog 모델: 색상 accessor, 경로 추출 - 뷰: 통계, 필터링, 페이지네이션 - 사이드바에 'API 요청 로그' 메뉴 추가 - JSON 출력 stripslashes 적용 (이스케이프 제거)
128 lines
5.0 KiB
PHP
128 lines
5.0 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', 'API 로그 상세')
|
|
|
|
@section('content')
|
|
<!-- 페이지 헤더 -->
|
|
<div class="flex justify-between items-center mb-6">
|
|
<div class="flex items-center gap-4">
|
|
<a href="{{ route('dev-tools.api-logs.index') }}" class="text-gray-500 hover:text-gray-700">
|
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
|
|
</svg>
|
|
</a>
|
|
<h1 class="text-2xl font-bold text-gray-800">API 로그 상세</h1>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 기본 정보 -->
|
|
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">요청 정보</h2>
|
|
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
|
|
<div>
|
|
<div class="text-sm text-gray-500">메서드</div>
|
|
<span class="px-2 py-1 text-sm font-medium rounded {{ $log->method_color }}">
|
|
{{ $log->method }}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<div class="text-sm text-gray-500">상태 코드</div>
|
|
<span class="px-2 py-1 text-sm font-medium rounded {{ $log->status_color }}">
|
|
{{ $log->response_status }}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<div class="text-sm text-gray-500">응답 시간</div>
|
|
<div class="text-lg font-semibold">{{ number_format($log->duration_ms) }}ms</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-sm text-gray-500">요청 시간</div>
|
|
<div class="text-sm">{{ $log->created_at->format('Y-m-d H:i:s') }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<div class="text-sm text-gray-500 mb-1">URL</div>
|
|
<div class="bg-gray-100 rounded-lg p-3 font-mono text-sm break-all">
|
|
{{ $log->url }}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div>
|
|
<div class="text-sm text-gray-500">라우트</div>
|
|
<div class="text-sm font-mono">{{ $log->route_name ?? '-' }}</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-sm text-gray-500">IP 주소</div>
|
|
<div class="text-sm">{{ $log->ip_address ?? '-' }}</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-sm text-gray-500">User ID</div>
|
|
<div class="text-sm">{{ $log->user_id ?? 'guest' }}</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-sm text-gray-500">Tenant ID</div>
|
|
<div class="text-sm">{{ $log->tenant_id ?? '-' }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- User Agent -->
|
|
@if($log->user_agent)
|
|
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">User Agent</h2>
|
|
<div class="bg-gray-100 rounded-lg p-3 font-mono text-sm break-all">
|
|
{{ $log->user_agent }}
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- 요청 헤더 -->
|
|
@if($log->request_headers)
|
|
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">요청 헤더</h2>
|
|
<div class="bg-gray-900 rounded-lg p-4 overflow-x-auto">
|
|
<pre class="text-green-400 text-sm font-mono">{!! stripslashes(json_encode($log->request_headers, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)) !!}</pre>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- 쿼리 파라미터 -->
|
|
@if($log->request_query && count($log->request_query) > 0)
|
|
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">쿼리 파라미터</h2>
|
|
<div class="bg-gray-900 rounded-lg p-4 overflow-x-auto">
|
|
<pre class="text-green-400 text-sm font-mono">{!! stripslashes(json_encode($log->request_query, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)) !!}</pre>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- 요청 바디 -->
|
|
@if($log->request_body && count($log->request_body) > 0)
|
|
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">요청 바디</h2>
|
|
<div class="bg-gray-900 rounded-lg p-4 overflow-x-auto">
|
|
<pre class="text-green-400 text-sm font-mono">{!! stripslashes(json_encode($log->request_body, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)) !!}</pre>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- 응답 바디 -->
|
|
@if($log->response_body)
|
|
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">응답 바디</h2>
|
|
<div class="bg-gray-900 rounded-lg p-4 overflow-x-auto max-h-96">
|
|
@php
|
|
$responseData = json_decode($log->response_body, true);
|
|
@endphp
|
|
@if($responseData)
|
|
<pre class="text-green-400 text-sm font-mono">{!! stripslashes(json_encode($responseData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)) !!}</pre>
|
|
@else
|
|
<pre class="text-green-400 text-sm font-mono">{{ $log->response_body }}</pre>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@endif
|
|
@endsection |