# Zeichnen Sie Aktionsüberwachungsereignisse mit einer nativen Überwachungssenke auf

> Beobachten Sie die Audit-Option und explizite $.audit()-Aufrufe, ohne einen Protokollierungsdienst zu kontaktieren oder vertrauliche Eingaben in ein Anwendungsprotokoll zu schreiben.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: de
Content-SHA256: 1aada85af6a8a041384e00b9d7b74cbdc64ad17d6d798dc9938d466ed8f8f291
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

Eine Aktion kann `audit` auf eine Text-Vorlage setzen. Bei erfolgreichem Abschluss sendet das Framework einen Audit-Datensatz an `DEF.onAudit(name, data, context)`. Der automatische Datensatz verwendet den Senkennamen `actions` und enthält die ID der Aktion. Eine Aktion kann auch explizit `$.audit(message, type)` aufrufen; das sendet einen eigenen Datensatz und kann einen Typ wie `info` tragen.

Das Beispiel ersetzt die Audit-Senke durch einen Sammler im Speicher, um ihren Vertrag zu untersuchen. Er erfasst nur Name, Aktions-ID, Nachricht und Typ. Das Framework bereitet außerdem Kontextdaten und serialisierte Anfragedaten vor: Eine echte Senke braucht eine explizite Richtlinie für Geheimnisse, Aufbewahrung, Zugriff und Fehler. Ein Audit-Ereignis ist kein Beweis, dass eine Geschäftstransaktion committet wurde; die Aktion sollte ihren Erfolgs-Callback erst aufrufen, nachdem der beabsichtigte Schreibvorgang gelungen ist.

In dieser Version tritt das automatische Audit-Event nach dem erfolgreichen Aktionsrufweg auf. Es logiert nicht automatisch Validierungsfehler oder fehlende Aktionen.

```js definitions/audit.js
MAIN.auditEvents = [];
DEF.onAudit = function(name, data) {
	MAIN.auditEvents.push({ sink: name || null, action: data.action, message: data.message || '', type: data.type || null });
};

NEWACTION('AuditExample|save', {
	input: '*name:String',
	audit: 'Saved the example',
	action: function($) {
		$.callback({ ok: true });
	}
});

NEWACTION('AuditExample|explicit', {
	action: function($) {
		$.audit('Explicit example event', 'info');
		$.success();
	}
});

NEWACTION('AuditExample|fail', {
	audit: 'This must not become a success event',
	action: function($) {
		$.invalid(409);
	}
});
```

```js controllers/audit.js
exports.install = function() {
	ROUTE('POST /save/ --> *AuditExample|save');
	ROUTE('POST /explicit/ --> *AuditExample|explicit');
	ROUTE('POST /fail/ --> *AuditExample|fail');
	ROUTE('GET /events/', function($) { $.json(MAIN.auditEvents); });
};
```
