Filament Activity Timeline
Transformez les journaux d’activité techniques en événements métier clairs, localisés et lisibles dans les widgets, pages et infolists Filament.
Lisez et fouillez vos fichiers de logs Laravel sans quitter votre panel Filament, regroupés par canal de logging.
| PHP | ^8.2 |
|---|---|
| Laravel | ^12.0|^13.0 |
| Filament | ^4.0|^5.0 |
| Version | v1.0.0 |
| Licence | MIT |
Installation
composer require laboiteacode/filament-logs-explorer
Quand une erreur remonte en production, la lecture des logs passe encore trop souvent par un accès SSH, un tail -f et un peu de patience. Filament Logs Explorer déplace cette étape là où vous êtes déjà : dans votre panel d'administration.
Le plugin lit les fichiers de logs déclarés dans votre config/logging.php, et non un répertoire codé en dur. Vos canaux single, daily, les handlers de flux monolog et les membres d'un stack sont retrouvés automatiquement, puis présentés par canal. Un clic sur un fichier l'ouvre dans une visionneuse latérale, avec recherche interne, navigation entre les occurrences et raccourcis clavier.
/ pour chercher, n et N pour parcourir les occurrences, g et G pour aller au début ou à la fin du fichier.Les fichiers volumineux ne font pas tomber le navigateur : au-delà d'une taille configurable, la visionneuse tronque le contenu et charge la fin du fichier, là où se trouvent les entrées les plus récentes, en signalant clairement la troncature.
Côté sécurité, le front ne manipule jamais de chemin de fichier : chaque fichier est référencé par un identifiant opaque et résolu côté serveur à partir de votre configuration de logging. L'accès à la page et la suppression de fichiers ont chacun leur propre autorisation, ce qui permet d'ouvrir la consultation des logs sans donner le droit d'effacer quoi que ce soit.
Le plugin est distribué sous licence MIT, et livré avec les traductions française, anglaise et espagnole.
Installez le package avec Composer :
composer require laboiteacode/filament-logs-explorer
Enregistrez ensuite le plugin sur chaque panel où il doit apparaître, en général dans app/Providers/Filament/AdminPanelProvider.php :
use LaBoiteACode\FilamentLogsExplorer\FilamentLogsExplorerPlugin;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->plugin(FilamentLogsExplorerPlugin::make());
}
L'installation s'arrête là : une entrée Logs apparaît dans la navigation et liste tous les canaux basés sur des fichiers que le plugin a pu détecter.
Le CSS et le JS de la visionneuse sont enregistrés automatiquement auprès de Filament. En production, publiez-les comme n'importe quel asset Filament :
php artisan filament:assets
Les trois groupes publiables sont facultatifs :
# config/filament-logs-explorer.php
php artisan vendor:publish --tag="filament-logs-explorer-config"
# lang/vendor/filament-logs-explorer/{locale}/filament-logs-explorer.php
php artisan vendor:publish --tag="filament-logs-explorer-translations"
# resources/views/vendor/filament-logs-explorer/
php artisan vendor:publish --tag="filament-logs-explorer-views"
La page affiche une section repliable par canal, chacune listant les fichiers les plus récents avec leur nom, leur taille et leur date de modification. Une action Rafraîchir dans l'en-tête relance l'analyse du disque.
Les fichiers que le processus ne peut pas lire restent listés, mais signalés comme illisibles : un problème de permissions se voit, au lieu de disparaître silencieusement.
| Action | Comment |
|---|---|
| Chercher dans le fichier | Saisir dans le champ de recherche, les occurrences sont surlignées |
| Passer d'une occurrence à l'autre | Les boutons haut et bas, ou n et N |
| Aller au début ou à la fin | Les deux boutons dédiés, ou g et G |
| Ouvrir le fichier précédent ou suivant | Les boutons < et >, sans fermer le panneau |
| Placer le curseur dans la recherche | / |
| Télécharger le fichier brut | Le bouton de téléchargement |
| Supprimer le fichier | Le bouton corbeille, après confirmation |
Quand le champ de recherche a le focus, Entrée passe à l'occurrence suivante, Maj+Entrée à la précédente et Échap efface la recherche. Les raccourcis d'une seule lettre ne sont actifs qu'en dehors du champ : taper n dans une requête fait bien ce que vous attendez.
Les fichiers dépassant reader.max_bytes (5 Mo par défaut) sont tronqués. La visionneuse charge la fin du fichier, là où se trouvent les entrées les plus récentes, et affiche un bandeau expliquant la troncature et invitant à télécharger le fichier complet. Passez reader.tail_when_exceeded à false pour charger le début à la place.
Chaque option se règle globalement dans le fichier config/filament-logs-explorer.php publié, ou par panel via l'API fluide du plugin. La valeur fluide l'emporte toujours, ce qui permet à plusieurs panels d'une même application d'exposer des sous-ensembles de logs différents.
Par défaut, le plugin détecte tous les canaux basés sur des fichiers déclarés dans config/logging.php. Fournissez une liste explicite pour les restreindre et les ordonner :
// config/filament-logs-explorer.php
'channels' => ['daily', 'single'], // tableau vide => détection automatique
'exclude_channels' => ['emergency'],
'expand_stacks' => true, // éclate les canaux "stack" en leurs membres
'files_per_channel' => 15,
FilamentLogsExplorerPlugin::make()
->channels(['daily', 'single'])
->excludeChannels(['emergency'])
->expandStacks()
->filesPerChannel(20);
Pour faire remonter aussi les fichiers *.log qui ne dépendent d'aucun canal, activez le balayage du répertoire. Ces fichiers sont regroupés dans leur propre section :
'discover_untracked_files' => true,
'log_directory' => null, // null => storage_path('logs')
'untracked_channel_label' => null, // null => le libellé traduit
FilamentLogsExplorerPlugin::make()
->discoverUntrackedFiles(directory: storage_path('logs'));
FilamentLogsExplorerPlugin::make()
->navigationLabel('Logs applicatifs')
->navigationIcon('heroicon-o-bug-ant')
->activeNavigationIcon('heroicon-s-bug-ant')
->navigationGroup('Système')
->navigationSort(99)
->navigationParentItem('Outils')
->navigationBadge() // affiche le nombre de canaux en badge
->registerNavigation(false) // conserve la route, masque l'entrée de menu
->slug('logs-applicatifs');
Pour imbriquer la page dans un cluster Filament, passez le nom de sa classe :
FilamentLogsExplorerPlugin::make()
->cluster(SystemCluster::class);
La page est accessible à toute personne pouvant accéder au panel. Restreignez-la avec une capacité de Gate :
'authorization' => [
'gate' => 'view-logs',
],
Ou avec une closure, prioritaire sur le gate configuré :
FilamentLogsExplorerPlugin::make()
->canAccessUsing(fn (): bool => auth()->user()?->can('viewLogs') ?? false);
Dans les deux cas, cela pilote la méthode canAccess() de la page, donc la visibilité dans la navigation et l'autorisation de la route en même temps.
La suppression est active par défaut et dispose de sa propre autorisation, distincte de l'accès en lecture : vos utilisateurs peuvent consulter les logs sans pouvoir les effacer. Le bouton corbeille demande confirmation avant de retirer le fichier du disque, et supprimer le fichier ouvert ferme la visionneuse.
'deletion' => [
'enabled' => true,
'gate' => 'delete-logs', // null => toute personne pouvant accéder à la page
],
// Masquer complètement les boutons de suppression.
FilamentLogsExplorerPlugin::make()->deletable(false);
// Ou décider utilisateur par utilisateur.
FilamentLogsExplorerPlugin::make()
->canDeleteUsing(fn (): bool => auth()->user()?->can('deleteLogs') ?? false);
'reader' => [
'max_bytes' => 5 * 1024 * 1024,
'tail_when_exceeded' => true,
],
FilamentLogsExplorerPlugin::make()
->maxBytes(10 * 1024 * 1024)
->tailWhenExceeded();
| Clé de config | Méthode fluide | Défaut |
|---|---|---|
navigation.register |
registerNavigation() |
true |
navigation.label |
navigationLabel() |
« Logs » traduit |
navigation.icon |
navigationIcon() |
heroicon-o-document-magnifying-glass |
navigation.active_icon |
activeNavigationIcon() |
heroicon-s-document-magnifying-glass |
navigation.group |
navigationGroup() |
null |
navigation.sort |
navigationSort() |
null |
navigation.parent_item |
navigationParentItem() |
null |
navigation.badge |
navigationBadge() |
false |
slug |
slug() |
logs |
cluster |
cluster() |
null |
channels |
channels() |
[] (détection auto) |
exclude_channels |
excludeChannels() |
[] |
expand_stacks |
expandStacks() |
true |
discover_untracked_files |
discoverUntrackedFiles() |
false |
log_directory |
logDirectory() |
null (storage_path('logs')) |
untracked_channel_label |
aucune | null (libellé traduit) |
files_per_channel |
filesPerChannel() |
15 |
reader.max_bytes |
maxBytes() |
5242880 (5 Mo) |
reader.tail_when_exceeded |
tailWhenExceeded() |
true |
authorization.gate |
canAccessUsing() |
null |
deletion.enabled |
deletable() |
true |
deletion.gate |
canDeleteUsing() |
null |
Le package est livré en français, anglais et espagnol, et suit la locale de votre application. Publiez les fichiers pour ajuster la formulation ou ajouter une langue :
php artisan vendor:publish --tag="filament-logs-explorer-translations"
Puis modifiez ou créez lang/vendor/filament-logs-explorer/{locale}/filament-logs-explorer.php.
La visionneuse ne lit que les fichiers qu'elle a elle-même résolus depuis votre configuration de logging. Le front référence les fichiers par un identifiant opaque et non réversible plutôt que par leur chemin : un chemin envoyé par le navigateur n'est donc jamais lu sur le disque, et la lecture comme la suppression sont ré-autorisées côté serveur.
Si vous découvrez une faille de sécurité, signalez-la par email plutôt que via le gestionnaire d'issues.
À découvrir aussi
Transformez les journaux d’activité techniques en événements métier clairs, localisés et lisibles dans les widgets, pages et infolists Filament.