-
Notifications
You must be signed in to change notification settings - Fork 543
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
Refactor console logs to render on server and use virtualization #3075
Conversation
@tlmii I haven't looked at console logs closely before. Why does the current source code sort log entries and build HTML in the client? |
Short answer: This was one of the first things we implemented... it started off all in Blazor (sans virtualization - I didn't know about the Virtualize component (not to mention a lot of other Blazor stuff at the time)), someone commented that that'd be too much for Blazor to push to the client as the dataset got larger and we should only send changes to the client manually. So we did. And it hasn't been a priority to fix since then. |
await _cancellationSeries.ClearAsync(); | ||
if (logEntry.ParentId != null) | ||
{ | ||
// If we have a parent id, then we know we're on a non-timestamped line that is part |
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.
Was hoping the need to do this interleaving would go away at some point. I guess that some point is not yet...
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.
I just replicated what JS was doing. I'm not a fan of it. Reordering data from the server just before it is rendered is probably the wrong place. If reordering is required, it should happen before storing the data inside the host.
I'm thinking about line numbers right now, and this reordering makes it difficult.
Can you talk more about why it is required? What was the original issue?
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.
Yeah, sorry, I probably could have been more clear on that comment. I had hoped it was going to go away with streaming logs, but @karolz-ms indicated there were still two separate streams so there might be an issue.
The reordering was required because the logs arrived out of order from the two different streams (stdout and stderr). This was especially true with logs being written to the file system - the first stderr line could have been seconds or minutes after the first stdout line, but since the two files were read at the same time, we'd get them in unpredictable order. Though whatever the source is (docker logs acted slightly differently) they'd still need to be interleaved at some point.
Looking through the current code on the dashboard side, I don't see anywhere obvious where we see the two different streams anymore. Maybe @karolz-ms can speak to how that works in the streaming world now?
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.
There are still two streams, they now come from k8s service:
aspire/src/Aspire.Hosting/Dcp/ResourceLogSource.cs
Lines 28 to 29 in 0783a60
var stdoutStream = await kubernetesService.GetLogStreamAsync(resource, Logs.StreamTypeStdOut, follow: true, timestamps: timestamps, cancellationToken).ConfigureAwait(false); | |
var stderrStream = await kubernetesService.GetLogStreamAsync(resource, Logs.StreamTypeStdErr, follow: true, timestamps: timestamps, cancellationToken).ConfigureAwait(false); |
I think this would still be a problem.
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.
DCP could combine the streams (and apply timestamps to Executable logs), but then we need to figure out how to convey what entries come from stdout vs stderr. E.g. change the format to JSON lines or something similar, but then there is a question of how to deal with non-printable characters etc.
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 DCP combined the streams, would they be in the correct order? How does DCP get its data? Is it reading from files written to disk, or receiving it more directly?
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.
E.g. change the format to JSON lines or something similar, but then there is a question of how to deal with non-printable characters etc.
I guess a JSON serializer would escape them to \uXXXX
format.
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.
For Containers the logs arrive in the order the container orchestrator is providing them. But since we are using the CLI to talk to the orchestrator, it boils down to reading stdout
and stderr
.
The same applies to Executables. When DCP launches Executables directly, it is also responsible for reading stdout
and stderr
streams. When using the IDE to launch Executables (i.e. dealing with VS projects), it is relying on the IDE to provide the logs.
Bottom line this is probably sufficient for UI to have logs emitted ROUGHLY at the same time to surface close in the combined stream. But there will definitively be some jitter involved, and if the expectation is that developers will be able to infer the order in which things happened based on the order in which they appeared in the (combined) log stream, especially if we are talking about microseconds delay between writes to stdout
vs stderr
, that is probably a stretch.
9a013dd
to
980d502
Compare
@davidfowl I modified the resource logger API to have a struct record to represent line information. It now has a line number on it. |
When the page is scrolled to the bottom, there's a bit of a flicker every time the content is updated (the gif doesn't catch all the flickers): I switched back to main branch and that doesn't seem to be happening there. Just a function of the way the Virtualize works? I don't think its a blocker since this PR makes the page usable with lots of content which is much more important. But it is kind of annoying when watching the logs come in waiting for something. |
32752cd
to
b2a3cb1
Compare
I think it's a problem with I created an issue about it: dotnet/aspnetcore#54742 I don't think there is a way to improve it (short of copying the source code of Virtualize and changing how it works) right now, but hopefully it can be improved in the next .NET. |
Review please 🙏 |
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.
One thing I'm seeing fairly consistently here is that if I launch TestShop, let the Resources page load, go to Console Logs, and choose the dashboard entry from the list, the page doesn't scroll with the logs. It seems like it just stays at wherever it is when the page loads (several pages of logs down from the top, but I guess not all the way at the bottom since it doesn't auto-scroll). Sometimes if I leave the page and come back, it'll act as expected.
That particular log source is the one that is already more than a page of data by the time you get to it and still continues adding logs, so its hard to repro it for other resources.
I think the rest of this looks good other than this and the flicker (which I know is not from our code) so I'll go ahead and approve it. Workaround is easy enough - just use keyboard or mouse to scroll to the bottom.
I've noticed it not scrolling with new content as the page loads as well. I'll see if I can figure it out. |
e914f4f
to
99064dc
Compare
I've fixed it. |
/backport to release/8.0-preview5 |
Started backporting to release/8.0-preview5: https://github.com/dotnet/aspire/actions/runs/8436937421 |
Fixes #2507
TODO:
Line numbers need work. Especially if the total logs are truncated. For example, if logs are truncated from 20,000 to 10,000, the first visible line should have a line number of 10,001.Some old JS needs to be removedMicrosoft Reviewers: Open in CodeFlow