pulsehub / laravel
PulseHub Laravel SDK — send live error reports and health snapshots from your Laravel app to a PulseHub server.
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.5
- illuminate/console: ^10.0|^11.0|^12.0|^13.0
- illuminate/contracts: ^10.0|^11.0|^12.0|^13.0
- illuminate/http: ^10.0|^11.0|^12.0|^13.0
- illuminate/queue: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^9.0|^10.0|^11.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
This package is not auto-updated.
Last update: 2026-05-22 18:59:54 UTC
README
Heartbeat of all your systems.
The official Laravel package for PulseHub.
Drop it into your Laravel app and every uncaught exception is sent live to
your PulseHub dashboard, where it becomes a task you can triage through
new → in_progress → in_review → done.
What this package does
In one line: catches errors from your Laravel app and POSTs them to your PulseHub server, live.
It also:
- Sends an hourly health report (PHP version, memory, CPU load, queue size).
- Validates your API key against the server.
- Detects when the PulseHub server is down or your token is bad — and logs
exactly what's wrong to
storage/logs/laravel.logso you spot the problem.
What about the URL?
There are two URLs in play. To make sure they don't get confused:
| Setting | What it is | Example value |
|---|---|---|
PULSEHUB_URL |
The server you POST to. Your PulseHub installation. | https://pulsehub.diqcare.com |
APP_URL |
Your Laravel app — leave it alone, that's not PulseHub. | https://my-shop.example.com |
The package never opens incoming ports. It only makes outbound HTTPS calls to
PULSEHUB_URLcarrying your bearer token.
1. Install (60 seconds)
composer require pulsehub/laravel php artisan vendor:publish --tag=pulsehub-config
Not on Packagist yet? Until the package is on Packagist, pick one of the two alternative install paths below — both let you keep using the same
composer require pulsehub/laravelcommand.
Install from GitHub (works today)
Add a VCS repository to your Laravel app's composer.json:
"repositories": [ { "type": "vcs", "url": "https://github.com/taiaburbd/PulseHub" } ]
Then run the bare command:
composer require pulsehub/laravel
Install from a local clone (for SDK contributors)
Clone the SDK next to your Laravel app and add a path repository:
"repositories": [ { "type": "path", "url": "../PulseHub", "options": { "symlink": true } } ]
Then run:
composer require pulsehub/laravel
Symlink mode means edits in your clone show up in vendor/pulsehub/laravel/
instantly — no reinstall needed.
After install
Open .env and add:
PULSEHUB_URL=https://pulsehub.diqcare.com PULSEHUB_TOKEN=ph_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx PULSEHUB_SOURCE=my-ecommerce-site PULSEHUB_TRANSPORT=queue PULSEHUB_INTERVAL=hourly
Where does the token come from? Register at https://pulsehub.diqcare.com/admin/register
(it's a free SaaS — your workspace and a starter source are created automatically),
go to API Tokens → Generate API token, copy the ph_live_... value immediately
— it's only shown once.
Viewer-role users can't generate tokens; ask your workspace admin.
2. Capture exceptions
For Laravel 11+ apps, add one line to bootstrap/app.php:
->withExceptions(function (Exceptions $exceptions) { \PulseHub\Laravel\Facades\PulseHub::registerExceptionHandler($exceptions); })
That's it. Every uncaught Throwable in your app is now sent to PulseHub.
Common noisy exceptions (404, validation, auth) are filtered out of the box;
see config/pulsehub.php → ignore_exceptions to customize.
Manual reporting
use PulseHub\Laravel\Facades\PulseHub; try { importInvoices($batchId); } catch (Throwable $e) { PulseHub::context(['batch' => $batchId]) ->user(auth()->id(), auth()->user()?->email) ->reportException($e); }
3. Verify the connection
php artisan pulsehub:test
You'll see one of four outcomes:
| Result | What it means |
|---|---|
| Connected. HTTP 200. | Token valid, server reachable. You're good. |
| Bad API key (HTTP 401/403) | Token wrong or revoked. Generate a fresh one in the dashboard. |
| Endpoint not found (404) | PULSEHUB_URL is pointing at the wrong host. |
| Server unreachable (5xx/network) | PulseHub is down OR network/firewall is blocking outbound HTTPS. |
These exact diagnoses also land in storage/logs/laravel.log whenever a real
report fails — so if reports stop arriving, just tail your logs:
production.ERROR: [PulseHub] Bad API key — server rejected the token. Check PULSEHUB_TOKEN.
production.ERROR: [PulseHub] Server unreachable or erroring — PulseHub may be down.
Live vs queued delivery
By default the package queues outbound calls so they never block a user request:
PULSEHUB_TRANSPORT=queue # default — uses your existing queue worker
If you want immediate (live) sends — useful for tiny apps or debugging:
PULSEHUB_TRANSPORT=sync
In dev environments with no queue worker (QUEUE_CONNECTION=sync) the package
auto-downgrades to sync, so things "just work" without configuration.
Hourly health reports
The package auto-registers an hourly schedule. As long as your Laravel scheduler cron is running:
* * * * * cd /path-to-your-app && php artisan schedule:run >> /dev/null 2>&1
…PulseHub gets a snapshot every hour:
{
"source": "my-ecommerce-site",
"php_version": "8.2.10",
"framework_version": "11.x",
"environment": "production",
"memory_usage_mb": 45.2,
"cpu_load": 0.18,
"queue_status": { "connection": "redis", "size": 12, "status": "ok" },
"error_count_last_hour": 3,
"status": "healthy",
"timestamp": "2026-01-01T10:00:00+00:00"
}
Run it manually any time:
php artisan pulsehub:report # queue (default) php artisan pulsehub:report --sync # send immediately
Useful Artisan commands
php artisan pulsehub:test # validate token + connectivity php artisan pulsehub:report # send a health report now php artisan pulsehub:status # show config + last delivery result
Capturing 5xx responses (optional middleware)
If you want HTTP 5xx responses reported even when no exception was thrown:
// bootstrap/app.php ->withMiddleware(function (Middleware $middleware) { $middleware->append(\PulseHub\Laravel\Middleware\PulseHubMiddleware::class); })
Configuration reference
Full config lives in config/pulsehub.php. Most-used keys:
| Key | Default | What it does |
|---|---|---|
token |
null |
PulseHub bearer token. Required. |
base_url |
pulsehub.io |
The PulseHub server URL. |
source_name |
APP_NAME |
Label shown in the dashboard. |
enabled |
true |
Master kill switch. |
interval |
hourly |
Health report frequency. null to disable. |
transport |
queue |
queue or sync. |
retry.attempts |
3 |
HTTP retry attempts. |
sample_rate |
1.0 |
Probability errors are forwarded (0–1). |
ignore_exceptions |
(defaults) | Classes to drop before sending. |
before_send |
null |
Hook to mutate or drop the payload. |
local_log.enabled |
false |
Persist every attempt to pulsehub_logs for debugging. |
Events you can hook into
use PulseHub\Laravel\Events\ReportSent; use PulseHub\Laravel\Events\ReportFailed; Event::listen(ReportSent::class, fn ($e) => /* ... */); Event::listen(ReportFailed::class, function ($e) { if ($e->category() === 'auth_invalid') { // page the on-call: PulseHub key is broken } });
Troubleshooting
"PULSEHUB_TOKEN is not set"
→ You forgot to add the token to your .env, or you haven't restarted PHP-FPM
/ queue worker after adding it.
"Bad API key" in logs → Token revoked or copy/paste error. Generate a fresh one from the dashboard.
Reports not arriving despite "Delivered (HTTP 200)"
→ Check that the source slug in the dashboard matches PULSEHUB_SOURCE in
your .env. The server identifies sources by their token, not by name.
"Server unreachable" but curl https://pulsehub.diqcare.com works
→ The queue worker is on a host with different outbound firewall rules. Try
PULSEHUB_TRANSPORT=sync to isolate.
Reports stop arriving after deploy
→ The package config is cached. Run php artisan config:clear or
php artisan config:cache.
Testing the package itself
composer install ./vendor/bin/phpunit
22 tests covering payload shape, queue dispatch, retries, failure categorization, and CLI commands.
Publishing to Packagist (maintainer notes)
After Packagist is set up, anyone in the world can run
composer require pulsehub/laravel — no VCS or path repository tricks.
One-time setup
- Push to GitHub (the repo is
https://github.com/taiaburbd/PulseHub). - Remove the
"version"field fromcomposer.json— Packagist derives versions from Git tags. The field is only there today so path-repo installs resolve as1.0.0instead ofdev-main. - Tag the first release:
git tag v1.0.0 git push origin v1.0.0
- Submit at https://packagist.org/packages/submit, paste the GitHub URL.
Packagist validates
composer.json, scans tags, and the package goes live. - Wire up the GitHub webhook (Settings → Webhooks → Add webhook) so Packagist picks up future tags automatically. Packagist provides the URL and secret in your package's "Settings" tab.
Cutting a new release
# 1. Bump CHANGELOG, commit # 2. Tag and push git tag v1.1.0 git push origin v1.1.0 # 3. Packagist picks it up via webhook (or hit "Update" in the Packagist UI)
Why the version field is in composer.json today
Composer's path repository assigns dev-main to every package unless the
package's own composer.json declares a version. That made
composer require pulsehub/laravel (no version constraint) fail with
"Could not find a version… matching your minimum-stability (stable)".
The version: 1.0.0 we added is a local development aid. Strip it before
submitting to Packagist (Composer prints a warning reminding you).
License
MIT — see LICENSE.