Audit log viewer

A filterable security log table with severity badges, row-level background tinting for critical entries, a fixed header so column names stay visible while scrolling, and a live search that filters across multiple fields at once.

Audit log viewer

Search across user, action, resource, and IP, or filter by severity. The header stays fixed while the body scrolls.

Timestamp
Severity
User
Action
Resource
IP
2024-05-16 09:01:12
info
aria.chen
LOGIN
/dashboard
10.0.1.42
2024-05-16 09:03:44
info
marcus.webb
VIEW
/reports/q1
10.0.1.18
2024-05-16 09:12:05
warning
aria.chen
EXPORT
/users/all
10.0.1.42
2024-05-16 09:15:30
error
unknown
LOGIN_FAILED
/auth
203.0.113.7
2024-05-16 09:15:31
error
unknown
LOGIN_FAILED
/auth
203.0.113.7
2024-05-16 09:15:32
critical
unknown
BRUTE_FORCE
/auth
203.0.113.7
2024-05-16 09:22:18
info
priya.kapoor
UPDATE
/settings/theme
10.0.1.55
2024-05-16 09:31:00
warning
jordan.ellis
DELETE
/reports/draft-4
10.0.2.11
2024-05-16 09:45:09
info
sam.rivera
DEPLOY
/infra/staging
10.0.1.99
2024-05-16 10:02:44
critical
system
DB_CONN_LOST
/db/primary
10.0.0.1
2024-05-16 10:03:01
critical
system
FAILOVER
/db/replica
10.0.0.2
2024-05-16 10:15:22
info
aria.chen
LOGOUT
/auth
10.0.1.42
2024-05-16 10:28:33
warning
taylor.brooks
PERMISSION_DENY
/admin/users
10.0.1.77
2024-05-16 10:55:50
error
system
DISK_FULL
/storage/logs
10.0.0.5
2024-05-16 11:10:04
info
marcus.webb
LOGIN
/dashboard
10.0.1.18

This demo uses Tailwind utility classes for layout — swap in your own CSS when copying into your project.

Fixed header with capped scroll height

Set fixedHeader and fixedHeaderScrollHeight so the table body scrolls independently while the column headers stay pinned:

<DataTable
  fixedHeader
  fixedHeaderScrollHeight="340px"
  columns={columns}
  data={logs}
/>

Severity row tinting

Use conditionalRowStyles to give critical and error rows a distinct background without adding a visual column:

const conditionalRowStyles: ConditionalStyles<LogEntry>[] = [
  { when: r => r.severity === 'critical', style: { backgroundColor: '#fef2f2' } },
  { when: r => r.severity === 'error',    style: { backgroundColor: '#fff7f7' } },
];

Multi-field live search

Filter client-side across several fields by combining a search string with a severity toggle — no extra library needed:

const filtered = logs.filter(r => {
  if (severity !== 'all' && r.severity !== severity) return false;
  if (search) {
    const q = search.toLowerCase();
    return r.user.includes(q) || r.action.includes(q)
      || r.resource.includes(q) || r.ip.includes(q);
  }
  return true;
});