Rename metric labels for your backend
mainSystemMetricsMonitor, use MappingMetricsFactory from the Swift Metrics package. This allows you to rename labels without modifying the SystemMetrics library itself.repository·main·Indexed 41 days ago
https://github.com/apple/swift-system-metricsA library for reporting process-level system metrics—such as memory usage, CPU time, and file descriptors—to the Swift Metrics ecosystem. It provides the SystemMetricsMonitor to collect metrics like process_cpu_seconds_total and process_resident_memory_bytes, and is designed for integration with Swift Service Lifecycle for background monitoring in applications and tools.
SystemMetricsMonitor, use MappingMetricsFactory from the Swift Metrics package. This allows you to rename labels without modifying the SystemMetrics library itself.SystemMetricsMonitor, do not modify the library. Instead, use MappingMetricsFactory from the swift-metrics package to intercept and rename the labels before they reach your backend.To use Swift System Metrics in your application, add it as a dependency in your Package.swift file.
Note: This package is intended for use in tools and applications directly, rather than being used as a dependency within a library. If you are building a library and want to report metrics, use the Swift Metrics API directly.
// Add the package dependency
.package(url: "https://github.com/apple/swift-system-metrics", from: "1.0.0")
// Add the product to your target
.product(name: "SystemMetrics", package: "swift-system-metrics")To collect and report process-level metrics (like CPU and memory), create a SystemMetricsMonitor and include it in a ServiceGroup (from swift-service-lifecycle). This ensures the monitor runs periodically as a background service. You must also bootstrap a MetricsSystem implementation to receive the reported data.
import SystemMetrics
import ServiceLifecycle
import Metrics
import Logging
@main
struct Application {
static func main() async throws {
let logger = Logger(label: "Application")
// 1. Bootstrap your metrics backend
let metrics = MyMetricsBackendImplementation()
MetricsSystem.bootstrap(metrics)
let service = FooService()
// 2. Create the monitor service
let systemMetricsMonitor = SystemMetricsMonitor(logger: logger)
// 3. Run the monitor within a ServiceGroup
let serviceGroup = ServiceGroup(
services: [service, systemMetricsMonitor],
gracefulShutdownSignals: [.sigint],
cancellationSignals: [.sigterm],
logger: logger
)
try await serviceGroup.run()
}
}For non-trivial changes that affect the public API, the project uses a lightweight version of the Swift Evolution process. To propose a change, follow these steps:
SSM-NNNN.md template, replacing NNNN with the next available proposal number.Ready for Implementation or Deferred.Approved once the implementation and proposal PRs are merged and any associated feature flags are enabled unconditionally.The ServiceIntegration example demonstrates how to build a complete observability stack using swift-system-metrics. It combines several components to provide a production-ready monitoring setup:
SwiftServiceLifecycle: Integrates metric collection into the service lifecycle.SwiftMetrics: Configures the export of collected system metrics.Refer to the ServiceIntegration directory for the full implementation and Docker Compose configuration.
# See the ServiceIntegration directory for the full implementation
# It includes SwiftServiceLifecycle, SwiftMetrics, and Docker Compose setup.You can monitor process-level system metrics by creating an instance of SystemMetricsMonitor. To ensure the monitor runs alongside your application, it is recommended to integrate it into a ServiceGroup from the ServiceLifecycle package.
Before running the monitor, ensure you have bootstrapped a MetricsSystem (e.g., using a custom backend or a standard implementation) so that the collected metrics have a destination.
import SystemMetrics
import ServiceLifecycle
import Metrics
import Logging
@main
struct Application {
static func main() async throws {
let logger = Logger(label: "Application")
let metrics = MyMetricsBackendImplementation()
MetricsSystem.bootstrap(metrics)
let service = FooService()
let systemMetricsMonitor = SystemMetricsMonitor(logger: logger)
let serviceGroup = ServiceGroup(
services: [service, systemMetricsMonitor],
gracefulShutdownSignals: [.sigint],
cancellationSignals: [.sigterm],
logger: logger
)
try await serviceGroup.run()
}
}To use this library, add it as a dependency to your app and executable target using the Swift Package Manager.
Run the following commands in your terminal:
swift package add-dependency https://github.com/apple/swift-system-metrics --from 1.0.0
swift package add-target-dependency SystemMetrics MyExecutableTarget --package swift-system-metricsTo ensure the monitor runs as a background service with support for graceful shutdown and UNIX signal handling, integrate it into a ServiceGroup using the Swift Service Lifecycle library.
Include the SystemMetricsMonitor instance in the services array of your ServiceGroup.
import SystemMetrics
import ServiceLifecycle
import Metrics
import Logging
@main
struct Application {
static func main() async throws {
let logger = Logger(label: "Application")
let metrics = MyMetricsBackendImplementation()
MetricsSystem.bootstrap(metrics)
let service = FooService()
let systemMetricsMonitor = SystemMetricsMonitor(logger: logger)
let serviceGroup = ServiceGroup(
services: [service, systemMetricsMonitor],
gracefulShutdownSignals: [.sigint],
cancellationSignals: [.sigterm],
logger: logger
)
try await serviceGroup.run()
}
}The package formerly known as swift-metrics-extras has been renamed to swift-system-metrics to better reflect its purpose of collecting and reporting process system metrics.
API Stability: This rename does not affect the API surface. Existing code using the library's functions and types will continue to work without modification.
Dependency Update: While GitHub provides redirects for the repository URL, it is recommended to update your Package.swift dependency to point to the new repository URL: apple/swift-system-metrics.
To run periodic system metrics collection in the background for the duration of your application, use SystemMetricsMonitor. Because it conforms to the Service protocol from swift-service-lifecycle, the recommended pattern is to include it in a ServiceGroup alongside your application services. This ensures the monitor's lifecycle is managed automatically and it shuts down gracefully with your application.
import SystemMetrics
import ServiceLifecycle
import UnixSignals
import Metrics
@main
struct Application {
static func main() async throws {
let logger = Logger(label: "Application")
let metrics = MyMetricsBackendImplementation()
MetricsSystem.bootstrap(metrics)
let service = FooService()
let systemMetricsMonitor = SystemMetricsMonitor()
let serviceGroup = ServiceGroup(
services: [service, systemMetricsMonitor],
gracefulShutdownSignals: [.sigint],
cancellationSignals: [.sigterm],
logger: logger
)
try await serviceGroup.run()
}
}To run the full integration example, including the monitor and a Grafana dashboard, execute the following command from the swift-system-metrics package root:
docker-compose -f Examples/ServiceIntegration/docker-compose.yaml up --build