| 
									
										
										
										
											2016-12-27 09:14:17 -08:00
										 |  |  | // Copyright 2015 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-03 04:35:24 -07:00
										 |  |  | //go:build !nomeminfo
 | 
					
						
							| 
									
										
										
										
											2016-12-27 09:14:17 -08:00
										 |  |  | // +build !nomeminfo
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package collector | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // #include <mach/mach_host.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-19 06:51:30 -08:00
										 |  |  | // #include <sys/sysctl.h>
 | 
					
						
							|  |  |  | // typedef struct xsw_usage xsw_usage_t;
 | 
					
						
							| 
									
										
										
										
											2016-12-27 09:14:17 -08:00
										 |  |  | import "C" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"encoding/binary" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 	"log/slog" | 
					
						
							| 
									
										
										
										
											2016-12-27 09:14:17 -08:00
										 |  |  | 	"unsafe" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"golang.org/x/sys/unix" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 05:27:55 -07:00
										 |  |  | type meminfoCollector struct { | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 	logger *slog.Logger | 
					
						
							| 
									
										
										
										
											2024-07-14 05:27:55 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewMeminfoCollector returns a new Collector exposing memory stats.
 | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | func NewMeminfoCollector(logger *slog.Logger) (Collector, error) { | 
					
						
							| 
									
										
										
										
											2024-07-14 05:27:55 -07:00
										 |  |  | 	return &meminfoCollector{ | 
					
						
							|  |  |  | 		logger: logger, | 
					
						
							|  |  |  | 	}, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-27 09:14:17 -08:00
										 |  |  | func (c *meminfoCollector) getMemInfo() (map[string]float64, error) { | 
					
						
							| 
									
										
										
										
											2018-12-06 07:47:20 -08:00
										 |  |  | 	host := C.mach_host_self() | 
					
						
							|  |  |  | 	infoCount := C.mach_msg_type_number_t(C.HOST_VM_INFO64_COUNT) | 
					
						
							|  |  |  | 	vmstat := C.vm_statistics64_data_t{} | 
					
						
							|  |  |  | 	ret := C.host_statistics64( | 
					
						
							|  |  |  | 		C.host_t(host), | 
					
						
							|  |  |  | 		C.HOST_VM_INFO64, | 
					
						
							| 
									
										
										
										
											2016-12-27 09:14:17 -08:00
										 |  |  | 		C.host_info_t(unsafe.Pointer(&vmstat)), | 
					
						
							|  |  |  | 		&infoCount, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	if ret != C.KERN_SUCCESS { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("Couldn't get memory statistics, host_statistics returned %d", ret) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	totalb, err := unix.Sysctl("hw.memsize") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-02-19 06:51:30 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	swapraw, err := unix.SysctlRaw("vm.swapusage") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	swap := (*C.xsw_usage_t)(unsafe.Pointer(&swapraw[0])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-27 09:14:17 -08:00
										 |  |  | 	// Syscall removes terminating NUL which we need to cast to uint64
 | 
					
						
							|  |  |  | 	total := binary.LittleEndian.Uint64([]byte(totalb + "\x00")) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-06 07:47:20 -08:00
										 |  |  | 	var pageSize C.vm_size_t | 
					
						
							|  |  |  | 	C.host_page_size(C.host_t(host), &pageSize) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ps := float64(pageSize) | 
					
						
							| 
									
										
										
										
											2016-12-27 09:14:17 -08:00
										 |  |  | 	return map[string]float64{ | 
					
						
							| 
									
										
										
										
											2018-09-07 13:27:52 -07:00
										 |  |  | 		"active_bytes":            ps * float64(vmstat.active_count), | 
					
						
							| 
									
										
										
										
											2018-12-06 07:47:20 -08:00
										 |  |  | 		"compressed_bytes":        ps * float64(vmstat.compressor_page_count), | 
					
						
							| 
									
										
										
										
											2018-09-07 13:27:52 -07:00
										 |  |  | 		"inactive_bytes":          ps * float64(vmstat.inactive_count), | 
					
						
							|  |  |  | 		"wired_bytes":             ps * float64(vmstat.wire_count), | 
					
						
							|  |  |  | 		"free_bytes":              ps * float64(vmstat.free_count), | 
					
						
							|  |  |  | 		"swapped_in_bytes_total":  ps * float64(vmstat.pageins), | 
					
						
							|  |  |  | 		"swapped_out_bytes_total": ps * float64(vmstat.pageouts), | 
					
						
							| 
									
										
										
										
											2021-12-06 13:56:13 -08:00
										 |  |  | 		"internal_bytes":          ps * float64(vmstat.internal_page_count), | 
					
						
							|  |  |  | 		"purgeable_bytes":         ps * float64(vmstat.purgeable_count), | 
					
						
							| 
									
										
										
										
											2018-09-07 13:27:52 -07:00
										 |  |  | 		"total_bytes":             float64(total), | 
					
						
							| 
									
										
										
										
											2020-02-19 06:51:30 -08:00
										 |  |  | 		"swap_used_bytes":         float64(swap.xsu_used), | 
					
						
							|  |  |  | 		"swap_total_bytes":        float64(swap.xsu_total), | 
					
						
							| 
									
										
										
										
											2016-12-27 09:14:17 -08:00
										 |  |  | 	}, nil | 
					
						
							|  |  |  | } |