-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
process_collector: add a proof-of-concept for collecting RSS and VSIZ…
…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 <[email protected]>
- Loading branch information
1 parent
ac114f3
commit eca836e
Showing
5 changed files
with
134 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
//go:build ignore || (darwin && cgo) | ||
|
||
#include <mach/mach_init.h> | ||
#include <mach/task.h> | ||
// Compiler warns shared_memory_server.h is deprecated, use this instead. | ||
// But this doesn't define SHARED_XXX_REGION_SIZE. | ||
//#include <mach/shared_region.h> | ||
#include <mach/shared_memory_server.h> // SHARED_DATA_REGION_SIZE, SHARED_TEXT_REGION_SIZE | ||
#include <mach/mach_vm.h> | ||
#include <stdio.h> | ||
|
||
int getmem (unsigned long long *rss, unsigned long long *vs) | ||
{ | ||
// https://github.com/apple-oss-distributions/adv_cmds/blob/8744084ea0ff41ca4bb96b0f9c22407d0e48e9b7/ps/tasks.c#L109 | ||
|
||
kern_return_t error; | ||
task_t task = MACH_PORT_NULL; | ||
struct task_basic_info t_info; | ||
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; | ||
|
||
error = task_info(mach_task_self(), | ||
TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count); | ||
|
||
if( error != KERN_SUCCESS ) | ||
{ | ||
return error; | ||
} | ||
|
||
*rss = t_info.resident_size; | ||
*vs = t_info.virtual_size; | ||
|
||
{ | ||
vm_region_basic_info_data_64_t b_info; | ||
mach_vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT; | ||
mach_vm_size_t size; | ||
mach_port_t object_name; | ||
|
||
/* | ||
* try to determine if this task has the split libraries | ||
* mapped in... if so, adjust its virtual size down by | ||
* the 2 segments that are used for split libraries | ||
*/ | ||
t_info_count = VM_REGION_BASIC_INFO_COUNT_64; | ||
error = mach_vm_region(mach_task_self(), &address, &size, VM_REGION_BASIC_INFO, | ||
(vm_region_info_t)&b_info, &t_info_count, &object_name); | ||
|
||
if (error == KERN_SUCCESS) { | ||
if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) && | ||
*vs > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) { | ||
*vs -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE); | ||
} | ||
} | ||
} | ||
|
||
// `ps -o rss,vsize,command` prints values in KB | ||
printf("rss is %qd (%qd KB)\n", *rss, (unsigned long long) (*rss / 1024)); | ||
printf("vs is %qd (%qd KB)\n", *vs, (unsigned long long) (*vs / 1024)); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright 2024 The Prometheus Authors | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
//go:build darwin && cgo | ||
|
||
package prometheus | ||
|
||
/* | ||
int getmem(unsigned long long *rss, unsigned long long *vs); | ||
*/ | ||
import "C" | ||
import "fmt" | ||
|
||
func getMemory() (uint64, uint64, error) { | ||
var ( | ||
rss, vs C.ulonglong | ||
) | ||
|
||
if err := C.getmem(&rss, &vs); err != 0 { | ||
return 0, 0, fmt.Errorf("task_info() failed with 0x%x", int(err)) | ||
} | ||
|
||
return uint64(rss), uint64(vs), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright 2024 The Prometheus Authors | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
//go:build !darwin || !cgo | ||
|
||
package prometheus | ||
|
||
func getMemory() (uint64, uint64, error) { | ||
return 0, 0, nil | ||
} |