›
byrcsc/laravel-data-sync · 1.x
Inspect sync status, progress, counters, warnings, and row failures.
php artisan sync:status # the last 10 runs
php artisan sync:status products # one definition
php artisan sync:status products --limit=25
php artisan sync:status --failures # one line per failed rowRuns are listed newest first, across all definitions unless you name one.
Run Sync Status · path C/U/S/F Progress
01JQ8Z3M0K2N4P6R8T0V2X4Y6A products completed · bulk 980/20/0/0 1000 rows
01JQ8Z2A9F1M3P5R7T9V1X3Y5B products running · bulk 420/0/0/0 42% (84/200 jobs)
01JQ8Z1K7D0L2N4Q6S8U0W2Y4C products completed · bulk (dry run) 0/0/0/0 12 rows| Column | What it shows |
|---|---|
| Run | The run ULID, what sync:retry takes |
| Sync | The definition name |
| Status · path | The run status, a dry-run marker, and the write path |
| C/U/S/F | Rows created, updated, skipped, failed |
| Progress | Queued batch progress when a batch exists, otherwise the row total |
The write path reads bulk, eloquent, or transfer. It is stored on the run
at creation, so which path a run took is recorded rather than inferred. See the
write path tradeoff.
| Status | Meaning |
|---|---|
pending | Recorded, waiting on a worker |
running | In progress |
completed | Every row written |
completed_with_errors | Finished; some rows failed and were recorded |
failed | The run did not finish |
cancelled | The queued batch was cancelled |
completed_with_errors is a success for the file and a problem for some of
its rows: the checksum is marked processed, the file is archived, and the failed
rows sit in sync_row_failures waiting for you. A failed run does not mark the
file as processed and preserves it for retry.
CreateOnly on an existing
row, UpdateOnly on a new one), rows that lost a duplicate resolution, and
rows a beforeSave() hook returned false for.For a transfer, one file is one row: 1 created for a
transferred file, 1 skipped when the destination already held it or the
filename did not match.
While a queued run is in flight, sync:status reads its batch record and
reports real progress, 42% (84/200 jobs), instead of a row count. Once the
batch record is pruned by the framework, the row total is shown instead.
A run stuck at running with no batch progress usually means a dead worker.
sync:doctor warns about runs that have been running for more than an hour.
php artisan sync:status products --failures01JQ8Z3M0K2N4P6R8T0V2X4Y6A row 412: {"price_cents":["The price cents must be an integer."]} {"SKU":"DS-1041","Price":"n\/a"}
01JQ8Z3M0K2N4P6R8T0V2X4Y6A row 907: {"row":["Undefined array key \"Currency\""]} [payload capture disabled]Each line carries the run ULID, the row number as the reader counts it, the
validation errors keyed by attribute, and the captured raw payload. Rows whose
payload capture was off show [payload capture disabled], see sensitive
data.
The run itself also carries a summary: error_summary holds a JSON histogram of
field: message counts, which answers "what went wrong with this file" without
reading 900 individual rows.
sync_runs.warnings records non-fatal problems, most often a source cleanup
that failed after a successful import, such as a read-only supplier directory.
The run still completed and the data is still imported. Query the column when a
supplier reports files reappearing:
SyncRun::query()->whereNotNull('warnings')->latest('id')->get();use ByRcsc\LaravelDataSync\Models\SyncRun;
$run = SyncRun::query()->where('ulid', $ulid)->firstOrFail();
$run->status; // RunStatus enum
$run->write_path; // WritePath enum, or null for a transfer
$run->dry_run; // bool
$run->rows_created;
$run->unmapped_columns; // columns in the file no field mapped
$run->error_summary;
$run->archive_path;
$run->file; // the SyncFile ledger row
$run->failures; // SyncRowFailure records
SyncRun::query()
->where('definition', 'products')
->whereIn('status', ['failed', 'completed_with_errors'])
->whereDate('created_at', today())
->get();Both models read their table names from data-sync.tables, so custom names work
without subclassing. They are plain Eloquent models: build a dashboard, expose
them through an admin panel, or ship a daily digest from them.
Runs are pruned on a retention schedule, while the ledger is not. See retention and pruning before building reporting that assumes runs live forever.