Audit
L’historique de tout ce qui modifie un mineur ou la configuration, sort des données du Pi ou scanne le réseau, que ce soit depuis le dashboard ou par l’application elle-même (planificateur, sauvegarde de chaque nuit).

La page affiche les dernières 24 heures par défaut, du plus récent au plus ancien. Le calendrier affiche une autre journée, de minuit à minuit UTC. Les heures sont en UTC, comme les Sauvegardes et le rapport d’audit par mail : un même événement porte la même heure partout.
- Filtres — par mineur, par type d’événement et par jour. Chaque filtre actif apparaît en étiquette sous la barre : la croix le retire, Tout effacer les retire tous. Le nombre d’événements de la période s’affiche à droite.
- Une ligne par événement — un point vert si l’opération a réussi, rouge si elle a échoué, suivi du type d’événement et du mineur concerné. En dessous :
- pour une opération faite depuis le dashboard : l’heure, l’adresse IP et le navigateur de l’appareil (le détail complet au survol) ;
- pour une opération du planificateur : l’heure et l’expression cron qui l’a déclenchée ;
- pour la sauvegarde de chaque nuit : l’heure et le mois mis à jour ;
- en cas d’échec, le code d’erreur et le message.
- Copier — l’icône en bout de ligne copie l’entrée complète, au format JSON.
- Exporter — télécharge toutes les entrées de la période et des filtres en cours (pas seulement la page affichée) dans un fichier JSON.
📋 Événements enregistrés
L’audit trace ce qui a été fait depuis l’outil : par quelqu’un dans le dashboard, ou par l’application elle-même (son planificateur, sa sauvegarde de chaque nuit). Chaque entrée dit quoi (le type), quand, qui (l’IP et le navigateur de l’appareil, ou le planificateur et sa tâche), sur quoi (le mineur) et avec quel résultat (réussite, ou échec avec le message d’erreur). Une action qui échoue est enregistrée aussi.
⚙️ Actions sur les mineurs
| Type | Libellé | D'où | Ce que l'entrée contient |
|---|---|---|---|
restart | Redémarrage | panneau d'un mineur › Redémarrer ; ou une tâche du planificateur | le mineur redémarré |
switch_primary | Bascule vers le pool principal | panneau d'un mineur › Changer de pool ; ou une tâche du planificateur | le mineur basculé — tous les mineurs si la bascule les vise tous (appel direct à l'API) |
switch_fallback | Bascule vers le pool de secours | idem | idem |
🛠️ Configuration
| Type | Libellé | D'où | Ce que l'entrée contient |
|---|---|---|---|
save_miners | Enregistrement des mineurs | page Configuration : enregistrer la détection, activer / désactiver, tout désactiver, alias, pools, planification | par mineur modifié, ce qui a changé hors changements sensibles : alias, nom d'hôte, modèle (avant → après). En cas d'échec : une seule entrée, sans mineur |
save_settings | Enregistrement des paramètres | page Configuration › Réglages de l'application : tarif, autres appareils, dashboards de pool, accès distant | ce qui a changé hors changements sensibles : le tarif (avant → après), les appareils, les dashboards de pool et les dépôts firmware ajoutés ou supprimés. En cas d'échec : une seule entrée |
📤 Données et réseau
| Type | Libellé | D'où | Ce que l'entrée contient |
|---|---|---|---|
export_audit | Export de l'audit | page Audit › Exporter | la période et les filtres exportés |
download_backups | Téléchargement de sauvegardes | page Sauvegardes › Télécharger | les mois téléchargés |
discover | Détection réseau | page Configuration › Détection automatique (scan du réseau, ou ajout par IP) | la plage scannée ou l'IP sondée |
backup | Sauvegarde mise à jour | chaque nuit, par l'application : la journée terminée est ajoutée à l'archive de son mois (voir Sauvegardes) | le ou les mois dont l'archive a été mise à jour |
audit_report | Rapport d'audit envoyé | la nuit, par le mailer, selon la fréquence choisie dans Configuration › Notifications | la période couverte et les destinataires ; l'erreur en cas d'échec |
🔐 Changements sensibles
Un enregistrement de la configuration qui contient des changements sensibles produit, à la place de save_miners ou save_settings, une entrée dédiée par changement sensible : une seule écriture par fait, aucune ligne en double. Chaque entrée a son détail (valeurs avant → après, ou la tâche ajoutée ou supprimée), pour pouvoir la rechercher directement. Un seul enregistrement peut en produire plusieurs (par exemple le pool et la planification d’un mineur).
| Type | Libellé | Quand | Détail |
|---|---|---|---|
miner_pool | Pool du mineur modifié | l'URL, le port ou l'utilisateur du pool principal ou de secours d'un mineur change | chaque champ modifié — ex. Utilisateur de secours : bc1q…abc.w1 → bc1q…xyz.w1 |
miner_schedule | Planification modifiée | une tâche planifiée est ajoutée ou supprimée (une tâche n'est jamais modifiée : changer une tâche, c'est en supprimer une et en ajouter une autre) | chaque tâche ajoutée ou supprimée, écrite en clair — ex. Tâche ajoutée : Redémarrage · À 00:00, uniquement le mercredi (0 0 0 * * WED) |
miner_identity | IP du mineur modifiée | l'IP d'un mineur déjà configuré change (le mineur est reconnu par sa MAC) | l'ancienne et la nouvelle IP |
miner_disabled / miner_enabled | Mineur désactivé / activé | un mineur est désactivé (il n'est plus surveillé ni planifié) ou réactivé | — |
miner_added | Mineur ajouté | un mineur entre dans la configuration | ses pools (URL, port, utilisateur) et ses tâches planifiées |
remote_push | Accès distant modifié | l'URL de push ou la clé API hashboard change | l'URL avant et après ; la clé API n'est jamais écrite, seulement « modifiée » |
mail_settings | Notifications modifiées | le serveur SMTP ou les destinataires des mails changent | chaque champ du serveur avant et après, les destinataires ajoutés ou retirés ; le mot de passe n'est jamais écrit, seulement « modifié » |
Le reste d’un enregistrement (alias, nom d’hôte, modèle, tarif, appareils, dashboards de pool, dépôts firmware) est détaillé sous save_miners / save_settings : chaque fait n’est écrit qu’une fois, sous un seul type. Un enregistrement qui ne change rien n’est pas tracé.
🔎 Contenu d’une entrée
Une opération faite depuis le dashboard :
{
"ts": "2026-10-10T07:57:41Z",
"source": "api",
"type": "restart",
"target": "192.168.1.65",
"ip": "192.168.1.20",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36",
"requestId": "raspberrypi/xzGLtihnkN-000057",
"status": 204
}
Une opération du planificateur, ici en échec :
{
"ts": "2026-10-09T21:59:59Z",
"source": "system",
"service": "scheduler",
"type": "switch_fallback",
"target": "192.168.1.65",
"cron": "59 59 23 * * FRI",
"error": "switch pool for 192.168.1.65: … connect: connection refused"
}
| Champ | Contenu |
|---|---|
ts | Date et heure, en UTC |
source | api (depuis le dashboard) ou system (par l'application elle-même) |
type | Le type d'événement — voir le tableau ci-dessus |
target | L'IP du mineur concerné — absent pour un enregistrement de configuration ou une bascule sur tous les mineurs |
ip | api — l'adresse IP de l'appareil qui a fait la demande |
userAgent | api — le navigateur de cet appareil |
requestId | api — l'identifiant de la requête, le même que dans les logs du dashboard |
status | api — le code HTTP de la réponse (400 ou plus : échec) |
query | api — les paramètres de la demande : les mois téléchargés, la période et les filtres exportés, le mineur ciblé… |
service | system — la partie de l'application qui a agi : scheduler (planificateur), backup (sauvegarde de chaque nuit) ou mailer (notifications) |
cron | system — l'expression cron qui a déclenché l'opération |
error | Le message d'erreur, en cas d'échec |
changes | Ce qui a changé — chaque champ avec sa nature (kind) : changed (valeur avant before → après after), ou un élément de liste added (after) ou removed (before) |
🗄️ Stockage et API
Les entrées sont ajoutées dans un fichier par jour (UTC) : {dataDir}/data/audit/AAAA-MM-JJ.jsonl (./storage/data/audit/ avec Docker), une entrée JSON par ligne.
Trois routes de l’API les exposent :
GET /api/audit— les entrées entrefrometto(dates RFC 3339, les dernières 24 heures par défaut, un an au maximum), filtrables parip(mineur) ettype, paginées avecpageetpageSize.GET /api/audit/types— la liste de tous les types, dans l’ordre où le dashboard les propose : la valeur attendue partype.GET /api/audit/export— mêmes paramètres, sans pagination : le fichier JSON du bouton Exporter, qui reprend la période et les filtres avant la liste des entrées.
{
"from": "2026-10-09T08:00:00Z",
"to": "2026-10-10T08:00:00Z",
"type": "restart",
"exportedAt": "2026-10-10T08:00:00Z",
"total": 6,
"entries": [ … ]
}
La réponse de GET /api/audit/types — chaque type est expliqué dans Événements enregistrés :
{
"types": [
"restart",
"switch_primary",
"switch_fallback",
"save_miners",
"save_settings",
"export_audit",
"download_backups",
"discover",
"backup",
"audit_report",
"miner_pool",
"miner_schedule",
"miner_identity",
"miner_disabled",
"miner_enabled",
"miner_added",
"remote_push",
"mail_settings"
]
}
Le détail des paramètres est sur la page API.
🙈 Masquer la page
La page et son entrée dans le menu se masquent depuis dashboard.yml (redémarrage du dashboard nécessaire). Le dashboard continue d’enregistrer les événements.
ui:
page:
audit: hidden # enabled (par défaut) | hidden