Batch Logs | laravel-activitylog | Spatie

 SPATIE

  Laravel Activity Log
=======================

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Laravel-activitylog](https://spatie.be/docs/laravel-activitylog/v4)  Advanced-usage  Batch Logs

 Version   v5   v4   v3   v2   v1

 Other versions for crawler [v5](https://spatie.be/docs/laravel-activitylog/v5) [v4](https://spatie.be/docs/laravel-activitylog/v4) [v3](https://spatie.be/docs/laravel-activitylog/v3) [v2](https://spatie.be/docs/laravel-activitylog/v2) [v1](https://spatie.be/docs/laravel-activitylog/v1)

- [ Introduction ](https://spatie.be/docs/laravel-activitylog/v4/introduction)
- [ Support us ](https://spatie.be/docs/laravel-activitylog/v4/support-us)
- [ Requirements ](https://spatie.be/docs/laravel-activitylog/v4/requirements)
- [ Installation and Setup ](https://spatie.be/docs/laravel-activitylog/v4/installation-and-setup)
- [ Questions and issues ](https://spatie.be/docs/laravel-activitylog/v4/questions-and-issues)
- [ Changelog ](https://spatie.be/docs/laravel-activitylog/v4/changelog)
- [ Upgrading ](https://spatie.be/docs/laravel-activitylog/v4/upgrading)
- [ About us ](https://spatie.be/docs/laravel-activitylog/v4/about-us)

Basic usage
-----------

- [ Logging activity ](https://spatie.be/docs/laravel-activitylog/v4/basic-usage/logging-activity)
- [ Cleaning up the log ](https://spatie.be/docs/laravel-activitylog/v4/basic-usage/cleaning-up-the-log)

Advanced usage
--------------

- [ Logging model events ](https://spatie.be/docs/laravel-activitylog/v4/advanced-usage/logging-model-events)
- [ Manipulate changes array ](https://spatie.be/docs/laravel-activitylog/v4/advanced-usage/manipulate-changes-array)
- [ Batch Logs ](https://spatie.be/docs/laravel-activitylog/v4/advanced-usage/batch-logs)
- [ Define causer for runtime ](https://spatie.be/docs/laravel-activitylog/v4/advanced-usage/define-causer-for-runtime)
- [ Using placeholders ](https://spatie.be/docs/laravel-activitylog/v4/advanced-usage/using-placeholders)
- [ Using multiple logs ](https://spatie.be/docs/laravel-activitylog/v4/advanced-usage/using-multiple-logs)
- [ Disabling logging ](https://spatie.be/docs/laravel-activitylog/v4/advanced-usage/disabling-logging)

API
---

- [ Log Options ](https://spatie.be/docs/laravel-activitylog/v4/api/log-options)
- [ Log Batch ](https://spatie.be/docs/laravel-activitylog/v4/api/log-batch)
- [ Causer Resolver ](https://spatie.be/docs/laravel-activitylog/v4/api/causer-resolver)
- [ Event Bag ](https://spatie.be/docs/laravel-activitylog/v4/api/event-bag)

      You are viewing the documentation for **an older version** of this package. You can check the version you are using with the following command:

 `                                    composer show spatie/laravel-activitylog                                                                                                                                                                                                                                    `

Batch Logs
==========

###  On this page

1. [ Retrieve Activities by batch ](#content-retrieve-activities-by-batch)
2. [ Note on starting new batches ](#content-note-on-starting-new-batches)
3. [ Check if batch is open ](#content-check-if-batch-is-open)
4. [ Keep LogBatch openend during multiple job/requests ](#content-keep-logbatch-openend-during-multiple-jobrequests)
5. [ Batch activities using callback ](#content-batch-activities-using-callback)

In some situations you may want to process multiple activities back to a single activity batch.

For example when a `User` deletes an `Author`, then that cascades soft deletes to the `Book`s that were owned by the `Author`. This way all modifications caused by that initial action are still associated with the same causer and batch UUID.

To start a new batch call `LogBatch::startBatch()` before any activity is done. Then all following actions will link back by UUID to that batch. After finishing activities you should end the batch by calling `LogBatch::endBatch()`.

Here's an example:

```
use Spatie\Activitylog\Facades\LogBatch;
use Spatie\Activitylog\Models\Activity;

LogBatch::startBatch();
$author = Author::create(['name' => 'Philip K. Dick']);
$book = Book::create(['name' => 'A Scanner Brightly', 'author_id' => $author->id]);
$book->update(['name' => 'A Scanner Darkly']);
$author->delete();
LogBatch::endBatch();
```

Doing this would allow all the activities within this batch to log together as described. This helps ensure those non-explicit actions like the cascade delete of the book get captured too.

Retrieve Activities by batch
--------------------------------------------------------------------------------------------------------------------------------------------

Once the batch is closed, if you save the batch's UUID, then you can retrieve all activities related to that batch. Do this by using the `Activity::whereBatchUuid($batchUuid)` lookup scope.

For example:

```
// ... started batch and other code
$batchUuid = LogBatch::getUuid(); // save batch id to retrieve activities later
LogBatch::endBatch();

$batchActivities = Activity::forBatch($batchUuid)->get();
```

Example results:

**Note** that in the examples both `Author` and `Book` are implementing `LogsActivity` trait.

```
use Spatie\Activitylog\Facades\LogBatch;
use Spatie\Activitylog\Models\Activity;

LogBatch::startBatch();

$author = Author::create(['name' => 'Philip K. Dick']);
$book = Book::create(['name' => 'A Scanner Brightly', 'author_id' => $author->id]);
$book->update(['name' => 'A Scanner Darkly']);
$book2 = Book::create(['name' => 'Paycheck', 'author_id' => $author->id]);

$author->delete();

$batchUuid = LogBatch::getUuid(); // save batch id to retrieve activities later
LogBatch::endBatch();

$batchActivities = Activity::forBatch($batchUuid)->get();
var_dump($batchActivities); // A collection of Activity models...
// They will be in order: Author;created, Book;created, Book;updated,
//      Book;created, Author;deleted, Book;deleted and Book;deleted
```

Note on starting new batches
--------------------------------------------------------------------------------------------------------------------------------------------

You may **not** start a new batch before ending the current open batch. Opening new batch while another one is open in the same request will result in the same `uuid`.

Activity batches works similarly to database transactions where number of started transactions/batches must be equal to the number of committed/closed transactions/batches.

Check if batch is open
--------------------------------------------------------------------------------------------------------------------------

It's important to not open a new batch from within an existing batch. This type of thing may come up within a queue job or middleware.

To verify if a batch is open or closed you can do the following:

```
// in middleware
LogBatch::startBatch();

//... Other middlewares

if(LogBatch::isOpen()) {
    // do something
}

```

Keep LogBatch openend during multiple job/requests
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

In some cases when you have multiple jobs that goes through queue batch, and you want to log all the activities during these different jobs using the same `LogBatch`, or you want to log multiple activities throughout multiple requests.

You may utilize `LogBatch::setBatch($uuid)` passing `$uuid` or any unique value that identify the batch to keep it open.

Here's an example:

```
use Spatie\Activitylog\Facades\LogBatch;
use Illuminate\Bus\Batch;
use Illuminate\Support\Str;

$uuid =  Str::uuid();

Bus::batch([
    // First job will open a batch
    new SomeJob('some value', $uuid), // pass uuid as a payload to the job
    new AnotherJob($uuid), // pass uuid as a payload to the job
    new WorkJob('work work work', $uuid), // pass uuid as a payload to the job
])->then(function (Batch $batch) {
    // All jobs completed successfully...
})->catch(function (Batch $batch, Throwable $e) {
    // First batch job failure detected...
})->finally(function (Batch $batch) use ($uuid) {
    // The batch has finished executing...
    LogBatch::getUuid() === $uuid // true
    LogBatch::endBatch();
})->dispatch();

// Later on..
Activity::forBatch($uuid)->get(); // all the activity that happend in the batch

```

```
class SomeJob
{
    public function handle(string $value, ?string $batchUuid = null)
    {
        LogBatch::startBatch();
        if($batchUuid) LogBatch::setBatch($batchUuid);

        // other code ..
    }
}

```

Batch activities using callback
-----------------------------------------------------------------------------------------------------------------------------------------------------

You can also batch activities using closure passed to `LogBatch::withinBatch()`. Every activity executed will happen inside that closure will be included in the same batch.

Here's an example:

```
use Spatie\Activitylog\Facades\LogBatch;

LogBatch::withinBatch(function(string $uuid) {
    $uuid; // 5cce9cb3-3144-4d35-9015-830cf0f20691
    activity()->log('my message');
    $item = NewsItem::create(['name' => 'new batch']);
    $item->update(['name' => 'updated']);
    $item->delete();
});

Activity::latest()->get(); // batch_uuid: 5cce9cb3-3144-4d35-9015-830cf0f20691

```
