Search code examples
laravelconsolekernelmiddlewarelumen

Lumen custom middleware in Console lifecycle


I am trying to create a logging middleware for when my commands run. The logger is working when a user makes an HTTP Request but I can't figure out how to make it work when a scheduled command is called.

Can anyone help please?

class LoggingMiddleware {

  /**
   * Handle an incoming request.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Closure  $next
   * @return mixed
   */
  public function handle($request, Closure $next) {
    return $next($request);
  }

  /**
   * Perform any final actions for the request lifecycle.
   *
   * @param  Request  $request
   * @param  Response  $response
   * @return void
   */
  public function terminate($request, $response) {
    dd('HELLOWORLD');
  }
}

And I register it here on the framework:

$app->middleware([
  App\Http\Middleware\LoggingMiddleware::class
]);

So if the Console and Http requests' lifecycle is the same as I saw on the documentation shouldn't this work on Console side too?


Solution

  • Due to the nature of the terminate method you cannot use it in the artisan commands, from the laravel docs:

    If you define a terminate method on your middleware, it will automatically be called after the response is ready to be sent to the browser.

    This illustrates the behavior of the termination and since it is a status indicator for the response being ready to be sent to the browser it would not make since in the case of a console command.

    Also if you delve into the laravel source code you will see that both kernels (http and console kernel) handle the lifecycle a little bit differently in the last phase. It is true that they have the same lifecycle regarding the handle method, but they have different behavior when terminating:

    The console kernel only calls $this->app->terminate(); which just terminates the whole application, whereas the http kernel also executes $this->terminateMiddleware($request, $response); before calling the app terminate. Thus this is why the terminate method does not work on console commands.

    So in order to log at the end of the command you should just put it at the end of the handle function. Or you could define your own terminate function which does have to be called manually.

    I hope this answers your question.