Overview
Swift System Metrics 1.0 is a Swift package that provides a unified API for collecting process-level system metrics such as CPU utilization time, memory usage, file descriptor counts, and process start time. It runs on both Linux and macOS, making cross-platform monitoring straightforward. By integrating this package into your service, you can detect performance issues, optimize resource usage, and ensure reliability under varying loads—all with just a few lines of code. This tutorial walks you through adding Swift System Metrics to a Swift project, configuring it with the swift-metrics API and swift-service-lifecycle, and avoiding common pitfalls.

Prerequisites
Before you begin, ensure you have the following:
- Swift 5.5 or later (Swift System Metrics 1.0 requires Swift 5.5+ for structured concurrency support)
- A Swift package manager project (
Package.swift) - Basic familiarity with async/await and Swift concurrency
- Understanding of metrics backends like Prometheus or OpenTelemetry (optional but helpful for visualization)
- Linux or macOS development environment (the package works on both)
Step-by-Step Instructions
Step 1: Add the Dependency
Open your Package.swift file and add swift-system-metrics as a dependency:
// swift-tools-version:5.7
import PackageDescription
let package = Package(
name: "YourProject",
dependencies: [
.package(url: "https://github.com/apple/swift-system-metrics", from: "1.0.0"),
// Add other dependencies like OTel or Prometheus as needed
],
targets: [
.executableTarget(
name: "YourTarget",
dependencies: [
.product(name: "SystemMetrics", package: "swift-system-metrics"),
]
),
]
)
Step 2: Import and Set Up a Metrics Backend
Swift System Metrics reports data through swift-metrics (the Metrics API). You need to bootstrap a backend like OpenTelemetry or Prometheus. Here we use swift-otel as an example:
import OTel
import Logging
let logger = Logger(label: "com.example.app")
var otelConfig = OTel.Configuration.default
otelConfig.serviceName = "MyMonitoredService"
let otelService = try OTel.bootstrap(configuration: otelConfig)
Note: The bootstrap function installs the OTel metrics backend into MetricsSystem, so all collected metrics are automatically forwarded.
Step 3: Create a SystemMetricsMonitor
Import SystemMetrics and create a monitor instance. The monitor is a Swift Service Lifecycle service that periodically collects metrics:
import SystemMetrics
import ServiceLifecycle
let systemMetricsMonitor = SystemMetricsMonitor(logger: logger)
Step 4: Integrate with Service Lifecycle
Use ServiceGroup to manage your services together with the monitor. This ensures graceful startup and shutdown:
let serviceGroup = ServiceGroup(
services: [otelService, yourActualService, systemMetricsMonitor],
gracefulShutdownSignals: [.sigint],
cancellationSignals: [.sigterm],
logger: logger
)
try await serviceGroup.run()
Replace yourActualService with your own service (must conform to Service). The monitor will automatically start collecting CPU time, memory (virtual and resident), open file descriptors, and process start time.

Step 5: Visualize (Optional)
The package includes a sample Grafana dashboard JSON configuration. Once your metrics are exported (e.g., via Prometheus), you can import the dashboard from Sources/SystemMetrics/Grafana/Dashboard.json in the repository to see real-time graphs.
Common Mistakes
Mistake 1: Forgetting to Bootstrap the Metrics Backend
Without calling OTel.bootstrap (or equivalent for another backend), the metrics collected by SystemMetricsMonitor have nowhere to go. Always install a backend before starting the monitor.
Mistake 2: Not Including the Monitor in the Service Group
The monitor must be part of ServiceGroup to run its collection loop. Adding it as a standalone object without lifecycle integration will result in no metrics being collected.
Mistake 3: Misunderstanding Cross-Platform Features
While the API is identical on Linux and macOS, certain metrics may not be available on all kernels (e.g., file descriptor limits are platform-specific). Test on your target OS.
Mistake 4: Ignoring Permissions
On Linux, reading /proc usually requires no special permissions, but containerized environments may restrict access. Ensure the process has read access to /proc/self/.
Mistake 5: Using Old Package Name
Swift System Metrics was previously called swift-metrics-extras. Update your Package.swift to use the new URL and product name SystemMetrics.
Summary
Swift System Metrics 1.0 makes process-level monitoring easy and portable. You’ve learned how to add the dependency, set up a metrics backend, create a monitor, and integrate it with Swift Service Lifecycle. By avoiding the common pitfalls outlined above, you can quickly gain visibility into CPU, memory, file descriptors, and process start time—right from your Swift application. Start monitoring today and ensure your services run reliably under any load.