The previous round crammed every control into the widget header as one flex
row, which read as cluttered. Restore the stock Portainer two-row shape:
- header bar: the "Logs" title on the left; Search + Copy + Download logs
right-aligned in the header's transclude slot;
- a single clean horizontal toolbar in the widget body: Since / Lines /
Wrap lines / Display timestamps (no longer stacked form-groups);
- the log <pre> pane below, unchanged.
Auto-refresh and the line-selection controls stay removed (already gone from
the controller). Template-only change; no controller edits.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Backend (the "logs arrive every ~5s / pipe clogged" bug):
- dockerLocalProxy.ServeHTTP streamed the docker socket response via
io.Copy, which buffers ~2KB into the ResponseWriter and only flushes
when full or on handler return. Low-throughput streaming endpoints
(container logs follow=1, events, stats, attach) therefore arrived in
multi-second batches. Stream manually and Flush() after each chunk so
they are delivered live. Behaviour is otherwise identical to io.Copy
(full-write contract, EOF handling, Debug error logging); hijacked
attach/exec go through a separate websocket handler, unaffected.
- NewSingleHostReverseProxyWithHostHeader: set FlushInterval = -1 so the
remote-endpoint path streams live too.
Frontend (maintainer UI asks):
- Remove the line-selection mechanic entirely (Copy-selected-lines and
Unselect buttons, selectLine/copySelection/clearSelection, selectedLines
state, line_selected highlight): selecting/copying is mouse-native. Copy
(all visible) and Download stay.
- Rename the unclear "Fetch" since-selector label to "Since".
- Move the settings controls into the widget header (rd-widget-header
default transclude slot) so they share one row with the "Log viewer
settings" title, reclaiming vertical space for the log pane.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per maintainer request: remove the 'Auto-refresh logs' toggle entirely — logs are
now always collected (container always streams, service/task always poll). Drops
state.logCollection and its whole cascade (handleLogsCollectionChange, the
logCollectionChange binding, changeLogCollection in all three view controllers,
the log-collection-change attribute) and the now-dead manual flush-on-pause
machinery (pausedFlushCount / removeTailLines / the flush branch); pauseStream is
kept for $destroy/reconnect teardown, and the stream/poll start unconditionally.
Collapse the seven stacked settings rows into a single compact flex row
(wrap-lines, timestamps, fetch, lines, search, actions) — bindings unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
logViewer.html is shared by the container, service and task log views, but only
the container view is a live HTTP stream — service/task still poll. Revert the
toggle wording to a mode-neutral 'Auto-refresh logs' / 'pauses log collection'
so it is accurate for both, keeping the added auto-scroll clarification.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the 3s $interval polling of container logs with a live HTTP
stream, and stop re-writing already-rendered lines (fixes selection bug).
- streamContainerLogs (containers.service.ts): fetch + ReadableStream
reader with follow=1, same-origin credentials:'include' (httpOnly JWT
cookie; CSRF only guards mutations), agent-target / manager-operation
headers replicated for Agent/Edge, AbortSignal-driven lifetime.
- containerLogsController: stream instead of poll; append parsed lines
into the buffer (push, never replace), cap at 5000 lines trimming from
the head; AbortController on pause/destroy/param-change; reconnect with
3s backoff resuming from `since` (dropping tail) on stream end/error;
Live toggle pauses/resumes the stream; tail/since/timestamps changes
restart the stream.
- log-viewer: `track by log.id` (was $index), filtering moved out of the
template into the controller (applyFilter via $watchCollection), removed
inert force-glue, decoupled auto-scroll from log collection, relabelled
"Auto-refresh logs" -> "Live logs", clearer empty states.
Backend unchanged (logs already stream transparently through the Docker
proxy). Shared task/service log views keep working via the new id'd lines.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(logging): default to pretty logging EE-4371
* feat(app/logs): prettify stack traces in JSON logs
* feat(nomad/logs): prettify JSON logs in log viewer
* feat(kubernetes/logs): prettigy JSON logs in log viewers
* feat(app/logs): format and color zerolog prettified logs
* fix(app/logs): pre-parse logs when they are double serialized
Co-authored-by: andres-portainer <andres-portainer@users.noreply.github.com>
Co-authored-by: LP B <xAt0mZ@users.noreply.github.com>