legionio 1.5.11 → 1.5.12
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
- data/CHANGELOG.md +8 -0
- data/CLAUDE.md +1 -0
- data/legionio.gemspec +1 -1
- data/lib/legion/api/openapi.rb +37 -0
- data/lib/legion/api/stats.rb +219 -0
- data/lib/legion/api.rb +2 -0
- data/lib/legion/cli/debug_command.rb +79 -54
- data/lib/legion/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2b5d012d4df4a245648fe489a4c998c34fa209c119b74301d209f29cdeb44977
|
|
4
|
+
data.tar.gz: 2f818144217a965f4353201773843cbfef1e151406b27996f6d493f144fa7de9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e436068fa3c9159a904fd9a57434916ad49a1e332b6220c2b89c290725094da4173aadea83c0656cccb564a05b0033521ad5ee37b6e0dc054eb83fa7facf2114
|
|
7
|
+
data.tar.gz: d83cacb7a7afddfb35892ef4d1183c32cce83c64bfa53fed51d599b8eb04a99589af9fc1202a778a7389b257ea2c9fdd9a71010f2ebfb2c8b2b193b54fbe31fe
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Legion Changelog
|
|
2
2
|
|
|
3
|
+
## [1.5.12] - 2026-03-25
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `GET /api/stats` endpoint — comprehensive daemon runtime stats: extensions (loaded/actor counts), gaia (status/channels/phases), transport (session/channels), cache/cache_local (pool stats), llm (provider health/routing), data/data_local (pool/tuning via legion-data stats), api (puma threads/routes)
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- Bumped gemspec dependency: legion-data >= 1.6.0 (required for `Legion::Data.stats`)
|
|
10
|
+
|
|
3
11
|
## [1.5.11] - 2026-03-25
|
|
4
12
|
|
|
5
13
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -633,6 +633,7 @@ rack-test, rake, rspec, rubocop, rubocop-rspec, simplecov
|
|
|
633
633
|
| `lib/legion/telemetry.rb` | Opt-in OpenTelemetry tracing: `with_span` wrapper, `sanitize_attributes`, `record_exception` |
|
|
634
634
|
| `lib/legion/metrics.rb` | Opt-in Prometheus metrics: event-driven counters, pull-based gauges, `prometheus-client` guarded |
|
|
635
635
|
| `lib/legion/api/metrics.rb` | `GET /metrics` Prometheus text-format endpoint with gauge refresh |
|
|
636
|
+
| `lib/legion/api/stats.rb` | `GET /api/stats` comprehensive daemon runtime stats (extensions, gaia, transport, cache, llm, data, api) |
|
|
636
637
|
| `lib/legion/chat/notification_queue.rb` | Thread-safe priority queue for background notifications (critical/info/debug) |
|
|
637
638
|
| `lib/legion/chat/notification_bridge.rb` | Event-driven bridge: matches Legion events to chat notifications via fnmatch patterns |
|
|
638
639
|
| `lib/legion/api/middleware/auth.rb` | Auth: JWT Bearer auth middleware (real token validation, skip paths for health/ready) |
|
data/legionio.gemspec
CHANGED
|
@@ -54,7 +54,7 @@ Gem::Specification.new do |spec|
|
|
|
54
54
|
|
|
55
55
|
spec.add_dependency 'legion-cache', '>= 1.3.16'
|
|
56
56
|
spec.add_dependency 'legion-crypt', '>= 1.4.12'
|
|
57
|
-
spec.add_dependency 'legion-data', '>= 1.
|
|
57
|
+
spec.add_dependency 'legion-data', '>= 1.6.0'
|
|
58
58
|
spec.add_dependency 'legion-json', '>= 1.2.1'
|
|
59
59
|
spec.add_dependency 'legion-logging', '>= 1.3.2'
|
|
60
60
|
spec.add_dependency 'legion-settings', '>= 1.3.19'
|
data/lib/legion/api/openapi.rb
CHANGED
|
@@ -155,6 +155,7 @@ module Legion
|
|
|
155
155
|
.merge(gaia_paths)
|
|
156
156
|
.merge(apollo_paths)
|
|
157
157
|
.merge(openapi_paths)
|
|
158
|
+
.merge(stats_paths)
|
|
158
159
|
end
|
|
159
160
|
private_class_method :paths
|
|
160
161
|
|
|
@@ -1661,6 +1662,42 @@ module Legion
|
|
|
1661
1662
|
}
|
|
1662
1663
|
end
|
|
1663
1664
|
private_class_method :openapi_paths
|
|
1665
|
+
|
|
1666
|
+
def self.stats_paths
|
|
1667
|
+
{
|
|
1668
|
+
'/api/stats' => {
|
|
1669
|
+
get: {
|
|
1670
|
+
tags: ['Stats'],
|
|
1671
|
+
summary: 'Comprehensive daemon runtime stats',
|
|
1672
|
+
description: 'Returns runtime statistics for all subsystems: extensions, gaia, transport, cache, llm, data, and api. ' \
|
|
1673
|
+
'Each section collects independently — one subsystem failure does not affect others.',
|
|
1674
|
+
operationId: 'getStats',
|
|
1675
|
+
responses: {
|
|
1676
|
+
'200' => ok_response('Stats', wrap_data('StatsObject').merge(
|
|
1677
|
+
properties: {
|
|
1678
|
+
data: {
|
|
1679
|
+
type: 'object',
|
|
1680
|
+
properties: {
|
|
1681
|
+
extensions: { type: 'object' },
|
|
1682
|
+
gaia: { type: 'object' },
|
|
1683
|
+
transport: { type: 'object' },
|
|
1684
|
+
cache: { type: 'object' },
|
|
1685
|
+
cache_local: { type: 'object' },
|
|
1686
|
+
llm: { type: 'object' },
|
|
1687
|
+
data: { type: 'object' },
|
|
1688
|
+
data_local: { type: 'object' },
|
|
1689
|
+
api: { type: 'object' }
|
|
1690
|
+
}
|
|
1691
|
+
},
|
|
1692
|
+
meta: { '$ref' => '#/components/schemas/Meta' }
|
|
1693
|
+
}
|
|
1694
|
+
))
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
end
|
|
1700
|
+
private_class_method :stats_paths
|
|
1664
1701
|
end
|
|
1665
1702
|
end
|
|
1666
1703
|
end
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
class API < Sinatra::Base
|
|
5
|
+
module Routes
|
|
6
|
+
module Stats
|
|
7
|
+
def self.registered(app)
|
|
8
|
+
app.get '/api/stats' do
|
|
9
|
+
result = {}
|
|
10
|
+
result[:extensions] = Routes::Stats.collect_extensions
|
|
11
|
+
result[:gaia] = Routes::Stats.collect_gaia
|
|
12
|
+
result[:transport] = Routes::Stats.collect_transport
|
|
13
|
+
result[:cache] = Routes::Stats.collect_cache
|
|
14
|
+
result[:cache_local] = Routes::Stats.collect_cache_local
|
|
15
|
+
result[:llm] = Routes::Stats.collect_llm
|
|
16
|
+
result[:data] = Routes::Stats.collect_data
|
|
17
|
+
result[:data_local] = Routes::Stats.collect_data_local
|
|
18
|
+
result[:api] = Routes::Stats.collect_api
|
|
19
|
+
json_response(result)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
EXTENSION_IVARS = {
|
|
24
|
+
loaded: :@loaded_extensions,
|
|
25
|
+
discovered: :@extensions,
|
|
26
|
+
subscription: :@subscription_tasks,
|
|
27
|
+
every: :@timer_tasks,
|
|
28
|
+
poll: :@poll_tasks,
|
|
29
|
+
once: :@once_tasks,
|
|
30
|
+
loop: :@loop_tasks,
|
|
31
|
+
running: :@running_instances
|
|
32
|
+
}.freeze
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
def collect_extensions
|
|
36
|
+
ext = Legion::Extensions
|
|
37
|
+
EXTENSION_IVARS.transform_values { |ivar| ext.instance_variable_get(ivar)&.count || 0 }
|
|
38
|
+
rescue StandardError => e
|
|
39
|
+
{ error: e.message }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def collect_gaia
|
|
43
|
+
return { started: false } unless defined?(Legion::Gaia) && Legion::Gaia.respond_to?(:started?) && Legion::Gaia.started?
|
|
44
|
+
|
|
45
|
+
Legion::Gaia.status
|
|
46
|
+
rescue StandardError => e
|
|
47
|
+
{ error: e.message }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def collect_transport
|
|
51
|
+
conn = Legion::Transport::Connection
|
|
52
|
+
connected = begin
|
|
53
|
+
Legion::Settings[:transport][:connected]
|
|
54
|
+
rescue StandardError
|
|
55
|
+
false
|
|
56
|
+
end
|
|
57
|
+
connector = defined?(Legion::Transport::TYPE) ? Legion::Transport::TYPE.to_s : 'unknown'
|
|
58
|
+
|
|
59
|
+
info = { connected: connected, connector: connector }
|
|
60
|
+
|
|
61
|
+
session = conn.session
|
|
62
|
+
if session.respond_to?(:open?) && session.open?
|
|
63
|
+
info[:session_open] = true
|
|
64
|
+
info[:channel_max] = session.channel_max if session.respond_to?(:channel_max)
|
|
65
|
+
# Bunny tracks open channels in @channels hash
|
|
66
|
+
channels = session.instance_variable_get(:@channels)
|
|
67
|
+
info[:channels_open] = channels.is_a?(Hash) ? channels.count : nil
|
|
68
|
+
else
|
|
69
|
+
info[:session_open] = false
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
info[:build_session_open] = conn.build_session_open?
|
|
73
|
+
info[:lite_mode] = conn.lite_mode?
|
|
74
|
+
info
|
|
75
|
+
rescue StandardError => e
|
|
76
|
+
{ error: e.message }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def collect_cache
|
|
80
|
+
return { connected: false } unless defined?(Legion::Cache)
|
|
81
|
+
|
|
82
|
+
info = { connected: Legion::Cache.connected? }
|
|
83
|
+
info[:using_local] = Legion::Cache.using_local? if Legion::Cache.respond_to?(:using_local?)
|
|
84
|
+
info[:using_memory] = Legion::Cache.instance_variable_get(:@using_memory) == true
|
|
85
|
+
info[:driver] = begin
|
|
86
|
+
Legion::Settings[:cache][:driver]
|
|
87
|
+
rescue StandardError
|
|
88
|
+
nil
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
if Legion::Cache.connected? && Legion::Cache.respond_to?(:size)
|
|
92
|
+
info[:pool_size] = begin
|
|
93
|
+
Legion::Cache.size
|
|
94
|
+
rescue StandardError
|
|
95
|
+
nil
|
|
96
|
+
end
|
|
97
|
+
info[:pool_available] = begin
|
|
98
|
+
Legion::Cache.available
|
|
99
|
+
rescue StandardError
|
|
100
|
+
nil
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
info
|
|
104
|
+
rescue StandardError => e
|
|
105
|
+
{ error: e.message }
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def collect_cache_local
|
|
109
|
+
return { connected: false } unless defined?(Legion::Cache::Local)
|
|
110
|
+
|
|
111
|
+
info = { connected: Legion::Cache::Local.connected? }
|
|
112
|
+
if Legion::Cache::Local.connected?
|
|
113
|
+
info[:pool_size] = begin
|
|
114
|
+
Legion::Cache::Local.size
|
|
115
|
+
rescue StandardError
|
|
116
|
+
nil
|
|
117
|
+
end
|
|
118
|
+
info[:pool_available] = begin
|
|
119
|
+
Legion::Cache::Local.available
|
|
120
|
+
rescue StandardError
|
|
121
|
+
nil
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
info
|
|
125
|
+
rescue StandardError => e
|
|
126
|
+
{ error: e.message }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def collect_llm
|
|
130
|
+
return { started: false } unless defined?(Legion::LLM) && Legion::LLM.started?
|
|
131
|
+
|
|
132
|
+
info = { started: true }
|
|
133
|
+
s = Legion::LLM.settings
|
|
134
|
+
info[:default_model] = s[:default_model]
|
|
135
|
+
info[:default_provider] = s[:default_provider]
|
|
136
|
+
info[:pipeline_enabled] = s[:pipeline_enabled] == true
|
|
137
|
+
|
|
138
|
+
if defined?(Legion::LLM::Router) && Legion::LLM::Router.routing_enabled?
|
|
139
|
+
info[:routing_enabled] = true
|
|
140
|
+
tracker = Legion::LLM::Router.health_tracker
|
|
141
|
+
if tracker
|
|
142
|
+
providers = s[:providers] || {}
|
|
143
|
+
info[:provider_health] = providers.each_with_object({}) do |(name, _cfg), h|
|
|
144
|
+
h[name] = { circuit: tracker.circuit_state(name)&.to_s }
|
|
145
|
+
rescue StandardError
|
|
146
|
+
nil
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
else
|
|
150
|
+
info[:routing_enabled] = false
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
if defined?(Legion::LLM::ConversationStore)
|
|
154
|
+
store = Legion::LLM::ConversationStore
|
|
155
|
+
info[:conversations] = store.respond_to?(:size) ? store.size : nil
|
|
156
|
+
end
|
|
157
|
+
info
|
|
158
|
+
rescue StandardError => e
|
|
159
|
+
{ error: e.message }
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def collect_data
|
|
163
|
+
return { connected: false } unless defined?(Legion::Data) && Legion::Settings[:data][:connected]
|
|
164
|
+
|
|
165
|
+
if Legion::Data.respond_to?(:stats)
|
|
166
|
+
stats = Legion::Data.stats
|
|
167
|
+
stats[:shared] || stats
|
|
168
|
+
else
|
|
169
|
+
{ connected: true, adapter: begin
|
|
170
|
+
Legion::Data::Connection.adapter
|
|
171
|
+
rescue StandardError
|
|
172
|
+
nil
|
|
173
|
+
end }
|
|
174
|
+
end
|
|
175
|
+
rescue StandardError => e
|
|
176
|
+
{ error: e.message }
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def collect_data_local
|
|
180
|
+
return { connected: false } unless defined?(Legion::Data::Local) && Legion::Data::Local.connected?
|
|
181
|
+
|
|
182
|
+
if Legion::Data::Local.respond_to?(:stats)
|
|
183
|
+
Legion::Data::Local.stats
|
|
184
|
+
else
|
|
185
|
+
{ connected: true }
|
|
186
|
+
end
|
|
187
|
+
rescue StandardError => e
|
|
188
|
+
{ error: e.message }
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def collect_api
|
|
192
|
+
port = Legion::Settings.dig(:api, :port) || Legion::Settings.dig(:http, :port) || 4567
|
|
193
|
+
info = { port: port }
|
|
194
|
+
|
|
195
|
+
# Puma thread pool stats if available
|
|
196
|
+
puma_server = Puma::Server.current if defined?(Puma::Server) && Puma::Server.respond_to?(:current)
|
|
197
|
+
if puma_server.respond_to?(:pool_capacity)
|
|
198
|
+
info[:puma] = {
|
|
199
|
+
pool_capacity: puma_server.pool_capacity,
|
|
200
|
+
max_threads: puma_server.max_threads,
|
|
201
|
+
running: puma_server.running,
|
|
202
|
+
backlog: puma_server.backlog
|
|
203
|
+
}
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
info[:routes] = begin
|
|
207
|
+
Legion::API.routes.values.flatten.count
|
|
208
|
+
rescue StandardError
|
|
209
|
+
nil
|
|
210
|
+
end
|
|
211
|
+
info
|
|
212
|
+
rescue StandardError => e
|
|
213
|
+
{ error: e.message }
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
data/lib/legion/api.rb
CHANGED
|
@@ -45,6 +45,7 @@ require_relative 'api/marketplace'
|
|
|
45
45
|
require_relative 'api/apollo'
|
|
46
46
|
require_relative 'api/costs'
|
|
47
47
|
require_relative 'api/traces'
|
|
48
|
+
require_relative 'api/stats'
|
|
48
49
|
require_relative 'api/graphql' if defined?(GraphQL)
|
|
49
50
|
|
|
50
51
|
module Legion
|
|
@@ -135,6 +136,7 @@ module Legion
|
|
|
135
136
|
register Routes::Apollo
|
|
136
137
|
register Routes::Costs
|
|
137
138
|
register Routes::Traces
|
|
139
|
+
register Routes::Stats
|
|
138
140
|
register Routes::GraphQL if defined?(Routes::GraphQL)
|
|
139
141
|
|
|
140
142
|
use Legion::API::Middleware::RequestLogger
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'fileutils'
|
|
3
4
|
require 'net/http'
|
|
4
5
|
require 'json'
|
|
5
6
|
require 'socket'
|
|
@@ -23,35 +24,58 @@ module Legion
|
|
|
23
24
|
desc 'dump', 'Full diagnostic dump (markdown, suitable for piping to LLM)'
|
|
24
25
|
default_task :dump
|
|
25
26
|
def dump
|
|
26
|
-
sections =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
sections[:apollo] = section_apollo
|
|
39
|
-
sections[:remote_redis] = section_remote_redis
|
|
40
|
-
sections[:local_redis] = section_local_redis
|
|
41
|
-
sections[:postgresql] = section_postgresql
|
|
42
|
-
sections[:rabbitmq] = section_rabbitmq
|
|
43
|
-
sections[:api_health] = section_api_health
|
|
44
|
-
|
|
45
|
-
if options[:json]
|
|
46
|
-
puts ::JSON.pretty_generate(sections)
|
|
47
|
-
else
|
|
48
|
-
render_markdown(sections)
|
|
49
|
-
end
|
|
27
|
+
sections = collect_all_sections
|
|
28
|
+
|
|
29
|
+
output = if options[:json]
|
|
30
|
+
::JSON.pretty_generate(sections)
|
|
31
|
+
else
|
|
32
|
+
build_markdown(sections)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
puts output
|
|
36
|
+
|
|
37
|
+
path = write_dump_file(output)
|
|
38
|
+
warn "Saved to #{path}" if path
|
|
50
39
|
end
|
|
51
40
|
|
|
41
|
+
DEBUG_DIR = File.expand_path('~/.legionio/debug')
|
|
42
|
+
|
|
52
43
|
no_commands do # rubocop:disable Metrics/BlockLength
|
|
53
44
|
private
|
|
54
45
|
|
|
46
|
+
def collect_all_sections
|
|
47
|
+
sections = {}
|
|
48
|
+
sections[:versions] = section_versions
|
|
49
|
+
sections[:doctor] = section_doctor
|
|
50
|
+
sections[:config] = section_config
|
|
51
|
+
sections[:gems] = section_gems
|
|
52
|
+
sections[:extensions] = section_extensions
|
|
53
|
+
sections[:rbac] = section_rbac
|
|
54
|
+
sections[:llm] = section_llm
|
|
55
|
+
sections[:gaia] = section_gaia
|
|
56
|
+
sections[:transport] = section_transport
|
|
57
|
+
sections[:events] = section_events
|
|
58
|
+
sections[:apollo] = section_apollo
|
|
59
|
+
sections[:remote_redis] = section_remote_redis
|
|
60
|
+
sections[:local_redis] = section_local_redis
|
|
61
|
+
sections[:postgresql] = section_postgresql
|
|
62
|
+
sections[:rabbitmq] = section_rabbitmq
|
|
63
|
+
sections[:api_health] = section_api_health
|
|
64
|
+
sections
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def write_dump_file(output)
|
|
68
|
+
FileUtils.mkdir_p(DEBUG_DIR)
|
|
69
|
+
ext = options[:json] ? 'json' : 'md'
|
|
70
|
+
filename = "#{Time.now.utc.strftime('%Y-%m-%d_%H%M%S')}.#{ext}"
|
|
71
|
+
path = File.join(DEBUG_DIR, filename)
|
|
72
|
+
File.write(path, output)
|
|
73
|
+
path
|
|
74
|
+
rescue StandardError => e
|
|
75
|
+
warn "Warning: could not write debug file: #{e.message}"
|
|
76
|
+
nil
|
|
77
|
+
end
|
|
78
|
+
|
|
55
79
|
def api_host
|
|
56
80
|
options[:host] || '127.0.0.1'
|
|
57
81
|
end
|
|
@@ -390,37 +414,38 @@ module Legion
|
|
|
390
414
|
end
|
|
391
415
|
end
|
|
392
416
|
|
|
393
|
-
def
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
417
|
+
def build_markdown(sections)
|
|
418
|
+
lines = []
|
|
419
|
+
lines << '# LegionIO Diagnostic Dump'
|
|
420
|
+
lines << ''
|
|
421
|
+
lines << "Generated: #{Time.now.utc.iso8601}"
|
|
422
|
+
lines << ''
|
|
423
|
+
|
|
424
|
+
{ 'Versions' => :versions,
|
|
425
|
+
'Doctor Checks' => :doctor,
|
|
426
|
+
'Configuration (redacted)' => :config,
|
|
427
|
+
'Installed Gems' => :gems,
|
|
428
|
+
'Loaded Extensions' => :extensions,
|
|
429
|
+
'RBAC Roles' => :rbac,
|
|
430
|
+
'LLM Status' => :llm,
|
|
431
|
+
'GAIA Status' => :gaia,
|
|
432
|
+
'Transport Status' => :transport,
|
|
433
|
+
'Recent Events (last 20)' => :events,
|
|
434
|
+
'Apollo Stats' => :apollo,
|
|
435
|
+
'Remote Redis' => :remote_redis,
|
|
436
|
+
'Local Redis' => :local_redis,
|
|
437
|
+
'PostgreSQL' => :postgresql,
|
|
438
|
+
'RabbitMQ' => :rabbitmq,
|
|
439
|
+
'API Health' => :api_health }.each do |title, key|
|
|
440
|
+
lines << "## #{title}"
|
|
441
|
+
lines << ''
|
|
442
|
+
lines << '```json'
|
|
443
|
+
lines << ::JSON.pretty_generate(sections[key])
|
|
444
|
+
lines << '```'
|
|
445
|
+
lines << ''
|
|
446
|
+
end
|
|
416
447
|
|
|
417
|
-
|
|
418
|
-
puts "## #{title}"
|
|
419
|
-
puts
|
|
420
|
-
puts '```json'
|
|
421
|
-
puts ::JSON.pretty_generate(data)
|
|
422
|
-
puts '```'
|
|
423
|
-
puts
|
|
448
|
+
lines.join("\n")
|
|
424
449
|
end
|
|
425
450
|
end
|
|
426
451
|
end
|
data/lib/legion/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: legionio
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.
|
|
4
|
+
version: 1.5.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -253,14 +253,14 @@ dependencies:
|
|
|
253
253
|
requirements:
|
|
254
254
|
- - ">="
|
|
255
255
|
- !ruby/object:Gem::Version
|
|
256
|
-
version: 1.
|
|
256
|
+
version: 1.6.0
|
|
257
257
|
type: :runtime
|
|
258
258
|
prerelease: false
|
|
259
259
|
version_requirements: !ruby/object:Gem::Requirement
|
|
260
260
|
requirements:
|
|
261
261
|
- - ">="
|
|
262
262
|
- !ruby/object:Gem::Version
|
|
263
|
-
version: 1.
|
|
263
|
+
version: 1.6.0
|
|
264
264
|
- !ruby/object:Gem::Dependency
|
|
265
265
|
name: legion-json
|
|
266
266
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -479,6 +479,7 @@ files:
|
|
|
479
479
|
- lib/legion/api/relationships.rb
|
|
480
480
|
- lib/legion/api/schedules.rb
|
|
481
481
|
- lib/legion/api/settings.rb
|
|
482
|
+
- lib/legion/api/stats.rb
|
|
482
483
|
- lib/legion/api/tasks.rb
|
|
483
484
|
- lib/legion/api/tenants.rb
|
|
484
485
|
- lib/legion/api/token.rb
|