-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Implement process collector for Windows #596
Conversation
Signed-off-by: Calle Pettersson <carlpett@users.noreply.github.com>
8652d6b
to
427315c
Compare
ping @beorn7, what do you think? (Apart from my apparently having missed something with go modules, I'll fix that) |
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.
Looks very cool at a first glance. I'll have a closer look ASAP.
Also, it would make sense to have somebody with some Windows foo looking at this. (Anybody?)
The test failures are because you haven't updated the go.mod file. (Let me know if you need help with the Go modules part.) |
} | ||
ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.WorkingSetSize)) | ||
ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(mem.PeakWorkingSetSize)) | ||
ch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.PrivateUsage)) |
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 think RSS is WorkingSetSize
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, the Windows terminology is kind of weird. WSS is something else than RSS, but apparently, when Windows says "WSS", it means "RSS".
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.
Yes, that seems correct.
The "working set" of a process is the set of memory pages currently visible to the process in physical RAM memory. These pages are resident and available for an application to use without triggering a page fault
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.
Left a few comments.
This looks good in general, we just need to figure out the memory nomenclature of MS Windows.
return | ||
} | ||
ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.WorkingSetSize)) | ||
ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(mem.PeakWorkingSetSize)) |
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.
maxVsize is the maximum possible virtual memory size, not the observed peak. Not sure if there is a way to get this from somewhere on MS Windows. Perhaps it has to be hardcoded depending on whether it's 64bit or 32bit.
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.
It seems it might depend on OS version as well. I found this source https://blogs.technet.microsoft.com/markrussinovich/2008/11/17/pushing-the-limits-of-windows-virtual-memory/ where they claim 8TB on 64 bit. They have a reference table which goes to Windows 2012. On my Windows lab host, I could reserve 128TB, though.
I'll see if this is available through some API, but otherwise I don't know. Not super keen on the idea of maintaining a lookup table which is hard to know when it needs to be updated.
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.
Alternatively, on Linux it seems we represent unlimited
with -1. Might make sense here too?
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.
We could not export it. I doubt there's many 32bit systems out there that would care (and it's a hardcoded value if they need it).
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.
That's also an option, of course. But 32-bit isn't actually something we can hardcode, if I understand it correctly. The value will depend on if the OS is 32 bit or not, and if booted with a 2/2 GB or 3/1 GB split between OS and application. On a 64 bit OS, it depends on if the IMAGE_FILE_LARGE_ADDRESS_AWARE
flag is set on the binary by the go compiler, which seems to be the case: https://github.com/golang/go/blob/e883d000f4ce0c47711c3a7c59df8bb2f0ec557f/src/cmd/link/internal/ld/pe.go#L785-L788
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.
But again, it is not clear if those hoops are worth jumping through.
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.
In doubt, let's just not export this metric, as Brian suggested.
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.
Sounds good to me. In that case, should we drop the "max fds" too? That value is pretty uninteresting (although "correct"), and I added it to try to keep parity.
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.
Yes, let's keep it as it is the technically correct value and doesn't imply any maintenance overhead to keep it correct.
} | ||
ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.WorkingSetSize)) | ||
ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(mem.PeakWorkingSetSize)) | ||
ch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.PrivateUsage)) |
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, the Windows terminology is kind of weird. WSS is something else than RSS, but apparently, when Windows says "WSS", it means "RSS".
c.reportError(ch, nil, err) | ||
return | ||
} | ||
ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.WorkingSetSize)) |
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.
Concluding from the comments below, the WorkingSetSize
is more like the RSS. I have no clue how to get something like the vsize on Windows.
Wild guess: For vsize, we have to check PagefileUsage. If it is zero, we have to use PrivateUsage. But it would be really good if somebody with a good understanding of Windows's memory management could help out. |
Signed-off-by: Calle Pettersson <carlpett@users.noreply.github.com>
51cceab
to
5c67f39
Compare
@beorn7 From my understanding of PROCESS_MEMORY_COUNTERS_EX, |
It seemed to me that |
Yeah, it is weirdly formulated. My interpretation is that PagefileUsage=PrivateUsage, except on older versions where PagefileUsage=0 (but PrivateUsage is still set). But I may be wrong. |
In lack of better information, let's do it as discussed. I think the only remaining change is to remove the |
Signed-off-by: Calle Pettersson <calle@cape.nu>
e397318
to
09741ab
Compare
Done! |
Thanks 1M! |
This PR implements a process collector for Windows, resolves #376.
Some discussion points:
process_cpu_seconds_total
uses an underlying data source that is, from my understanding, incremented with a resolution of ~16 ms. There might be better APIs to use? The ones I've found work with cycles, though, which isn't that easy to convert to seconds.