-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
RFC: add a flag --heap-prof (similar to --cpu-prof but for the heap) #27421
Comments
cc @nodejs/diagnostics |
is it possible to combine both flags and get two profiles in one run? |
@targos In terms of implementation, it is possible. Maybe we could just add a flag |
I like the idea, having a flag makes it easier for development and lowers the barrier for users. But on production it would be more useful to have an API that allows us to start and get the heap profile during runtime. This would allow to take the profile at different points in time and compare them to see what changed (which can help users to identify which functions are misbehaving). Also, getting the profile without saving to disk can be useful for users of serverless or users who send the profile to another place and want to avoid the unnecessary overhead of writing to disk. Having both the flag and the API would be ideal in my opinion. |
@mmarchini Yes, these profiling functionalities would be more useful for servers if they can be turned on/off on demand - in terms of programmable API there the inspector module already allows you to do these, although it is less straightforward to use. Another thing that we need to consider for production-use is the serializer implementation. As mentioned in #26878 I think it is fine to use the inspector from C++ and do Implementation-wise, for profiling on-demand I think the ideal solution is to expose JSON serializers for the profiles in the V8 embedder API (like I think one of the things we should get to before moving these flags out of experiment is a consistent API to trigger these diagnostics functionalities (both |
I opened https://bugs.chromium.org/p/v8/issues/detail?id=9182 in the upstream to see if the idea about having |
Funny thing, i recently started to work on a piece of software that focus on profiling at runtime (specially in production). I've come up with a API that pretty much look like this: const profilingAgent = new ProfilingAgent()
const session = new inspector.Session()
profilingAgent.register(new SignalTrigger({ signal: 'SIGUSR2' }), new InspectorHeapProfiler({ session }))
profilingAgent.register(new SignalTrigger({ signal: 'SIGUSR1' }), new InspectorCPUProfiler({ session }))
profilingAgent.start({ exporter: new FileExporter() }) I can't speak about the C++ implementation behind the inspector but i thought that since the topic of runtime profiling was brought up, i could get some feedback about how to make it available to more users. |
@vmarchaud Thanks for the demo! Is I think if possible we should unify this with the |
Regarding use of inspector API in production: Are there any docs available regarding side-effects/overhead by just enabling inspector and create a session? |
@joyeecheung Indeed, every profiler/trigger/exporter is an interface that can be implemented in his own package. If you want i just made public the project there. If anyone has some feedback on it, it would be much appreciated. |
I guess the reason for that is that we create ~210 Error classes in there. |
Now the subclasses only need to override methods to - Get the profile node from the profiler response message object - Return the directory and file path And the V8ProfilerConnection() would handle the rest of profile serialization and message parsing. This makes it easier to add other types of profiles in the future. PR-URL: #27475 Refs: #27421 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Now the subclasses only need to override methods to - Get the profile node from the profiler response message object - Return the directory and file path And the V8ProfilerConnection() would handle the rest of profile serialization and message parsing. This makes it easier to add other types of profiles in the future. PR-URL: #27475 Refs: #27421 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
I moved my comment from pull request to here since I believe that it is better place for discussion.. Sorry for being a little bit late! I believe that --heap-prof flag can be fully implemented in much flexible way using inspector. Please take a look on gist that I created: https://gist.github.com/ak239/b24c07d7d5b45d83514435cacf3e9b4e It is important that it uses out of process inspection over websocket instead of inspector bindings. With this approach we can avoid polluting inspected process with scripts required for inspector and fs. In solution with inspector we can use any available in inspector profiler, e.g. type profiler, cpu profiler, sampling or allocation memory profilers, coverage profile, and we fully control how we store information that we get - we can store it to file, convert to different format and do anything else. At the same time inspector protocol designed in a way that as an user you pay only for what you use, so there is ~ zero overhead of running node process with What are benefits of having separate flags for different type of profiles over using inspector? End process detection will become cleaner as soon as #27600 landed. And inspector port discovery might become easier with nodejs/diagnostics#298. |
I think that the flag are easier to understand for end user, in which case they don't need to understand the way |
Flag is easier - I agree but Imagine you have an npm module that can capture heap snapshot using inspector and instead of running |
I agree that it's easy to implement it userland when you already know the
We also could test the |
I am not talking about using All protocol methods are tested on V8 CI, protocol maintainers give you a guarantee that protocol API is stable. So I believe that inspector protocol is even more safe option from compatibility point of view than node flag. I am not sure that in long run there is any difference in two mindsets:
Second one actually allows more people to work on making CLI tool better. |
I built some proof of concept and release it on |
I believe there are several constraints that come with this approach:
|
And about making this functionality in the user land as an npm module v.s. being in core: while we used to leave this kind of stuff in the user land, we now tend to move them into core - recent examples are node-report (which was an npm module by itself) and
|
It is good point, I would like to propose
I am not sure about this point. Why do we need crypto for inspector protocol implementation? Protocol implementation is self contained and located inside V8. If crypto is required for inspector web socket server implementation inside Node then using pipe instead of WebSocket will resolve this issue as well. On-demand profiling can easily be done with out of process inspection as well. I will add something like this to thetool this evening. At the same time |
It is definitely valid point as well. Could we then put In general I am worried that we are building second API surface for the data that is already available when V8 team already has a commitment to maintain inspector protocol API and it has huge user base - Chrome DevTools, VSCode, puppeteer, e.t.c. - all of them use protocol. As a result we might get to the point when data exposed using flags from Node is different with data exposed using protocol from Chromium and Node and I can not build some nice tool to analyze V8 behavior that works equally great for V8 inside Chromium and for V8 inside Node anymore. In any case, if we can add flags for profiling, could I add |
I don't really know why, but this is currently the case if you build with
It would be possible but I think we need to be sure that we actually want to stick with the inspector approach before doing that...is the inspector protocol suitable to use in production servers in general? Running an inspector server in your applications enables remote execution via
I personally think |
It looks like inspector source files use SHA1 from openssl. @eugeneo do you think that we can not make inspector work without ssl? We use ws:// scheme for inspector WebSocket so I assume that our connection is not secure. At the same time over the pipe we can use much simpler format - the same as Chromium use - pass messages as is with \0 as delimiter so pipe definitely does not require ssl.
I believe that inspector is suitable to use in production. It produces ~0 overhead if there is no active inspector session. Overhead of active session depends on what features are used, e.g. sampling heap profiler has very small overhead, enabled debugger sometimes might have huge overhead. In general it is not about policy to allow some domains and disable another domains but about making inspector channel (websocket or pipe) available for non local process or not available. |
Inspector infrastructure was designed to be used in production:
We know that it has zero performance overhead and withheld the test of load and evolution. I would claim that there is no other API that would stand close to these metrics in production. So if we want to see further adoption and the blooming of the tooling around diagnostics in Node, I would go all in.
Diagnostics API should only be exposed to the trusted party. When running over the Web Socket It is not available to the one accessing an open port, it requires a crypto-secure unguessable token to be present in order to engage. When running as a pipe, it trusts the launcher process to handle this diagnostics channel in a secure manner. |
@ak239 @pavelfeldman Thanks for sharing your insights here! I ran a Twitter poll to see if there are concerns from experiences using inspector protocol in the wild: https://twitter.com/JoyeeCheung/status/1128314669209272321 Most concerns were around the However coming back to the original proposal - adding a |
In addition implements --heap-prof-name, --heap-prof-dir and --heap-prof-interval. These flags are similar to --cpu-prof flags but they are meant for the V8 sampling heap profiler instead of the CPU profiler. PR-URL: #27596 Fixes: #27421 Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
Refs: #26878
I am working on a flag
--heap-prof
here similar to--cpu-prof
and would like to see the general feeling about this flag. It's pretty similar to--cpu-prof
, and reuses most of the CPU profiler and coverage integration (with an abstract class).When opening the profile in the Chrome DevTools it looks like this:
(to my surprise
makeNodeErrorWithCode
allocates quite an amount of memory during startup)There is still a remaining issue with the current implementation (and it's also the case for
--cpu-prof
but reproduce less often): the default sampling interval is too high which makes the test quite flaky - but we can't allocate too much memory in the test in case it times out in the CI on the less powerful machines. It would be pretty simple to add--cpu-prof-interval
/--heap-prof-interval
and make them customizable, but I am not sure if people are comfortable with this kind of API design (passing everything with flags, though that's already the case for--report-*
)The text was updated successfully, but these errors were encountered: