Recent activity ¶
Recent activity log displays last actions in the repository (whatever their origin is, for example, back office, REST, migration, CLI, or CRON).
To learn more about its back office usage and the actions logged by default, see Recent activity in User Documentation.
Configuration and cronjob¶
With some configuration, you can customize the log length in the database or on screen. A command maintains the log size in database, it should be scheduled through CRON.
- The configuration
ibexa.system.<scope>.activity_log.pagination.activity_logs_limit
sets the number of log items shown per page in the back office (default value: 25). A log item is a group of entries, or an entry without group. - The configuration
ibexa.repositories.<repository>.activity_log.truncate_after_days
sets the number of days a log entry is kept before it's deleted by theibexa:activity-log:truncate
command (default value: 30 days).
For example, the following configuration sets 15 days of life to the log entries on the default
repository, and 20 context groups per page for the admin_group
SiteAccess group:
1 2 3 4 5 6 7 8 9 10 |
|
To automate a regular truncation, the command ibexa:activity-log:truncate
must be added to a crontab.
To minimize the number of entries to delete, it's recommended to execute the command more than one time a day.
For every exact hour, the cronjob line is:
0 * * * * cd [path-to-ibexa]; php bin/console ibexa:activity-log:truncate --quiet --env=prod
Permission and security¶
The activity_log/read
policy gives a role the access to the Admin -> Activity list, the dashboard's Recent activity block, and the user profile's Recent activity.
It can be limited to "Only own logs" (ActivityLogOwner
).
The policy should be given to every roles having access to the back office, at least with the ActivityLogOwner
owner limitation, to allow them to use the "Recent activity" block in the default dashboard or their custom dashboard.
This policy is required to view activity log in user profile, if profile is enabled.
Caution
Don't assign activity_log/read
permission to the Anonymous role, even with the owner limitation, because this role is shared among all unauthenticated users.
User privacy¶
Caution
A username of the User who performs the action is logged. When acting through the web server, the User's IP address is also logged. Other access, such as console commands, doesn't log an IP. Your Data Protection Officer or GDPR representative should be aware of this, so they can ensure users are informed if needed, depending on your use case, jurisdiction, and company policy.
For example, if a content edition feature, such as reader's comments, is available in the front office, the recent activity log records the front users' IPs.
PHP API¶
The ActivityLogService
PHP API can be used to browse activity logs and write new entries.
Searching in the Activity Log groups¶
You can search among the activity log entry groups with the ActivityLogService::findGroups
method, by passing an Ibexa\Contracts\ActivityLog\Values\ActivityLog\Query
object.
This Query
's constructor has four arguments:
$criteria
- an array of criteria fromIbexa\Contracts\ActivityLog\Values\ActivityLog\Criterion
combined as a logical AND.$sortClauses
- an array ofIbexa\Contracts\ActivityLog\Values\ActivityLog\SortClause
.$offset
- a zero-based index integer indicating at which group to start, its default value is0
(zero, nothing skipped).$limit
- an integer as the maximum returned group count, default is 25.
See Activity Log Search Criteria reference and Activity Log Search Sort Clauses reference to discover query possibilities.
In the following example, log groups that contain at least one creation of a Content item are displayed in terminal, with a maximum of 10 groups within the last hour.
It uses the default admin
user that has a permission to list everyone's entries.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
Add custom Activity Log entries¶
Caution
Keep activity logging as light as possible. Don't make database requests or heavy computation at logging time. Keep them for activity log list display time.
Create an entry¶
Your custom features can write into the activity log.
First, inject Ibexa\Contracts\ActivityLog\ActivityLogServiceInterface
into your PHP class from where you want to log an activity (such as a custom event subscriber, event listener, service, or controller).
In the following example, an event subscriber is subscribing to an event dispatched by a custom feature. This event has the information needed by a log entry (see details after the example).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
ActivityLogService::build()
function returns an Ibexa\Contracts\ActivityLog\Values\CreateActivityLogStruct
which can then be passed to ActivityLogService::save
.
ActivityLogService::build
has three arguments:
$className
is a FQCN of the object actually manipulated by the feature, for exampleIbexa\Contracts\Core\Repository\Values\Content\Content::class
$id
is an ID or identifier of the manipulated object, for example, the Content ID cast to string$action
is an identifier of the performed object manipulation, or example,create
,update
ordelete
The returned CreateActivityLogStruct
is always related to the currently logged-in user.
You can still display activity log of an object which was deleted or renamed.
To store the name of the log, you need to use CreateActivityLogStruct::setName
before saving the log entry.
This stored name can be used at the time of displaying information whether the associated object isn't available anymore, or to check if it has been renamed.
Context group¶
If you log several related entries at once, you can group them into a context. Context is a set of actions done for the same purpose, for example, it could group the actions of a CRON that fetches third party data and updates content items. The built-in contexts include:
web
- groups actions made in the back office, like the update and the publishing of a new content item's versionmigration
- groups every action from a migration file execution
A context group counts as one item in regard to activity_logs_limit
configuration and ActivityLogService::findGroups
's $limit
argument.
To open a context group, use ActivityLogService::prepareContext
which has two arguments:
$source
- describes, usually through a short identifier, what is triggering the set of actions. For example, some already existing sources areweb
(incl. actions from the back office),graphql
,rest
andmigration
$description
- an optional, more specific contextualisation. For example,migration
context source is associated with the migration file name in its context description.
To close a context group, use ActivityLogService::dismissContext
.
In the following example, several actions are logged into one context group, even those triggered by a cascade outside the piece of code:
my_feature
init
create
publish
simulate
complete
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Context groups can't be nested. If a new context is prepared when a context is already grouping log entries, this new context is ignored. To start a new context, make sure to previously dismiss the existing one.
When displayed in the back office, a context group is folded below its first entry.
The my_feature
context from the example is folded below its first action, the init
action.
Other actions are displayed after you click the Show more button.
Display log entries¶
To display your log entry, if your object's PHP class isn't already covered, you have to:
- implement
ClassNameMapperInterface
to associate the class name with an identifier, - eventually create a
PostActivityListLoadEvent
subscriber if you need to load the object for the template, - create a template to display this class log entries.
You can have a template that is:
- specific to a class identifier and placed in
templates/themes/<theme>/activity_log/ui/<identifier>.html.twig
- specific to an action on an identifier and placed in
templates/themes/<theme>/activity_log/ui/<identifier>/<action>.html.twig
Template existence is tested in reverse order: if there is no action that specifies the template, the identifier's default is used. For the same identifier, you could have specific templates for few actions, and a default one for the remaining actions.
A default template is used if no template is found for the identifier.
The built-in default template @ibexadesign/activity_log/ui/default.html.twig
has an empty activity_log_description_widget
block and doesn't display anything for unknown objects.
Your template can extend @ibexadesign/activity_log/ui/default.html.twig
, and only redefine the activity_log_description_widget
block for your objects.
First, follow an example of a default template overriding the one from the bundle. It can be used during development as a fallback for classes that aren't mapped yet.
1 2 3 4 5 |
|
Here is an example of a ClassNameMapperInterface
associating the class App\MyFeature\MyFeature
with the identifier my_feature
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
This mapper also provides a translation for the class name in the Filters menu.
This translation can be extracted with php bin/console translation:extract en --domain=ibexa_activity_log --dir=src --output-dir=translations
.
To be taken into account, this mapper must be registered as a service:
1 2 3 |
|
Here is an example of a PostActivityListLoadEvent
subscriber which loads the related object when it's an App\MyFeature\MyFeature
, and attaches it to the log entry:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
|
The following template is made to display the object of App\MyFeature\MyFeature
(now identified as my_feature
) when the action is simulate
,
so, it's named in templates/themes/admin/activity_log/ui/my_feature/simulate.html.twig
.
Thanks to the previous subscriber, the related object is available at display time:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
REST API¶
You can browse activity logs with REST API. For more information, see the REST API reference.