├── .gitignore ├── LICENSE.md ├── README.md ├── composer.json ├── config └── apilog.php ├── database └── migrations │ ├── 2019_09_17_051112_create_api_logs_table.php │ └── 2022_03_22_051112_update_api_logs_table.php ├── resources └── views │ └── index.blade.php ├── routes └── web.php ├── screenshot.png └── src ├── AbstractLogger.php ├── ApiLog.php ├── Console └── Commands │ └── ClearApiLogger.php ├── Contracts └── ApiLoggerInterface.php ├── DBLogger.php ├── FileLogger.php ├── Http ├── Controllers │ └── ApiLogController.php ├── Exceptions │ └── InvalidApiLogDriverException.php └── Middleware │ └── ApiLogger.php └── Providers └── ApiLogServiceProvider.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /vendor/ 3 | node_modules/ 4 | npm-debug.log 5 | 6 | # Laravel 4 specific 7 | bootstrap/compiled.php 8 | app/storage/ 9 | 10 | # Laravel 5 & Lumen specific 11 | public/storage 12 | public/hot 13 | storage/*.key 14 | .env.*.php 15 | .env.php 16 | .env 17 | Homestead.yaml 18 | Homestead.json 19 | 20 | # Rocketeer PHP task runner and deployment package. https://github.com/rocketeers/rocketeer 21 | .rocketeer/ 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Aung Win Thant 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # API Logger 2 | 3 | This is a small package that can helps in debugging api logs. It can log 4 | request method, url, duration, request payload, which models are retrieved, controller and method. 5 | 6 | ![screenshot](screenshot.png) 7 | 8 | ## Installation 9 | 10 | 1. Install the package via composer 11 | 12 | ```bash 13 | composer require awt/apilogger @dev 14 | ``` 15 | ## Usage 16 | 17 | 1. Laravel 5.5 and higher uses Package Auto-Discovery, so doesn't require you to manually add 18 | the ServiceProvider. If you use a lower version of Laravel you must register it in your 19 | _app.php_ file: 20 | 21 | ```bash 22 | AWT\Providers\ApiLogServiceProvider::class 23 | ``` 24 | 25 | 2. Publish the config file with: 26 | 27 | ```bash 28 | php artisan vendor:publish --tag=config --provider="AWT\Providers\ApiLogServiceProvider" 29 | ``` 30 | 31 | The config file is called *apilogs.php*. Currently supported drivers are *db* and *file* 32 | 33 | By default the logger will use *file* to log the data. But if you want to use Database for logging, migrate table by using 34 | 35 | You can also configure which fields should not be logged like passwords, secrets, etc. 36 | 37 | ***You dont need to migrate if you are just using file driver*** 38 | 39 | ```bash 40 | php artisan migrate 41 | ``` 42 | 43 | 3. Add middleware named ***apilogger*** to the route or controller you want to log data 44 | 45 | ```php 46 | //in route.php or web.php 47 | Route::middleware('apilogger')->post('/test',function(){ 48 | return response()->json("test"); 49 | }); 50 | ``` 51 | 52 | 4. Dashboard can be accessible via ***yourdomain.com/apilogs*** 53 | 54 | ## Clear the logs 55 | 56 | You can permenently clear the logs by using the following command. 57 | ```bash 58 | php artisan apilog:clear 59 | ``` 60 | ## Implement your own log driver 61 | 62 | 1. Your driver class ***must*** implement ApiLoggerInterface for saving, retrieving and deleting the logs. 63 | 2. Your driver class may extends `AbstractLogger` class which provide helpful methods such as logData and mapArrayToModel. 64 | 3. Substitude in your new class name instead of `db` or `file` as the driver. eg: `\App\Apilogs\CustomLogger::class` 65 | 66 | ## Security 67 | ### Add Auth 68 | In config/apilog.php you have 'route' option, you can change the prefix and add auth middleware or any other middleware 69 | ```php 70 | 'route' => [ 71 | 'prefix' => 'apilogs', 72 | 'middleware' => null,//Can be change to ['auth'] or others 73 | ] 74 | ``` 75 | 76 | 77 | If you discover any security related issues, please email agwinthant@gmail.com instead of using the issue tracker. 78 | 79 | ## License 80 | 81 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 82 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "ext-libxml": "*", 4 | "ext-json": "*" 5 | }, 6 | "autoload": { 7 | "psr-4": { 8 | "AWT\\": "src/" 9 | } 10 | }, 11 | "name": "awt/apilogger", 12 | "description": "Small laravel package for viewing api logs which can be used in debugging.", 13 | "type": "library", 14 | "license": "MIT", 15 | "authors": [ 16 | { 17 | "name": "aung win thant", 18 | "email": "agwinthant@gmail.com" 19 | } 20 | ], 21 | "extra": { 22 | "laravel": { 23 | "providers": [ 24 | "AWT\\Providers\\ApiLogServiceProvider" 25 | ] 26 | } 27 | }, 28 | "minimum-stability": "dev" 29 | } 30 | -------------------------------------------------------------------------------- /config/apilog.php: -------------------------------------------------------------------------------- 1 | env('API_LOGS_DRIVER', 'file'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Per page 23 | |-------------------------------------------------------------------------- 24 | | 25 | | If you use DB how many item per page do you want 26 | | 27 | */ 28 | 29 | 'per_page' => 25, 30 | 31 | 32 | 33 | /* 34 | |-------------------------------------------------------------------------- 35 | | Filename Format 36 | |-------------------------------------------------------------------------- 37 | | 38 | | The name and format of the log files which are created. 39 | | Only applicable if the 'file' driver is being used 40 | | [uuid] is a unique id for the request, if not present in filename it will 41 | | append before the extension 42 | | 43 | */ 44 | 45 | 'filename' => env('API_LOGS_FILENAME_FORMAT', 'api-{Y-m-d}-[uuid].log'), 46 | 47 | /* 48 | |-------------------------------------------------------------------------- 49 | | Routes group config 50 | |-------------------------------------------------------------------------- 51 | | 52 | | The default group settings for the routes. 53 | | 54 | */ 55 | 'route' => [ 56 | 'prefix' => 'apilogs', 57 | 'middleware' => null, 58 | ], 59 | 60 | /* 61 | |-------------------------------------------------------------------------- 62 | | Log raw payload 63 | |-------------------------------------------------------------------------- 64 | | 65 | | This will log the raw request from php://input so you will get all details 66 | | BUT this will also log the exclusions, since we are not able to find field 67 | | in the php://input, by default we use request()->all() encoded in JSON 68 | | 69 | */ 70 | 'payload_raw' => false, 71 | 72 | /* 73 | |-------------------------------------------------------------------------- 74 | | Log response 75 | |-------------------------------------------------------------------------- 76 | | 77 | | This will log the result send to the client 78 | | 79 | */ 80 | 'response' => true, 81 | 82 | /* 83 | |-------------------------------------------------------------------------- 84 | | Try to autodetect json, xml, html and make a pretty display 85 | |-------------------------------------------------------------------------- 86 | | 87 | | If this is false plain response will be show 88 | | 89 | */ 90 | 'response_autodetect' => true, 91 | 92 | 93 | /* 94 | |-------------------------------------------------------------------------- 95 | | Request Exclusions 96 | |-------------------------------------------------------------------------- 97 | | 98 | | This sets which request data is excluded from the logging 99 | | 100 | */ 101 | 'dont_log' => [ 102 | 'password', 'password_confirmation', 'new_password', 'old_password', 103 | ], 104 | 105 | 106 | /* 107 | |-------------------------------------------------------------------------- 108 | | Headers Exclusions 109 | |-------------------------------------------------------------------------- 110 | | 111 | | This sets which headers data is excluded from the logging, case non-sensitive 112 | | 113 | */ 114 | 'dont_log_headers' => [ 115 | 'Authorization' 116 | ] 117 | ]; 118 | -------------------------------------------------------------------------------- /database/migrations/2019_09_17_051112_create_api_logs_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->string('method'); 19 | $table->string('url'); 20 | $table->longText('payload'); 21 | $table->longText('response'); 22 | $table->string('duration'); 23 | $table->string('controller'); 24 | $table->string('action'); 25 | $table->string('models'); 26 | $table->string('ip'); 27 | $table->timestamps(); 28 | }); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | * 34 | * @return void 35 | */ 36 | public function down() 37 | { 38 | Schema::dropIfExists('api_logs'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /database/migrations/2022_03_22_051112_update_api_logs_table.php: -------------------------------------------------------------------------------- 1 | renameColumn('response', 'status_code'); 18 | }); 19 | Schema::table('api_logs', function(Blueprint $table) { 20 | $table->integer('status_code')->change(); 21 | $table->longText('payload_raw')->nullable()->after('payload'); 22 | $table->longText('response')->after('payload_raw'); 23 | $table->longText('response_headers')->after('response'); 24 | $table->text('headers')->nullable()->after('response'); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::table('api_logs', function(Blueprint $table) { 36 | $table->dropColumn('response'); 37 | $table->dropColumn('response_headers'); 38 | $table->dropColumn('payload_raw'); 39 | $table->dropColumn('headers'); 40 | }); 41 | 42 | Schema::table('api_logs', function(Blueprint $table) { 43 | $table->renameColumn('status_code', 'response'); 44 | }); 45 | 46 | Schema::table('api_logs', function(Blueprint $table) { 47 | $table->longText('response')->change(); 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /resources/views/index.blade.php: -------------------------------------------------------------------------------- 1 | = 0x20 && $i <= 0x7E) ? chr($i) : $pad; 14 | } 15 | } 16 | 17 | $hex = str_split(bin2hex($data), $width * 2); 18 | $chars = str_split(strtr($data, $from, $to), $width); 19 | 20 | $offset = 0; 21 | foreach($hex as $i => $line) { 22 | echo sprintf('%6X', $offset) . ' : ' . implode(' ', str_split($line, 2)) . ' [' . $chars[$i] . ']' . $newline; 23 | $offset += $width; 24 | } 25 | } 26 | 27 | ?> 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | {{ config('app.name', 'APILogger') }} 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 55 | 56 |
57 |
58 |

Api Logger

59 |
60 | {{ csrf_field() }} 61 | {{ method_field('DELETE') }} 62 |
63 | 64 |
65 |
66 |
67 |
68 | @forelse ($apilogs as $key => $log) 69 |
70 |
71 | 72 | @if ($log->status_code>=400) 73 | 74 | @elseif($log->status_code>=300) 75 | 76 | @else 77 | 78 | @endif 79 | 80 | 81 | {{$log->status_code}} - {{url($log->url)}} 82 | 83 | 84 |
85 |

Duration : {{$log->duration * 1000}}ms
86 | Models(Retrieved) :
{!! empty($log->models) ? 'None' : implode('
', explode(', ', $log->models)) !!}

87 |
88 |
89 |

IP : {{$log->ip}}
90 | Date : {{$log->created_at}}

91 |
92 |
93 |

Controller : {{ empty($log->controller) ? 'None' : $log->controller }}
94 | Method : {{ empty($log->action) ? 'Closure' : $log->action }}

95 |
96 |
97 | 118 |
119 |
120 | @dump(json_decode($log->payload, true)) 121 |
122 | @if(config('apilog.payload_raw')) 123 |
124 |
{{$log->payload_raw}}
125 |
HexDump
126 |
{{hex_dump($log->payload_raw)}}
127 |
128 | @endif 129 |
130 | @dump(json_decode($log->headers, true)) 131 |
132 | @if(config('apilog.response')) 133 |
134 | @if(config('apilog.response_autodetect')) 135 | response))) { 137 | dump(json_decode($log->response, true)); 138 | } elseif(preg_match('/<\s?[^\>]*\/?\s?>/i', $log->response)) { 139 | echo ''; 140 | } else { 141 | libxml_use_internal_errors(true); 142 | simplexml_load_string($log->response); 143 | $errors = libxml_get_errors(); 144 | libxml_clear_errors(); 145 | if(empty($errors)) { 146 | echo highlight_string($log->response); 147 | } else { 148 | echo '
'.$log->response.'
'; 149 | } 150 | } 151 | ?> 152 | @else 153 |
{{$log->response}}
154 | @endif 155 |
156 |
157 | @dump(json_decode($log->response_headers, true)) 158 |
159 | @endif 160 |
161 |
162 | @empty 163 |
164 | No Records 165 |
166 | @endforelse 167 | 168 |
169 | @if(config('apilog.driver') === 'db') 170 |
171 | {!! $apilogs->links() !!} 172 |
173 | @endif 174 |
175 | 176 | 177 | 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | 'AWT\\Http\\Controllers']); 15 | Route::group($config, function($router) 16 | { 17 | Route::get('/', 'ApiLogController@index')->name("apilogs.index"); 18 | Route::delete('/delete', 'ApiLogController@delete')->name("apilogs.deletelogs"); 19 | }); 20 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aungwinthant/apilogger/558119656dccd34220edc82f22a57ff56de495f5/screenshot.png -------------------------------------------------------------------------------- /src/AbstractLogger.php: -------------------------------------------------------------------------------- 1 | boot(); 25 | } 26 | /** 27 | * starting method just for cleaning code 28 | * 29 | * @return void 30 | */ 31 | public function boot(){ 32 | Event::listen('eloquent.*', function ($event, $models) { 33 | if (Str::contains($event, 'eloquent.retrieved')) { 34 | foreach (array_filter($models) as $model) { 35 | $class = get_class($model); 36 | $this->models[$class] = ($this->models[$class] ?? 0) + 1; 37 | } 38 | } 39 | }); 40 | } 41 | 42 | /** 43 | * logs into associative array 44 | * 45 | * @param Request $request 46 | * @param Response|JsonResponse|RedirectResponse $response 47 | * 48 | * @return array 49 | */ 50 | public function logData(Request $request, Response|JsonResponse|RedirectResponse $response){ 51 | $currentRouteAction = Route::currentRouteAction(); 52 | 53 | // Initialiaze controller and action variable before use them 54 | $controller = ""; 55 | $action = ""; 56 | 57 | /* 58 | * Some routes will not contain the `@` symbole (e.g. closures, or routes using a single action controller). 59 | */ 60 | if ($currentRouteAction) { 61 | if (strpos($currentRouteAction, '@') !== false) { 62 | [$controller, $action] = explode('@', $currentRouteAction); 63 | } else { 64 | // If we get a string, just use that. 65 | if (is_string($currentRouteAction)) { 66 | [$controller, $action] = ["", $currentRouteAction]; 67 | } else { 68 | // Otherwise force it to be some type of string using `json_encode`. 69 | [$controller, $action] = ["", (string)json_encode($currentRouteAction)]; 70 | } 71 | } 72 | } 73 | 74 | $endTime = microtime(true); 75 | 76 | $implode_models = $this->models; 77 | 78 | array_walk($implode_models, function(&$value, $key) { 79 | $value = "{$key} ({$value})"; 80 | }); 81 | 82 | $models = implode(', ',$implode_models); 83 | $this->logs['created_at'] = Carbon::now(); 84 | $this->logs['method'] = $request->method(); 85 | $this->logs['url'] = $request->path(); 86 | $this->logs['payload'] = $this->payload($request); 87 | $this->logs['payload_raw'] = config('apilog.payload_raw', false) ? file_get_contents('php://input') : null; 88 | $this->logs['headers'] = $this->headers($request); 89 | $this->logs['status_code'] = $response->status(); 90 | $this->logs['response'] = $response->getContent(); 91 | $this->logs['response_headers'] = $this->headers($response); 92 | $this->logs['duration'] = number_format($endTime - LARAVEL_START, 3); 93 | $this->logs['controller'] = $controller; 94 | $this->logs['action'] = $action; 95 | $this->logs['models'] = $models; 96 | $this->logs['ip'] = $request->ip(); 97 | 98 | return $this->logs; 99 | } 100 | 101 | 102 | /** 103 | * Formats the request payload for logging 104 | * 105 | * @param $request 106 | * @return string 107 | */ 108 | protected function payload($request) 109 | { 110 | $allFields = $request->all(); 111 | 112 | foreach (config('apilog.dont_log', []) as $key) { 113 | if (array_key_exists($key, $allFields)) { 114 | unset($allFields[$key]); 115 | } 116 | } 117 | 118 | return json_encode($allFields); 119 | } 120 | 121 | /** 122 | * Formats the headers payload for logging 123 | * 124 | * @param $request 125 | * @return string 126 | */ 127 | protected function headers($request) 128 | { 129 | $allHeaders = $request->headers->all(); 130 | 131 | foreach (config('apilog.dont_log_headers', []) as $key) { 132 | if (array_key_exists($key, $allHeaders)) { 133 | unset($allHeaders[$key]); 134 | } 135 | } 136 | 137 | return json_encode($allHeaders); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/ApiLog.php: -------------------------------------------------------------------------------- 1 | deleteLogs(); 42 | 43 | $this->info("All records are deleted"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Contracts/ApiLoggerInterface.php: -------------------------------------------------------------------------------- 1 | logger = $logger; 24 | } 25 | /** 26 | * return all models 27 | */ 28 | public function getLogs() 29 | { 30 | return $this->logger->orderByDesc('created_at')->paginate(config('apiloger.per_page', 25)); 31 | } 32 | /** 33 | * save logs in database 34 | */ 35 | public function saveLogs(Request $request, Response|JsonResponse|RedirectResponse $response) 36 | { 37 | $data = $this->logData($request,$response); 38 | 39 | $this->logger->fill($data); 40 | 41 | $this->logger->save(); 42 | } 43 | /** 44 | * delete all logs 45 | */ 46 | public function deleteLogs() 47 | { 48 | $this->logger->truncate(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/FileLogger.php: -------------------------------------------------------------------------------- 1 | path = storage_path('logs/apilogs'); 24 | } 25 | 26 | /** 27 | * read files from log directory 28 | * 29 | * @return array 30 | */ 31 | public function getLogs() 32 | { 33 | //check if the directory exists 34 | if (File::isDirectory($this->path)) { 35 | //scann the directory 36 | $files = glob($this->path."/*.*"); 37 | 38 | $contentCollection = collect(); 39 | 40 | //loop each files 41 | foreach ($files as $file) { 42 | if (!File::isDirectory($file)) { 43 | $contentCollection->add((object) unserialize(file_get_contents($file))); 44 | } 45 | } 46 | return collect($contentCollection)->sortByDesc('created_at'); 47 | } else { 48 | return []; 49 | } 50 | } 51 | 52 | /** 53 | * write logs to file 54 | * 55 | * @param Request $request 56 | * @param Response|JsonResponse|RedirectResponse $response 57 | * 58 | * @return void 59 | */ 60 | public function saveLogs(Request $request, Response|JsonResponse|RedirectResponse $response) 61 | { 62 | $data = $this->logData($request, $response); 63 | 64 | $filename = $this->getLogFilename(); 65 | 66 | $contents = serialize($data); 67 | 68 | if(!File::isDirectory($this->path)) 69 | File::makeDirectory($this->path, 0777, true, true); 70 | 71 | File::append(($this->path.DIRECTORY_SEPARATOR.$filename), $contents.PHP_EOL); 72 | 73 | } 74 | 75 | /** 76 | * get log file if defined in constants 77 | * 78 | * @return string 79 | */ 80 | public function getLogFilename() 81 | { 82 | // original default filename 83 | $filename = 'apilogger-'.date('d-m-Y') . '.log'; 84 | 85 | $configFilename = config('apilog.filename'); 86 | preg_match('/{(.*?)}/', $configFilename, $matches, PREG_OFFSET_CAPTURE); 87 | if (sizeof($matches) > 0) { 88 | $filename = str_replace($matches[0][0], date("{$matches[1][0]}"), $configFilename); 89 | } 90 | 91 | if(strpos($filename, '[uuid]') !== false) { 92 | $filename = str_replace('[uuid]', uniqid(), $filename); 93 | } else { 94 | $extension = File::extension($filename); 95 | $filename = substr($filename, 0, -strlen($extension)).uniqid().".$extension"; 96 | } 97 | return $filename; 98 | } 99 | 100 | /** 101 | * delete all api log files 102 | * 103 | * @return void 104 | */ 105 | public function deleteLogs() 106 | { 107 | if (is_dir($this->path)) { 108 | File::deleteDirectory($this->path); 109 | } 110 | 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/Http/Controllers/ApiLogController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 21 | } 22 | 23 | /** 24 | * Show the application dashboard. 25 | * 26 | * @return \Illuminate\Contracts\Support\Renderable 27 | */ 28 | public function index(ApiLoggerInterface $logger) 29 | { 30 | $apilogs = $logger->getLogs(); 31 | 32 | return view('apilog::index',compact('apilogs')); 33 | 34 | } 35 | public function delete(ApiLoggerInterface $logger) 36 | { 37 | $logger->deleteLogs(); 38 | 39 | return redirect()->back(); 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/Http/Exceptions/InvalidApiLogDriverException.php: -------------------------------------------------------------------------------- 1 | logger = $logger; 19 | } 20 | /** 21 | * Handle an incoming request. 22 | * 23 | * @param \Illuminate\Http\Request $request 24 | * @param \Closure $next 25 | * 26 | * @return mixed 27 | */ 28 | public function handle(Request $request, Closure $next) 29 | { 30 | $response = $next($request); 31 | return $response; 32 | } 33 | 34 | public function terminate(Request $request, Response|JsonResponse|RedirectResponse $response) { 35 | $this->logger->saveLogs($request, $response); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Providers/ApiLogServiceProvider.php: -------------------------------------------------------------------------------- 1 | mergeConfigFrom( 25 | __DIR__.'/../../config/apilog.php', 'apilog' 26 | ); 27 | $this->bindServices(); 28 | } 29 | 30 | /** 31 | * Bootstrap services. 32 | * 33 | * @return void 34 | */ 35 | public function boot() 36 | { 37 | $this->loadConfig(); 38 | $this->loadRoutes(); 39 | $this->loadViews(); 40 | $this->loadCommand(); 41 | $this->loadMigrations(); 42 | } 43 | 44 | public function bindServices(){ 45 | $driver = config('apilog.driver'); 46 | $instance = ""; 47 | switch ($driver) { 48 | case 'file': 49 | $instance = FileLogger::class; 50 | break; 51 | case 'db': 52 | $instance = DBLogger::class; 53 | break; 54 | default: 55 | try { 56 | $instance = $driver; 57 | if(!(resolve($instance) instanceof ApiLoggerInterface)) 58 | { 59 | throw new InvalidApiLogDriverException(); 60 | } 61 | } 62 | catch(\ReflectionException $exception){ 63 | throw new InvalidApiLogDriverException(); 64 | } 65 | break; 66 | } 67 | $this->app->singleton(ApiLoggerInterface::class,$instance); 68 | 69 | $this->app->singleton('apilogger', function ($app) use ($instance){ 70 | return new ApiLogger($app->make($instance)); 71 | }); 72 | } 73 | 74 | public function loadConfig(){ 75 | $this->publishes([ 76 | __DIR__.'/../../config/apilog.php' => config_path('apilog.php') 77 | ], 'config'); 78 | } 79 | 80 | public function loadRoutes(){ 81 | $this->loadRoutesFrom(__DIR__.'/../../routes/web.php'); 82 | } 83 | 84 | public function loadViews(){ 85 | $this->loadViewsFrom(__DIR__.'/../../resources/views', 'apilog'); 86 | } 87 | 88 | public function loadCommand(){ 89 | $this->commands([ 90 | ClearApiLogger::class 91 | ]); 92 | } 93 | 94 | public function loadMigrations(){ 95 | if(config('apilog.driver') === 'db') 96 | $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); 97 | } 98 | } 99 | --------------------------------------------------------------------------------