Sources/Instrumentation/MemorySampler/MemorySampler.swift (31 lines of code) (raw):

// Copyright © 2021 Elasticsearch BV // // 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. import Foundation import OpenTelemetryApi import OpenTelemetrySdk public class MemorySampler { let meter: Meter var gauge: IntObserverMetric public init() { meter = OpenTelemetry.instance.meterProvider.get(instrumentationName: "Memory Sampler", instrumentationVersion: "0.0.1") gauge = meter.createIntObservableGauge(name: "system.memory.usage") { gauge in if let memoryUsage = MemorySampler.memoryFootprint() { gauge.observe(value: Int(memoryUsage), labels: ["state": "app"]) } } } static func memoryFootprint() -> mach_vm_size_t? { // The `TASK_VM_INFO_COUNT` and `TASK_VM_INFO_REV1_COUNT` macros are too // complex for the Swift C importer, so we have to define them ourselves. let TASK_VM_INFO_COUNT = mach_msg_type_number_t(MemoryLayout<task_vm_info_data_t>.size / MemoryLayout<integer_t>.size) let TASK_VM_INFO_REV1_COUNT = mach_msg_type_number_t(MemoryLayout.offset(of: \task_vm_info_data_t.min_address)! / MemoryLayout<integer_t>.size) var info = task_vm_info_data_t() var count = TASK_VM_INFO_COUNT let kr = withUnsafeMutablePointer(to: &info) { infoPtr in infoPtr.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { intPtr in task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), intPtr, &count) } } guard kr == KERN_SUCCESS, count >= TASK_VM_INFO_REV1_COUNT else { return nil } return info.phys_footprint } }