⌘K

Core

Audit Log

Stopa, kterou wire-core zapisuje sám — které události, na kterých modelech a jak vypadala každá změněná hodnota před a po.

Na této stránce

Wire Core obsahuje audit log pro záznam změn modelů a událostí spojených s tabulkami. Ukládá typ události, auditovaný záznam, uživatele, staré hodnoty, nové hodnoty, metadata a timestamp.

Instalace

Audit log je součástí wire-core. Pokud jste nainstalovali wire-table nebo wire-forms, core je už nainstalován.

Publikujte config a migraci:

php artisan vendor:publish --tag=wire-core::config
php artisan vendor:publish --tag=wire-core::migrations
php artisan migrate

To je celé nastavení — balíček registruje audit event subscriber automaticky a logger je řízen wire-core.audit.enabled (ve výchozím stavu zapnuto). Pokud jste AuditEventSubscriber registrovali ručně v aplikačním service provideru (setup před 1.7.1), můžete ten řádek odstranit; subscription je idempotentní, takže jeho ponechání nezpůsobí dvojité logování.

Zapnutí auditu na modelu

Přidejte HasAuditable na jakýkoli Eloquent model, který chcete sledovat.

use Illuminate\Database\Eloquent\Model;
use NyonCode\WireCore\Audit\Concerns\HasAuditable;
 
class Order extends Model
{
use HasAuditable;
}

Trait zaznamenává Eloquent události created, updated a deleted.

Vidí to, co vidí model, a nic víc. Zápis přes query builder žádnou událost modelu nevyvolá — tak je navržený Laravel, ne tenhle balíček — takže po sobě nezanechá záznam:

$order->update(['status' => 'paid']); // zaznamená se
Order::query()->where('region', 'EU')->update([...]); // nezaznamená se
Order::query()->where('status', 'draft')->delete(); // nezaznamená se

Totéž platí pro insert(), upsert() a increment() nad dotazem. Když má takový zápis v trailu být, projděte modely ve smyčce, nebo záznam vyvolejte sami jednou z manuálních audit událostí. Soft delete nepotřebuje ani jedno: restore() ukládá, takže je to záznam updated, kde se deleted_at vrací na null, a forceDelete() je záznam deleted.

Vyloučení nebo zahrnutí sloupců

Použijte getAuditExclude() pro skrytí šumivých nebo citlivých sloupců pro jeden model.

class Order extends Model
{
use HasAuditable;
 
protected function getAuditExclude(): array
{
return ['cached_total', 'internal_token'];
}
}

Použijte getAuditInclude(), když chcete whitelist.

protected function getAuditInclude(): array
{
return ['status', 'total', 'assigned_user_id'];
}

Globální vyloučení žijí v config/wire-core.php a * je povolená:

'audit' => [
'exclude_columns' => [
'password',
'remember_token',
'billing_*',
],
],

Tenhle seznam se k podlaze přidává, nedefinuje ji. Hesla, cokoli končící na _token nebo _secret, sloupce dvoufaktoru, recovery kódy a api_key se do trailu nezapíšou nikdy a vyprázdnění seznamu je nevrátí. Trail je ve výchozím stavu dlouhověký a modul auditu staré i nové hodnoty vykresluje na obrazovku — takže přihlašovací údaj, který se tam dostane, je přihlašovací údaj na stránce, a tři roky starý publikovaný config soubor nesmí být to jediné, co mezi vámi a tím stojí.

Zobrazení audit záznamů

Každý auditovatelný model dostane relaci audits().

$entries = $order->audits()->latest()->get();

Audit záznamy vystavují helpery pro běžné dotazy:

use NyonCode\WireCore\Audit\AuditEntry;
 
AuditEntry::forRecord($order)->get();
AuditEntry::forEvent('updated')->get();
AuditEntry::byUser($user->id)->get();
AuditEntry::olderThan(90)->delete();

Pro zobrazení řádkového audit trailu ve Wire Table přidejte vestavěnou akci:

