-
Notifications
You must be signed in to change notification settings - Fork 23
[docs] organization, style, and grammar updates #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
d01f521
8ca1c01
ec5253f
bed4a8f
7b0f3fb
e31d564
43a8171
c670dae
cebd6d9
cff9040
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,74 @@ | ||||||||||||
| # Capturing and reporting host system metrics | ||||||||||||
|
|
||||||||||||
| Use the system metrics monitor in your application to provide metrics from the host system where you run your service. | ||||||||||||
heckj marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||
|
|
||||||||||||
| ### 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 your monitor to a service group. | ||||||||||||
heckj marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||
|
|
||||||||||||
| ```swift | ||||||||||||
| import SystemMetrics | ||||||||||||
| // Import and create a logger, or use one of the existing loggers | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| 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`` when you create the monitor: | ||||||||||||
heckj marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||
|
|
||||||||||||
| ```swift | ||||||||||||
| let systemMetricsMonitor = SystemMetricsMonitor( | ||||||||||||
| configuration: .init(pollInterval: .seconds(5)), | ||||||||||||
| logger: logger | ||||||||||||
|
Comment on lines
+37
to
+38
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did we want to promote the initializer with the custom factory as a baseline expectation? I got the impression that the one without would be more commonly used/desired here.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggested the change because the text above it mentions the factory. It was strange to mention it without showing the code. But we can also remove it and also remove the mention in the text, either is fine. |
||||||||||||
| ) | ||||||||||||
| ``` | ||||||||||||
|
|
||||||||||||
| ### 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 into a service group and run the group in your application. | ||||||||||||
heckj marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||
|
|
||||||||||||
| 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 | ||||||||||||
heckj marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
|
|
||||||||||||
| @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() | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| ``` | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # ``SystemMetricsMonitor/Configuration`` | ||
|
|
||
| ## Topics | ||
|
|
||
| ### Creating a monitor configuration | ||
|
|
||
| - ``init(pollInterval:)`` | ||
| - ``default`` | ||
|
|
||
| ### Inspecting the configuration | ||
|
|
||
| - ``interval`` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # ``SystemMetricsMonitor`` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've been meaning to ask - what's the docc command to generate these? Or did you hand-write them?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol - I hand wrote these. There's not a DocC command to generate them one off, unfortunately- I've just got 'my pattern' of how I do it, which it mostly stub, see what show's up in preview, then iterate to drop the right pieces into place. That said, there is a curation generation command - although I'm not certain if anyone actually uses it, as it's not detailed anywhere in the docs. The gist of which is:
So it's kind of a pain to use... |
||
|
|
||
| ## Topics | ||
|
|
||
| ### Creating a system metrics monitor | ||
|
|
||
| - ``init(configuration:logger:)`` | ||
| - ``init(configuration:metricsFactory:logger:)`` | ||
| - ``Configuration`` | ||
|
|
||
| ### Running a monitor | ||
|
|
||
| - ``run()`` | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,102 +4,26 @@ 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. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should preserve the short code snippet, including the dependency snippets, here as well. We try to do that in most of our other packages, as that's what most people landing on this page want to see. We should still preserve the new, more detailed getting started guide, though. So, I think this should show up on this page (the least customized way to run a system metrics monitor): 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()
}
} |
||||||
|
|
||||||
| ### Available metrics | ||||||
| The monitor collects the following metrics: | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can maybe move the constants into a nested bullet point under each metric? That way they'll always start on the same column. |
||||||
|
|
||||||
| 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. | ||||||
| ## Topics | ||||||
|
|
||||||
| ## Getting started | ||||||
| ### Monitor system metrics | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think "Essentials" is the usual name of the first section.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We see it commonly, but at least in the broader API guides, the last guidance I got here was essentials was meant to be "the things you critically had to know to be able to use the API", which I took as a placeholder to mean explanatory content prefixed into the getting started pieces when needed. This didn't quite seem to hit that bar for me, so I leaned into just giving a functional heading that made it reinforced what this was doing, especially since this is just a simple API surface.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah that's fair - though I'd argue if you don't learn the SystemMetricMonitor API, then there isn't much you can do with the library. So IMO it does raise to the bar of being essential. |
||||||
|
|
||||||
| ### Basic usage | ||||||
| - <doc:GettingStarted> | ||||||
| - ``SystemMetricsMonitor`` | ||||||
|
|
||||||
| After adding `swift-system-metrics` as a dependency, import the `SystemMetrics` module: | ||||||
| ### Contribute to the project | ||||||
heckj marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
| ```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 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 | ||||||
| ) | ||||||
| ``` | ||||||
|
|
||||||
| ## 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) | ||||||
| ``` | ||||||
|
|
||||||
| ## Swift Service Lifecycle integration | ||||||
|
|
||||||
| [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`: | ||||||
|
|
||||||
| ```swift | ||||||
| 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(logger: logger) | ||||||
|
|
||||||
| let serviceGroup = ServiceGroup( | ||||||
| services: [service, systemMetricsMonitor], | ||||||
| gracefulShutdownSignals: [.sigint], | ||||||
| cancellationSignals: [.sigterm], | ||||||
| logger: logger | ||||||
| ) | ||||||
|
|
||||||
| try await serviceGroup.run() | ||||||
| } | ||||||
| } | ||||||
| ``` | ||||||
| - <doc:Proposals> | ||||||

Uh oh!
There was an error while loading. Please reload this page.