├── composer.json ├── config └── blink-logger.php └── src ├── Http └── Middleware │ ├── RequestLogger.php │ └── ResponseLogger.php ├── Listeners ├── QueryExecutedLogger.php ├── RequestSendingLogger.php ├── ResponseReceivedLogger.php ├── TransactionBeginningLogger.php ├── TransactionCommittedLogger.php └── TransactionRolledBackLogger.php └── Providers └── LaravelBlinkLoggerServiceProvider.php /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ucan-lab/laravel-blink-logger", 3 | "description": "Comprehensive Logging Tool for Laravel.", 4 | "keywords": [ 5 | "php", 6 | "laravel", 7 | "logger" 8 | ], 9 | "type": "library", 10 | "license": "MIT", 11 | "autoload": { 12 | "psr-4": { 13 | "LaravelBlinkLogger\\": "src/" 14 | } 15 | }, 16 | "authors": [ 17 | { 18 | "name": "ucan-lab", 19 | "email": "35098175+ucan-lab@users.noreply.github.com" 20 | } 21 | ], 22 | "require": { 23 | "php": "^8.1", 24 | "laravel/framework": "^10.15|^11.0" 25 | }, 26 | "config": { 27 | "optimize-autoloader": true, 28 | "preferred-install": "dist", 29 | "sort-packages": true 30 | }, 31 | "extra": { 32 | "laravel": { 33 | "providers": [ 34 | "LaravelBlinkLogger\\Providers\\LaravelBlinkLoggerServiceProvider" 35 | ] 36 | } 37 | }, 38 | "require-dev": { 39 | "laravel/pint": "^1.15" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /config/blink-logger.php: -------------------------------------------------------------------------------- 1 | [ 19 | 'enabled' => env('LOG_QUERY_ENABLED', false), 20 | 'channel' => config('logging.default'), 21 | 'slow_query_time' => env('LOG_SQL_SLOW_QUERY_TIME', 2000), // ms 22 | 'listeners' => [ 23 | \Illuminate\Database\Events\QueryExecuted::class => \LaravelBlinkLogger\Listeners\QueryExecutedLogger::class, 24 | \Illuminate\Database\Events\TransactionBeginning::class => \LaravelBlinkLogger\Listeners\TransactionBeginningLogger::class, 25 | \Illuminate\Database\Events\TransactionCommitted::class => \LaravelBlinkLogger\Listeners\TransactionCommittedLogger::class, 26 | \Illuminate\Database\Events\TransactionRolledBack::class => \LaravelBlinkLogger\Listeners\TransactionRolledBackLogger::class, 27 | ], 28 | ], 29 | 30 | 'http' => [ 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Request Logger 34 | |-------------------------------------------------------------------------- 35 | */ 36 | 'request' => [ 37 | 'enabled' => env('LOG_HTTP_REQUEST_ENABLED', false), 38 | 'channel' => config('logging.default'), 39 | 'include_paths' => [], 40 | 'exclude_paths' => [], 41 | 'middleware' => \LaravelBlinkLogger\Http\Middleware\RequestLogger::class, 42 | 'middleware_group_names' => [ 43 | 'web', 44 | 'api', 45 | ], 46 | ], 47 | 48 | /* 49 | |-------------------------------------------------------------------------- 50 | | Response Logger 51 | |-------------------------------------------------------------------------- 52 | */ 53 | 'response' => [ 54 | 'enabled' => env('LOG_HTTP_RESPONSE_ENABLED', false), 55 | 'channel' => config('logging.default'), 56 | 'include_paths' => [], 57 | 'exclude_paths' => [], 58 | 'middleware' => \LaravelBlinkLogger\Http\Middleware\ResponseLogger::class, 59 | 'middleware_group_names' => [ 60 | 'api', 61 | ], 62 | ], 63 | ], 64 | 65 | 'http_client' => [ 66 | /* 67 | |-------------------------------------------------------------------------- 68 | | Request Logger 69 | |-------------------------------------------------------------------------- 70 | */ 71 | 'request' => [ 72 | 'enabled' => env('LOG_HTTP_CLIENT_REQUEST_ENABLED', false), 73 | 'channel' => config('logging.default'), 74 | 'listeners' => [ 75 | \Illuminate\Http\Client\Events\RequestSending::class => \LaravelBlinkLogger\Listeners\RequestSendingLogger::class, 76 | ], 77 | ], 78 | 79 | /* 80 | |-------------------------------------------------------------------------- 81 | | Response Logger 82 | |-------------------------------------------------------------------------- 83 | */ 84 | 'response' => [ 85 | 'enabled' => env('LOG_HTTP_CLIENT_RESPONSE_ENABLED', false), 86 | 'channel' => config('logging.default'), 87 | 'listeners' => [ 88 | \Illuminate\Http\Client\Events\RequestSending::class => \LaravelBlinkLogger\Listeners\RequestSendingLogger::class, 89 | ], 90 | ], 91 | ], 92 | ]; 93 | -------------------------------------------------------------------------------- /src/Http/Middleware/RequestLogger.php: -------------------------------------------------------------------------------- 1 | isWrite($request)) { 27 | $this->write($request); 28 | } 29 | 30 | return $next($request); 31 | } 32 | 33 | protected function isWrite(Request $request): bool 34 | { 35 | $includePaths = $this->config->get('blink-logger.http.request.include_paths'); 36 | if (count($includePaths) > 0) { 37 | return in_array($request->path(), $includePaths, true); 38 | } 39 | 40 | $excludePaths = $this->config->get('blink-logger.http.request.exclude_paths'); 41 | if (count($excludePaths) > 0) { 42 | return ! in_array($request->path(), $excludePaths, true); 43 | } 44 | 45 | return true; 46 | } 47 | 48 | protected function write(Request $request): void 49 | { 50 | $data = [ 51 | 'request' => $request->all(), 52 | 'headers' => $request->headers->all(), 53 | ]; 54 | 55 | $this->logger->channel($this->config->get('blink-logger.http.request.channel')) 56 | ->debug(sprintf('%s: %s', $request->method(), $request->fullUrl()), $data); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Http/Middleware/ResponseLogger.php: -------------------------------------------------------------------------------- 1 | isWrite($request)) { 34 | $this->write($response); 35 | } 36 | } 37 | 38 | protected function isWrite(Request $request): bool 39 | { 40 | $includePaths = $this->config->get('blink-logger.http.response.include_paths'); 41 | if (count($includePaths) > 0) { 42 | return in_array($request->path(), $includePaths, true); 43 | } 44 | 45 | $excludePaths = $this->config->get('blink-logger.http.response.exclude_paths'); 46 | if (count($excludePaths) > 0) { 47 | return ! in_array($request->path(), $excludePaths, true); 48 | } 49 | 50 | return true; 51 | } 52 | 53 | protected function write(Response|JsonResponse $response): void 54 | { 55 | $this->logger->channel($this->config->get('blink-logger.http.response.channel'))->debug(sprintf( 56 | '%d %s', 57 | $response->status(), 58 | $response->statusText(), 59 | ), [ 60 | 'body' => $response->content(), 61 | 'headers' => $response->headers->all(), 62 | ]); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Listeners/QueryExecutedLogger.php: -------------------------------------------------------------------------------- 1 | connection 26 | ->getQueryGrammar() 27 | ->substituteBindingsIntoRawSql( 28 | sql: $event->sql, 29 | bindings: $event->connection->prepareBindings($event->bindings), 30 | ); 31 | 32 | if ($event->time > config('blink-logger.query.slow_query_time')) { 33 | $this->logger->channel($this->config->get('blink-logger.query.channel'))->warning(sprintf('%.2f ms, SQL: %s;', $event->time, $sql)); 34 | } else { 35 | $this->logger->channel($this->config->get('blink-logger.query.channel'))->debug(sprintf('%.2f ms, SQL: %s;', $event->time, $sql)); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Listeners/RequestSendingLogger.php: -------------------------------------------------------------------------------- 1 | logger->channel($this->config->get('blink-logger.http_client.response.channel'))->debug(sprintf( 26 | '%s: %s', 27 | $event->request->method(), 28 | $event->request->url(), 29 | ), [ 30 | 'body' => $event->request->data(), 31 | 'headers' => $event->request->headers(), 32 | ]); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Listeners/ResponseReceivedLogger.php: -------------------------------------------------------------------------------- 1 | logger->channel($this->config->get('blink-logger.http_client.response.channel'))->debug(sprintf( 28 | '%d %s', 29 | $event->response->status(), 30 | $event->response->reason(), 31 | ), [ 32 | 'body' => $this->isJson($event->response) ? $event->response->json() : $event->response->body(), 33 | 'headers' => $event->response->headers(), 34 | ]); 35 | } 36 | 37 | private function isJson(Response $response): bool 38 | { 39 | return Str::startsWith($response->headers()['Content-Type'][0] ?? '', 'application/json'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Listeners/TransactionBeginningLogger.php: -------------------------------------------------------------------------------- 1 | logger->channel($this->config->get('blink-logger.query.channel'))->debug('START TRANSACTION'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Listeners/TransactionCommittedLogger.php: -------------------------------------------------------------------------------- 1 | logger->channel($this->config->get('blink-logger.query.channel'))->debug('COMMIT'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Listeners/TransactionRolledBackLogger.php: -------------------------------------------------------------------------------- 1 | logger->channel($this->config->get('blink-logger.query.channel'))->debug('ROLLBACK'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Providers/LaravelBlinkLoggerServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 17 | __DIR__ . '/../../config/blink-logger.php' => config_path('blink-logger.php'), 18 | ], 'blink-logger'); 19 | 20 | // Query Logger 21 | if ($config->get('blink-logger.query.enabled')) { 22 | foreach ($config->get('blink-logger.query.listeners') as $event => $listener) { 23 | $events->listen($event, $listener); 24 | } 25 | } 26 | 27 | // HTTP Request Logger 28 | if ($config->get('blink-logger.http.request.enabled')) { 29 | $middleware = $config->get('blink-logger.http.request.middleware'); 30 | $middlewareGroupNames = $config->get('blink-logger.http.request.middleware_group_names'); 31 | foreach ($middlewareGroupNames as $middlewareGroupName) { 32 | $router->pushMiddlewareToGroup($middlewareGroupName, $middleware); 33 | } 34 | } 35 | 36 | // HTTP Response Logger 37 | if ($config->get('blink-logger.http.response.enabled')) { 38 | $middleware = $config->get('blink-logger.http.response.middleware'); 39 | $middlewareGroupNames = $config->get('blink-logger.http.response.middleware_group_names'); 40 | foreach ($middlewareGroupNames as $middlewareGroupName) { 41 | $router->pushMiddlewareToGroup($middlewareGroupName, $middleware); 42 | } 43 | } 44 | 45 | // HTTP Client Request Logger 46 | if ($config->get('blink-logger.http_client.request.enabled')) { 47 | foreach ($config->get('blink-logger.http_client.request.listeners') as $event => $listener) { 48 | $events->listen($event, $listener); 49 | } 50 | } 51 | 52 | // HTTP Client Response Logger 53 | if ($config->get('blink-logger.http_client.response.enabled')) { 54 | foreach ($config->get('blink-logger.http_client.response.listeners') as $event => $listener) { 55 | $events->listen($event, $listener); 56 | } 57 | } 58 | } 59 | 60 | public function register(): void 61 | { 62 | $this->mergeConfigFrom( 63 | __DIR__ . '/../../config/blink-logger.php', 'blink-logger' 64 | ); 65 | } 66 | } 67 | --------------------------------------------------------------------------------