How GitHub Actions renders large-scale logs
github.blog
github.blog
Chrome has no problems loading >140k lines of logs (~10mb, biggest job I could find) and scrolling/searching/selecting/copying/etc. Obviously not as snappy as smaller logs, and also not as snappy as downloading the log file to browse in IntelliJ, but it works OK-ish. It's a lot higher than the ~20k line soft limit they described in the post!
The biggest difference I could find is that Github Action's log browser generates 6 HTML elements with ~673 characters of HTML overhead per log line, whereas our own log browser generates 1 HTML element with ~45 characters of HTML element per log line (basically a single div with a timestamp attribute for a non-colored line). In that light I guess it's not surprising that browsers have more trouble with Github Actions logs given how much more work they are making the browser do to render each line of logs!
The minimal-HTML nature of our log browser was an intentional design goal. It's interesting what kind of limits you hit: you cannot use opacity (too slow), no rounded corners (too slow), one-div-per-line is faster than using spans and line wrapping (no idea why), no per-line JS logic (attach your event handlers to the parent container and wait for propagation). Kind of restrictive, but it's certainly nice not to have to implement an entire virtualized scroll window (which I have done before, and would rather not do again if possible!)
Even more sad, vim 20 years ago could handle these files with ease, and here we are where 20kb causes the browser to choke.
alias vi='vim -u NONE'
which makes it skip vimrc.
All of which is to say—have you tried going this route? I'm not familiar with Yocto, but I feel like it's worth a shot regardless of the UI. There's only so much useful information to log, and it makes it easier to read the logs too, even with a perfect UI.
How exactly is seeing all this progress mess in your log helpful? If your network connection suddenly breaks at 158K, are you going to do anything different than if it broke at 60K? Do you really need every single line here when all you're doing is just an external download?
0K .......... .......... .......... .......... .......... 0% 153K 67s
50K .......... .......... .......... .......... .......... 0% 310K 49s
100K .......... .......... .......... .......... .......... 1% 300K 44s
150K .......... .......... .......... .......... .......... 1% 10.5M 33s
200K .......... .......... .......... .......... .......... 2% 305K 33s
250K .......... .......... .......... .......... .......... 2% 152K 38s
300K .......... .......... .......... .......... .......... 3% 51.1M 33s
350K .......... .......... .......... .......... .......... 3% 305K 32s
400K .......... .......... .......... .......... .......... 4% 302K 32s
450K .......... .......... .......... .......... .......... 4% 306K 32s
500K .......... .......... .......... .......... .......... 5% 158K 35s
What I think you're not realizing is you waste so much time normally filtering through all this cruft every time you scroll through and filter logs; it's not a zero-cost addition. You're paying for it every single time, and the noise actually makes it harder to find stuff you're looking for. At best it wastes seconds of your (and your teammates') time every time; at worst it makes you (and your teammates) actually miss real problems. It actually helps productivity to filter things out, and often (like here) it doesn't even have an ongoing downside to begin with.For starters, your entire premise was "you don't have the run the build again". But now that I ask what you're going to do, you tell me you're... going to run the build again. So you've basically proven my point... you're going to waste that time sitting around anyway, and you'll need to reproduce it anyway, so just kick off an extra build or two in parallel if you need to correlate offsets. It's not like the 2nd one was going to be your last build anyway.
Now re: diagnosing networks by looking at the byte offsets... so you correlate it (2 builds sufficed apparently?) and then... what exactly are you going to do now? This is GitHub Actions we're talking about, with dependencies downloaded from third-party servers. You're not managing either party's network or storage infrastructure to try to diagnose intermittent "network troubles". All you see is, for whatever reason, ubuntu/pypi/nuget/whatever isn't returning the full file. Maybe it fails in the same spot every time, maybe it doesn't. What exactly are you going to do differently based on what # byte it's failing to return? Either you can increase some timeout or switch to another server or whatever, or you can't. It's not like you're going to pull half the file and just use that. All the progress information does is satisfy idle curiosity and make you go "oh, that's funny...", and then you're left with the same options you had anyway.
And honestly, how often does this even happen that you can't afford to tweak the build and increase the verbosity or whatever? These messages are just as useful as garbage >99.9% for the time, for the entire team... you really encounter these issues often enough (and find 2 builds sufficient for fixing them) to warrant that? To say I have a hard time swallowing this is quite the understatement.
As for what I would do once I have that information…for GitHub Actions not much other than report it to someone who might actually have use for that information. But for internal CI it can be useful because it can tell you things like “oh the build always fails 30 minutes in, perhaps something is timing out” or “it always fails at 68%…hmm, I can download this file when not on the corporate network. Ah, the firewall doesn’t like that packet”.
Again, I’m not saying I don’t agree with you that this is often not useful, but if you have a way to hide it away until it is necessary I would generally lean towards keeping it.
APT::Install-Recommends "0";
APT::Install-Suggests "0";
APT::Acquire::Retries "20";
Dpkg::Use-Pty "0";
Dpkg::Options "--force-confnew";They're connected to open source, but i don't think the GitHub app is open source. Maybe it's not reasonable to expect
Maybe it’s too much of a pain for people to reverse engineer?
- only a small area of the screen is actually used for logging messages
- I'm constantly fighting the per-runstep folding views, but it's hard to describe what the actual problem is, except "it's awkward to use"
- when new messages are added to the log, the view scrolls to the end of the log, it's impossible to "catch" the view with the mouse.
- I don't know if I remember right, but searching only seems to work on the unfolded views, which is a pretty dumb idea.
etc...etc... it's really not a nice experience IMHO. From my POV (mostly C/C++ compile logs) performance is fine, but everything else sucks :)
Please have a look at any other CI system for inspiration, AppVeyor, Travis, Gitlab... I never had a problem with their log views, I guess mostly because they are much simpler.
However this may be because I am a FireFox user. I have found that for fairly simple HTML (basically just colouring and some links) such as this FireFox handles all but the largest files very well (and my build logs aren't very large in the grand scheme of things) but Chrome often locks up on much smaller files.
I hope there is a way to disable this, or at least click though to the raw log without the JS nonsense.
UX at scale is really difficult sometimes and there are constant trade-offs and limitations to deal with. Everyone expects perfectly smooth performance with data available at an instant and it's easy to be the other side and judge than to have to actually work through the complications of solving it.
I maintain Jenkins and sometime we pull log that has is about 500MB and it's crashed no matter what I do. If I switch to console plain text then browser is no longer crash but very slow.
If Github action allow a plain text download option will make thing way easier.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ca...
Each canvas element can tell you the size of each rect, so for each of the 50k log lines, you'd have an element in the canvas. When scrolling, the html elements can fade. As the rect scrolls into view, it draws the html div over itself, since each rect is uniquely associated with a line of text.
It was a thought with some of the previous work I had done with canvas.