Laravel Vapor

How to make Inspector works on Laravel Vapor.

Inspector requires two natives PHP functions (proc_open, proc_close) to send monitoring data to the remote API.

But a serverless environment has different default settings than a normal LAMP server. So the integration in the Vapor environment depends on the type of runtime you use.

You can learn more about Vapor runtimes in this official video lesson.

Docker based runtimes offer much more control over the execution environment, so you can deploy applications up to 10GB in size and allow you to install additional PHP extensions or libraries.

In order to use a Docker image instead of the Vapor native runtimes, set the runtime configuration option to docker within your vapor.yml file:

id: 2
name: vapor-laravel-app
        runtime: docker # Use docker as runtime environment
            - 'composer install --no-dev'

Learn more about Docker runtime in Vapor.

To make Inspector works you must be sure that the current PHP installation in the Docker image has proc_open, and proc_close native functions enabled.

The default Docker runtime should have these functions enabled by default. In alternative you need to create a custom php.ini file in your project root directory with these two functions not listed in the disable_functions parameter:


Add the entry below in your environment .Dockerfile to override the default php.ini configuration:


# Update the `php.ini` file...
# Requires a `php.ini` file at the root of your project...
COPY ./php.ini /usr/local/etc/php/conf.d/overrides.ini

Now you can continue installing the library as usual:

Use Vapor native runtimes

The AWS standard serverless environment has the proc_open and proc_close functions disabled by default. So Inspector isn’t able to send data to the inspection API with the standard transport class included in the package.

In a normal server environment you can enable these functions changing the php.ini settings, but Vapor native runtimes currently doesn't provide a way to overwrite this configuration during deployment, so you can't enable them.

Set a custom transport

The design of the Inspector package allows developers to inject a custom transport implementation at runtime. Add the code below in the boot method of your AppServiceProvider:

$this->app->inspector->setTransport(function ($configuration) {
    return new QueueTransport($configuration);

The callback will receive an instance of the Inspector\Configuration class, that contains the Ingestion Key, the URL of our remote API, and all other information needed to build the appropriate HTTP call.

QueueTransport implementation

To keep the data sending process “asynchronously” the QueueTransport class should schedule a job to send monitoring data in background:

namespace App\Inspector\Transports;

use Exception;
use Inspector\Transports\AbstractApiTransport;
use Inspector\Transports\TransportInterface;
use App\Inspector\Jobs\SendInspectorChunkJob;

class QueueTransport extends AbstractApiTransport implements TransportInterface
     * @param string $data
     * @throws Exception
    protected function sendChunk($data)
          // You can eventually create a specific queue to take things under control.
          (new SendInspectorChunkJob($this->config, $data))->onQueue('inspector')

SendInspectorChunkJob receives the data in its constructor to be sent when the job is scheduled for execution. Here is the implementation of the Job:

namespace App\Inspector\Jobs;

use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Inspector\Transports\AbstractApiTransport;
use Inspector\Transports\TransportInterface;
use Inspector\Configuration;

class SendInspectorChunkJob implements ShouldQueue
    use Queueable;

     * Monitoring Data
     * @var string
    protected $data;

     * Inspector configuration.
     * @var Configuration 
    protected $configuration;

     * SendInspectorChunkJob constructor.
     * @param Configuration $configuration
     * @param string $data
    public function __construct(Configuration $configuration, string $data)
        $this->data = $data;
        $this->configuration = $configuration;

     * Use the original CurlTransport.
     * @param \Inspector\Configuration $configuration
     * @throws \Inspector\Exceptions\InspectorException
    public function handle()
        $transport = new \Inspector\Transports\CurlTransport($this->configuration);


Avoid the infinite loop

Finally we must inform Inspector to ignore the SendInspectorChunkJob from monitoring. Otherwise when the job is executed it will run a new transaction itself that generates another job and so on… the infine loop start.

Inspector provides a configuration property to specify the job classes that you want to exclude from monitoring.

Publish the inspector config file if you haven't already done, using the command below:

php artisan vendor:publish --provider="Inspector\Laravel\InspectorServiceProvider"

Now you should have the inspector.php file in your config directory.

Add the SendInspectorChunkJob class to the "ignore_jobs" array:

| Job classes to ignore
| Add at this list the job classes that you don't want monitoring
| in your Inspector dashboard.

'ignore_jobs' => [

Consider to switch to Docker runtime in order to use the built in transport method.

Test and Deploy

You can run the test command to verify everything is well configured before deploy:

php artisan inspector:test

Last updated