Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ray Laravel Package

spatie/ray

Send debug output from any PHP app to Ray, Spatie’s desktop debugging tool. Inspect arrays, HTML, queries, and more with a consistent API across Laravel/PHP/JS. Measure performance, pause execution, and keep fast, interactive feedback.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/ray
    

    For Laravel, use spatie/laravel-ray instead.

  2. Configuration:

    • Publish the config file:
      php artisan vendor:publish --provider="Spatie\Ray\RayServiceProvider"
      
    • Update .env with your Ray app credentials:
      RAY_APP_ID=your_app_id
      RAY_APP_SECRET=your_app_secret
      
  3. First Usage: Replace dd() or dump() with Ray’s methods:

    use Spatie\Ray\Ray;
    
    Ray::info('Debugging started');
    Ray::dump($user); // Inspects a variable
    Ray::table(['Name' => 'John', 'Age' => 30]); // Displays tabular data
    
  4. Run Ray:

    • Download the Ray desktop app and log in with your credentials.
    • Ensure your server can reach https://myray.app (no firewall blocking).

Implementation Patterns

Core Workflows

1. Debugging Variables

Replace dd() with Ray::dump() for interactive inspection:

Ray::dump($query->get(), 'User Query Results');
  • Pro Tip: Use Ray::inspect() for deep inspection without halting execution.

2. Logging and Context

Attach context (e.g., user ID, request data) to logs:

Ray::info('Order processed', [
    'user_id' => auth()->id(),
    'order_id' => $order->id,
]);
  • Laravel Integration: Automatically logs request data via middleware:
    use Spatie\Ray\Laravel\RayRequestLogger;
    
    class LogRayRequests extends RayRequestLogger {}
    

3. Performance Measurement

Measure execution time with Ray::spy():

Ray::spy('Fetching user data', function () {
    return User::find(1);
});
  • Group Spies: Nest spies to track hierarchical performance:
    Ray::spy('API Call', function () {
        Ray::spy('Database Query', fn() => User::find(1));
    });
    

4. Tabular and Structured Data

Display data in tables or JSON:

Ray::table($users->toArray(), 'Users List');
Ray::json($config, 'App Config');

5. Conditional Debugging

Use Ray::when() to debug only in specific environments:

Ray::when(config('app.debug'), function () {
    Ray::dump($this->data);
});

Laravel-Specific Patterns

Middleware Integration

Log requests automatically:

public function handle(Request $request, Closure $next)
{
    Ray::info('Request received', ['path' => $request->path()]);
    return $next($request);
}

Exception Handling

Log exceptions with stack traces:

use Spatie\Ray\Exceptions\Handler;

class RayExceptionHandler extends Handler
{
    public function report(Throwable $exception)
    {
        Ray::error($exception, 'Unhandled Exception');
    }
}

Artisan Commands

Debug CLI commands:

protected function handle()
{
    Ray::info('Running migration...');
    Artisan::call('migrate');
}

Event Listeners

Log events with payloads:

public function handle(OrderCreated $event)
{
    Ray::info('Order created', ['order_id' => $event->order->id]);
}

Testing

Use Ray::fake() in tests to mock Ray calls:

Ray::fake();
$response = $this->get('/users');
Ray::assertLogged('User fetched');

Advanced Features

Custom Themes and Styling

Apply themes or colors:

Ray::warning('Deprecation notice', [], 'dark');
Ray::success('Operation completed', [], 'green');

Clipboard Integration

Copy data to clipboard:

Ray::copy($user->email, 'User Email');

Livewire/Blade Debugging

Inspect Livewire properties or Blade templates:

Ray::dump($this->properties, 'Livewire Properties');

Remote Debugging

Debug server-side code from your local Ray app:

  1. Configure .env:
    RAY_REMOTE_DEBUG=true
    
  2. Use Ray::remote() to send data to your local Ray instance.

Gotchas and Tips

Common Pitfalls

1. Blocked Outbound Requests

  • Issue: Ray fails silently if myray.app is blocked by a firewall or proxy.
  • Fix: Whitelist myray.app in your server’s firewall or use a VPN.

2. Large Payloads

  • Issue: Sending large arrays (e.g., 10,000+ rows) may time out or crash Ray.
  • Fix: Use Ray::limit(100) or paginate data:
    Ray::table($users->take(100)->toArray());
    

3. Sensitive Data Leaks

  • Issue: Accidentally logging passwords or tokens.
  • Fix: Use Ray::mask() to redact sensitive fields:
    Ray::dump($user->only(['id', 'name']), 'User Data');
    

4. Performance Overhead

  • Issue: Excessive Ray::spy() calls slow down production.
  • Fix: Disable Ray in production:
    if (app()->environment('local')) {
        Ray::spy('Slow operation', fn() => $this->process());
    }
    

5. Laravel Caching Conflicts

  • Issue: Ray logs not appearing due to cached views or routes.
  • Fix: Clear cache after installing:
    php artisan cache:clear
    php artisan view:clear
    

Debugging Tips

1. Ray Not Showing Logs?

  • Check: Ensure RAY_APP_ID and RAY_APP_SECRET are correct.
  • Test: Run php artisan ray:test to verify connectivity.

2. Variables Not Displaying Properly

  • Issue: Complex objects (e.g., Closures, Resources) may not render.
  • Fix: Use Ray::inspect($variable) or cast to an array:
    Ray::dump((array) $resource);
    

3. Slow Debugging Sessions

  • Cause: High network latency or large payloads.
  • Fix: Use Ray::limit() or disable images in Ray settings.

4. Laravel Queue Workers

  • Issue: Ray logs not appearing in queue workers.
  • Fix: Ensure workers have access to .env and Ray is initialized:
    $this->app->make(\Spatie\Ray\Ray::class);
    

Configuration Quirks

1. .env Overrides

  • Priority: .env > config/ray.php.
  • Example: Override the endpoint:
    RAY_ENDPOINT=https://your-private-ray-server.com
    

2. Disabling Ray

  • Globally: Set RAY_ENABLED=false in .env.
  • Per-Request: Use middleware to disable:
    if (!$request->hasHeader('X-Debug')) {
        app()->forgetInstance(\Spatie\Ray\Ray::class);
    }
    

3. Custom Payload Formatting

  • Extend: Create a custom formatter:
    use Spatie\Ray\Formatters\Formatter;
    
    class CustomFormatter implements Formatter
    {
        public function format($payload): array
        {
            return ['custom' => json_encode($payload)];
        }
    }
    
    Register in config/ray.php:
    'formatters' => [
        \Spatie\Ray\Formatters\DefaultFormatter::class,
        \App\Formatters\CustomFormatter::class,
    ],
    

Extension Points

1. Custom Transport

Replace the default HTTP transport (e.g., for local debugging):

Ray::extend(function ($app) {
    $app->singleton(\Spatie\Ray\Ray::class, function () {
        return new \Spatie\Ray\Ray(new \App\Transports\LocalRayTransport());
    });
});

2. Hooks and Callbacks

Use afterSendCallbacks to modify payloads:

Ray::afterSend(function ($payload) {
    $payload['custom_metadata'] = ['timestamp' => now()];
    return $payload;
});

3. Rector for Code Cleanup

Remove Ray calls before production:

vendor/bin/rector process src --dry-run

Configure in rector.php:

use Spatie\Ray\Rector\RemoveRayCallRector;

$rules = [
    new RemoveRayCallRector(),
];

4. PHPStan Rules

Add PHPStan rules to detect Ray calls:

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport