Files
asset-management-system/app/Services/Logging/ActivityLogger.php

103 lines
3.0 KiB
PHP
Raw Normal View History

<?php
namespace App\Services\Logging;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
class ActivityLogger
{
public const CHANNEL = 'asset_activity';
/**
* Field yang disembunyikan agar tidak tercatat mentah di log.
*/
private array $hiddenRequestFields = [
'password',
'password_confirmation',
'current_password',
'token',
];
/**
* Tulis log aktivitas ke file dengan metadata yang mudah dibaca.
*/
public function log(string $message, array $context = [], string $level = 'info'): void
{
$request = request();
$payload = array_merge([
'action' => $message,
'actor_id' => optional(auth()->user())->getAuthIdentifier(),
'ip' => $request?->ip(),
'user_agent' => $request?->userAgent(),
'request_id' => $request?->headers->get('X-Request-Id'),
'performed_at' => now()->toIso8601String(),
], $context);
$payload['request_id'] = $payload['request_id'] ?? Str::uuid()->toString();
Log::channel(self::CHANNEL)->log($level, $message, $payload);
}
/**
* Tulis log request/response agar debugging controller lebih cepat.
*/
public function logHttp(string $action, Request $request, mixed $response = null, array $context = [], string $level = 'info'): void
{
$payload = [
'action' => $action,
'actor_id' => optional(auth()->user())->getAuthIdentifier(),
'request_id' => $request->headers->get('X-Request-Id') ?? Str::uuid()->toString(),
'performed_at' => now()->toIso8601String(),
'http' => [
'method' => $request->getMethod(),
'uri' => $request->fullUrl(),
'ip' => $request->ip(),
'user_agent' => $request->userAgent(),
'body' => $this->maskSensitiveFields($request->all()),
],
];
if ($response instanceof Response) {
$payload['http']['response'] = $this->normalizeResponse($response);
}
if (! empty($context)) {
$payload['context'] = $context;
}
Log::channel(self::CHANNEL)->log($level, $action, $payload);
}
private function maskSensitiveFields(array $input): array
{
foreach ($input as $key => &$value) {
if (in_array($key, $this->hiddenRequestFields, true)) {
$value = '[MASKED]';
}
}
return $input;
}
private function normalizeResponse(Response $response): array
{
$body = $response instanceof JsonResponse
? $response->getData(true)
: $response->getContent();
if (is_string($body) && strlen($body) > 2000) {
$body = Str::limit($body, 2000, '...[terpotong]');
}
return [
'status' => $response->getStatusCode(),
'body' => $body,
];
}
}