feat: add log source filter (app/agent) to runtime log viewers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -87,6 +87,11 @@ const LOG_LEVEL_ITEMS: ButtonGroupItem[] = [
|
||||
{ value: 'trace', label: 'Trace', color: 'var(--text-muted)' },
|
||||
];
|
||||
|
||||
const LOG_SOURCE_ITEMS: ButtonGroupItem[] = [
|
||||
{ value: 'app', label: 'App' },
|
||||
{ value: 'agent', label: 'Agent' },
|
||||
];
|
||||
|
||||
// ── AgentHealth page ─────────────────────────────────────────────────────────
|
||||
|
||||
export default function AgentHealth() {
|
||||
@@ -138,9 +143,10 @@ export default function AgentHealth() {
|
||||
|
||||
const [logSearch, setLogSearch] = useState('');
|
||||
const [logLevels, setLogLevels] = useState<Set<string>>(new Set());
|
||||
const [logSource, setLogSource] = useState<string>(''); // '' = all, 'app', 'agent'
|
||||
const [logSortAsc, setLogSortAsc] = useState(false);
|
||||
const [logRefreshTo, setLogRefreshTo] = useState<string | undefined>();
|
||||
const { data: rawLogs } = useApplicationLogs(appId, undefined, { toOverride: logRefreshTo });
|
||||
const { data: rawLogs } = useApplicationLogs(appId, undefined, { toOverride: logRefreshTo, source: logSource || undefined });
|
||||
const logEntries = useMemo<LogEntry[]>(() => {
|
||||
const mapped = (rawLogs || []).map((l) => ({
|
||||
timestamp: l.timestamp ?? '',
|
||||
@@ -554,6 +560,11 @@ export default function AgentHealth() {
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<ButtonGroup
|
||||
items={LOG_SOURCE_ITEMS}
|
||||
value={logSource ? new Set([logSource]) : new Set()}
|
||||
onChange={(v) => setLogSource(v.size === 0 ? '' : [...v][0])}
|
||||
/>
|
||||
<ButtonGroup items={LOG_LEVEL_ITEMS} value={logLevels} onChange={setLogLevels} />
|
||||
{logLevels.size > 0 && (
|
||||
<Button variant="ghost" size="sm" onClick={() => setLogLevels(new Set())}>
|
||||
|
||||
@@ -26,11 +26,17 @@ const LOG_LEVEL_ITEMS: ButtonGroupItem[] = [
|
||||
{ value: 'trace', label: 'Trace', color: 'var(--text-muted)' },
|
||||
];
|
||||
|
||||
const LOG_SOURCE_ITEMS: ButtonGroupItem[] = [
|
||||
{ value: 'app', label: 'App' },
|
||||
{ value: 'agent', label: 'Agent' },
|
||||
];
|
||||
|
||||
export default function AgentInstance() {
|
||||
const { appId, instanceId } = useParams();
|
||||
const { timeRange } = useGlobalFilters();
|
||||
const [logSearch, setLogSearch] = useState('');
|
||||
const [logLevels, setLogLevels] = useState<Set<string>>(new Set());
|
||||
const [logSource, setLogSource] = useState<string>(''); // '' = all, 'app', 'agent'
|
||||
const [logSortAsc, setLogSortAsc] = useState(false);
|
||||
const [eventSortAsc, setEventSortAsc] = useState(false);
|
||||
const [logRefreshTo, setLogRefreshTo] = useState<string | undefined>();
|
||||
@@ -136,7 +142,7 @@ export default function AgentInstance() {
|
||||
);
|
||||
|
||||
// Application logs
|
||||
const { data: rawLogs } = useApplicationLogs(appId, instanceId, { toOverride: logRefreshTo });
|
||||
const { data: rawLogs } = useApplicationLogs(appId, instanceId, { toOverride: logRefreshTo, source: logSource || undefined });
|
||||
const logEntries = useMemo<LogEntry[]>(() => {
|
||||
const mapped = (rawLogs || []).map((l) => ({
|
||||
timestamp: l.timestamp ?? '',
|
||||
@@ -435,6 +441,11 @@ export default function AgentInstance() {
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<ButtonGroup
|
||||
items={LOG_SOURCE_ITEMS}
|
||||
value={logSource ? new Set([logSource]) : new Set()}
|
||||
onChange={(v) => setLogSource(v.size === 0 ? '' : [...v][0])}
|
||||
/>
|
||||
<ButtonGroup items={LOG_LEVEL_ITEMS} value={logLevels} onChange={setLogLevels} />
|
||||
{logLevels.size > 0 && (
|
||||
<button className={logStyles.logClearFilters} onClick={() => setLogLevels(new Set())}>
|
||||
|
||||
Reference in New Issue
Block a user