legion-logging 1.5.3 → 1.5.4
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 +6 -0
- data/lib/legion/logging/async_writer.rb +3 -1
- data/lib/legion/logging/helper.rb +56 -7
- data/lib/legion/logging/methods.rb +77 -8
- data/lib/legion/logging/version.rb +1 -1
- data/lib/legion/logging.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3a7e958bdf135cd4798a6619992fd2661a9864b13dab2133c378d67ccea54380
|
|
4
|
+
data.tar.gz: 280391287ca3a8e15f91979e63bdbb3f4f7bab3c0e71bcc1f47b9a4eac378cb0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 55b8db2c9e50ad4d9d91f10379821c33c0cacdeed46a1da16a23d49835108f65ab9d59305bd3c421219510932d58f684c2816c7b39e39d51dc36ad65396a8afe
|
|
7
|
+
data.tar.gz: c7914b118692f0e2738ab5a68af4290e117b275b320a43a548ae5e85366f6f8cfec5f16f3c611f2b47a9f7e90a5446063f77c97ef3bb98a5e169a6dee177e9ad
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Legion::Logging Changelog
|
|
2
2
|
|
|
3
|
+
## [1.5.4] - 2026-05-22
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Structured log and exception AMQP writer headers now include `legion_protocol_version`, best-effort `x-legion-version`, and transport-standard `x-legion-identity-*` headers when process identity is resolved.
|
|
7
|
+
- `log_writer` now receives the same `headers:` and `properties:` envelope metadata shape as `exception_writer`.
|
|
8
|
+
|
|
3
9
|
## [1.5.3] - 2026-05-13
|
|
4
10
|
|
|
5
11
|
### Added
|
|
@@ -110,7 +110,9 @@ module Legion
|
|
|
110
110
|
lex_name = event[:lex] || 'core'
|
|
111
111
|
component = event.dig(:caller, :file).to_s[Legion::Logging::Methods::COMPONENT_REGEX, 1] || 'unknown'
|
|
112
112
|
routing_key = "legion.logging.log.#{level}.#{lex_name}.#{component}"
|
|
113
|
-
Legion::Logging.
|
|
113
|
+
headers = Legion::Logging.send(:build_log_headers, event, component, level)
|
|
114
|
+
properties = Legion::Logging.send(:build_log_properties, level)
|
|
115
|
+
Legion::Logging.log_writer.call(event, routing_key: routing_key, headers: headers, properties: properties)
|
|
114
116
|
Legion::Logging::Hooks.fire(level, entry.message, event) if defined?(Legion::Logging::Hooks)
|
|
115
117
|
rescue StandardError => e
|
|
116
118
|
warn("legion-log-writer writer error: #{e.message}")
|
|
@@ -559,21 +559,70 @@ module Legion
|
|
|
559
559
|
|
|
560
560
|
def build_exception_headers(event, comp, level)
|
|
561
561
|
headers = {
|
|
562
|
-
'
|
|
563
|
-
'x-
|
|
564
|
-
'x-
|
|
565
|
-
'x-
|
|
566
|
-
'x-
|
|
567
|
-
'x-
|
|
568
|
-
'x-
|
|
562
|
+
'legion_protocol_version' => '2.0',
|
|
563
|
+
'x-error-fingerprint' => event[:error_fingerprint],
|
|
564
|
+
'x-exception-class' => event[:exception_class],
|
|
565
|
+
'x-handled' => event[:handled].to_s,
|
|
566
|
+
'x-gem-name' => event[:gem_name].to_s,
|
|
567
|
+
'x-lex-version' => event[:lex_version].to_s,
|
|
568
|
+
'x-component-type' => comp.to_s,
|
|
569
|
+
'x-level' => level.to_s
|
|
569
570
|
}
|
|
571
|
+
append_legion_version_header(headers)
|
|
570
572
|
headers['x-task-id'] = event[:task_id].to_s if event[:task_id]
|
|
571
573
|
headers['x-conversation-id'] = event[:conversation_id].to_s if event[:conversation_id]
|
|
572
574
|
headers['x-chain-id'] = event[:chain_id].to_s if event[:chain_id]
|
|
573
575
|
headers['x-user'] = event[:user].to_s if event[:user]
|
|
576
|
+
append_identity_headers(headers)
|
|
574
577
|
headers
|
|
575
578
|
end
|
|
576
579
|
|
|
580
|
+
def append_identity_headers(headers)
|
|
581
|
+
return unless defined?(Legion::Identity::Process)
|
|
582
|
+
return if Legion::Identity::Process.respond_to?(:resolved?) && !Legion::Identity::Process.resolved?
|
|
583
|
+
|
|
584
|
+
id = identity_hash
|
|
585
|
+
append_optional_header(headers, 'x-legion-identity-canonical-name', id[:canonical_name])
|
|
586
|
+
append_optional_header(headers, 'x-legion-identity-trust', id[:trust])
|
|
587
|
+
append_optional_header(headers, 'x-legion-identity-id', id[:id])
|
|
588
|
+
append_optional_header(headers, 'x-legion-identity-kind', id[:kind])
|
|
589
|
+
append_optional_header(headers, 'x-legion-identity-mode', id[:mode])
|
|
590
|
+
append_optional_header(headers, 'x-legion-identity-source', id[:source])
|
|
591
|
+
headers['x-legion-identity-db-principal-id'] = id[:db_principal_id] if id[:db_principal_id]
|
|
592
|
+
headers['x-legion-identity-db-identity-id'] = id[:db_identity_id] if id[:db_identity_id]
|
|
593
|
+
rescue StandardError
|
|
594
|
+
nil
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
def append_optional_header(headers, key, value)
|
|
598
|
+
return if value.nil?
|
|
599
|
+
return if value.respond_to?(:empty?) && value.empty?
|
|
600
|
+
|
|
601
|
+
headers[key] = value.to_s
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
def append_legion_version_header(headers)
|
|
605
|
+
append_optional_header(headers, 'x-legion-version', Legion::VERSION) if defined?(Legion::VERSION)
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
def identity_hash
|
|
609
|
+
process = Legion::Identity::Process
|
|
610
|
+
return process.identity_hash if process.respond_to?(:identity_hash)
|
|
611
|
+
|
|
612
|
+
{
|
|
613
|
+
canonical_name: identity_value(process, :canonical_name),
|
|
614
|
+
id: identity_value(process, :id),
|
|
615
|
+
kind: identity_value(process, :kind),
|
|
616
|
+
mode: identity_value(process, :mode),
|
|
617
|
+
source: identity_value(process, :source),
|
|
618
|
+
trust: identity_value(process, :trust)
|
|
619
|
+
}
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
def identity_value(process, method_name)
|
|
623
|
+
process.public_send(method_name) if process.respond_to?(method_name)
|
|
624
|
+
end
|
|
625
|
+
|
|
577
626
|
def build_exception_properties(event, level)
|
|
578
627
|
{
|
|
579
628
|
content_type: 'application/json',
|
|
@@ -270,6 +270,48 @@ module Legion
|
|
|
270
270
|
false
|
|
271
271
|
end
|
|
272
272
|
|
|
273
|
+
def build_log_headers(event, component, level)
|
|
274
|
+
headers = {
|
|
275
|
+
'legion_protocol_version' => '2.0',
|
|
276
|
+
'x-component-type' => component.to_s,
|
|
277
|
+
'x-level' => level.to_s
|
|
278
|
+
}
|
|
279
|
+
append_legion_version_header(headers)
|
|
280
|
+
append_optional_header(headers, 'x-lex', event[:lex])
|
|
281
|
+
append_optional_header(headers, 'x-node', event[:node])
|
|
282
|
+
append_identity_headers(headers)
|
|
283
|
+
headers
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def build_log_properties(level)
|
|
287
|
+
{
|
|
288
|
+
content_type: 'application/json',
|
|
289
|
+
message_id: SecureRandom.uuid,
|
|
290
|
+
timestamp: Time.now.to_i,
|
|
291
|
+
app_id: 'legionio',
|
|
292
|
+
type: 'log_event',
|
|
293
|
+
priority: EXCEPTION_PRIORITY[level] || 0,
|
|
294
|
+
delivery_mode: 2
|
|
295
|
+
}
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def append_identity_headers(headers)
|
|
299
|
+
return unless defined?(Legion::Identity::Process)
|
|
300
|
+
return if Legion::Identity::Process.respond_to?(:resolved?) && !Legion::Identity::Process.resolved?
|
|
301
|
+
|
|
302
|
+
id = identity_hash
|
|
303
|
+
append_optional_header(headers, 'x-legion-identity-canonical-name', id[:canonical_name])
|
|
304
|
+
append_optional_header(headers, 'x-legion-identity-trust', id[:trust])
|
|
305
|
+
append_optional_header(headers, 'x-legion-identity-id', id[:id])
|
|
306
|
+
append_optional_header(headers, 'x-legion-identity-kind', id[:kind])
|
|
307
|
+
append_optional_header(headers, 'x-legion-identity-mode', id[:mode])
|
|
308
|
+
append_optional_header(headers, 'x-legion-identity-source', id[:source])
|
|
309
|
+
headers['x-legion-identity-db-principal-id'] = id[:db_principal_id] if id[:db_principal_id]
|
|
310
|
+
headers['x-legion-identity-db-identity-id'] = id[:db_identity_id] if id[:db_identity_id]
|
|
311
|
+
rescue StandardError
|
|
312
|
+
nil
|
|
313
|
+
end
|
|
314
|
+
|
|
273
315
|
def publish_exception_event(event, level)
|
|
274
316
|
lex_name = event[:lex] || 'core'
|
|
275
317
|
comp = event[:component_type] || :unknown
|
|
@@ -281,17 +323,20 @@ module Legion
|
|
|
281
323
|
|
|
282
324
|
def build_exception_headers(event, comp, level)
|
|
283
325
|
headers = {
|
|
284
|
-
'
|
|
285
|
-
'x-
|
|
286
|
-
'x-
|
|
287
|
-
'x-
|
|
288
|
-
'x-
|
|
289
|
-
'x-
|
|
290
|
-
'x-
|
|
326
|
+
'legion_protocol_version' => '2.0',
|
|
327
|
+
'x-error-fingerprint' => event[:error_fingerprint],
|
|
328
|
+
'x-exception-class' => event[:exception_class],
|
|
329
|
+
'x-handled' => event[:handled].to_s,
|
|
330
|
+
'x-gem-name' => event[:gem_name].to_s,
|
|
331
|
+
'x-lex-version' => event[:lex_version].to_s,
|
|
332
|
+
'x-component-type' => comp.to_s,
|
|
333
|
+
'x-level' => level.to_s
|
|
291
334
|
}
|
|
335
|
+
append_legion_version_header(headers)
|
|
292
336
|
append_optional_header(headers, 'x-task-id', event[:task_id])
|
|
293
337
|
append_optional_header(headers, 'x-conversation-id', event[:conversation_id])
|
|
294
338
|
append_optional_header(headers, 'x-user', event[:user])
|
|
339
|
+
append_identity_headers(headers)
|
|
295
340
|
headers
|
|
296
341
|
end
|
|
297
342
|
|
|
@@ -302,6 +347,28 @@ module Legion
|
|
|
302
347
|
headers[key] = value.to_s
|
|
303
348
|
end
|
|
304
349
|
|
|
350
|
+
def append_legion_version_header(headers)
|
|
351
|
+
append_optional_header(headers, 'x-legion-version', Legion::VERSION) if defined?(Legion::VERSION)
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
def identity_hash
|
|
355
|
+
process = Legion::Identity::Process
|
|
356
|
+
return process.identity_hash if process.respond_to?(:identity_hash)
|
|
357
|
+
|
|
358
|
+
{
|
|
359
|
+
canonical_name: identity_value(process, :canonical_name),
|
|
360
|
+
id: identity_value(process, :id),
|
|
361
|
+
kind: identity_value(process, :kind),
|
|
362
|
+
mode: identity_value(process, :mode),
|
|
363
|
+
source: identity_value(process, :source),
|
|
364
|
+
trust: identity_value(process, :trust)
|
|
365
|
+
}
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def identity_value(process, method_name)
|
|
369
|
+
process.public_send(method_name) if process.respond_to?(method_name)
|
|
370
|
+
end
|
|
371
|
+
|
|
305
372
|
def build_exception_properties(event, level)
|
|
306
373
|
{
|
|
307
374
|
content_type: 'application/json',
|
|
@@ -347,7 +414,9 @@ module Legion
|
|
|
347
414
|
lex_name = event[:lex] || 'core'
|
|
348
415
|
component = event.dig(:caller, :file).to_s[COMPONENT_REGEX, 1] || 'unknown'
|
|
349
416
|
routing_key = "legion.logging.log.#{level}.#{lex_name}.#{component}"
|
|
350
|
-
|
|
417
|
+
headers = build_log_headers(event, component, level)
|
|
418
|
+
properties = build_log_properties(level)
|
|
419
|
+
Legion::Logging.log_writer.call(event, routing_key: routing_key, headers: headers, properties: properties)
|
|
351
420
|
Legion::Logging::Hooks.fire(level, message, event) if defined?(Legion::Logging::Hooks)
|
|
352
421
|
rescue StandardError => e
|
|
353
422
|
rk = defined?(routing_key) ? routing_key : 'unknown'
|
data/lib/legion/logging.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Legion
|
|
|
25
25
|
attr_reader :color
|
|
26
26
|
attr_writer :log_writer, :exception_writer
|
|
27
27
|
|
|
28
|
-
DEFAULT_LOG_WRITER = ->(_event, routing_key:) {}
|
|
28
|
+
DEFAULT_LOG_WRITER = ->(_event, routing_key:, headers: nil, properties: nil) {}
|
|
29
29
|
DEFAULT_EXCEPTION_WRITER = ->(_event, routing_key:, headers:, properties:) {}
|
|
30
30
|
|
|
31
31
|
def log_writer
|