async-service-supervisor 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/service/supervisor/utilization_monitor.rb +9 -2
- data/lib/async/service/supervisor/version.rb +1 -1
- data/lib/metrics/provider/async/service/supervisor/process_monitor.rb +39 -0
- data/lib/metrics/provider/async/service/supervisor/utilization_monitor.rb +52 -0
- data/lib/metrics/provider/async/service/supervisor.rb +7 -0
- data/lib/traces/provider/async/service/supervisor/server.rb +25 -0
- data/lib/traces/provider/async/service/supervisor/supervisor_controller.rb +24 -0
- data/lib/traces/provider/async/service/supervisor.rb +7 -0
- data/readme.md +4 -7
- data/releases.md +4 -0
- data.tar.gz.sig +0 -0
- metadata +8 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: df5a5c251964d3435c184c712d4ccc2aa8c74a255d78f3632669a1a527ce78af
|
|
4
|
+
data.tar.gz: ea832f3d1e9136ccca58f5c5025fe180de773389a739d9b0ad99aae453df2ee2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f54af527ecda8c37129a39f6061095cbaf66b47eec102fd21c1aecb9e5791f487c3d48f567f0a0898a7168ba33bc3a60eef18f7fc1beb656640ce53e3b5f02ed
|
|
7
|
+
data.tar.gz: a9e0b9c6e8a489665d72ed11b0af0eeca18fa7256bfbcdf9d7bef364554fcd219a15c1dbae49d073d8631a92ca023c689f91936444630198b596fcf2eae110dc
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -277,10 +277,10 @@ module Async
|
|
|
277
277
|
:utilization_monitor
|
|
278
278
|
end
|
|
279
279
|
|
|
280
|
-
#
|
|
280
|
+
# Sample aggregated utilization data.
|
|
281
281
|
#
|
|
282
282
|
# @returns [Hash] Hash mapping service names to aggregated utilization metrics.
|
|
283
|
-
def
|
|
283
|
+
def sample
|
|
284
284
|
@guard.synchronize do
|
|
285
285
|
aggregated = {}
|
|
286
286
|
|
|
@@ -313,6 +313,13 @@ module Async
|
|
|
313
313
|
end
|
|
314
314
|
end
|
|
315
315
|
|
|
316
|
+
# Serialize utilization data for JSON.
|
|
317
|
+
#
|
|
318
|
+
# @returns [Hash] Hash mapping service names to aggregated utilization metrics.
|
|
319
|
+
def as_json
|
|
320
|
+
self.sample
|
|
321
|
+
end
|
|
322
|
+
|
|
316
323
|
# Emit the utilization metrics.
|
|
317
324
|
#
|
|
318
325
|
# @parameter status [Hash] The utilization metrics.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2026, by Samuel Williams.
|
|
5
|
+
|
|
6
|
+
require "metrics/provider"
|
|
7
|
+
|
|
8
|
+
require_relative "../../../../../async/service/supervisor/process_monitor"
|
|
9
|
+
|
|
10
|
+
class Async::Service::Supervisor::ProcessMonitor
|
|
11
|
+
Metrics::Provider(self) do
|
|
12
|
+
PROCESS_METRICS_GENERAL_PROCESSOR_UTILIZATION = Metrics.metric("process.metrics.general.processor_utilization", :gauge, description: "Processor utilization for a supervised process.")
|
|
13
|
+
PROCESS_METRICS_GENERAL_TOTAL_SIZE = Metrics.metric("process.metrics.general.total_size", :gauge, description: "Total memory size for a supervised process.", unit: "bytes")
|
|
14
|
+
PROCESS_METRICS_GENERAL_VIRTUAL_SIZE = Metrics.metric("process.metrics.general.virtual_size", :gauge, description: "Virtual memory size for a supervised process.", unit: "bytes")
|
|
15
|
+
PROCESS_METRICS_GENERAL_RESIDENT_SIZE = Metrics.metric("process.metrics.general.resident_size", :gauge, description: "Resident memory size for a supervised process.", unit: "bytes")
|
|
16
|
+
|
|
17
|
+
def emit(metrics)
|
|
18
|
+
metrics.each_value do |general|
|
|
19
|
+
if value = general[:processor_utilization]
|
|
20
|
+
PROCESS_METRICS_GENERAL_PROCESSOR_UTILIZATION.emit(value)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
if value = general[:total_size]
|
|
24
|
+
PROCESS_METRICS_GENERAL_TOTAL_SIZE.emit(value)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if value = general[:virtual_size]
|
|
28
|
+
PROCESS_METRICS_GENERAL_VIRTUAL_SIZE.emit(value)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if value = general[:resident_size]
|
|
32
|
+
PROCESS_METRICS_GENERAL_RESIDENT_SIZE.emit(value)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2026, by Samuel Williams.
|
|
5
|
+
|
|
6
|
+
require "metrics/provider"
|
|
7
|
+
require "metrics/tags"
|
|
8
|
+
|
|
9
|
+
require_relative "../../../../../async/service/supervisor/utilization_monitor"
|
|
10
|
+
|
|
11
|
+
class Async::Service::Supervisor::UtilizationMonitor
|
|
12
|
+
Metrics::Provider(self) do
|
|
13
|
+
UTILIZATION = Metrics.metric("async.utilization", :gauge, description: "Active requests per worker.")
|
|
14
|
+
UTILIZATION_CONNECTIONS_ACTIVE = Metrics.metric("async.utilization.connections.active", :gauge, description: "The number of active connections.")
|
|
15
|
+
UTILIZATION_CONNECTIONS_TOTAL = Metrics.metric("async.utilization.connections.total", :gauge, description: "The total number of connections.")
|
|
16
|
+
UTILIZATION_REQUESTS_ACTIVE = Metrics.metric("async.utilization.requests.active", :gauge, description: "The number of active requests.")
|
|
17
|
+
UTILIZATION_REQUESTS_TOTAL = Metrics.metric("async.utilization.requests.total", :gauge, description: "The total number of requests.")
|
|
18
|
+
UTILIZATION_WORKERS = Metrics.metric("async.utilization.workers", :gauge, description: "The number of workers contributing utilization metrics.")
|
|
19
|
+
|
|
20
|
+
def emit(metrics)
|
|
21
|
+
metrics.each do |service_name, fields|
|
|
22
|
+
tags = Metrics::Tags.normalize(service: service_name)
|
|
23
|
+
|
|
24
|
+
if connections_active = fields[:connections_active]
|
|
25
|
+
UTILIZATION_CONNECTIONS_ACTIVE.emit(connections_active, tags: tags)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if connections_total = fields[:connections_total]
|
|
29
|
+
UTILIZATION_CONNECTIONS_TOTAL.emit(connections_total, tags: tags)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if requests_active = fields[:requests_active]
|
|
33
|
+
UTILIZATION_REQUESTS_ACTIVE.emit(requests_active, tags: tags)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if requests_total = fields[:requests_total]
|
|
37
|
+
UTILIZATION_REQUESTS_TOTAL.emit(requests_total, tags: tags)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if worker_count = fields[:worker_count]
|
|
41
|
+
UTILIZATION_WORKERS.emit(worker_count, tags: tags)
|
|
42
|
+
|
|
43
|
+
if worker_count > 0 and requests_active = fields[:requests_active]
|
|
44
|
+
UTILIZATION.emit(requests_active.to_f / worker_count, tags: tags)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
super
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2026, by Samuel Williams.
|
|
5
|
+
|
|
6
|
+
require "traces/provider"
|
|
7
|
+
|
|
8
|
+
require_relative "../../../../../async/service/supervisor/server"
|
|
9
|
+
|
|
10
|
+
Traces::Provider(Async::Service::Supervisor::Server) do
|
|
11
|
+
def remove(controller)
|
|
12
|
+
return super unless controller.id
|
|
13
|
+
|
|
14
|
+
attributes = {
|
|
15
|
+
"worker.id" => controller.id,
|
|
16
|
+
"worker.process_id" => controller.process_id,
|
|
17
|
+
"service.name" => controller.state[:name],
|
|
18
|
+
"monitor.count" => @monitors.size,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
Traces.trace("async.service.supervisor.worker.remove", attributes: attributes) do
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2026, by Samuel Williams.
|
|
5
|
+
|
|
6
|
+
require "traces/provider"
|
|
7
|
+
|
|
8
|
+
require_relative "../../../../../async/service/supervisor/supervisor_controller"
|
|
9
|
+
|
|
10
|
+
Traces::Provider(Async::Service::Supervisor::SupervisorController) do
|
|
11
|
+
def register(worker, process_id:, state: {})
|
|
12
|
+
attributes = {
|
|
13
|
+
"worker.process_id" => process_id,
|
|
14
|
+
"service.name" => state[:name],
|
|
15
|
+
"monitor.count" => @server.monitors.size,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Traces.trace("async.service.supervisor.worker.register", attributes: attributes) do |span|
|
|
19
|
+
super.tap do |id|
|
|
20
|
+
span["worker.id"] = id
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/readme.md
CHANGED
|
@@ -28,6 +28,10 @@ Please see the [project documentation](https://socketry.github.io/async-service-
|
|
|
28
28
|
|
|
29
29
|
Please see the [project releases](https://socketry.github.io/async-service-supervisor/releases/index) for all releases.
|
|
30
30
|
|
|
31
|
+
### v0.17.0
|
|
32
|
+
|
|
33
|
+
- Add opt-in `metrics` and `traces` providers for supervisor process metrics, utilization metrics, and worker lifecycle tracing.
|
|
34
|
+
|
|
31
35
|
### v0.16.0
|
|
32
36
|
|
|
33
37
|
- Add `ProcessMonitor#emit(metrics)` as an override point for subclasses to consume captured process metrics (e.g. emitting StatsD gauges).
|
|
@@ -69,13 +73,6 @@ Please see the [project releases](https://socketry.github.io/async-service-super
|
|
|
69
73
|
|
|
70
74
|
- Close `Call` queue if asynchronous call fails during dispatch - further messages will fail with `ClosedQueueError`.
|
|
71
75
|
|
|
72
|
-
### v0.9.0
|
|
73
|
-
|
|
74
|
-
- Better handling of write failures in `Connection::Call.dispatch`, ensuring we don't leak calls.
|
|
75
|
-
- Robust monitor loop handling - restart on failure, and align loop iterations.
|
|
76
|
-
- Disable memory sampler by default and use text output format.
|
|
77
|
-
- Introduce support for redirecting dump output to logs.
|
|
78
|
-
|
|
79
76
|
## Contributing
|
|
80
77
|
|
|
81
78
|
We welcome contributions to this project.
|
data/releases.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v0.17.0
|
|
4
|
+
|
|
5
|
+
- Add opt-in `metrics` and `traces` providers for supervisor process metrics, utilization metrics, and worker lifecycle tracing.
|
|
6
|
+
|
|
3
7
|
## v0.16.0
|
|
4
8
|
|
|
5
9
|
- Add `ProcessMonitor#emit(metrics)` as an override point for subclasses to consume captured process metrics (e.g. emitting StatsD gauges).
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: async-service-supervisor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.17.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -176,6 +176,12 @@ files:
|
|
|
176
176
|
- lib/async/service/supervisor/version.rb
|
|
177
177
|
- lib/async/service/supervisor/worker.rb
|
|
178
178
|
- lib/async/service/supervisor/worker_controller.rb
|
|
179
|
+
- lib/metrics/provider/async/service/supervisor.rb
|
|
180
|
+
- lib/metrics/provider/async/service/supervisor/process_monitor.rb
|
|
181
|
+
- lib/metrics/provider/async/service/supervisor/utilization_monitor.rb
|
|
182
|
+
- lib/traces/provider/async/service/supervisor.rb
|
|
183
|
+
- lib/traces/provider/async/service/supervisor/server.rb
|
|
184
|
+
- lib/traces/provider/async/service/supervisor/supervisor_controller.rb
|
|
179
185
|
- license.md
|
|
180
186
|
- readme.md
|
|
181
187
|
- releases.md
|
|
@@ -199,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
199
205
|
- !ruby/object:Gem::Version
|
|
200
206
|
version: '0'
|
|
201
207
|
requirements: []
|
|
202
|
-
rubygems_version: 4.0.
|
|
208
|
+
rubygems_version: 4.0.10
|
|
203
209
|
specification_version: 4
|
|
204
210
|
summary: A supervisor for managing multiple container processes.
|
|
205
211
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|