===============
LIBRARY RULES
===============
From library maintainers:
- Requires PHP 8.2+, Symfony 6.4/7.x/8.x, and Doctrine ORM 3.4+. Storage backend: Elasticsearch 8 or 9 (default), any relational database via Doctrine DBAL, or in-memory for tests.
- Select the storage backend with the locastic_loggastic.storage config option: 'elasticsearch' (default, requires a PSR-18 HTTP client), 'doctrine' (stores logs in two shared database tables) or 'in_memory' (for test suites).
- Mark entities with the #[Loggable(groups: ['...'])] attribute and add the same serialization group to every field and relation you want tracked.
- Import Groups from Symfony\Component\Serializer\Attribute, not Symfony\Component\Serializer\Annotation; the Annotation import silently disables logging on Symfony 8.
- After configuring loggable entities, initialize the storage with bin/console locastic:activity-logs:create-loggable-indexes, then bin/console locastic:activity-logs:populate-current-data-trackers if data already exists.
- Read activity logs through the ActivityLogProviderInterface service instead of querying the storage backend directly.
- For a custom storage backend, implement ActivityLogStorageInterface, CurrentDataTrackerStorageInterface and StorageInitializerInterface, and alias the three interfaces to your services.
- The dataChanges field of an activity log holds two objects, previousValues and currentValues, each listing only the modified fields. It is not structured as per-field old/new pairs.
### Entity Creation Example
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/architecture.md
Demonstrates the basic creation and persistence of an entity using Doctrine. This is the starting point for logging entity mutations.
```php
$blogPost = new BlogPost();
$blogPost->setTitle('Hello');
$em->persist($blogPost);
$em->flush();
```
--------------------------------
### Example Workflow with Related Commands
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/console-commands.md
This example shows the typical sequence of commands for setting up logging, including creating indexes and populating trackers for existing data.
```bash
# 1. Create Elasticsearch indexes/database tables
bin/console locastic:activity-logs:create-loggable-indexes
# 2. If you have existing entities, populate their trackers
bin/console locastic:activity-logs:populate-current-data-trackers
# 3. Now logging will work correctly; updates will detect changes from the captured state
```
--------------------------------
### Basic Async Messenger Setup
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/configuration.md
Configure messages to be processed asynchronously. This setup routes specific message types to the default async handler.
```yaml
framework:
messenger:
routing:
'Locastic\Loggastic\Message\CreateActivityLogMessage': async
'Locastic\Loggastic\Message\UpdateActivityLogMessage': async
'Locastic\Loggastic\Message\DeleteActivityLogMessage': async
'Locastic\Loggastic\Message\PopulateCurrentDataTrackersMessage': async
```
--------------------------------
### Command Output Example
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/console-commands.md
This shows the expected output during the execution of the populate command, indicating progress and completion.
```text
Recreating App\Entity\BlogPost current data tracker storage...
Processing batch: 0-100
...............................
Processing batch: 100-200
...............................
Done!
```
--------------------------------
### Example Output for Index Creation
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/console-commands.md
This output shows the successful creation of storage resources for different loggable classes.
```text
Preparing activity log storage ...
Creating App\Entity\BlogPost activity log storage
Creating App\Entity\BlogPost current data tracker storage
Creating App\Entity\Product activity log storage
Creating App\Entity\Product current data tracker storage
Done!
```
--------------------------------
### Loggastic Configuration Example
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/README.md
Example of Loggastic configuration in YAML format. Specifies the storage backend and paths for loggable classes.
```yaml
# config/packages/loggastic.yaml
locastic_loggastic:
# Storage backend: elasticsearch, doctrine, or in_memory
storage: doctrine
# Path to loggable classes
loggable_paths:
- '%kernel.project_dir%/src/Entity'
```
--------------------------------
### CurrentDataTracker Example Usage
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/data-models.md
Demonstrates how to retrieve information from a CurrentDataTracker instance, representing the state of a BlogPost.
```php
// A tracker stores the latest state of a BlogPost
$tracker->getId(); // 'tracker-123' (from storage)
$tracker->getObjectId(); // '1' (BlogPost ID)
$tracker->getObjectClass(); // 'App\Entity\BlogPost'
$tracker->getData(); // ['title' => 'Hello', 'slug' => 'hello', ...]
$tracker->getDateTime(); // DateTime when this data was captured
```
--------------------------------
### Comprehensive Production Activity Log Enricher Example
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/pre-dispatch-event.md
An example of a production-ready event listener that enriches activity log messages with security and request context. It logs entity deletions at a higher severity level. Ensure you have the necessary Symfony security and http-foundation components installed.
```php
getActivityLogMessage();
$request = $this->requestStack->getCurrentRequest();
$user = $this->security->getUser();
// Enrich with security context
$message->setUser($this->getUserData($user, $request));
// Enrich with request context
$message->setRequestUrl($request?->getUri());
// Log deletions at a higher level
if ($message instanceof DeleteActivityLogMessageInterface) {
$this->logger->warning(
'Entity deletion logged',
[
'class' => $message->getClassName(),
'id' => $message->getObjectId(),
'user' => $user?->getUserIdentifier(),
]
);
}
}
private function getUserData($user, $request): array
{
if (!$user) {
return [
'anonymous' => true,
'ip' => $request?->getClientIp(),
];
}
return [
'id' => $user->getId(),
'username' => $user->getUserIdentifier(),
'email' => $user->getEmail() ?? null,
'roles' => $user->getRoles(),
'ip' => $request?->getClientIp(),
'user_agent' => $request?->headers->get('User-Agent'),
];
}
}
```
--------------------------------
### API Method Signature Example
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/README.md
Illustrates the standard format for documenting PHP methods, including parameters and their types, optionality, defaults, and descriptions, as well as the return type.
```php
public function methodName(Type $param, ?Type $optional = null): ReturnType
```
--------------------------------
### PopulateCurrentDataTrackersMessage getOffset Method
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/message-classes.md
Retrieves the starting position for the batch operation.
```php
public function getOffset(): int
```
--------------------------------
### Instantiate and Save CurrentDataTrackerInput
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/data-models.md
Example of creating a CurrentDataTrackerInput object, setting its properties including JSON encoded data, and saving it using a storage service.
```php
$input = new CurrentDataTrackerInput();
$input->setObjectId('1');
$input->setObjectClass('App\Entity\BlogPost');
$input->setData(json_encode(['title' => 'Hello']));
$storage->save($input, 'App\Entity\BlogPost');
```
--------------------------------
### Activity Log Retrieval Example
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/architecture.md
Shows how to retrieve activity logs for a specific entity class and ID using the ActivityLogProvider. This is used for reading persisted logs.
```php
$logs = $activityLogProvider->getActivityLogsByClassAndId($className, $objectId);
```
--------------------------------
### Activity Log Record Structure
Source: https://github.com/locastic/loggastic/blob/master/README.md
An example of the data structure for an activity log record, specifically showing changes for 'Edited' actions.
```json
{
"previousValues": {"title": "My first post"},
"currentValues": {"title": "My updated post"}
}
```
--------------------------------
### Example PHP Class Structure
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/README.md
Demonstrates the basic structure of a PHP class intended for use within the Loggastic framework. This serves as a template for implementing services that interact with the logging system.
```php
findByClass(
'App\Entity\BlogPost',
['loggedAt' => 'desc', 'action' => 'asc'],
20
);
```
--------------------------------
### Activity Log Test Case - PHP
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/in-memory-storage.md
Extends `KernelTestCase` to provide setup and assertion methods for testing activity logs. It initializes the logger and provider and includes helpers to verify specific actions and data changes.
```php
'test']);
$container = self::getContainer();
$this->logger = $container->get(ActivityLoggerInterface::class);
$this->provider = $container->get(ActivityLogProviderInterface::class);
}
protected function assertLoggedAction(string $className, $objectId, string $action): void
{
$logs = $this->provider->getActivityLogsByClassAndId($className, $objectId);
$actions = array_map(fn($log) => $log->getAction(), $logs);
$this->assertContains($action, $actions, "Action '$action' not found in logs");
}
protected function assertDataChangeLogged(string $className, $objectId, string $field): void
{
$logs = $this->provider->getActivityLogsByClassAndId($className, $objectId);
foreach ($logs as $log) {
$changes = $log->getDataChanges();
if ($changes && isset($changes[$field])) {
return; // Found
}
}
$this->fail("Field '$field' change not logged");
}
}
```
--------------------------------
### Display Activity Logs in Twig
Source: https://github.com/locastic/loggastic/blob/master/README.md
Example Twig template code for iterating through and displaying activity logs. Assumes `activityLogs` variable is available.
```twig
Activity logs for Blog Posts:
{% for log in activityLogs %}
{{ log.action }} {{ log.objectType }} with {{ log.objectId }} ID at {{ log.loggedAt|date('d.m.Y H:i:s') }} by {{ log.user.username }}
{% endfor %}
```
--------------------------------
### Unit Test with In-Memory Storage
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/in-memory-storage.md
Ideal for unit and integration tests where you don't want external dependencies. This example demonstrates logging blog post creation and updates using the in-memory storage.
```php
'test']);
$container = self::getContainer();
$this->logger = $container->get(ActivityLoggerInterface::class);
$this->provider = $container->get(ActivityLogProviderInterface::class);
}
public function testBlogPostCreationIsLogged(): void
{
$post = new BlogPost();
$post->setTitle('Test Post');
$this->logger->logCreatedItem($post);
$logs = $this->provider->getActivityLogsByClassAndId(BlogPost::class, $post->getId());
$this->assertCount(1, $logs);
$this->assertSame('Created', $logs[0]->getAction());
}
public function testBlogPostUpdateIsLogged(): void
{
$post = new BlogPost();
$post->setTitle('Original Title');
// Log creation
$this->logger->logCreatedItem($post);
// Update
$post->setTitle('Updated Title');
$this->logger->logUpdatedItem($post);
$logs = $this->provider->getActivityLogsByClassAndId(BlogPost::class, $post->getId());
$this->assertCount(2, $logs);
$this->assertSame('Created', $logs[0]->getAction());
$this->assertSame('Edited', $logs[1]->getAction());
}
}
```
--------------------------------
### Enriching Activity Log Messages with User Information
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/activity-log-message-dispatcher.md
Implement a listener to enrich activity log messages before dispatch. This example adds user details like username and ID to the message.
```php
getActivityLogMessage();
$user = $this->security->getUser();
$message->setUser([
'username' => $user?->getUserIdentifier(),
'id' => $user?->getId(),
]);
}
}
```
--------------------------------
### AMQP Transport Configuration
Source: https://github.com/locastic/loggastic/blob/master/README.md
Configure AMQP transports for 'activity_logs_default' and 'activity_logs_product' queues. This setup is suitable for high-throughput message processing.
```yaml
framework:
messenger:
transports:
activity_logs_default:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
exchange:
name: activity_logs_default
queues:
activity_logs_default: ~
activity_logs_product:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
options:
queues:
activity_logs_product: ~
exchange:
name: activity_logs_product
routing:
'Locastic\Loggastic\Message\PopulateCurrentDataTrackersMessage': activity_logs_default
'Locastic\Loggastic\Message\CreateActivityLogMessage': activity_logs_default
'Locastic\Loggastic\Message\DeleteActivityLogMessage': activity_logs_default
'Locastic\Loggastic\Message\UpdateActivityLogMessage': activity_logs_default
```
--------------------------------
### Log Fields from Relations (PHP)
Source: https://github.com/locastic/loggastic/blob/master/README.md
Example of logging fields from related entities in PHP. Ensure the related entity's fields also have the correct serialization groups.
```php
product;
}
public function setProduct(?Product $product): self
{
$this->product = $product;
return $this;
}
public function logTo(): ?object
{
return $this->product;
}
}
```
--------------------------------
### Get Activity Logs by Class
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/activity-log-provider.md
Retrieves all activity logs for a given entity class. Use this to fetch logs associated with a specific type of entity. Supports sorting and pagination.
```php
use Locastic\Loggastic\DataProvider\ActivityLogProvider;
// Assuming $activityLogProvider is an instance of ActivityLogProvider
// Get last 20 logs for BlogPost
$logs = $activityLogProvider->getActivityLogsByClass(
'App\Entity\BlogPost',
['loggedAt' => 'desc'],
20,
0
);
// Paginate through logs
$page = 2;
$perPage = 10;
$logs = $activityLogProvider->getActivityLogsByClass(
'App\Entity\BlogPost',
[],
$perPage,
($page - 1) * $perPage
);
```
--------------------------------
### Manual Logging in Tests
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/in-memory-storage.md
Example of manually triggering a log entry within a test method. This ensures logs are only captured via explicit calls when the Doctrine subscriber is disabled.
```php
public function testManualLogging(): void
{
// Only logs via explicit logger calls
$this->logger->logCreatedItem($entity);
}
```
--------------------------------
### Custom Activity Log Message Dispatcher
Source: https://github.com/locastic/loggastic/blob/master/README.md
Decorate the ActivityLogMessageDispatcher to implement custom logic for dispatching messages to specific transports. This example routes 'Product' entity logs to 'activity_logs_product'.
```php
getClassName() === Product::class) {
$this->decorated->dispatch($activityLogMessage, 'activity_logs_product');
return;
}
$this->decorated->dispatch($activityLogMessage, $transportName);
}
}
```
--------------------------------
### Enriching Activity Log Messages with an Event Listener
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/pre-dispatch-event.md
An example of an event listener that intercepts `PreDispatchActivityLogMessageEvent` to enrich the `ActivityLogMessageInterface` with user details (ID, username, roles) and the current request URL. This listener requires `Security` and `RequestStack` services.
```php
getActivityLogMessage();
// Set user information
$user = $this->security->getUser();
$message->setUser([
'id' => $user?->getId(),
'username' => $user?->getUserIdentifier(),
'roles' => $user?->getRoles() ?? [],
]);
// Set request URL
$request = $this->requestStack->getCurrentRequest();
$message->setRequestUrl($request?->getUri());
}
}
```
--------------------------------
### Initialize and Populate Activity Logs (Bash)
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/console-commands.md
Use this bash script for automated deployments to create storage indexes and populate trackers from existing data. It simulates non-interactive input for selecting options and batch size.
```bash
#!/bin/bash
# Create indexes/tables
bin/console locastic:activity-logs:create-loggable-indexes
# Populate trackers from existing data
# Use echo to provide non-interactive input: select "ALL" + batch size
echo -e "2\n100" | bin/console locastic:activity-logs:populate-current-data-trackers
```
--------------------------------
### Get Activity Logs by Class and ID
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/activity-log-provider.md
Retrieves activity logs for a specific entity instance. Use this to get the history of a particular record. Supports sorting and pagination.
```php
use Locastic\Loggastic\DataProvider\ActivityLogProvider;
// Assuming $activityLogProvider is an instance of ActivityLogProvider
// Get activity history for a specific blog post
$logs = $activityLogProvider->getActivityLogsByClassAndId(
'App\Entity\BlogPost',
1,
['loggedAt' => 'desc'],
50
);
foreach ($logs as $log) {
echo $log->getAction(); // 'Created', 'Edited', 'Deleted'
echo $log->getLoggedAt()->format('Y-m-d H:i:s');
echo $log->getUser()['username'] ?? 'anonymous';
}
```
--------------------------------
### Initialize Loggastic Storage
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/index.md
Run these console commands to create necessary indexes for activity logs and populate data trackers.
```bash
bin/console locastic:activity-logs:create-loggable-indexes
bin/console locastic:activity-logs:populate-current-data-trackers
```
--------------------------------
### Create Loggable Indexes
Source: https://github.com/locastic/loggastic/blob/master/README.md
Initialize the necessary Elasticsearch indexes or database tables for loggable entities using the console command.
```bash
bin/console locastic:activity-logs:create-loggable-indexes
```
--------------------------------
### Get Updated Item
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/message-classes.md
Retrieves the entity that was modified. This method is part of the UpdateActivityLogMessage class.
```php
public function getUpdatedItem(): object
```
--------------------------------
### Initialize Loggastic Storage
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/configuration.md
Run this command after configuration to initialize the necessary storage structures, such as creating indexes or tables.
```bash
# Initialize storage (create indexes or tables)
bin/console locastic:activity-logs:create-loggable-indexes
```
--------------------------------
### Get Message Date Time
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/message-classes.md
Retrieves the timestamp when the message was created. This method is part of the UpdateActivityLogMessage class.
```php
public function getDateTime():
DateTime
```
--------------------------------
### Initialize and Populate Activity Logs (PHP)
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/console-commands.md
Execute Loggastic console commands directly within PHP for creating storage and populating trackers. This method is useful when integrating command logic into existing PHP applications.
```php
use Locastic\Loggastic\Command\CreateLoggableIndexesCommand;
use Locastic\Loggastic\Command\PopulateCurrentDataTrackersCommand;
use Symfony\Component\Console\Input\StringInput;
// Create storage
$command = $application->find('locastic:activity-logs:create-loggable-indexes');
$command->run(new StringInput(''), $output);
// Populate trackers
$command = $application->find('locastic:activity-logs:populate-current-data-trackers');
$command->run(new StringInput('ALL 100'), $output);
```
--------------------------------
### CreateActivityLogMessage getDateTime Method
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/message-classes.md
Gets the timestamp when the log message was created. This typically defaults to the current time.
```php
public function getDateTime(): \DateTime
```
--------------------------------
### Populate Data Trackers with Custom Batch Size via Input
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/errors.md
Configure the populate command to process a larger number of entities at once for faster completion by piping input to specify the batch size.
```bash
# Process 1000 entities at a time for faster completion
echo -e "ALL\n1000" | bin/console locastic:activity-logs:populate-current-data-trackers
```
--------------------------------
### Elasticsearch JSON Document
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/data-models.md
Documents are stored as-is in Elasticsearch. This example shows the structure of a typical activity log entry.
```json
{
"id": "log-123",
"action": "Edited",
"loggedAt": "2024-01-15T10:30:00Z",
"objectId": "1",
"objectClass": "App\\Entity\\BlogPost",
"dataChanges": {
"title": {"old": "Hello", "new": "World"}
},
"user": {"username": "admin", "id": 1},
"requestUrl": "http://example.com/admin/posts/1/edit"
}
```
--------------------------------
### Get Elasticsearch Item by ID
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/elasticsearch-service.md
Retrieves a single document from an Elasticsearch index by its ID. The document is denormalized into the specified class.
```php
$log = $elasticsearchService->getItemById(
'log-123',
'blog_post_activity_log',
ActivityLog::class
);
```
--------------------------------
### Run Populate Current Data Trackers Command
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/console-commands.md
Execute the command to repopulate data trackers. This is a common step after database migrations or when setting up logging for existing entities.
```bash
bin/console locastic:activity-logs:populate-current-data-trackers
```
--------------------------------
### Get Normalized Item Data
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/message-classes.md
Returns the normalized (serialized) data of the entity as set by the logger. This method is part of the UpdateActivityLogMessage class.
```php
public function getNormalizedItem(): array
```
--------------------------------
### Constructor for ActivityLogProcessor
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/activity-log-processor.md
Initializes the ActivityLogProcessor with necessary dependencies for normalizing objects, managing activity logs, tracking current data, and creating input factories.
```php
public function __construct(
NormalizerInterface $objectNormalizer,
ActivityLogStorageInterface $activityLogStorage,
CurrentDataTrackerStorageInterface $currentDataTrackerStorage,
ActivityLogInputFactoryInterface $activityLogInputFactory,
CurrentDataTrackerInputFactoryInterface $currentDataTrackerInputFactory,
LoggableContextFactoryInterface $loggableContextFactory
)
```
--------------------------------
### Add Loggable Attribute to Entity (PHP)
Source: https://github.com/locastic/loggastic/blob/master/README.md
Example of adding the Loggable attribute to a PHP entity class. Define the serialization groups for logging.
```php
getCollection(
'blog_post_activity_log',
ActivityLog::class,
[
'query' => [
'term' => ['objectId' => '123']
],
'sort' => [
'loggedAt' => 'desc'
]
],
20,
0
);
foreach ($logs as $log) {
echo $log->getAction();
}
```
--------------------------------
### Get Elasticsearch Item by Query
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/elasticsearch-service.md
Retrieves a single document matching an Elasticsearch query. The document is denormalized into the specified class. An empty query body will match all documents.
```php
$log = $elasticsearchService->getItemByQuery(
'blog_post_activity_log',
ActivityLog::class,
[
'query' => [
'term' => ['objectId' => '123']
]
]
);
```
--------------------------------
### Get Current Data Tracker by Class and ID
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/current-data-tracker-provider.md
Retrieves the tracker containing the last known state of an entity. Use this to access previous values of fields before an update.
```php
public function __construct(CurrentDataTrackerStorageInterface $currentDataTrackerStorage)
```
```php
public function getCurrentDataTrackerByClassAndId(string $className, $objectId): ?CurrentDataTrackerInterface
```
```php
$tracker = $currentDataTrackerProvider->getCurrentDataTrackerByClassAndId(
'App\Entity\BlogPost',
1
);
if ($tracker) {
$oldData = $tracker->getData(); // Array of all tracked fields
echo $oldData['title']; // Previous value of title field
}
```
--------------------------------
### initializeActivityLogStorage
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/storage-interfaces.md
Creates activity log storage for a loggable class if it doesn't exist. Implementations must be safe to run repeatedly.
```APIDOC
## initializeActivityLogStorage
### Description
Creates activity log storage for a loggable class if it doesn't exist. Implementations must be safe to run repeatedly.
### Method Signature
`public function initializeActivityLogStorage(string $className): bool`
### Parameters
#### Path Parameters
- **className** (string) - Required - Fully qualified class name
### Returns
- **bool** - true if storage was created, false if it already existed
```
--------------------------------
### Initialize Current Data Tracker Storage
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/storage-interfaces.md
Creates storage for current data trackers for a specified class if it's not already present. This operation is designed to be safely repeatable.
```php
public function initializeCurrentDataTrackerStorage(string $className): bool
```
--------------------------------
### Populate Loggastic Trackers
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/configuration.md
Use this command to populate trackers from existing data, typically after schema changes have been made.
```bash
# Populate trackers from existing data (after schema changes)
bin/console locastic:activity-logs:populate-current-data-trackers
```
--------------------------------
### Log Created Item with Dispatch
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/activity-log-message-dispatcher.md
Logs a created item by creating a `CreateActivityLogMessage`, dispatching a pre-dispatch event, and then sending the message to the bus via the `ActivityLogMessageDispatcher`.
```php
public function logCreatedItem(object $item, ?string $actionName = null): void
{
$message = new CreateActivityLogMessage($item, $actionName);
// Dispatch the event so listeners can enrich the message
$this->eventDispatcher->dispatch(PreDispatchActivityLogMessageEvent::create($message));
// Send to message bus
$this->activityLogMessageDispatcher->dispatch($message);
}
```
--------------------------------
### YAML Configuration for Loggable Paths
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/errors.md
Specify YAML and XML configuration files within the loggable paths to avoid unsupported mapping type errors.
```yaml
locastic_loggastic:
loggable_paths:
- '%kernel.project_dir%/src/Entity'
- '%kernel.project_dir%/config/loggastic' # Place .yml and .xml here
```
--------------------------------
### Populate Current Data Trackers with Smaller Batch Size
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/errors.md
Use this command to populate data trackers. Specify a smaller batch size (e.g., 50) to prevent memory exhaustion during batch processing.
```bash
bin/console locastic:activity-logs:populate-current-data-trackers
# Choose batch size: 50 (instead of default 100)
```
--------------------------------
### UpdateActivityLogMessageInterface
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/types.md
Interface for updating activity log messages. It includes methods for getting and setting the updated item, its normalized representation, the date/time of the update, and a flag to check if the log was created without changes.
```APIDOC
## UpdateActivityLogMessageInterface
Interface for update messages.
### Methods
- **getUpdatedItem()**: object - Retrieves the updated item.
- **setUpdatedItem(object $updatedItem)**: void - Sets the updated item.
- **getNormalizedItem()**: array - Retrieves the normalized representation of the item.
- **setNormalizedItem(array $normalizedItem)**: void - Sets the normalized representation of the item.
- **isCreateLogWithoutChanges()**: bool - Checks if the log was created without any changes.
- **getDateTime()**: \DateTime - Retrieves the date and time of the update.
- **setDateTime(\DateTime $dateTime)**: void - Sets the date and time of the update.
```
--------------------------------
### Create Activity Log Input from Message
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/architecture.md
Use the `ActivityLogInputFactory` to create input models from incoming messages. This is part of the Factory Pattern implementation for message handling.
```php
$activityLogInput = $activityLogInputFactory->createFromActivityLogMessage($message);
```
--------------------------------
### ActivityLogInputInterface
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/types.md
Defines the structure for input data used when persisting activity logs. It includes methods for setting and getting various log-related attributes such as action, timestamp, object details, and user information.
```APIDOC
## Interface: ActivityLogInputInterface
### Description
Input model used to persist activity logs to storage.
### Methods
- `getAction(): ?string`
- `setAction(?string $action): void`
- `getLoggedAt(): \DateTime`
- `setLoggedAt(\DateTime $loggedAt): void`
- `getObjectId(): string`
- `setObjectId($objectId): void`
- `getObjectClass(): ?string`
- `setObjectClass(?string $objectClass): void`
- `getRequestUrl(): ?string`
- `setRequestUrl(?string $requestUrl): void`
- `getDataChanges(): ?string`
- `setDataChanges(?string $dataChanges = null): void`
- `getUser(): ?array`
- `setUser(?array $user): void`
### Location
`src/Model/Input/ActivityLogInputInterface.php`
```
--------------------------------
### PreDispatchActivityLogMessageEvent::create
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/types.md
Creates a new PreDispatchActivityLogMessageEvent instance.
```APIDOC
## create
### Description
Creates a new PreDispatchActivityLogMessageEvent instance.
### Method
`create(ActivityLogMessageInterface $activityLogMessage): self`
### Parameters
#### Path Parameters
- **activityLogMessage** (ActivityLogMessageInterface) - Required - The activity log message associated with the event.
```
--------------------------------
### InMemoryStorageInitializer No-Op Implementation
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/in-memory-storage.md
Demonstrates the no-operation implementation of InMemoryStorageInitializer. The initializeActivityLogStorage method always returns true, indicating no actual initialization is needed for in-memory storage.
```php
public function initializeActivityLogStorage(string $className): bool
{
return true; // Always return true (no actual storage to initialize)
}
```
--------------------------------
### PopulateCurrentDataTrackersMessage Constructor
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/message-classes.md
Use this constructor to create a message for batch operations to populate current data trackers. Specify the offset, batch size, loggable class, and context.
```php
public function __construct(int $offset, int $batchSize, string $loggableClass, array $loggableContext)
```
--------------------------------
### Populate Current Data Trackers Command
Source: https://github.com/locastic/loggastic/blob/master/README.md
Command to populate the current data trackers table. Use this if you have existing data and are enabling logging.
```bash
bin/console locastic:activity-logs:populate-current-data-trackers
```
--------------------------------
### Verify Loggable Paths Existence
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/errors.md
Use shell commands to check if the configured paths for loggable files exist and are accessible.
```bash
ls -la config/packages/loggastic
ls -la src/Entity
```
--------------------------------
### initializeCurrentDataTrackerStorage
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/storage-interfaces.md
Creates current data tracker storage for a loggable class if it doesn't exist. Implementations must be safe to run repeatedly.
```APIDOC
## initializeCurrentDataTrackerStorage
### Description
Creates current data tracker storage for a loggable class if it doesn't exist. Implementations must be safe to run repeatedly.
### Method Signature
`public function initializeCurrentDataTrackerStorage(string $className): bool`
### Parameters
#### Path Parameters
- **className** (string) - Required - Fully qualified class name
### Returns
- **bool** - true if storage was created, false if it already existed
```
--------------------------------
### recreateCurrentDataTrackerStorage
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/storage-interfaces.md
Drops existing current data tracker storage and creates it from scratch.
```APIDOC
## recreateCurrentDataTrackerStorage
### Description
Drops existing current data tracker storage and creates it from scratch.
### Method Signature
`public function recreateCurrentDataTrackerStorage(string $className): void`
### Parameters
#### Path Parameters
- **className** (string) - Required - Fully qualified class name
### Returns
- **void**
```
--------------------------------
### ActivityLogDoctrineSubscriber Constructor
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/activity-log-doctrine-subscriber.md
Initializes the subscriber with an ActivityLoggerInterface service to dispatch logging messages.
```php
public function __construct(ActivityLoggerInterface $activityLogger)
```
--------------------------------
### Interactive Mode Prompts
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/console-commands.md
When run interactively, the command prompts for the loggable class and batch size. This allows for targeted repopulation or processing of large datasets in manageable chunks.
```text
Choose loggable class to repopulate current data:
[0] App\Entity\BlogPost
[1] App\Entity\Product
[2] ALL
> 2
Enter batch size (number of entities to process per batch) [100]:
> 500
```
--------------------------------
### Log Created Item
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/activity-logger.md
Logs the creation of an entity. Use a custom action name if the default 'CREATED' is not suitable.
```php
$activityLogger->logCreatedItem($blogPost);
// or with custom action name
$activityLogger->logCreatedItem($blogPost, 'BlogPostCreated');
```
--------------------------------
### Verify Elasticsearch Host Configuration
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/errors.md
Check the Loggastic configuration file to ensure the correct Elasticsearch host is specified.
```bash
# Verify config
grep elastic_host config/packages/loggastic.yaml
```
--------------------------------
### Register Custom Activity Log Storage
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/architecture.md
Register your custom activity log storage implementation as a service. Ensure it implements the ActivityLogStorageInterface.
```yaml
services:
Locastic\Loggastic\Storage\ActivityLogStorageInterface: '@App\MyActivityLogStorage'
```
--------------------------------
### PHP: Correctly Retrieve Activity Logs
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/errors.md
Ensure the fully qualified class name is used when retrieving activity logs to avoid 'Missing Activity Log' errors.
```php
// Correct
$logs = $provider->getActivityLogsByClassAndId('App\Entity\BlogPost', 1);
// Wrong
$logs = $provider->getActivityLogsByClassAndId('BlogPost', 1);
```
--------------------------------
### Loggastic Storage Interfaces
Source: https://github.com/locastic/loggastic/blob/master/README.md
These are the core interfaces that must be implemented for custom storage backends. They define the contracts for writing/reading logs, tracking data, and initializing storage.
```php
Locastic\Loggastic\Storage\ActivityLogStorageInterface # writes and reads activity logs
Locastic\Loggastic\Storage\CurrentDataTrackerStorageInterface # tracks the latest state of each loggable object
Locastic\Loggastic\Storage\StorageInitializerInterface # creates the underlying storage (indexes, tables, ...)
```
--------------------------------
### Configuring Loggable Entities with XML
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/loggable-attribute.md
Define loggable classes and their associated serialization groups using an XML configuration file. This provides another alternative to PHP attributes.
```xml
```
--------------------------------
### Listen to Specific Activity Log Message Types
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/pre-dispatch-event.md
Register a listener that specifically handles create messages. The listener checks the message type and returns early if it's not a create message, allowing for custom logic only for create operations.
```php
#[AsEventListener(event: PreDispatchActivityLogMessageEvent::class)]
final class CreateActivityLogEnricher
{
public function __invoke(PreDispatchActivityLogMessageEvent $event): void
{
$message = $event->getActivityLogMessage();
// Only handle create messages
if (!$message instanceof CreateActivityLogMessageInterface) {
return;
}
// Custom logic for creates
}
}
```
--------------------------------
### Listen to All Activity Log Message Types
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/pre-dispatch-event.md
Register a listener to enrich all activity log messages (Create, Update, Delete). This listener is triggered for every pre-dispatch activity log event.
```php
#[AsEventListener(event: PreDispatchActivityLogMessageEvent::class)]
final class AllActivityLogEnricher
{
public function __invoke(PreDispatchActivityLogMessageEvent $event): void
{
// Enrich all messages (Create, Update, Delete)
$message = $event->getActivityLogMessage();
$message->setUser(['id' => 1, 'username' => 'admin']);
}
}
```
--------------------------------
### ActivityLogInputInterface PHP
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/types.md
Interface for input models used to persist activity logs. Implement this to provide data for logging.
```php
interface ActivityLogInputInterface
{
public function getAction(): ?string;
public function setAction(?string $action): void;
public function getLoggedAt(): \DateTime;
public function setLoggedAt(\DateTime $loggedAt): void;
public function getObjectId(): string;
public function setObjectId($objectId): void;
public function getObjectClass(): ?string;
public function setObjectClass(?string $objectClass): void;
public function getRequestUrl(): ?string;
public function setRequestUrl(?string $requestUrl): void;
public function getDataChanges(): ?string;
public function setDataChanges(?string $dataChanges = null): void;
public function getUser(): ?array;
public function setUser(?array $user): void;
}
```
--------------------------------
### ElasticsearchService Constructor
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/elasticsearch-service.md
The constructor for the ElasticsearchService initializes the service with necessary dependencies for Elasticsearch interaction and data serialization.
```APIDOC
## Constructor
```php
public function __construct(
ElasticsearchClientInterface $elasticsearchClient,
NormalizerInterface $normalizer,
DenormalizerInterface $denormalizer
)
```
### Parameters
- **$elasticsearchClient** (ElasticsearchClientInterface) - Required - Low-level Elasticsearch client wrapper
- **$normalizer** (NormalizerInterface) - Required - Symfony serializer for normalizing objects to arrays
- **$denormalizer** (DenormalizerInterface) - Required - Symfony serializer for denormalizing arrays back to objects
```
--------------------------------
### Retrieve Activity Logs
Source: https://github.com/locastic/loggastic/blob/master/README.md
Use the `ActivityLogProviderInterface` service to fetch activity logs for a specific class and ID.
```php
$activityLogs = $activityLogProvider->getActivityLogsByClassAndId(BlogPost::class, $blogPost->getId());
```
--------------------------------
### Process Created Item in ActivityLogProcessor
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/activity-log-processor.md
Saves a creation activity log and an initial current data tracker snapshot for a new item. This method is called internally by the CreateActivityLogHandler.
```php
public function processCreatedItem(CreateActivityLogMessageInterface $message): void
```
```php
// Called by CreateActivityLogHandler
$message = new CreateActivityLogMessage($blogPost);
$processor->processCreatedItem($message);
// Results in:
// - ActivityLog: action='Created', objectId=1, dataChanges=null
// - CurrentDataTracker: objectId=1, data={title:'...', content:'...', ...}
```
--------------------------------
### Configure Doctrine Storage
Source: https://github.com/locastic/loggastic/blob/master/README.md
Set the storage to 'doctrine' in the configuration file to store activity logs in your relational database instead of Elasticsearch.
```yaml
# config/packages/loggastic.yaml
locastic_loggastic:
storage: doctrine
```
--------------------------------
### Loggastic Project File Organization
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/index.md
An overview of the Loggastic project's directory structure, showing the placement of source files, configuration, and tests.
```tree
loggastic/
├── src/
│ ├── Annotation/
│ │ └── Loggable.php
│ ├── Bridge/
│ │ ├── Doctrine/
│ │ │ └── Storage/
│ │ └── Elasticsearch/
│ │ └── Storage/
│ ├── Command/
│ ├── DataProcessor/
│ ├── DataProvider/
│ ├── Enum/
│ ├── Event/
│ ├── EventListener/
│ ├── EventSubscriber/
│ ├── Factory/
│ ├── Identifier/
│ ├── Logger/
│ ├── Loggable/
│ ├── Message/
│ ├── MessageDispatcher/
│ ├── MessageHandler/
│ ├── Metadata/
│ ├── Model/
│ │ ├── Input/
│ │ └── Output/
│ ├── Serializer/
│ ├── Storage/
│ │ └── InMemory/
│ ├── Util/
│ └── LocasticLoggasticBundle.php
├── config/
│ └── (YAML configuration files)
└── tests/
```
--------------------------------
### General Loggastic Configuration
Source: https://github.com/locastic/loggastic/blob/master/README.md
Defines the storage backend, paths for loggable classes, and enables/disables the Doctrine subscriber and identifier extractor.
```yaml
# config/packages/loggastic.yaml
locastic_loggastic:
# storage backend for activity logs: 'elasticsearch', 'doctrine' or 'in_memory'
storage: elasticsearch
# directory paths containing loggable classes or xml/yaml files
loggable_paths:
- '%kernel.project_dir%/Resources/config/loggastic'
- '%kernel.project_dir%/src/Entity'
# Turn on/off the default Doctrine subscriber
default_doctrine_subscriber: true
# Turn on/off collection identifier extractor
# if set to `true` objects identifiers in collections will be used as array keys
# if set to `false` default numeric array keys will be used
identifier_extractor: true
```
--------------------------------
### ActivityLog Model Methods
Source: https://github.com/locastic/loggastic/blob/master/_autodocs/api-reference/data-models.md
Provides getter and setter methods for all properties of the ActivityLog model. Note that setDataChanges() decodes a JSON string into an array.
```php
public function getId(): ?string
public function setId(?string $id): void
public function getAction(): ?string
public function setAction(?string $action): void
public function getLoggedAt(): \DateTime
public function setLoggedAt(\DateTime $loggedAt): void
public function getObjectId(): string
public function setObjectId($objectId): void
public function getObjectClass(): ?string
public function setObjectClass(?string $objectClass): void
public function getDataChanges(): ?array
public function setDataChanges(?string $dataChanges = null): void
public function getRequestUrl(): ?string
public function setRequestUrl(?string $requestUrl): void
public function getUser(): ?array
public function setUser(?array $user): void
```