diff --git a/ui/src/components/logs/logs-filters.tsx b/ui/src/components/logs/logs-filters.tsx
index f1c4436c..4d00d830 100644
--- a/ui/src/components/logs/logs-filters.tsx
+++ b/ui/src/components/logs/logs-filters.tsx
@@ -44,6 +44,9 @@ export interface LogsFiltersProps {
onRequestIdChange?: (v: string) => void;
timeWindow?: LogsTimeWindow;
onTimeWindowChange?: (v: LogsTimeWindow) => void;
+ /** When true, hides entries from `web-server:*` sources. Default ON. */
+ hideDashboardInternals?: boolean;
+ onHideDashboardInternalsChange?: (next: boolean) => void;
onClearAll?: () => void;
}
@@ -88,6 +91,8 @@ export function LogsFilters({
onRequestIdChange,
timeWindow = 'all',
onTimeWindowChange,
+ hideDashboardInternals = true,
+ onHideDashboardInternalsChange,
onClearAll,
}: LogsFiltersProps) {
const [advancedOpen, setAdvancedOpen] = useState(false);
@@ -312,6 +317,31 @@ export function LogsFilters({
) : null}
+ {onHideDashboardInternalsChange ? (
+
+
+
+
+ Suppress web-server:*{' '}
+ self-polling.
+
+
+
onHideDashboardInternalsChange(e.target.checked)}
+ className={cn('mt-0.5 h-4 w-4 cursor-pointer accent-foreground', FOCUS_RING)}
+ aria-label="Hide dashboard internals"
+ />
+
+ ) : null}
diff --git a/ui/src/components/logs/logs-shell.tsx b/ui/src/components/logs/logs-shell.tsx
index 2e985696..a659ee27 100644
--- a/ui/src/components/logs/logs-shell.tsx
+++ b/ui/src/components/logs/logs-shell.tsx
@@ -137,6 +137,18 @@ export function LogsShell({ workspace, updateConfig }: LogsShellProps) {
[workspace.entriesQuery.data]
);
+ // Derive header stat strip values once per data refetch.
+ const headerStats = useMemo(() => {
+ const data = workspace.entriesQuery.data ?? [];
+ const requestIds = new Set();
+ let errors = 0;
+ for (const entry of data) {
+ if (entry.requestId) requestIds.add(entry.requestId);
+ if (entry.level === 'error') errors += 1;
+ }
+ return { entries: data.length, traces: requestIds.size, errors };
+ }, [workspace.entriesQuery.data]);
+
const focusSearch = useCallback(() => {
const input = document.getElementById('logs-search') as HTMLInputElement | null;
if (input) {
@@ -180,6 +192,8 @@ export function LogsShell({ workspace, updateConfig }: LogsShellProps) {
onRequestIdChange={workspace.setRequestIdFilter}
timeWindow={workspace.timeWindow}
onTimeWindowChange={workspace.setTimeWindow}
+ hideDashboardInternals={workspace.hideDashboardInternals}
+ onHideDashboardInternalsChange={workspace.setHideDashboardInternals}
onClearAll={workspace.clearAdvancedFilters}
/>
);
@@ -228,6 +242,7 @@ export function LogsShell({ workspace, updateConfig }: LogsShellProps) {
isFetching={workspace.entriesQuery.isFetching || workspace.sourcesQuery.isFetching}
hasError={Boolean(workspace.entriesQuery.error)}
capturedCount={workspace.entriesQuery.data?.length ?? 0}
+ stats={headerStats}
onRefresh={handleRefresh}
onOpenSettings={openSettings}
onOpenShortcuts={() => setShortcutsOpen(true)}
diff --git a/ui/src/hooks/use-logs.ts b/ui/src/hooks/use-logs.ts
index 254b9285..702db1f6 100644
--- a/ui/src/hooks/use-logs.ts
+++ b/ui/src/hooks/use-logs.ts
@@ -116,6 +116,10 @@ export function useLogsWorkspace() {
const [limit, setLimit] = useState(DEFAULT_LIMIT);
const [selectedEntryId, setSelectedEntryId] = useState(null);
const [isPaused, setIsPaused] = useState(false);
+ // Default ON: dashboard self-polling generates 100s of identical entries
+ // per refresh which drown out real provider activity. Users can opt in to
+ // see internals via the advanced filter toggle.
+ const [hideDashboardInternals, setHideDashboardInternals] = useState(true);
const frozenIdsRef = useRef>(new Set());
const deferredSearch = useDeferredValue(search.trim());
@@ -151,6 +155,7 @@ export function useLogsWorkspace() {
debouncedRequestId,
timeWindow,
limit,
+ hideDashboardInternals ? 'hide-internals' : 'show-internals',
mockEnabled ? 'mock' : 'live',
],
queryFn: async () => {
@@ -191,6 +196,9 @@ export function useLogsWorkspace() {
const ts = Date.parse(entry.timestamp);
if (Number.isFinite(ts) && now - ts > cutoffMs) return false;
}
+ // Hide dashboard self-polling unless user opted in. Preserves the
+ // signal-to-noise ratio for fresh-load investigations.
+ if (hideDashboardInternals && /^web-server:/i.test(entry.source)) return false;
return true;
});
const head = filtered[0];
@@ -265,6 +273,7 @@ export function useLogsWorkspace() {
setStageFilter('');
setRequestIdFilter('');
setTimeWindow('all');
+ setHideDashboardInternals(true);
}, []);
return {
@@ -285,6 +294,8 @@ export function useLogsWorkspace() {
setRequestIdFilter,
timeWindow,
setTimeWindow,
+ hideDashboardInternals,
+ setHideDashboardInternals,
limit,
setLimit,
selectedEntryId: activeSelectedEntryId,