Connectors
Connectors pull logs from a local directory or a remote SSH host into an
application, appending new bytes to a canonical mirror under sources/ and
running them through the normal ingestion pipeline. Endpoint reference:
reference/endpoint-connectors.md.
Types
Local directory
Points at any directory the PHP process can read; discovers files matching the log-file pattern, optionally recursively.
{"name":"Local exports","type":"local","config":{"directory":"/absolute/path","recursive":true}}
SSH
Reads files over SSH using your agent or a key path, always with host-key
verification (StrictHostKeyChecking=yes, BatchMode=yes). Paths may be exact
or use safe single-level globs for daily/rotated logs.
{
"name":"Production","type":"ssh","module_id":3,"enabled":true,
"config":{
"host":"app.example.com","port":22,"user":"deploy",
"key_path":"/Users/me/.ssh/id_ed25519",
"paths":[
"/var/www/app/storage/logs/laravel-*.log",
"/var/www/app/storage/logs/laravel.log.[0-9]*"
]
}
}
Paths must be absolute, contain no traversal (..) or control characters, and
use only single-level globs (no **). Up to 100 paths; discovery is capped by
sync.max_discovered_files.
Preview to snapshot to sync
Synchronization is always a two-step, race-safe flow:
- Preview (
POST /?api=connector-preview) returns the exact discovered files, the planned action per file (new / append / rotation / rename / reconcile / unchanged), bytes to fetch, and a snapshot hash of the file set and calculated plan. - Sync (
POST /?api=connector-sync) with that snapshot. If the remote file set or calculated plan changed since the preview, the sync is rejected. The endpoint queues a detached worker and returns202; pollconnector-runsfor live actionable-file, byte, and event progress. Unchanged files are not processed or included in the run total.
Only appended byte ranges are fetched (in sync.chunk_size chunks). Rotation
generations are preserved, and a manual import and a connector stream that share
a unique full-prefix hash are reconciled into one canonical source so
switching ingestion methods does not inflate occurrence counts.
Scheduling (CLI)
php bin/sync.php --app=my-app # all enabled connectors
php bin/sync.php --app=my-app --connector=2 # one connector
Run from cron or a supervisor. Each connector is locked during sync (a second concurrent sync of the same connector is refused), and it resumes from the canonical mirror/checkpoint after an interruption.
In the Laravel adapter, use php artisan log-lens:sync (schedule it in the
console kernel). See Laravel Package.