Skip to main content

Audit Logs

The platform records a detailed trail of admin activity so you can answer "who changed this?" without guesswork. Audit data is available in the admin UI and persists for the tenant's full lifetime (subject to your retention policy).

What's recorded

App-service calls

By default, every app-service method call is recorded in the AbpAuditLogs table:

  • Caller user id and tenant id.
  • Service and method name.
  • Parameters (the request payload).
  • Return value (success path) or exception (error path).
  • Execution duration, client IP, browser info.

This means every admin action — creating a campaign, updating a member, sending a broadcast — leaves a row you can find later.

Entity changes

Entities decorated as audited (most domain entities derive from FullAuditedEntity<long> which gives you this for free) get change-level audit rows:

  • Create / update / delete actions.
  • Before and after values for each changed property.

This lets you reconstruct the exact "diff" of a record change without comparing snapshots.

Soft-delete

Most entities don't get hard-deleted — instead, the row is marked IsDeleted=true with DeleterUserId and DeletionTime. Deleted rows are filtered out of normal queries automatically, but they're still in the database for audit (and can be undeleted with an admin escalation).

Domain-specific audit

In addition to the generic audit, several subsystems keep their own purpose-built audit rows:

  • GDPR erasureGdprErasureCertificate records each erasure with operator, timestamp, and counts of redacted entities. See GDPR erasure.
  • Raffle drawsCampaignRaffleDraw stores the seed, the pool hash, the output hash, and the execution duration so a draw is fully reproducible. See Multi-platform raffle.
  • Campaign winners export — every winners CSV export is logged with the exporter user and timestamp.
  • Meta health — one snapshot row per health probe per channel. See Meta health.
  • Funnel events — per-step traces through conversation flows.
  • Outbound messages — every send through every channel, with the provider's response code.
  • Loyalty transactions — every points movement, by definition append-only.

The audit log UI

Go to Administration → Audit logs. The page lets you filter by:

  • User — who acted.
  • Service / method — what they did.
  • Date range — when.
  • Tenant (host scope) — for cross-tenant audits.

Click a row to see the full call detail: parameters, return value, exception. If the row corresponds to an entity change, drilling deeper shows the property-level diff.

Step-by-step

Find what a user changed today

  1. Open Administration → Audit logs.
  2. Filter by User and Today.
  3. The table lists every call. Sort by time to follow the sequence.

Reconstruct an entity's history

  1. Open the entity in the admin (e.g. a campaign).
  2. Click History (where exposed) — the platform shows the entity-change rows.
  3. Each row shows the changed properties with before/after.

Investigate a security event

If you suspect unauthorised access:

  1. Open audit logs and filter by client IP (use search).
  2. Cross-reference with the access-info page (access-info.md topic) for which users are tied to which sessions.

Limits and gotchas

  • Retention. Audit rows can grow large fast. Configure retention according to your data-protection policy. The platform does not auto-prune.
  • PII in parameters. Audit logs include the parameters of app-service calls. A method that takes a phone number records the phone in the audit row. Be aware of GDPR implications.
  • Permission: Pages.Administration.AuditLogs to view; Pages.Administration.EntityChanges.FullHistory for the full entity-change diff (otherwise you see a summary).
  • System actions are also recorded. Background workers acting on tenant data show up with a system user id (or null) — useful to distinguish manual from automated changes.