feat: add Logs tab with cursor-paginated search, level filters, and live tail
- Extend GET /api/v1/logs with cursor pagination, multi-level filtering, optional application scoping, and level count aggregation - Add exchangeId, instanceId, application, mdc fields to log responses - Refactor ClickHouseLogStore with keyset pagination (N+1 pattern) - Add LogSearchRequest/LogSearchResponse core domain records - Create LogSearchPageResponse wrapper DTO - Add Logs as 4th content tab (Exchanges | Dashboard | Runtime | Logs) - Implement LogSearch component with debounced search, level filter bar, expandable log entries, cursor pagination, and live tail mode - Add cross-navigation: exchange header → logs, log tab → logs tab - Update ClickHouseLogStoreIT with cursor, multi-level, cross-app tests Closes: #104 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { GitBranch, Server, RotateCcw } from 'lucide-react';
|
||||
import { GitBranch, Server, RotateCcw, FileText } from 'lucide-react';
|
||||
import { StatusDot, MonoText, Badge } from '@cameleer/design-system';
|
||||
import { useCorrelationChain } from '../../api/queries/correlation';
|
||||
import { useAgents } from '../../api/queries/agents';
|
||||
@@ -100,6 +100,13 @@ export function ExchangeHeader({ detail, onCorrelatedSelect, onClearSelection }:
|
||||
</>
|
||||
)}
|
||||
<span className={styles.duration}>{formatDuration(detail.durationMs)}</span>
|
||||
<button
|
||||
className={styles.linkBtn}
|
||||
onClick={() => navigate(`/logs/${detail.applicationId}?exchangeId=${detail.exchangeId}`)}
|
||||
title="View surrounding logs"
|
||||
>
|
||||
<FileText size={12} className={styles.icon} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Route control / replay — only if agent supports it AND user has operator+ role */}
|
||||
|
||||
Reference in New Issue
Block a user