use NyonCode\WireCore\Audit\Actions\AuditTrailAction;
 
return $table
->model(Order::class)
->actions([
AuditTrailAction::make(),
]);

Akce otevře slide-over s historií záznamu.

Manuální audit události

Audit události můžete odesílat ručně pro operace, které neprocházejí auditovanou událostí modelu.

K loggeru vede pět událostí a první tři vyvolává HasAuditable za vás — vlastní ruční odeslání má smysl tam, kde zápis proběhl mimo dohled modelových událostí (přímý dotaz, import, změna stavu z jobu):

Událost Konstruktor Kdo ji vyvolá za vás
RecordCreated (Model $record, array $newValues = [], array $metadata = []) HasAuditable, při vytvoření
RecordUpdated (Model $record, array $oldValues = [], array $newValues = [], array $metadata = []) HasAuditable, při úpravě
RecordDeleted (Model $record, array $oldValues = [], array $metadata = []) HasAuditable, při smazání
BulkActionExecuted (string $actionName, string $modelType, array $recordIds, bool $success, array $metadata = []) nikdo — vyvoláte ji sám
InlineCellUpdated viz níže inline editace v tabulce
use NyonCode\WireCore\Audit\Events\BulkActionExecuted;
 
event(new BulkActionExecuted(
actionName: 'archive',
modelType: Order::class,
recordIds: $orders->modelKeys(),
success: true,
metadata: ['source' => 'orders-table'],
));

Pro aktualizaci jedné buňky:

use NyonCode\WireCore\Audit\Events\InlineCellUpdated;
 
event(new InlineCellUpdated(
modelType: Order::class,
recordId: $order->id,
column: 'status',
oldValue: 'draft',
newValue: 'approved',
));

Dočasné vypnutí

Vypněte audit logging během importů, seederů nebo údržbových jobů:

use NyonCode\WireCore\Audit\AuditLogger;
 
AuditLogger::withoutAuditing(function () use ($orders) {
$orders->each->update(['synced_at' => now()]);
});

Umlčí zápisy přes model — ty, které by se jinak zaznamenaly. update() přes query builder obalovat netřeba, protože se nezaznamenal nikdy.

Retence

Nastavte retenční období ve dnech:

'audit' => [
'retention_days' => 180,
],

Pak naplánujte přibalený prune příkaz:

use Illuminate\Support\Facades\Schedule;
 
Schedule::command('wire-core:audit-prune')->daily();

Spusťte ho manuálně s ad-hoc přepisem období:

php artisan wire-core:audit-prune --days=90

Bez nakonfigurovaného retention_days (a bez --days) příkaz varuje a neprořeže nic. Programové prořezávání je stále dostupné přes app(AuditLogger::class)->prune(?int $days = null).

Období, které by nenechalo nic, se odmítne. --days=0 by znamenalo „všechno zapsané před touto sekundou" a záporné sahá do budoucnosti, takže obojí — i prázdné --days= z proměnné plánovače, která nebyla nastavená — skončí nenulově a nesmaže nic. prune() pro stejné hodnoty hodí InvalidRetentionException a retention_days nastavené na 0 se odmítne stejně. Naplánovaný prune, který hlasitě selže, si někdo všimne; ten, který trail vymaže a nahlásí úspěch, ne.

Konfigurace

Klíč Výchozí Popis
enabled true Globální on/off přepínač
model AuditEntry::class Vlastní model audit záznamu
user_model App\Models\User Model uživatele pro relaci user()
events null null loguje všechny podporované události; pole loguje jen vybrané typy událostí
exclude_columns password, remember_token Globální vyloučení sloupců, * povolená — přidává se k vestavěné podlaze, která přihlašovací údaje redaguje vždy
retention_days null Počet dní, po které se záznamy uchovávají

Podporované typy událostí jsou created, updated, deleted, bulk_action a cell_updated.

Kompletní referenci configu viz Konfigurace.