diff --git a/Examples/ServiceIntegration/README.md b/Examples/ServiceIntegration/README.md index 80aea94..46c7aee 100644 --- a/Examples/ServiceIntegration/README.md +++ b/Examples/ServiceIntegration/README.md @@ -22,15 +22,15 @@ let systemMetricsMonitor = SystemMetricsMonitor( This approach decouples the monitor from global state and allows you to use different metrics backends for different components. -## Running the Example +## Running the example -From the `swift-system-metrics` package root run: +From the `swift-system-metrics` package root, run: ```bash docker-compose -f Examples/ServiceIntegration/docker-compose.yaml up --build ``` -This will build and run 2 containers: `grafana` and `systemmetricsmonitor`. +The command builds and runs 2 containers: `grafana` and `systemmetricsmonitor`. ## Grafana Dashboard @@ -42,6 +42,6 @@ The dashboard provides four visualizations that map to the metrics collected by 1. CPU Usage % calculated as `rate(process_cpu_seconds_total)`. -1. Residential Memory (`process_resident_memory_bytes`) and Virtual Memory (`process_virtual_memory_bytes`) consumption. +1. Resident Memory (`process_resident_memory_bytes`) and Virtual Memory (`process_virtual_memory_bytes`) consumption. 1. Open File Descriptors (`process_open_fds`) and Max File Descriptors (`process_max_fds`) diff --git a/README.md b/README.md index 5a8d437..03f6dc0 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ Automatically collects process-level system metrics (memory, CPU, file descriptors) and reports them through the [SwiftMetrics](https://github.com/apple/swift-metrics) API. -## Collected Metrics +## Collected metrics -The following metrics are collected and reported as gauges: +The monitor collects and reports the following metrics as gauges: - **Virtual Memory** (`process_virtual_memory_bytes`) - Virtual memory size in bytes - **Resident Memory** (`process_resident_memory_bytes`) - Resident Set Size (RSS) in bytes @@ -16,25 +16,34 @@ The following metrics are collected and reported as gauges: ## Quick start ```swift -import Logging import SystemMetrics +import ServiceLifecycle +import Metrics +import Logging -// Create a logger, or use one of the existing loggers -let logger = Logger(label: "MyLogger") - -// Create the monitor -let monitor = SystemMetricsMonitor(logger: logger) - -// Create the service -let serviceGroup = ServiceGroup( - services: [monitor], - gracefulShutdownSignals: [.sigint], - cancellationSignals: [.sigterm], - logger: logger -) - -// Start collecting metrics -try await serviceGroup.run() +@main +struct Application { + static func main() async throws { + // Create a logger, or use one of the existing loggers + let logger = Logger(label: "Application") + let metrics = MyMetricsBackendImplementation() + MetricsSystem.bootstrap(metrics) + + let service = FooService() + // Create the monitor + let systemMetricsMonitor = SystemMetricsMonitor(logger: logger) + + // Create the service + let serviceGroup = ServiceGroup( + services: [service, systemMetricsMonitor], + gracefulShutdownSignals: [.sigint], + cancellationSignals: [.sigterm], + logger: logger + ) + + try await serviceGroup.run() + } +} ``` See the [`SystemMetrics` documentation](https://swiftpackageindex.com/apple/swift-system-metrics/documentation/systemmetrics) for details. @@ -45,24 +54,24 @@ Add Swift System Metrics as a dependency in your `Package.swift`: ```swift dependencies: [ - .package(url: "https://github.com/apple/swift-system-metrics.git", from: "1.0.0") + .package(url: "https://github.com/apple/swift-system-metrics.git", from: "1.0.0") ] ``` -Then add ``SystemMetrics`` to your target: +Then add `SystemMetrics` to your target: ```swift .target( - name: "YourTarget", - dependencies: [ - .product(name: "SystemMetrics", package: "swift-system-metrics") - ] + name: "YourTarget", + dependencies: [ + .product(name: "SystemMetrics", package: "swift-system-metrics") + ] ) ``` -## Example & Grafana Dashboard +## Example and Grafana dashboard -A complete working example with a pre-built Grafana dashboard is available in [Examples/ServiceIntegration](Examples/ServiceIntegration). The example includes: +[Examples/ServiceIntegration](Examples/ServiceIntegration) provides a complete working example with a pre-built Grafana dashboard. The example includes: - `SwiftServiceLifecycle` integration. - `SwiftMetrics` configured to export the metrics. diff --git a/Sources/SystemMetrics/Docs.docc/GettingStarted.md b/Sources/SystemMetrics/Docs.docc/GettingStarted.md new file mode 100644 index 0000000..122e3b3 --- /dev/null +++ b/Sources/SystemMetrics/Docs.docc/GettingStarted.md @@ -0,0 +1,75 @@ +# Capturing and reporting process metrics + +Use the system metrics monitor in your application to provide metrics from the process where you run your service. + +### Add the project dependency + +Add `swift-system-metrics` as a dependency to your app and executable target: + +```bash +swift package add-dependency https://github.com/apple/swift-system-metrics --from 1.0.0 +``` + +```bash +swift package add-target-dependency SystemMetrics MyExecutableTarget --package swift-system-metrics +``` + +### Create a system monitor service + +Import the `SystemMetrics` module, then create and add a ``SystemMetricsMonitor`` to a service group. + +```swift +import SystemMetrics +// Import and create a logger, or use one of the existing loggers +import Logging + +let logger = Logger(label: "MyService") + +// Create the monitor +let systemMetricsMonitor = SystemMetricsMonitor(logger: logger) +``` + +The monitor collects and reports metrics periodically using the global `MetricsSystem` that Swift Metrics provides. +You can configure the polling interval with your own ``SystemMetricsMonitor/Configuration``, as well as the `MetricsSystem`, when you create the monitor: + +```swift +let systemMetricsMonitor = SystemMetricsMonitor( + configuration: .init(pollInterval: .seconds(5)), + logger: logger +) +``` + +### Run the service in your app + +Use [Swift Service Lifecycle](https://github.com/swift-server/swift-service-lifecycle) to run the monitor as a background service with support for graceful shutdown and UNIX signal handling. +To do so, include the system metrics monitor you created in a service group and run the group in your application. + +The following code bootstraps your own metrics backend, creates a system metrics monitor, and uses service lifecycle to run both: + +```swift +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() + } +} +``` diff --git a/Sources/SystemMetrics/Docs.docc/Proposals/Proposals.md b/Sources/SystemMetrics/Docs.docc/Proposals/Proposals.md index 5f3bcd9..c58366e 100644 --- a/Sources/SystemMetrics/Docs.docc/Proposals/Proposals.md +++ b/Sources/SystemMetrics/Docs.docc/Proposals/Proposals.md @@ -6,11 +6,11 @@ Collaborate on API changes to Swift System Metrics by writing a proposal. For non-trivial changes that affect the public API, the Swift System Metrics project adopts a lightweight version of the [Swift Evolution](https://github.com/apple/swift-evolution/blob/main/process.md) process. -Writing a proposal first helps discuss multiple possible solutions early, apply useful feedback from other contributors, and avoid reimplementing the same feature multiple times. +Writing a proposal first helps you discuss multiple possible solutions early, apply useful feedback from other contributors, and avoid reimplementing the same feature multiple times. -While it's encouraged to get feedback by opening a pull request with a proposal early in the process, it's also important to consider the complexity of the implementation when evaluating different solutions. For example, this might mean including a link to a branch containing a prototype implementation of the feature in the pull request description. +Get feedback early by opening a pull request with your proposal, but also consider the complexity of the implementation when evaluating different solutions. For example, include a link to a branch containing a prototype implementation of the feature in the pull request description. -> Note: The goal of this process is to help solicit feedback from the whole community around the project, and we will continue to refine the proposal process itself. Use your best judgement, and don't hesitate to propose changes to the proposal structure itself! +> Note: The goal of this process is to solicit feedback from the whole community around the project, and the project continues to refine the proposal process itself. Use your best judgment, and don't hesitate to propose changes to the proposal structure itself. ### Steps @@ -18,9 +18,9 @@ While it's encouraged to get feedback by opening a pull request with a proposal 2. Duplicate the `SSM-NNNN.md` document and replace `NNNN` with the next available proposal number. 3. Link the GitHub issue from your proposal, and fill in the proposal. 4. Open a pull request with your proposal and solicit feedback from other contributors. -5. Once a maintainer confirms that the proposal is ready for review, the state is updated accordingly. The review period is 7 days, and ends when one of the maintainers marks the proposal as Ready for Implementation, or Deferred. -6. Before the pull request is merged, there should be an implementation ready, either in the same pull request, or a separate one, linked from the proposal. -7. The proposal is considered Approved once the implementation, proposal PRs have been merged, and, if originally disabled by a feature flag, feature flag enabled unconditionally. +5. Once a maintainer confirms that the proposal is ready for review, we update the state accordingly. The review period is 7 days, and ends when one of the maintainers marks the proposal as Ready for Implementation, or Deferred. +6. Before merging the pull request, ensure an implementation is ready, either in the same pull request or in a separate one linked from the proposal. +7. A proposal becomes Approved once you merge the implementation and proposal PRs, and enable any feature flags unconditionally. If you have any questions, ask in an issue on GitHub. @@ -37,3 +37,4 @@ If you have any questions, ask in an issue on GitHub. - - +- diff --git a/Sources/SystemMetrics/Docs.docc/Proposals/SSM-NNNN.md b/Sources/SystemMetrics/Docs.docc/Proposals/SSM-NNNN.md index b160008..9c5ebdc 100644 --- a/Sources/SystemMetrics/Docs.docc/Proposals/SSM-NNNN.md +++ b/Sources/SystemMetrics/Docs.docc/Proposals/SSM-NNNN.md @@ -20,23 +20,23 @@ A short, one-sentence overview of the feature or change. ### Motivation -Describe the problems that this proposal aims to address, and what workarounds adopters have to employ currently, if any. +Describe the problems that this proposal addresses, and what workarounds adopters currently use, if any. ### Proposed solution Describe your solution to the problem. Provide examples and describe how they work. Show how your solution is better than current workarounds. -This section should focus on what will change for the _adopters_ of Swift System Metrics. +Focus this section on what will change for the _adopters_ of Swift System Metrics. ### Detailed design -Describe the implementation of the feature, a link to a prototype implementation is encouraged here. +Describe the implementation of the feature. Include a link to a prototype implementation. -This section should focus on what will change for the _contributors_ to Swift System Metrics. +Focus this section on what will change for the _contributors_ to Swift System Metrics. ### API stability -Discuss the API implications, making sure to considering all of: +Discuss the API implications, making sure to consider all of: - existing metrics data provider implementations - existing users of `SystemMetrics` @@ -46,4 +46,4 @@ Discuss any potential future improvements to the feature. ### Alternatives considered -Discuss the alternative solutions considered, even during the review process itself. +Discuss the alternative solutions you considered, even during the review process itself. diff --git a/Sources/SystemMetrics/Docs.docc/Reference/SystemMetricsMonitor-Configuration.md b/Sources/SystemMetrics/Docs.docc/Reference/SystemMetricsMonitor-Configuration.md new file mode 100644 index 0000000..3c373b2 --- /dev/null +++ b/Sources/SystemMetrics/Docs.docc/Reference/SystemMetricsMonitor-Configuration.md @@ -0,0 +1,12 @@ +# ``SystemMetricsMonitor/Configuration`` + +## Topics + +### Creating a monitor configuration + +- ``init(pollInterval:)`` +- ``default`` + +### Inspecting the configuration + +- ``interval`` diff --git a/Sources/SystemMetrics/Docs.docc/Reference/SystemMetricsMonitor.md b/Sources/SystemMetrics/Docs.docc/Reference/SystemMetricsMonitor.md new file mode 100644 index 0000000..ffee799 --- /dev/null +++ b/Sources/SystemMetrics/Docs.docc/Reference/SystemMetricsMonitor.md @@ -0,0 +1,13 @@ +# ``SystemMetricsMonitor`` + +## Topics + +### Creating a system metrics monitor + +- ``init(configuration:logger:)`` +- ``init(configuration:metricsFactory:logger:)`` +- ``Configuration`` + +### Running a monitor + +- ``run()`` diff --git a/Sources/SystemMetrics/Docs.docc/index.md b/Sources/SystemMetrics/Docs.docc/index.md index c29768c..1aac35b 100644 --- a/Sources/SystemMetrics/Docs.docc/index.md +++ b/Sources/SystemMetrics/Docs.docc/index.md @@ -4,102 +4,56 @@ Collect and report process-level system metrics in your application. ## Overview -``SystemMetricsMonitor`` automatically collects key process metrics and reports them through the Swift Metrics API. +Create an instance of ``SystemMetricsMonitor`` to automatically collect key process metrics and report them through the Swift Metrics API. -### Available metrics +The monitor collects the following metrics: -The following metrics are collected: +- **Virtual Memory**: Total virtual memory, in bytes, that the process allocates. The monitor reports the metric as `process_virtual_memory_bytes`. +- **Resident Memory**: Physical memory, in bytes, that the process currently uses. The monitor reports the metric as `process_resident_memory_bytes`. +- **Start Time**: Process start time, in seconds, since UNIX epoch. The monitor reports the metric as `process_start_time_seconds`. +- **CPU Time**: Cumulative CPU time the process consumes, in seconds. The monitor reports the metric as `process_cpu_seconds_total`. +- **Max File Descriptors**: The maximum number of file descriptors the process can open. The monitor reports the metric as `process_max_fds`. +- **Open File Descriptors**: The number of file descriptors the process currently has open. The monitor reports the metric as `process_open_fds`. -- **Virtual Memory**: Total virtual memory allocated by the process (in bytes), reported as `process_virtual_memory_bytes`. -- **Resident Memory**: Physical memory currently used by the process (in bytes), reported as `process_resident_memory_bytes`. -- **Start Time**: Process start time since Unix epoch (in seconds), reported as `process_start_time_seconds`. -- **CPU Time**: Cumulative CPU time consumed (in seconds), reported as `process_cpu_seconds_total`. -- **Max File Descriptors**: Maximum number of file descriptors the process can open, reported as `process_max_fds`. -- **Open File Descriptors**: Number of file descriptors currently open, reported as `process_open_fds`. +> Note: The monitor supports these metrics only on Linux and macOS platforms. -> Note: These metrics are currently implemented on Linux and macOS platforms only. - -## Getting started - -### Basic usage - -After adding `swift-system-metrics` as a dependency, import the `SystemMetrics` module: +This example shows how to create a monitor and run it with the service group alongside your service: ```swift import SystemMetrics -``` - -Create and start a monitor with default settings and a logger: - -```swift -// Import and create a logger, or use one of the existing loggers +import ServiceLifecycle +import Metrics import Logging -let logger = Logger(label: "MyService") - -// Create the monitor -let monitor = SystemMetricsMonitor(logger: logger) - -// Create the service -let serviceGroup = ServiceGroup( - services: [monitor], - gracefulShutdownSignals: [.sigint], - cancellationSignals: [.sigterm], - logger: logger -) - -// Start collecting metrics -try await serviceGroup.run() -``` - -The monitor will collect and report metrics periodically using the global `MetricsSystem`. - -## Configuration - -Polling interval can be configured through the ``SystemMetricsMonitor/Configuration``: -```swift -let systemMetricsMonitor = SystemMetricsMonitor( - configuration: .init(pollInterval: .seconds(5)), - logger: logger -) +@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() + } +} ``` -## Using custom Metrics Factory - -``SystemMetricsMonitor`` can be initialized with a specific metrics factory, so it does not rely on the global `MetricsSystem`: - -```swift -let monitor = SystemMetricsMonitor(metricsFactory: myPrometheusMetricsFactory, logger: logger) -``` +## Topics -## Swift Service Lifecycle integration +### Monitor system metrics -[Swift Service Lifecycle](https://github.com/swift-server/swift-service-lifecycle) provides a convenient way to manage background service tasks, which is compatible with the `SystemMetricsMonitor`: +- +- ``SystemMetricsMonitor`` -```swift -import SystemMetrics -import ServiceLifecycle -import UnixSignals -import Metrics +### Contribute to the project -@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() - } -} -``` +- diff --git a/Sources/SystemMetrics/SystemMetricsMonitor+Darwin.swift b/Sources/SystemMetrics/SystemMetricsMonitor+Darwin.swift index 3665fcf..ae109b6 100644 --- a/Sources/SystemMetrics/SystemMetricsMonitor+Darwin.swift +++ b/Sources/SystemMetrics/SystemMetricsMonitor+Darwin.swift @@ -18,12 +18,11 @@ import Darwin extension SystemMetricsMonitorDataProvider: SystemMetricsProvider { /// Collect current system metrics data. /// - /// On supported Darwin platforms, this delegates to the static + /// On supported Darwin platforms, this method delegates to the static /// `darwinSystemMetrics()` function. /// - /// - Note: System metrics collection is not yet implemented for Darwin-based - /// platforms other than macOS. This method always returns `nil` on - /// other platforms. + /// - Note: This method doesn't yet support Darwin-based platforms other than + /// macOS and always returns `nil` on those platforms. /// - Returns: Current system metrics, or `nil` if collection failed. package func data() async -> SystemMetricsMonitor.Data? { #if os(macOS) diff --git a/Sources/SystemMetrics/SystemMetricsMonitor+Linux.swift b/Sources/SystemMetrics/SystemMetricsMonitor+Linux.swift index 0cb559e..2b914e2 100644 --- a/Sources/SystemMetrics/SystemMetricsMonitor+Linux.swift +++ b/Sources/SystemMetrics/SystemMetricsMonitor+Linux.swift @@ -94,7 +94,7 @@ extension SystemMetricsMonitorDataProvider: SystemMetricsProvider { private static let systemStartTimeInSecondsSinceEpoch: Int? = { // Read system boot time from /proc/stat btime field - // This provides the Unix timestamp when the system was booted + // This provides the UNIX timestamp when the system was booted let systemStatFile = CFile("/proc/stat") systemStatFile.open() defer { @@ -142,14 +142,14 @@ extension SystemMetricsMonitorDataProvider: SystemMetricsProvider { /// - `/proc/self/fd/` directory enumeration - Count of open file descriptors /// /// - Returns: A `Data` struct containing all collected metrics, or `nil` if - /// metrics could not be collected (e.g., due to file read errors). + /// the function can't collect metrics (for example, due to file read errors). package static func linuxSystemMetrics() -> SystemMetricsMonitor.Data? { /// The current implementation below reads /proc/self/stat. Then, /// presumably to accommodate whitespace in the `comm` field /// without dealing with null-terminated C strings, it splits on the /// closing parenthesis surrounding the value. It then splits the /// remaining string by space, meaning the first element in the - /// resulting array, at index 0, refers to the the third field. + /// resulting array, at index 0, refers to the third field. /// /// Note that the man page documents fields starting at index 1. /// @@ -196,8 +196,8 @@ extension SystemMetricsMonitorDataProvider: SystemMetricsProvider { static let startTimeTicks = 19 } - /// Use sysconf to get system configuration values that do not change - /// during the lifetime of the process. They are used later to convert + /// Use sysconf to get system configuration values that don't change + /// during the lifetime of the process. The code uses them later to convert /// ticks into seconds and memory pages into total bytes. enum SystemConfiguration { static let clockTicksPerSecond = sysconf(Int32(_SC_CLK_TCK)) diff --git a/Sources/SystemMetrics/SystemMetricsMonitor.swift b/Sources/SystemMetrics/SystemMetricsMonitor.swift index c56de52..c1d5f0e 100644 --- a/Sources/SystemMetrics/SystemMetricsMonitor.swift +++ b/Sources/SystemMetrics/SystemMetricsMonitor.swift @@ -19,8 +19,8 @@ public import ServiceLifecycle /// A monitor that periodically collects and reports system metrics. /// -/// ``SystemMetricsMonitor`` provides a way to automatically collect process-level system metrics -/// (such as memory usage, CPU time) and report them through the Swift Metrics API. +/// `SystemMetricsMonitor` automatically collects process-level system metrics +/// (such as memory usage and CPU time) and reports them through the Swift Metrics API. /// /// Example usage: /// ```swift @@ -58,11 +58,11 @@ public struct SystemMetricsMonitor: Service { let maxFileDescriptorsGauge: Gauge let openFileDescriptorsGauge: Gauge - /// Create a new ``SystemMetricsMonitor`` using the global metrics factory. + /// Create a new monitor for system metrics. /// /// - Parameters: /// - configuration: The configuration for the monitor. - /// - metricsFactory: The metrics factory to use for creating metrics. + /// - metricsFactory: The metrics factory to use for creating metrics. If `nil`, the monitor initializes with the global metrics factory. /// - dataProvider: The provider to use for collecting system metrics data. /// - logger: A custom logger. package init( @@ -110,7 +110,7 @@ public struct SystemMetricsMonitor: Service { ) } - /// Create a new ``SystemMetricsMonitor`` with a custom data provider. + /// Create a new monitor for system metrics with a custom data provider that you provide. /// /// - Parameters: /// - configuration: The configuration for the monitor. @@ -129,11 +129,11 @@ public struct SystemMetricsMonitor: Service { ) } - /// Create a new ``SystemMetricsMonitor`` with a custom metrics factory. + /// Create a new monitor for system metrics that send metrics to backend using the metrics factory that you provide. /// /// - Parameters: /// - configuration: The configuration for the monitor. - /// - metricsFactory: The metrics factory to use for creating metrics. + /// - metricsFactory: The [metrics factory](https://swiftpackageindex.com/apple/swift-metrics/documentation/coremetrics/metricsfactory) to use for creating metrics. /// - logger: A custom logger. public init( configuration: SystemMetricsMonitor.Configuration = .default, @@ -148,7 +148,13 @@ public struct SystemMetricsMonitor: Service { ) } - /// Create a new ``SystemMetricsMonitor`` using the global metrics factory. + /// Create a new monitor for system metrics using the global metrics factory. + /// + /// If you can't, or don't want to use the process global metrics that the Metrics API provides, + /// consider using ``init(configuration:metricsFactory:logger:)`` instead. + /// For example, if you have different backends for different metrics, + /// use a [metrics factory](https://swiftpackageindex.com/apple/swift-metrics/documentation/coremetrics/metricsfactory) + /// from the backend where you want to send system metrics. /// /// - Parameters: /// - configuration: The configuration for the monitor. @@ -169,7 +175,7 @@ public struct SystemMetricsMonitor: Service { /// /// This method collects current system metrics and reports them as gauges /// using the configured labels and dimensions. If metric collection fails - /// or is unsupported on the current platform, this method returns without + /// or the current platform doesn't support it, this method returns without /// reporting any metrics. package func updateMetrics() async { guard let metrics = await self.dataProvider.data() else { @@ -219,23 +225,23 @@ public struct SystemMetricsMonitor: Service { } } -/// A protocol for providing system metrics data. +/// Provides system metrics data. /// -/// Types conforming to this protocol can provide system metrics data +/// Types that conform to this protocol provide system metrics data /// to a ``SystemMetricsMonitor``. This allows for flexible data collection /// strategies, including custom implementations for testing. package protocol SystemMetricsProvider: Sendable { /// Retrieve current system metrics data. /// /// - Returns: Current system metrics, or `nil` if collection failed - /// or is unsupported on the current platform. + /// or the current platform doesn't support it. func data() async -> SystemMetricsMonitor.Data? } -/// Default implementation of ``SystemMetricsProvider`` for collecting system metrics data. +/// Default implementation of system metrics provider that collects system metrics data. /// /// This provider collects process-level metrics from the operating system. -/// It is used as the default data provider when no custom provider is specified. +/// Use this provider as the default when you don't specify a custom provider. package struct SystemMetricsMonitorDataProvider: Sendable { let configuration: SystemMetricsMonitor.Configuration @@ -245,15 +251,16 @@ package struct SystemMetricsMonitorDataProvider: Sendable { } extension SystemMetricsMonitor { - /// System Metrics data. + /// System metrics data. /// - /// The current list of metrics exposed is a superset of the [Prometheus Client Library Guidelines](https://prometheus.io/docs/instrumenting/writing_clientlibs/#standard-and-runtime-collectors). + /// The current list of metrics exposed is a superset of the + /// [Prometheus Client Library Guidelines](https://prometheus.io/docs/instrumenting/writing_clientlibs/#standard-and-runtime-collectors). package struct Data: Sendable { /// Virtual memory size in bytes. package var virtualMemoryBytes: Int /// Resident memory size in bytes. package var residentMemoryBytes: Int - /// Start time of the process since Unix epoch in seconds. + /// Start time of the process since UNIX epoch in seconds. package var startTimeSeconds: Int /// Total user and system CPU time spent in seconds. package var cpuSeconds: Double @@ -262,12 +269,12 @@ extension SystemMetricsMonitor { /// Number of open file descriptors. package var openFileDescriptors: Int - /// Create a new `Data` instance. + /// Create a new instance of metrics data. /// - /// - parameters: + /// - Parameters: /// - virtualMemoryBytes: Virtual memory size in bytes /// - residentMemoryBytes: Resident memory size in bytes. - /// - startTimeSeconds: Process start time since Unix epoch in seconds. + /// - startTimeSeconds: Process start time since UNIX epoch in seconds. /// - cpuSeconds: Total user and system CPU time spent in seconds. /// - maxFileDescriptors: Maximum number of open file descriptors. /// - openFileDescriptors: Number of open file descriptors. diff --git a/Sources/SystemMetrics/SystemMetricsMonitorConfiguration.swift b/Sources/SystemMetrics/SystemMetricsMonitorConfiguration.swift index ba3b0fc..b772699 100644 --- a/Sources/SystemMetrics/SystemMetricsMonitorConfiguration.swift +++ b/Sources/SystemMetrics/SystemMetricsMonitorConfiguration.swift @@ -13,14 +13,16 @@ //===----------------------------------------------------------------------===// extension SystemMetricsMonitor { - /// This object controls the behaviour of the ``SystemMetricsMonitor``. + /// The configuration that controls the behavior of the system metrics monitor. public struct Configuration: Sendable { - /// Default SystemMetricsMonitor configuration. + /// The default system metrics monitor configuration. /// /// See individual property documentation for specific default values. public static let `default`: Self = .init() - /// Interval between system metrics data scrapping + /// The interval between system metrics data scraping. + /// + /// The default interval is 2 seconds. public var interval: Duration /// String labels associated with the metrics @@ -29,10 +31,10 @@ extension SystemMetricsMonitor { /// Additional dimensions attached to every metric package let dimensions: [(String, String)] - /// Create new instance of ``Configuration`` + /// Create new monitor configuration. /// /// - Parameters: - /// - interval: The interval at which system metrics should be updated. + /// - interval: The interval at which system metrics should be updated, defaults to 2 seconds. public init( pollInterval interval: Duration = .seconds(2) ) { @@ -41,7 +43,7 @@ extension SystemMetricsMonitor { self.dimensions = [] } - /// Create new instance of ``SystemMetricsMonitor.Configuration`` + /// Creates a new configuration. /// /// - Parameters: /// - interval: The interval at which system metrics should be updated. @@ -60,18 +62,18 @@ extension SystemMetricsMonitor { } extension SystemMetricsMonitor.Configuration { - /// Labels for the reported System Metrics Data. + /// Labels for the reported system metrics data. /// - /// Backend implementations are encouraged to provide a static extension with + /// Backend implementations can provide a static extension with /// defaults that suit their specific backend needs. package struct Labels: Sendable { - /// Prefix to prefix all other labels with. + /// Prefix for all other labels. package var prefix: String = "process_" /// Label for virtual memory size in bytes. package var virtualMemoryBytes: String = "virtual_memory_bytes" /// Label for resident memory size in bytes. package var residentMemoryBytes: String = "resident_memory_bytes" - /// Label for process start time since Unix epoch in seconds. + /// Label for process start time since UNIX epoch in seconds. package var startTimeSeconds: String = "start_time_seconds" /// Label for total user and system CPU time spent in seconds. package var cpuSecondsTotal: String = "cpu_seconds_total" @@ -80,10 +82,10 @@ extension SystemMetricsMonitor.Configuration { /// Label for number of open file descriptors. package var openFileDescriptors: String = "open_fds" - /// Construct a label for a metric as a concatenation of prefix and the corresponding label. + /// Construct a label for a metric by concatenating the prefix with the corresponding label. /// /// - Parameters: - /// - for: a property to construct the label for + /// - for: The property to construct the label for. package func label(for keyPath: KeyPath) -> String { self.prefix + self[keyPath: keyPath] } @@ -96,10 +98,10 @@ extension SystemMetricsMonitor.Configuration { /// Create a new `Labels` instance. /// /// - Parameters: - /// - prefix: Prefix to prefix all other labels with. + /// - prefix: Prefix for all other labels. /// - virtualMemoryBytes: Label for virtual memory size in bytes /// - residentMemoryBytes: Label for resident memory size in bytes. - /// - startTimeSeconds: Label for process start time since Unix epoch in seconds. + /// - startTimeSeconds: Label for process start time since UNIX epoch in seconds. /// - cpuSecondsTotal: Label for total user and system CPU time spent in seconds. /// - maxFileDescriptors: Label for maximum number of open file descriptors. /// - openFileDescriptors: Label for number of open file descriptors.