Skip to content
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

process_xxx_memory statistics for macOS (cgo) #1616

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mharbison72
Copy link
Contributor

This is built on top of the much easier to get process metrics in PR1600, so only the last commit is interesting here (and the commit message has more details). I don't expect or want this to be landed as-is, but am posting it here to help with any discussion about finishing off #1590.

I've not paid much attention to the RSS values of Go processes on macOS, but after ~5 minutes of banging on my own exporter with curl, I only ever see the value going up. The values agree with the ps command. There should be ~0 code other than from this module running, but we'll see what happens.

@bwplotka

…E on macOS

This unfortunately uses cgo, which I think everyone agrees is not great.  I
dislike using it because it breaks cross-compiling, but this code allows opting
out (at the cost of not publishing `process_resident_memory_bytes` and
`process_virtual_memory_bytes`), by setting `CGO_ENABLED=0` in the environment.
That's not ideal, but good enough for me where I can cross-compile locally most
of the time without `cgo`, and enable it always on the CI server.  But that may
not be reasonable for other projects.

The build-tag comment in the C file avoids the usual "C source files not allowed
when not using cgo or SWIG" error on the non-darwin platforms that aren't using
cgo, without any changes needing to be made to the client project.  Otherwise,
the file is compiled on darwin by default, unless `CGO_ENABLED=0`, in which case
the dummy function is used and the metrics aren't exported.  Therefore, the only
potential hardships for client programs with this change are limited to darwin
builds.

I'm still looking into 3rd party modules to call this without cgo, but this code
will help test out those implementations, and hopefully highlights the problems
getting at these native APIs.  The non-cgo implementation will get much more
verbose because the structs in play each have a handful of fields, each of which
with a train of typedefs that are platform specific.  That said, even though the
members may be typed slightly differently on amd64 vs arm64, it looks like the
field widths are the same, with the minimal testing I did so far.

Signed-off-by: Matt Harbison <mharbison72@gmail.com>
@mharbison72
Copy link
Contributor Author

As an alternative to this, I have now managed to also get it working without cgo, using github.com/ebitengine/purego. The problem was a native structure had a 32 bit field, followed by a 64 bit field, but was packed. This package doesn't handle that missing padding, but encoding/binary.Read() does. This alternative allows compiling on any platform and always exporting the metrics (whereas the cgo solution here silently ignores the C code in favor of a stub method that causes the metrics to not be exported if cgo is not supported).

The one wrinkle that I noticed is that the command code passed to the native API is a macro that evaluates to 5 on amd64, and 18 on arm64. It's this kind of nuisance stuff that gives me pause using this mechanism, though there's clear benefit instead of silently dropping some metrics. Maybe a reasonable solution is using github.com/ebitengine/purego, plus some _test.go that uses cgo to pass back offsetof(), sizeof(), and any other C macro evaluation that is relevant, so they can be compared against constants defined in Go. It's more or less what I did to validate my reading of the C headers, and would provide sanity checks similar to just using cgo, but without hassling client program build environments. But IDK if there are any macOS test runners available for this project.

So I guess the choices are simpler code, but slightly limited (this cgo PR), or a dependency + a bit more code without C compiler checks by default, but more flexible for users. Let me know if this second approach is reasonable, and I can clean up and submit this alternative in a different PR.

@mharbison72 mharbison72 changed the title process_xxx_memory statistics for macOS process_xxx_memory statistics for macOS (cgo) Sep 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant