-
Notifications
You must be signed in to change notification settings - Fork 770
Add a pause button to console logs, structured logs, traces, and metrics pages #8184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a pause button to console logs, structured logs, traces, and metrics pages #8184
Conversation
… traces (start time)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a pause/resume feature across dashboard pages (console logs, structured logs, traces, and metrics) by introducing a reusable PauseResumeButton component and updating data retrieval logic to honor a paused timestamp.
- Added a PauseResumeButton component with binding for a paused timestamp.
- Updated LogViewer, ChartContainer, TracesViewModel, and StructuredLogsViewModel to filter data based on the paused timestamp.
- Modified multiple page components to integrate the pause functionality with the new component and corresponding event callbacks.
Reviewed Changes
Copilot reviewed 30 out of 33 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/Aspire.Dashboard/Components/Controls/PauseResumeButton.razor.cs | New component to toggle pause/resume state. |
| src/Aspire.Dashboard/Components/Controls/LogViewer.razor.cs | Updated to use a filtered data method based on PausedAt. |
| src/Aspire.Dashboard/Components/Controls/Chart/ChartContainer.razor.cs | Modified to skip data refresh when paused. |
| src/Aspire.Dashboard/Model/Otlp/TelemetryFilter.cs | Extended filtering to apply a timestamp condition on spans. |
| src/Aspire.Dashboard/Model/TracesViewModel.cs and StructuredLogsViewModel.cs | Adjusted data retrieval methods to accept an optional paused timestamp. |
| Various page components (Metrics, ConsoleLogs, StructuredLogs, Traces) | Integrated PauseResumeButton and updated callbacks to support pause/resume behavior. |
Files not reviewed (3)
- src/Aspire.Dashboard/Resources/ControlsStrings.Designer.cs: Language not supported
- src/Aspire.Dashboard/Resources/ControlsStrings.resx: Language not supported
- src/Aspire.Dashboard/Resources/xlf/ControlsStrings.cs.xlf: Language not supported
Comments suppressed due to low confidence (3)
src/Aspire.Dashboard/Components/Controls/LogViewer.razor.cs:94
- Consider storing the result of logEntries.GetEntries() in a local variable to avoid calling it twice. This would improve clarity and guarantee consistency of the retrieved log entries before applying the filter.
return PausedAt is null ? logEntries.GetEntries() : logEntries.GetEntries().Where(logEntry => logEntry.Timestamp is { } timestamp && timestamp <= PausedAt).ToList();
src/Aspire.Dashboard/Model/Otlp/TelemetryFilter.cs:135
- Verify that using 'OtlpLogEntry.TimeStamp' as the field for filtering spans is intentional. If spans should be filtered based on a different timestamp property (e.g. StartTime), update the field name accordingly.
nameof(OtlpLogEntry.TimeStamp) => ApplyTimeStamp(),
src/Aspire.Dashboard/Components/Controls/Chart/ChartContainer.razor.cs:94
- [nitpick] Document the rationale for skipping updates when PausedAt is set. A brief comment would clarify that data refresh is intentionally paused to prevent unnecessary API calls while the view is paused.
if (_instrument == null || PausedAt is not null)
|
There is a design decision that needs to be made here that I mentioned on the issue: whether the pause happens in the UI, or collecting telemetry. That needs to be figured out first. |
src/Aspire.Dashboard/Components/Controls/Chart/ChartContainer.razor.cs
Outdated
Show resolved
Hide resolved
Sometimes the line number is updated to skip values, other times it isn't: |
Hmm, I'm not able to reproduce this? |
|
|
||
| if (foundRange is not null && foundRange.FilteredLogsByApplication.GetValueOrDefault(application)?.Contains(entry) is not true) | ||
| { | ||
| ImmutableInterlocked.Update( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every filtered log is going to recreate a constantly growing immutable has set? What happens if there are thousands of log entries being filtered very quickly?
|
I didn't take a close look at the console pausing logic until now. I think the way counts are calculated and stored needs to be rewritten. We can't hold onto all the log entries in memory until the user unpauses. All memory could be consumed. |
When a pause log entry is created it have some kind of pause view model, and it's associated with the range and has a count. When something is filtered out, the count on the pause view model is incremented. Keep the logic needed for this page (the counts) on this page. Don't put it into global state. |
|
I think line number of pause log entries also need to be rethought.
|
|
|
||
| var logEntry = logParser.CreateLogEntry(content, isErrorOutput); | ||
| if (timestampFilterDate is null || logEntry.Timestamp is null || logEntry.Timestamp > timestampFilterDate) | ||
| if (logEntry.Timestamp is not null && _logEntries.GetPauseEntries().Select(e => e.Pause).Cast<LogPauseViewModel>().FirstOrDefault(pause => pause.Contains(logEntry.Timestamp.Value)) is { } pause) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the user refreshes the page, may add several prior pauses to log entries. Each needs to be checked. I added a list of pause entries to LogEntries to speed up this call
|
I think it's much better. I fixed a bug when you remove log entries while a pause is active. I noticed a race condition bug on log entries so added locks around modifying it. Also did some minor clean up. |



Description
Adds a pause/resume button to those 4 pages to the left of the clear signals button.

For console logs, an entry appears when a pause is active noting how many logs have been filtered out for that resource.

If, after a pause has ended, one or more logs were filtered, text appears in the console log noting the dates of the pause and how many logs were filtered. These lines are filtered out when downloading logs. Additionally, line numbers increment by the # of filtered logs, as can be seen in the screenshot below.

For metrics, the X axis of a visible graph stays consistent during a pause.
Fixes #7610
Checklist
<remarks />and<code />elements on your triple slash comments?breaking-changetemplate):doc-ideatemplate):