Skip to content

Instantly share code, notes, and snippets.

@lesstif
Last active August 5, 2021 04:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lesstif/e69e2b5bc4fd02e6d64a96fb19a51323 to your computer and use it in GitHub Desktop.
Save lesstif/e69e2b5bc4fd02e6d64a96fb19a51323 to your computer and use it in GitHub Desktop.
Laravel Event Listener 을 이용한 eloquent query logging
<?php
namespace App\Providers;
use App\Listeners\LoggingEloquentQueryListener;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
\Illuminate\Database\Events\QueryExecuted::class => [
LoggingEloquentQueryListener::class,
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}
<?php
// config/logging.php
use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
// console 실행 여부 판단해서 채널 분리
$log_channel = env('LOG_CHANNEL', 'stack');
if ($app->runningInConsole()) {
$log_channel = 'cli';
}
return [
'query_logging' => env('QUERY_LOGGING', false),
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => $log_channel,
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "monolog",
| "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
'ignore_exceptions' => false,
],
// console 용 channel
'cli' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel-cli.log'),
'level' => 'debug',
'days' => 14,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 60,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
'papertrail' => [
'driver' => 'monolog',
'level' => 'debug',
'handler' => SyslogUdpHandler::class,
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
],
],
'stderr' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'errorlog' => [
'driver' => 'errorlog',
'level' => 'debug',
],
'null' => [
'driver' => 'monolog',
'handler' => NullHandler::class,
],
'emergency' => [
'path' => storage_path('logs/laravel.log'),
],
// query logging 용 channel
'sql' => [
'driver' => 'daily',
'path' => storage_path('logs/sql.log'),
'level' => env('QUERY_LOG_LEVEL','info'),
'days' => 14,
],
],
];
<?php
namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
class LoggingEloquentQueryListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param QueryExecuted $event
* @return void
*/
public function handle(QueryExecuted $event)
{
// production 이 아니거나 logging.query_logging 이 true 일 경우 로깅
if (app()->environment() !== 'production' || config('logging.query_logging')) {
// php-fpm 이 생성하는 log 와 권한 충돌을 막기 위해 console 에서 실행시에는 별도 채널에 로그 기록
$channel = 'sql';
if (app()->runningInConsole()) {
$channel = 'sql-cli';
}
$message = [
'sql' => $event->sql,
'bindings' => $event->bindings,
'time' => $event->time,
'connection' => $event->connectionName,
];
Log::channel($channel)->info(json_encode($message, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment