This log formatter will preserve log output generated by the application and written to standard out/err when running
on artisan serve
. Users can still specify a custom log format, or even bring their own date format; we prefix all log
messages with a special Artisan date format string that is the same as the one generated by the built-in HTTP server.
This works by overriding the log formatter in the app process using an environment variable, while preserving the original formatter in a second variable. On formatter creatiom time, we create an instance of the original formatter and return its output, prefixed with the serve
-save date sequence.
Note: This requires two changes in ServeCommand
:
- The
explode
call in the prcoess output handling needs to be limited to two segments:} elseif (!empty($line)) { - $warning = explode('] ', $line); + $warning = explode('] ', $line, 2); $this->components->warn(count($warning) > 1 ? $warning[1] : $warning[0]); }
- The environment needs to by extended with the formatter variables:
protected function startProcess($hasEnvironment) { - $process = new Process($this->serverCommand(), public_path(), collect($_ENV)->mapWithKeys(function ($value, $key) use ($hasEnvironment) { + $env = collect($_ENV)->mapWithKeys(function ($value, $key) use ($hasEnvironment) { - if ($this->option('no-reload') || ! $hasEnvironment) { - return [$key => $value]; - } - - return in_array($key, static::$passthroughVariables) ? [$key => $value] : [$key => false]; - })->all()); + }); + $process = new Process($this->serverCommand(), public_path(), $env->merge([ + 'ORIGINAL_LOG_FORMATTER' => $env->get('LOG_FORMATTER', config('logging.channels.stderr.formatter')), + 'LOG_FORMATTER' => ArtisanServeFormatter::class, + ])->all() + ); $process->start($this->handleProcessOutput()); return $process; }
With these two changes and the formatter in place, logs will be printed to the console in an arbitrary, user-defined, format. I can't call it elegant with a straight face, but at least most of the heavy lifting will be handled by the existing logging infrastructure.
Ideally, the ServeCommand
would either not need to split process output at all, or employ better heuristics to do it… If that isn't possible, the suggestion here could be improved by setting up some way to let Laravel know it's running within a serve
process, and accomodate to that.