feat(auth): add recent activity logging to access tracker
CI / build-and-test (push) Failing after 0s

* Introduced AccessLogEntry type for logging access details
* Updated AccessTracker to maintain a recent activity log
* Modified Metrics to include recent activity log in response
* Added RecentActivityLog component to display logged activities
This commit is contained in:
2026-05-24 16:36:59 +02:00
parent e38a0377d5
commit 0227912325
6 changed files with 106 additions and 5 deletions
+31
View File
@@ -17,12 +17,24 @@ type AccessSnapshot struct {
LastAccessedAt time.Time `json:"last_accessed_at"`
}
const maxRecentLog = 100
type AccessLogEntry struct {
Timestamp time.Time `json:"timestamp"`
KeyID string `json:"key_id"`
IP string `json:"ip"`
UserAgent string `json:"user_agent"`
Tool string `json:"tool"`
Path string `json:"path"`
}
type AccessTracker struct {
mu sync.RWMutex
entries map[string]AccessSnapshot
ipCounts map[string]int
agentCounts map[string]int
toolCounts map[string]int
recentLog []AccessLogEntry
totalRequests int
}
@@ -32,6 +44,7 @@ func NewAccessTracker() *AccessTracker {
ipCounts: make(map[string]int),
agentCounts: make(map[string]int),
toolCounts: make(map[string]int),
recentLog: make([]AccessLogEntry, 0, maxRecentLog),
}
}
@@ -64,6 +77,19 @@ func (t *AccessTracker) Record(keyID, path, remoteAddr, userAgent, toolName stri
if tool := strings.TrimSpace(toolName); tool != "" {
t.toolCounts[tool]++
}
logEntry := AccessLogEntry{
Timestamp: now.UTC(),
KeyID: keyID,
IP: normalizedRemoteAddr,
UserAgent: userAgent,
Tool: strings.TrimSpace(toolName),
Path: path,
}
t.recentLog = append([]AccessLogEntry{logEntry}, t.recentLog...)
if len(t.recentLog) > maxRecentLog {
t.recentLog = t.recentLog[:maxRecentLog]
}
}
func normalizeRemoteAddr(value string) string {
@@ -130,6 +156,7 @@ type AccessMetrics struct {
TopIPs []RequestAggregate `json:"top_ips"`
TopAgents []RequestAggregate `json:"top_agents"`
TopTools []RequestAggregate `json:"top_tools"`
RecentLog []AccessLogEntry `json:"recent_log"`
}
func (t *AccessTracker) Metrics(topN int) AccessMetrics {
@@ -143,6 +170,9 @@ func (t *AccessTracker) Metrics(topN int) AccessMetrics {
t.mu.RLock()
defer t.mu.RUnlock()
log := make([]AccessLogEntry, len(t.recentLog))
copy(log, t.recentLog)
return AccessMetrics{
TotalRequests: t.totalRequests,
UniquePrincipals: len(t.entries),
@@ -152,6 +182,7 @@ func (t *AccessTracker) Metrics(topN int) AccessMetrics {
TopIPs: topAggregates(t.ipCounts, topN),
TopAgents: topAggregates(t.agentCounts, topN),
TopTools: topAggregates(t.toolCounts, topN),
RecentLog: log,
}
}