smplkit 3.0.15 → 3.0.16
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/lib/smplkit/logging/client.rb +173 -11
- data/lib/smplkit/logging/resolution.rb +118 -0
- data/lib/smplkit/management/client.rb +57 -0
- data/lib/smplkit.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 215caf14863d35bebf83849e104befe12423a9ef468a547cb44714e6a9ea1932
|
|
4
|
+
data.tar.gz: 928ab9e89ea2dca1548eb82a06aa8d9b525f874026437bb6b862b4cdc254a4c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f77af115d5412a34711fb54af8de0c402e47f33e53512fb808794a103a046d514494d947a6ed9d7d42998d9aca3f196db433914de52f96b785e3b35e5c63972
|
|
7
|
+
data.tar.gz: d028dd314e06e87fc6185f80695ba0c4bdf21b5d77d548c62e32bc2c4138590f7566c327cc83946191c26e233be9b0d923d1ba0d3d6fb59f835f91ca9f6f3bfa
|
|
@@ -9,6 +9,11 @@ module Smplkit
|
|
|
9
9
|
# Obtained via +Smplkit::Client#logging+. Manages the discovery and level
|
|
10
10
|
# application for a customer's logging frameworks via pluggable adapters.
|
|
11
11
|
# CRUD has moved to +mgmt.loggers.*+ / +mgmt.log_groups.*+.
|
|
12
|
+
#
|
|
13
|
+
# Level resolution is client-side: the server stores raw configuration
|
|
14
|
+
# and the SDK walks the chain (env override → base → group chain →
|
|
15
|
+
# dot-notation ancestry) to compute each managed logger's effective
|
|
16
|
+
# level. See {Smplkit::Logging::Resolution}.
|
|
12
17
|
class LoggingClient
|
|
13
18
|
def initialize(parent, manage:, metrics:, logging_base_url:, app_base_url:)
|
|
14
19
|
@parent = parent
|
|
@@ -21,6 +26,23 @@ module Smplkit
|
|
|
21
26
|
@global_listeners = []
|
|
22
27
|
@key_listeners = Hash.new { |h, k| h[k] = [] }
|
|
23
28
|
@lock = Mutex.new
|
|
29
|
+
# original_name → normalized_id for every adapter-discovered logger.
|
|
30
|
+
# We keep originals so adapter.apply_level receives whatever the
|
|
31
|
+
# framework's registry indexes by.
|
|
32
|
+
@name_map = {}
|
|
33
|
+
# normalized_id → resolution-cache entry. Populated by
|
|
34
|
+
# +_fetch_and_apply+ and mutated by the +logger_changed+ /
|
|
35
|
+
# +logger_deleted+ WS handlers.
|
|
36
|
+
@loggers_cache = {}
|
|
37
|
+
# group id → resolution-cache entry. Without this, any managed
|
|
38
|
+
# logger with +level=null+ that inherits from a group silently
|
|
39
|
+
# keeps whatever level its adapter had at startup.
|
|
40
|
+
@groups_cache = {}
|
|
41
|
+
# normalized_id → resolved level (string). Used to decide whether
|
|
42
|
+
# to fire change listeners on a re-resolution — a group-driven
|
|
43
|
+
# change isn't visible in the raw +loggers_cache+ but moves the
|
|
44
|
+
# resolved value.
|
|
45
|
+
@resolved_levels = {}
|
|
24
46
|
end
|
|
25
47
|
|
|
26
48
|
# Install the logging integration.
|
|
@@ -39,8 +61,15 @@ module Smplkit
|
|
|
39
61
|
adapter.install_hook { |name, _explicit, effective| observe_logger(adapter, name, effective) }
|
|
40
62
|
end
|
|
41
63
|
|
|
64
|
+
flush_initial_registration
|
|
65
|
+
fetch_and_apply(trigger: "install")
|
|
66
|
+
|
|
42
67
|
@ws_manager = @parent._ensure_ws
|
|
43
68
|
@ws_manager.on("logger_changed") { |data| handle_logger_changed(data) }
|
|
69
|
+
@ws_manager.on("logger_deleted") { |data| handle_logger_deleted(data) }
|
|
70
|
+
@ws_manager.on("group_changed") { |data| handle_group_changed(data) }
|
|
71
|
+
@ws_manager.on("group_deleted") { |data| handle_group_deleted(data) }
|
|
72
|
+
@ws_manager.on("loggers_changed") { |data| handle_loggers_changed(data) }
|
|
44
73
|
@installed = true
|
|
45
74
|
self
|
|
46
75
|
end
|
|
@@ -71,6 +100,12 @@ module Smplkit
|
|
|
71
100
|
@manage.loggers.delete(name)
|
|
72
101
|
end
|
|
73
102
|
|
|
103
|
+
# Re-fetch all loggers and groups and re-apply resolved levels. Fires
|
|
104
|
+
# change listeners for any logger whose resolved level moved.
|
|
105
|
+
def refresh
|
|
106
|
+
fetch_and_apply(trigger: "refresh")
|
|
107
|
+
end
|
|
108
|
+
|
|
74
109
|
def on_change(name = nil, &block)
|
|
75
110
|
raise ArgumentError, "on_change requires a block" unless block
|
|
76
111
|
|
|
@@ -102,15 +137,17 @@ module Smplkit
|
|
|
102
137
|
|
|
103
138
|
return unless @adapters.empty?
|
|
104
139
|
|
|
105
|
-
#
|
|
106
|
-
#
|
|
140
|
+
# Defensive log — unreachable in practice because stdlib +Logger+
|
|
141
|
+
# is always present, so +StdlibLoggerAdapter+ is always
|
|
107
142
|
# constructible.
|
|
143
|
+
# :nocov:
|
|
108
144
|
Smplkit.debug("registration", "no logging adapters loaded; runtime features disabled")
|
|
109
145
|
# :nocov:
|
|
110
146
|
end
|
|
111
147
|
|
|
112
148
|
def observe_logger(_adapter, raw_name, level)
|
|
113
149
|
normalized = Normalize.normalize_logger_name(raw_name)
|
|
150
|
+
@name_map[raw_name] = normalized
|
|
114
151
|
@manage.loggers.register(LoggerSource.new(
|
|
115
152
|
name: normalized,
|
|
116
153
|
resolved_level: level,
|
|
@@ -120,16 +157,135 @@ module Smplkit
|
|
|
120
157
|
))
|
|
121
158
|
end
|
|
122
159
|
|
|
160
|
+
def flush_initial_registration
|
|
161
|
+
@manage.loggers.flush
|
|
162
|
+
rescue StandardError => e
|
|
163
|
+
Smplkit.debug("registration", "initial logger flush failed: #{e.class}: #{e.message}")
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Full re-fetch of loggers + groups, then apply resolved levels.
|
|
167
|
+
# Fires change listeners for any logger whose resolved level moved.
|
|
168
|
+
def fetch_and_apply(trigger:)
|
|
169
|
+
Smplkit.debug("resolution", "full resolution pass starting (trigger: #{trigger})")
|
|
170
|
+
loggers = @manage.loggers.list_logger_entries
|
|
171
|
+
groups = @manage.log_groups.list_group_entries
|
|
172
|
+
@loggers_cache = loggers
|
|
173
|
+
@groups_cache = groups
|
|
174
|
+
apply_levels(source: "websocket")
|
|
175
|
+
rescue StandardError => e
|
|
176
|
+
Smplkit.debug("resolution", "fetch_and_apply failed (trigger: #{trigger}): #{e.class}: #{e.message}")
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Resolve the effective level for every locally-known managed logger
|
|
180
|
+
# and push it to every adapter. Returns the list of normalized ids
|
|
181
|
+
# whose resolved level changed.
|
|
182
|
+
#
|
|
183
|
+
# +source+ is the +LoggerChangeEvent#source+ for any change-listener
|
|
184
|
+
# event we fire. The default reflects callers that arrived through a
|
|
185
|
+
# server event (WebSocket).
|
|
186
|
+
def apply_levels(source: "websocket")
|
|
187
|
+
changed = []
|
|
188
|
+
@name_map.each do |raw_name, normalized_id|
|
|
189
|
+
entry = @loggers_cache[normalized_id]
|
|
190
|
+
next if entry.nil?
|
|
191
|
+
next unless entry["managed"]
|
|
192
|
+
|
|
193
|
+
resolved_string = Resolution.resolve_level(
|
|
194
|
+
normalized_id, @parent._environment, @loggers_cache, @groups_cache
|
|
195
|
+
)
|
|
196
|
+
coerced = LogLevel.coerce(resolved_string)
|
|
197
|
+
push_to_adapters(raw_name, coerced)
|
|
198
|
+
previous = @resolved_levels[normalized_id]
|
|
199
|
+
if previous != resolved_string
|
|
200
|
+
@resolved_levels[normalized_id] = resolved_string
|
|
201
|
+
changed << [normalized_id, coerced]
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
fire_resolved_change_events(changed, source: source)
|
|
205
|
+
changed
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def push_to_adapters(raw_name, coerced_level)
|
|
209
|
+
@adapters.each do |a|
|
|
210
|
+
a.apply_level(raw_name, coerced_level)
|
|
211
|
+
rescue StandardError => e
|
|
212
|
+
Smplkit.debug("logging", "adapter apply_level raised: #{e.class}: #{e.message}")
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def fire_resolved_change_events(changed, source:)
|
|
217
|
+
changed.each do |(normalized_id, coerced_level)|
|
|
218
|
+
event = LoggerChangeEvent.new(name: normalized_id, level: coerced_level, source: source)
|
|
219
|
+
(@global_listeners + @key_listeners[normalized_id]).each do |cb|
|
|
220
|
+
cb.call(event)
|
|
221
|
+
rescue StandardError => e
|
|
222
|
+
Smplkit.debug("logging", "listener raised: #{e.class}: #{e.message}")
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
123
227
|
def handle_logger_changed(data)
|
|
124
|
-
|
|
125
|
-
|
|
228
|
+
key = data["id"] || data["name"] || ""
|
|
229
|
+
normalized = Normalize.normalize_logger_name(key)
|
|
230
|
+
return if normalized.empty?
|
|
126
231
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
232
|
+
begin
|
|
233
|
+
entry_id, entry = @manage.loggers.get_logger_entry(normalized)
|
|
234
|
+
@loggers_cache[entry_id || normalized] = entry
|
|
235
|
+
rescue StandardError => e
|
|
236
|
+
Smplkit.debug("websocket", "logger_changed fetch failed for #{normalized.inspect}: #{e.class}: #{e.message}")
|
|
237
|
+
return
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
apply_levels(source: "websocket")
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def handle_logger_deleted(data)
|
|
244
|
+
key = data["id"] || data["name"] || ""
|
|
245
|
+
normalized = Normalize.normalize_logger_name(key)
|
|
246
|
+
return if normalized.empty?
|
|
247
|
+
|
|
248
|
+
existed = @loggers_cache.delete(normalized)
|
|
249
|
+
@resolved_levels.delete(normalized)
|
|
250
|
+
return unless existed
|
|
251
|
+
|
|
252
|
+
apply_levels(source: "websocket")
|
|
253
|
+
fire_deletion_event(normalized)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def handle_group_changed(data)
|
|
257
|
+
key = data["id"] || data["key"] || ""
|
|
258
|
+
return if key.to_s.empty?
|
|
259
|
+
|
|
260
|
+
begin
|
|
261
|
+
entry_id, entry = @manage.log_groups.get_group_entry(key)
|
|
262
|
+
@groups_cache[entry_id || key] = entry
|
|
263
|
+
rescue StandardError => e
|
|
264
|
+
Smplkit.debug("websocket", "group_changed fetch failed for #{key.inspect}: #{e.class}: #{e.message}")
|
|
265
|
+
return
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
apply_levels(source: "websocket")
|
|
269
|
+
end
|
|
130
270
|
|
|
131
|
-
|
|
132
|
-
|
|
271
|
+
def handle_group_deleted(data)
|
|
272
|
+
key = data["id"] || data["key"] || ""
|
|
273
|
+
return if key.to_s.empty?
|
|
274
|
+
|
|
275
|
+
existed = @groups_cache.delete(key)
|
|
276
|
+
return unless existed
|
|
277
|
+
|
|
278
|
+
apply_levels(source: "websocket")
|
|
279
|
+
fire_deletion_event(key)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def handle_loggers_changed(_data)
|
|
283
|
+
fetch_and_apply(trigger: "loggers_changed WS event")
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def fire_deletion_event(key)
|
|
287
|
+
event = LoggerChangeEvent.new(name: key, level: nil, source: "websocket", deleted: true)
|
|
288
|
+
(@global_listeners + @key_listeners[key]).each do |cb|
|
|
133
289
|
cb.call(event)
|
|
134
290
|
rescue StandardError => e
|
|
135
291
|
Smplkit.debug("logging", "listener raised: #{e.class}: #{e.message}")
|
|
@@ -137,9 +293,15 @@ module Smplkit
|
|
|
137
293
|
end
|
|
138
294
|
end
|
|
139
295
|
|
|
140
|
-
LoggerChangeEvent = Struct.new(:name, :level, :source, keyword_init: true) do
|
|
296
|
+
LoggerChangeEvent = Struct.new(:name, :level, :source, :deleted, keyword_init: true) do
|
|
297
|
+
def initialize(name:, level:, source:, deleted: false)
|
|
298
|
+
super
|
|
299
|
+
end
|
|
300
|
+
|
|
141
301
|
def ==(other)
|
|
142
|
-
other.is_a?(LoggerChangeEvent) &&
|
|
302
|
+
other.is_a?(LoggerChangeEvent) &&
|
|
303
|
+
name == other.name && level == other.level &&
|
|
304
|
+
source == other.source && deleted == other.deleted
|
|
143
305
|
end
|
|
144
306
|
end
|
|
145
307
|
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "set"
|
|
4
|
+
|
|
5
|
+
module Smplkit
|
|
6
|
+
module Logging
|
|
7
|
+
# Client-side level resolution per ADR-034 §3.1.
|
|
8
|
+
#
|
|
9
|
+
# The server stores raw configuration and returns it as-is; the SDK is
|
|
10
|
+
# responsible for walking the inheritance chain. Mirrors the Python
|
|
11
|
+
# SDK's +smplkit.logging._resolution+ verbatim — both implementations
|
|
12
|
+
# MUST resolve identically for any given (loggers, groups, env) input.
|
|
13
|
+
module Resolution
|
|
14
|
+
FALLBACK_LEVEL = "INFO"
|
|
15
|
+
|
|
16
|
+
module_function
|
|
17
|
+
|
|
18
|
+
# Resolve the effective level for +logger_id+ in +environment+.
|
|
19
|
+
#
|
|
20
|
+
# Resolution chain (first non-nil wins):
|
|
21
|
+
#
|
|
22
|
+
# 1. Logger's own +environments[env].level+
|
|
23
|
+
# 2. Logger's own +level+
|
|
24
|
+
# 3. Group chain (recursive: group env level → group level → parent group …)
|
|
25
|
+
# 4. Dot-notation ancestry (+com.acme.payments+ → +com.acme+ → +com+,
|
|
26
|
+
# applying steps 1–3 at each)
|
|
27
|
+
# 5. System fallback: +"INFO"+
|
|
28
|
+
#
|
|
29
|
+
# +loggers+ and +groups+ are id-keyed Hashes whose values are Hashes
|
|
30
|
+
# with the same shape as the Python SDK: +"level"+, +"group"+ (parent
|
|
31
|
+
# group id for loggers; parent_id for groups), +"environments"+
|
|
32
|
+
# (Hash keyed by env name with +{"level" => "..."}+ values).
|
|
33
|
+
def resolve_level(logger_id, environment, loggers, groups)
|
|
34
|
+
result = resolve_for_entry(logger_id, environment, loggers, groups)
|
|
35
|
+
if result
|
|
36
|
+
if Smplkit::Debug.enabled
|
|
37
|
+
source = find_resolution_source(logger_id, environment, loggers, groups)
|
|
38
|
+
Smplkit.debug("resolution", "#{logger_id} -> #{result} (source: #{source})")
|
|
39
|
+
end
|
|
40
|
+
return result
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
parts = logger_id.split(".")
|
|
44
|
+
(parts.length - 1).downto(1) do |i|
|
|
45
|
+
ancestor_id = parts[0, i].join(".")
|
|
46
|
+
result = resolve_for_entry(ancestor_id, environment, loggers, groups)
|
|
47
|
+
if result
|
|
48
|
+
Smplkit.debug("resolution", "#{logger_id} -> #{result} (source: ancestor \"#{ancestor_id}\")")
|
|
49
|
+
return result
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
Smplkit.debug("resolution", "#{logger_id} -> #{FALLBACK_LEVEL} (source: system default)")
|
|
54
|
+
FALLBACK_LEVEL
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Try to resolve a level for a single entry (logger or ancestor).
|
|
58
|
+
# Returns +nil+ if no level is found at any step of 1–3.
|
|
59
|
+
def resolve_for_entry(logger_id, environment, loggers, groups)
|
|
60
|
+
entry = loggers[logger_id]
|
|
61
|
+
return nil if entry.nil?
|
|
62
|
+
|
|
63
|
+
env_level = env_level_of(entry, environment)
|
|
64
|
+
return env_level if env_level
|
|
65
|
+
|
|
66
|
+
base = entry["level"]
|
|
67
|
+
return base if base
|
|
68
|
+
|
|
69
|
+
resolve_group_chain(entry["group"], environment, groups)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Walk the group chain looking for a level. Cycle-safe via +visited+.
|
|
73
|
+
def resolve_group_chain(group_id, environment, groups)
|
|
74
|
+
visited = Set.new
|
|
75
|
+
current_id = group_id
|
|
76
|
+
while !current_id.nil? && !visited.include?(current_id)
|
|
77
|
+
visited.add(current_id)
|
|
78
|
+
group = groups[current_id]
|
|
79
|
+
break if group.nil?
|
|
80
|
+
|
|
81
|
+
env_level = env_level_of(group, environment)
|
|
82
|
+
return env_level if env_level
|
|
83
|
+
|
|
84
|
+
base = group["level"]
|
|
85
|
+
return base if base
|
|
86
|
+
|
|
87
|
+
current_id = group["group"]
|
|
88
|
+
end
|
|
89
|
+
nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Human-readable label for which resolution step won. Only consulted
|
|
93
|
+
# when debug logging is enabled; mirrors Python's +_find_resolution_source+.
|
|
94
|
+
def find_resolution_source(logger_id, environment, loggers, groups)
|
|
95
|
+
entry = loggers[logger_id]
|
|
96
|
+
return "not found" if entry.nil?
|
|
97
|
+
|
|
98
|
+
return %(env override "#{environment}") if env_level_of(entry, environment)
|
|
99
|
+
return "base level" if entry["level"]
|
|
100
|
+
|
|
101
|
+
group_id = entry["group"]
|
|
102
|
+
return %(group "#{group_id}") if resolve_group_chain(group_id, environment, groups)
|
|
103
|
+
|
|
104
|
+
"unknown"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def env_level_of(entry, environment)
|
|
108
|
+
envs = entry["environments"]
|
|
109
|
+
return nil unless envs.is_a?(Hash)
|
|
110
|
+
|
|
111
|
+
env_data = envs[environment]
|
|
112
|
+
return nil unless env_data.is_a?(Hash)
|
|
113
|
+
|
|
114
|
+
env_data["level"]
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -816,8 +816,38 @@ module Smplkit
|
|
|
816
816
|
Smplkit::Logging::Helpers.logger_resource_to_model(self, ResourceShim.from_model(response.data))
|
|
817
817
|
end
|
|
818
818
|
|
|
819
|
+
# Runtime entry — walks every page and returns an id-keyed Hash of
|
|
820
|
+
# resolution-cache entries (+level+, +group+, +managed+,
|
|
821
|
+
# +environments+). Mirrors the Python SDK's
|
|
822
|
+
# +LoggingClient._fetch_and_apply+ loggers branch.
|
|
823
|
+
def list_logger_entries
|
|
824
|
+
rows = PaginatedFetch.collect { |opts| @api.list_loggers(opts) }
|
|
825
|
+
rows.to_h { |r| logger_entry_from_resource(ResourceShim.from_model(r)) }
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
# Fetch one logger as a resolution-cache entry. Used by the
|
|
829
|
+
# +logger_changed+ WS handler.
|
|
830
|
+
def get_logger_entry(id)
|
|
831
|
+
normalized = Smplkit::Logging::Normalize.normalize_logger_name(id)
|
|
832
|
+
response = ErrorMapping.call { @api.get_logger(normalized) }
|
|
833
|
+
logger_entry_from_resource(ResourceShim.from_model(response.data))
|
|
834
|
+
end
|
|
835
|
+
|
|
819
836
|
private
|
|
820
837
|
|
|
838
|
+
def logger_entry_from_resource(resource)
|
|
839
|
+
attrs = resource["attributes"] || {}
|
|
840
|
+
[
|
|
841
|
+
resource["id"],
|
|
842
|
+
{
|
|
843
|
+
"level" => attrs["level"],
|
|
844
|
+
"group" => attrs["group"],
|
|
845
|
+
"managed" => attrs.key?("managed") ? attrs["managed"] : true,
|
|
846
|
+
"environments" => attrs["environments"] || {}
|
|
847
|
+
}
|
|
848
|
+
]
|
|
849
|
+
end
|
|
850
|
+
|
|
821
851
|
def logger_body(logger)
|
|
822
852
|
# Logger server schema: name, level, group, managed.
|
|
823
853
|
# +resolved_level+ is read-only, +service+/+environment+ are
|
|
@@ -880,8 +910,35 @@ module Smplkit
|
|
|
880
910
|
Smplkit::Logging::Helpers.log_group_resource_to_model(self, ResourceShim.from_model(response.data))
|
|
881
911
|
end
|
|
882
912
|
|
|
913
|
+
# Runtime entry — walks every page and returns an id-keyed Hash of
|
|
914
|
+
# resolution-cache entries (+level+, +group+, +environments+). The
|
|
915
|
+
# +group+ key carries the *parent group id* so the resolution
|
|
916
|
+
# algorithm can walk the chain with the same key shape it uses for
|
|
917
|
+
# loggers.
|
|
918
|
+
def list_group_entries
|
|
919
|
+
rows = PaginatedFetch.collect { |opts| @api.list_log_groups(opts) }
|
|
920
|
+
rows.to_h { |r| group_entry_from_resource(ResourceShim.from_model(r)) }
|
|
921
|
+
end
|
|
922
|
+
|
|
923
|
+
def get_group_entry(key)
|
|
924
|
+
response = ErrorMapping.call { @api.get_log_group(key) }
|
|
925
|
+
group_entry_from_resource(ResourceShim.from_model(response.data))
|
|
926
|
+
end
|
|
927
|
+
|
|
883
928
|
private
|
|
884
929
|
|
|
930
|
+
def group_entry_from_resource(resource)
|
|
931
|
+
attrs = resource["attributes"] || {}
|
|
932
|
+
[
|
|
933
|
+
resource["id"],
|
|
934
|
+
{
|
|
935
|
+
"level" => attrs["level"],
|
|
936
|
+
"group" => attrs["parent_id"],
|
|
937
|
+
"environments" => attrs["environments"] || {}
|
|
938
|
+
}
|
|
939
|
+
]
|
|
940
|
+
end
|
|
941
|
+
|
|
885
942
|
def log_group_body(group)
|
|
886
943
|
# LogGroup server schema: name, level, parent_id (no description).
|
|
887
944
|
SmplkitGeneratedClient::Logging::LogGroupResponse.new(
|
data/lib/smplkit.rb
CHANGED
|
@@ -55,6 +55,7 @@ require_relative "smplkit/logging/normalize"
|
|
|
55
55
|
require_relative "smplkit/logging/sources"
|
|
56
56
|
require_relative "smplkit/logging/models"
|
|
57
57
|
require_relative "smplkit/logging/helpers"
|
|
58
|
+
require_relative "smplkit/logging/resolution"
|
|
58
59
|
require_relative "smplkit/logging/adapters/base"
|
|
59
60
|
require_relative "smplkit/logging/adapters/stdlib_logger_adapter"
|
|
60
61
|
require_relative "smplkit/logging/client"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smplkit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.16
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Smpl Solutions LLC
|
|
@@ -701,6 +701,7 @@ files:
|
|
|
701
701
|
- lib/smplkit/logging/levels.rb
|
|
702
702
|
- lib/smplkit/logging/models.rb
|
|
703
703
|
- lib/smplkit/logging/normalize.rb
|
|
704
|
+
- lib/smplkit/logging/resolution.rb
|
|
704
705
|
- lib/smplkit/logging/sources.rb
|
|
705
706
|
- lib/smplkit/management/audit.rb
|
|
706
707
|
- lib/smplkit/management/buffer.rb
|