logbrew-sdk 0.1.2 → 0.1.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/README.md +334 -63
- data/examples/Makefile +5 -1
- data/examples/automatic_delivery.rb +1 -1
- data/examples/first_useful_telemetry.rb +90 -72
- data/examples/http_trace_correlation.rb +1 -0
- data/examples/issue_diagnostics.rb +55 -0
- data/examples/readme_example.rb +2 -1
- data/examples/real_user_smoke.rb +4 -2
- data/examples/sidekiq_tracing.rb +1 -1
- data/lib/logbrew/issue_diagnostics.rb +576 -0
- data/lib/logbrew/product_timeline.rb +24 -3
- data/lib/logbrew/rails.rb +105 -0
- data/lib/logbrew/rails_integration.rb +643 -0
- data/lib/logbrew/telemetry.rb +60 -0
- data/lib/logbrew/telemetry_context.rb +306 -0
- data/lib/logbrew/telemetry_context_value.rb +152 -0
- data/lib/logbrew/telemetry_resource.rb +161 -0
- data/lib/logbrew/version.rb +5 -0
- data/lib/logbrew-sdk.rb +4 -0
- data/lib/logbrew.rb +180 -48
- metadata +14 -4
data/lib/logbrew.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "digest"
|
|
3
4
|
require "json"
|
|
4
5
|
require "logger"
|
|
5
6
|
require "net/http"
|
|
@@ -8,6 +9,8 @@ require "time"
|
|
|
8
9
|
require "timeout"
|
|
9
10
|
require "uri"
|
|
10
11
|
|
|
12
|
+
require_relative "logbrew/version"
|
|
13
|
+
|
|
11
14
|
module LogBrew
|
|
12
15
|
SEVERITY_VALUES = %w[trace debug info warn warning error fatal critical].freeze
|
|
13
16
|
SEVERITY_ALIASES = {
|
|
@@ -39,6 +42,11 @@ module LogBrew
|
|
|
39
42
|
end
|
|
40
43
|
end
|
|
41
44
|
|
|
45
|
+
require_relative "logbrew/telemetry_context_value"
|
|
46
|
+
require_relative "logbrew/telemetry_resource"
|
|
47
|
+
require_relative "logbrew/telemetry_context"
|
|
48
|
+
require_relative "logbrew/telemetry"
|
|
49
|
+
|
|
42
50
|
require_relative "logbrew/event_batcher"
|
|
43
51
|
require_relative "logbrew/persistent_event_store"
|
|
44
52
|
require_relative "logbrew/bounded_event_queue"
|
|
@@ -369,6 +377,7 @@ module LogBrew
|
|
|
369
377
|
event_id_prefix: DEFAULT_EVENT_ID_PREFIX,
|
|
370
378
|
metadata: nil,
|
|
371
379
|
timestamp_provider: nil,
|
|
380
|
+
include_exception_message: true,
|
|
372
381
|
include_exception_backtrace: false,
|
|
373
382
|
on_error: nil,
|
|
374
383
|
raise_errors: false
|
|
@@ -384,10 +393,12 @@ module LogBrew
|
|
|
384
393
|
@event_id_prefix = event_id_prefix
|
|
385
394
|
@metadata = metadata || {}
|
|
386
395
|
@timestamp_provider = timestamp_provider
|
|
396
|
+
@include_exception_message = include_exception_message
|
|
387
397
|
@include_exception_backtrace = include_exception_backtrace
|
|
388
398
|
@on_error = on_error
|
|
389
399
|
@raise_errors = raise_errors
|
|
390
400
|
@next_event_number = 0
|
|
401
|
+
@event_id_mutex = Mutex.new
|
|
391
402
|
end
|
|
392
403
|
|
|
393
404
|
def call(env)
|
|
@@ -428,19 +439,21 @@ module LogBrew
|
|
|
428
439
|
end
|
|
429
440
|
|
|
430
441
|
def capture_exception_issue(env, error)
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
message: error.message,
|
|
442
|
+
attributes = IssueDiagnostics.from_exception(
|
|
443
|
+
error,
|
|
444
|
+
message: @include_exception_message ? error.message : nil,
|
|
445
|
+
mechanism_type: exception_mechanism_type,
|
|
446
|
+
handled: false,
|
|
437
447
|
metadata: exception_metadata(env, error)
|
|
438
448
|
)
|
|
449
|
+
@client.issue(next_event_id("issue"), logbrew_timestamp, attributes)
|
|
439
450
|
end
|
|
440
451
|
|
|
441
452
|
def next_event_id(kind)
|
|
442
|
-
@
|
|
443
|
-
|
|
453
|
+
@event_id_mutex.synchronize do
|
|
454
|
+
@next_event_number += 1
|
|
455
|
+
"#{@event_id_prefix}_#{kind}_#{@next_event_number}"
|
|
456
|
+
end
|
|
444
457
|
end
|
|
445
458
|
|
|
446
459
|
def logbrew_timestamp
|
|
@@ -491,12 +504,39 @@ module LogBrew
|
|
|
491
504
|
|
|
492
505
|
def exception_metadata(env, error)
|
|
493
506
|
request_metadata(env, 500).tap do |metadata|
|
|
494
|
-
|
|
495
|
-
|
|
507
|
+
exception_type = IssueDiagnostics.safe_exception_type(error)
|
|
508
|
+
frames = IssueDiagnostics.stack_frames_from_exception(error)
|
|
509
|
+
first_frame = frames.first
|
|
510
|
+
metadata["exceptionType"] = exception_type
|
|
511
|
+
metadata["errorName"] = exception_type
|
|
512
|
+
metadata["handled"] = false
|
|
513
|
+
metadata["mechanism"] = exception_mechanism_type
|
|
514
|
+
metadata["issueGroupingKey"] = exception_grouping_key(env, exception_type, first_frame)
|
|
515
|
+
metadata["issueGroupingSource"] = "exception_type_route_file"
|
|
516
|
+
unless first_frame.nil?
|
|
517
|
+
metadata["errorFrameFile"] = first_frame.fetch("filename")
|
|
518
|
+
metadata["errorFrameLine"] = first_frame.fetch("line")
|
|
519
|
+
end
|
|
520
|
+
metadata["exceptionMessage"] = error.message if @include_exception_message
|
|
496
521
|
metadata["exceptionBacktrace"] = error.backtrace.join("\n") if @include_exception_backtrace && error.backtrace
|
|
497
522
|
end
|
|
498
523
|
end
|
|
499
524
|
|
|
525
|
+
def exception_mechanism_type
|
|
526
|
+
"rack.middleware"
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def exception_grouping_prefix
|
|
530
|
+
"rack-exception"
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
def exception_grouping_key(env, exception_type, first_frame)
|
|
534
|
+
route = request_path(env)
|
|
535
|
+
frame_file = first_frame.nil? ? "" : first_frame.fetch("filename")
|
|
536
|
+
material = [exception_type, route, frame_file].join("\n")
|
|
537
|
+
"#{exception_grouping_prefix}-#{Digest::SHA256.hexdigest(material)}"
|
|
538
|
+
end
|
|
539
|
+
|
|
500
540
|
def rack_status(response)
|
|
501
541
|
return response[0].to_i if response.respond_to?(:[]) && !response[0].nil?
|
|
502
542
|
|
|
@@ -573,6 +613,7 @@ module LogBrew
|
|
|
573
613
|
event_id_prefix: DEFAULT_EVENT_ID_PREFIX,
|
|
574
614
|
metadata: nil,
|
|
575
615
|
timestamp_provider: nil,
|
|
616
|
+
include_exception_message: true,
|
|
576
617
|
include_exception_backtrace: false,
|
|
577
618
|
on_error: nil,
|
|
578
619
|
raise_errors: false
|
|
@@ -586,23 +627,36 @@ module LogBrew
|
|
|
586
627
|
@event_id_prefix = event_id_prefix
|
|
587
628
|
@metadata = metadata || {}
|
|
588
629
|
@timestamp_provider = timestamp_provider
|
|
630
|
+
@include_exception_message = include_exception_message
|
|
589
631
|
@include_exception_backtrace = include_exception_backtrace
|
|
590
632
|
@on_error = on_error
|
|
591
633
|
@raise_errors = raise_errors
|
|
592
634
|
@next_event_number = 0
|
|
635
|
+
@event_id_mutex = Mutex.new
|
|
593
636
|
end
|
|
594
637
|
|
|
595
638
|
def report(error, handled: true, severity: :error, context: nil, source: nil, **_options)
|
|
596
639
|
capture_safely do
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
640
|
+
attributes = if error.is_a?(Exception)
|
|
641
|
+
IssueDiagnostics.from_exception(
|
|
642
|
+
error,
|
|
643
|
+
title: error_title(error),
|
|
644
|
+
level: issue_level(severity),
|
|
645
|
+
message: @include_exception_message ? error_message(error) : nil,
|
|
646
|
+
mechanism_type: "rails.error_reporter",
|
|
647
|
+
handled: handled,
|
|
648
|
+
metadata: rails_metadata(error, handled, severity, context, source)
|
|
649
|
+
)
|
|
650
|
+
else
|
|
651
|
+
{
|
|
652
|
+
title: error_title(error),
|
|
653
|
+
level: issue_level(severity),
|
|
654
|
+
metadata: rails_metadata(error, handled, severity, context, source)
|
|
655
|
+
}.tap do |fallback|
|
|
656
|
+
fallback[:message] = error_message(error) if @include_exception_message
|
|
657
|
+
end
|
|
658
|
+
end
|
|
659
|
+
@client.issue(next_event_id, logbrew_timestamp, attributes)
|
|
606
660
|
flush_if_configured
|
|
607
661
|
end
|
|
608
662
|
end
|
|
@@ -629,6 +683,13 @@ module LogBrew
|
|
|
629
683
|
error.inspect
|
|
630
684
|
end
|
|
631
685
|
|
|
686
|
+
def next_event_id
|
|
687
|
+
@event_id_mutex.synchronize do
|
|
688
|
+
@next_event_number += 1
|
|
689
|
+
"#{@event_id_prefix}_#{@next_event_number}"
|
|
690
|
+
end
|
|
691
|
+
end
|
|
692
|
+
|
|
632
693
|
def issue_level(severity)
|
|
633
694
|
SEVERITY_TO_ISSUE_LEVEL.fetch(severity.to_s, "error")
|
|
634
695
|
end
|
|
@@ -654,11 +715,30 @@ module LogBrew
|
|
|
654
715
|
end
|
|
655
716
|
|
|
656
717
|
def add_exception_metadata(metadata, exception)
|
|
657
|
-
|
|
658
|
-
|
|
718
|
+
exception_type = IssueDiagnostics.safe_exception_type(exception)
|
|
719
|
+
frames = IssueDiagnostics.stack_frames_from_exception(exception)
|
|
720
|
+
first_frame = frames.first
|
|
721
|
+
metadata["exceptionType"] = exception_type
|
|
722
|
+
metadata["errorName"] = exception_type
|
|
723
|
+
metadata["handled"] = metadata.fetch("rails.handled")
|
|
724
|
+
metadata["mechanism"] = "rails.error_reporter"
|
|
725
|
+
metadata["issueGroupingKey"] = rails_error_grouping_key(exception_type, metadata, first_frame)
|
|
726
|
+
metadata["issueGroupingSource"] = "exception_type_source_file"
|
|
727
|
+
unless first_frame.nil?
|
|
728
|
+
metadata["errorFrameFile"] = first_frame.fetch("filename")
|
|
729
|
+
metadata["errorFrameLine"] = first_frame.fetch("line")
|
|
730
|
+
end
|
|
731
|
+
metadata["exceptionMessage"] = exception.message if @include_exception_message
|
|
659
732
|
metadata["exceptionBacktrace"] = exception.backtrace.join("\n") if @include_exception_backtrace && exception.backtrace
|
|
660
733
|
end
|
|
661
734
|
|
|
735
|
+
def rails_error_grouping_key(exception_type, metadata, first_frame)
|
|
736
|
+
source = metadata.fetch("rails.source", "rails")
|
|
737
|
+
frame_file = first_frame.nil? ? "" : first_frame.fetch("filename")
|
|
738
|
+
material = [exception_type, source, frame_file].join("\n")
|
|
739
|
+
"rails-exception-#{Digest::SHA256.hexdigest(material)}"
|
|
740
|
+
end
|
|
741
|
+
|
|
662
742
|
def copy_metadata(metadata)
|
|
663
743
|
metadata.each_with_object({}) do |(key, value), copied|
|
|
664
744
|
copied[key.to_s] = value if primitive_metadata_value?(value)
|
|
@@ -745,6 +825,26 @@ module LogBrew
|
|
|
745
825
|
value
|
|
746
826
|
end
|
|
747
827
|
|
|
828
|
+
def normalize_metric_description(value)
|
|
829
|
+
unless value.is_a?(String) && value.valid_encoding?
|
|
830
|
+
raise SdkError.new(
|
|
831
|
+
"validation_error",
|
|
832
|
+
"metric description must be a non-blank string of at most 1024 non-control characters"
|
|
833
|
+
)
|
|
834
|
+
end
|
|
835
|
+
normalized = value.strip
|
|
836
|
+
invalid = normalized.each_codepoint.any? do |character|
|
|
837
|
+
character <= 0x1f || (character >= 0x7f && character <= 0x9f) || character == 0x2028 || character == 0x2029
|
|
838
|
+
end
|
|
839
|
+
if normalized.empty? || normalized.each_codepoint.count > 1024 || invalid
|
|
840
|
+
raise SdkError.new(
|
|
841
|
+
"validation_error",
|
|
842
|
+
"metric description must be a non-blank string of at most 1024 non-control characters"
|
|
843
|
+
)
|
|
844
|
+
end
|
|
845
|
+
normalized
|
|
846
|
+
end
|
|
847
|
+
|
|
748
848
|
def read(attributes, key)
|
|
749
849
|
return nil unless attributes.is_a?(Hash)
|
|
750
850
|
|
|
@@ -776,12 +876,26 @@ module LogBrew
|
|
|
776
876
|
on_event_dropped: nil,
|
|
777
877
|
max_batch_size: EventBatcher::DEFAULT_MAX_SIZE,
|
|
778
878
|
max_batch_bytes: EventBatcher::DEFAULT_MAX_BYTES,
|
|
779
|
-
persistent_queue_path: nil
|
|
879
|
+
persistent_queue_path: nil,
|
|
880
|
+
context: nil,
|
|
881
|
+
capture_runtime_context: true
|
|
780
882
|
)
|
|
781
883
|
Validation.require_non_empty("api_key", api_key)
|
|
782
884
|
Validation.require_non_empty("sdk_name", sdk_name)
|
|
783
885
|
Validation.require_non_empty("sdk_version", sdk_version)
|
|
784
886
|
raise SdkError.new("validation_error", "max_retries must be non-negative") if max_retries.negative?
|
|
887
|
+
unless context.nil? || context.is_a?(TelemetryContext)
|
|
888
|
+
raise SdkError.new("validation_error", "client context must be a LogBrew::TelemetryContext")
|
|
889
|
+
end
|
|
890
|
+
unless capture_runtime_context == true || capture_runtime_context == false
|
|
891
|
+
raise SdkError.new("validation_error", "capture_runtime_context must be a boolean")
|
|
892
|
+
end
|
|
893
|
+
|
|
894
|
+
resolved_context = if capture_runtime_context
|
|
895
|
+
TelemetryContext.merge(TelemetryContext.runtime_defaults, context)
|
|
896
|
+
else
|
|
897
|
+
TelemetryContext.merge(nil, context)
|
|
898
|
+
end
|
|
785
899
|
|
|
786
900
|
new(
|
|
787
901
|
api_key: api_key,
|
|
@@ -796,7 +910,8 @@ module LogBrew
|
|
|
796
910
|
on_event_dropped: on_event_dropped,
|
|
797
911
|
max_batch_size: max_batch_size,
|
|
798
912
|
max_batch_bytes: max_batch_bytes,
|
|
799
|
-
persistent_queue_path: persistent_queue_path
|
|
913
|
+
persistent_queue_path: persistent_queue_path,
|
|
914
|
+
context: resolved_context
|
|
800
915
|
)
|
|
801
916
|
end
|
|
802
917
|
|
|
@@ -846,10 +961,12 @@ module LogBrew
|
|
|
846
961
|
on_event_dropped: nil,
|
|
847
962
|
max_batch_size: EventBatcher::DEFAULT_MAX_SIZE,
|
|
848
963
|
max_batch_bytes: EventBatcher::DEFAULT_MAX_BYTES,
|
|
849
|
-
persistent_queue_path: nil
|
|
964
|
+
persistent_queue_path: nil,
|
|
965
|
+
context: nil
|
|
850
966
|
)
|
|
851
967
|
@api_key = api_key
|
|
852
968
|
@sdk = sdk
|
|
969
|
+
@context = context
|
|
853
970
|
@max_retries = max_retries
|
|
854
971
|
@event_batcher = EventBatcher.new(sdk: sdk, max_size: max_batch_size, max_bytes: max_batch_bytes)
|
|
855
972
|
event_store = nil
|
|
@@ -940,31 +1057,31 @@ module LogBrew
|
|
|
940
1057
|
end
|
|
941
1058
|
|
|
942
1059
|
def release(id, timestamp, attributes)
|
|
943
|
-
push_event("release", id, timestamp, validate_release(attributes))
|
|
1060
|
+
push_event("release", id, timestamp, validate_release(attributes), event_context(attributes))
|
|
944
1061
|
end
|
|
945
1062
|
|
|
946
1063
|
def environment(id, timestamp, attributes)
|
|
947
|
-
push_event("environment", id, timestamp, validate_environment(attributes))
|
|
1064
|
+
push_event("environment", id, timestamp, validate_environment(attributes), event_context(attributes))
|
|
948
1065
|
end
|
|
949
1066
|
|
|
950
1067
|
def issue(id, timestamp, attributes)
|
|
951
|
-
push_event("issue", id, timestamp, validate_issue(attributes))
|
|
1068
|
+
push_event("issue", id, timestamp, validate_issue(attributes), event_context(attributes))
|
|
952
1069
|
end
|
|
953
1070
|
|
|
954
1071
|
def log(id, timestamp, attributes)
|
|
955
|
-
push_event("log", id, timestamp, validate_log(attributes))
|
|
1072
|
+
push_event("log", id, timestamp, validate_log(attributes), event_context(attributes))
|
|
956
1073
|
end
|
|
957
1074
|
|
|
958
1075
|
def span(id, timestamp, attributes)
|
|
959
|
-
push_event("span", id, timestamp, validate_span(attributes))
|
|
1076
|
+
push_event("span", id, timestamp, validate_span(attributes), event_context(attributes))
|
|
960
1077
|
end
|
|
961
1078
|
|
|
962
1079
|
def metric(id, timestamp, attributes)
|
|
963
|
-
push_event("metric", id, timestamp, validate_metric(attributes))
|
|
1080
|
+
push_event("metric", id, timestamp, validate_metric(attributes), event_context(attributes))
|
|
964
1081
|
end
|
|
965
1082
|
|
|
966
1083
|
def action(id, timestamp, attributes)
|
|
967
|
-
push_event("action", id, timestamp, validate_action(attributes))
|
|
1084
|
+
push_event("action", id, timestamp, validate_action(attributes), event_context(attributes))
|
|
968
1085
|
end
|
|
969
1086
|
|
|
970
1087
|
def flush(transport = nil)
|
|
@@ -1021,10 +1138,18 @@ module LogBrew
|
|
|
1021
1138
|
|
|
1022
1139
|
private
|
|
1023
1140
|
|
|
1024
|
-
def push_event(type, id, timestamp, attributes)
|
|
1141
|
+
def push_event(type, id, timestamp, attributes, event_context)
|
|
1025
1142
|
@automatic_delivery&.assert_process_ownership!
|
|
1026
1143
|
Validation.require_non_empty("event id", id)
|
|
1027
1144
|
Validation.require_timestamp(timestamp)
|
|
1145
|
+
ambient_context = Telemetry.current_context
|
|
1146
|
+
active_trace = defined?(LogBrew::Trace) ? LogBrew::Trace.current : nil
|
|
1147
|
+
ambient_context = TelemetryContext.with_trace(ambient_context, active_trace) unless active_trace.nil?
|
|
1148
|
+
merged_context = TelemetryContext.merge(
|
|
1149
|
+
TelemetryContext.merge(@context, ambient_context),
|
|
1150
|
+
event_context
|
|
1151
|
+
)
|
|
1152
|
+
attributes["context"] = merged_context.to_h unless merged_context.nil?
|
|
1028
1153
|
event = {
|
|
1029
1154
|
"type" => type,
|
|
1030
1155
|
"timestamp" => timestamp,
|
|
@@ -1203,20 +1328,7 @@ module LogBrew
|
|
|
1203
1328
|
end
|
|
1204
1329
|
|
|
1205
1330
|
def validate_issue(attributes)
|
|
1206
|
-
|
|
1207
|
-
level = Validation.read(attributes, "level")
|
|
1208
|
-
Validation.require_non_empty("issue title", title)
|
|
1209
|
-
level = normalize_severity("issue level", level)
|
|
1210
|
-
with_metadata(
|
|
1211
|
-
{
|
|
1212
|
-
"title" => title,
|
|
1213
|
-
"level" => level
|
|
1214
|
-
}.tap do |payload|
|
|
1215
|
-
message = Validation.read(attributes, "message")
|
|
1216
|
-
payload["message"] = message unless message.nil?
|
|
1217
|
-
end,
|
|
1218
|
-
attributes
|
|
1219
|
-
)
|
|
1331
|
+
IssueDiagnostics.validate_issue_attributes(attributes)
|
|
1220
1332
|
end
|
|
1221
1333
|
|
|
1222
1334
|
def validate_log(attributes)
|
|
@@ -1276,6 +1388,8 @@ module LogBrew
|
|
|
1276
1388
|
|
|
1277
1389
|
def validate_metric(attributes)
|
|
1278
1390
|
name = Validation.read(attributes, "name")
|
|
1391
|
+
description_present = attributes.is_a?(Hash) && (attributes.key?("description") || attributes.key?(:description))
|
|
1392
|
+
description = Validation.normalize_metric_description(Validation.read(attributes, "description")) if description_present
|
|
1279
1393
|
kind = Validation.read(attributes, "kind")
|
|
1280
1394
|
unit = Validation.read(attributes, "unit")
|
|
1281
1395
|
temporality = Validation.read(attributes, "temporality")
|
|
@@ -1291,11 +1405,12 @@ module LogBrew
|
|
|
1291
1405
|
with_metadata(
|
|
1292
1406
|
{
|
|
1293
1407
|
"name" => name,
|
|
1408
|
+
"description" => description,
|
|
1294
1409
|
"kind" => kind,
|
|
1295
1410
|
"value" => value,
|
|
1296
1411
|
"unit" => unit,
|
|
1297
1412
|
"temporality" => temporality
|
|
1298
|
-
},
|
|
1413
|
+
}.compact,
|
|
1299
1414
|
attributes
|
|
1300
1415
|
)
|
|
1301
1416
|
end
|
|
@@ -1308,6 +1423,23 @@ module LogBrew
|
|
|
1308
1423
|
with_metadata({ "name" => name, "status" => status }, attributes)
|
|
1309
1424
|
end
|
|
1310
1425
|
|
|
1426
|
+
def event_context(attributes)
|
|
1427
|
+
return nil unless attributes.is_a?(Hash)
|
|
1428
|
+
|
|
1429
|
+
string_key = attributes.key?("context")
|
|
1430
|
+
symbol_key = attributes.key?(:context)
|
|
1431
|
+
if string_key && symbol_key
|
|
1432
|
+
raise SdkError.new("validation_error", "event context must use one context field")
|
|
1433
|
+
end
|
|
1434
|
+
return nil unless string_key || symbol_key
|
|
1435
|
+
|
|
1436
|
+
value = string_key ? attributes["context"] : attributes[:context]
|
|
1437
|
+
unless value.is_a?(TelemetryContext)
|
|
1438
|
+
raise SdkError.new("validation_error", "event context must be a LogBrew::TelemetryContext")
|
|
1439
|
+
end
|
|
1440
|
+
value
|
|
1441
|
+
end
|
|
1442
|
+
|
|
1311
1443
|
def with_metadata(payload, attributes)
|
|
1312
1444
|
metadata = Validation.require_metadata(Validation.read(attributes, "metadata"))
|
|
1313
1445
|
payload["metadata"] = metadata unless metadata.nil?
|
|
@@ -1318,6 +1450,6 @@ module LogBrew
|
|
|
1318
1450
|
require_relative "logbrew/automatic_delivery"
|
|
1319
1451
|
end
|
|
1320
1452
|
|
|
1321
|
-
%w[product_timeline traceparent trace span_events operation_tracing http_client_tracing support_ticket worker_lifecycle].each do |path|
|
|
1453
|
+
%w[issue_diagnostics product_timeline traceparent trace span_events operation_tracing http_client_tracing support_ticket worker_lifecycle].each do |path|
|
|
1322
1454
|
require_relative "logbrew/#{path}"
|
|
1323
1455
|
end
|
metadata
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: logbrew-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- LogBrew
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-08-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
|
-
description: Public LogBrew Ruby SDK
|
|
14
|
-
|
|
13
|
+
description: Public LogBrew Ruby SDK with typed issue diagnostics, automatic Rails
|
|
14
|
+
request/error capture, and standard-library delivery.
|
|
15
15
|
email:
|
|
16
16
|
executables: []
|
|
17
17
|
extensions: []
|
|
@@ -22,24 +22,34 @@ files:
|
|
|
22
22
|
- examples/automatic_delivery.rb
|
|
23
23
|
- examples/first_useful_telemetry.rb
|
|
24
24
|
- examples/http_trace_correlation.rb
|
|
25
|
+
- examples/issue_diagnostics.rb
|
|
25
26
|
- examples/persistent_worker_delivery.rb
|
|
26
27
|
- examples/readme_example.rb
|
|
27
28
|
- examples/real_user_smoke.rb
|
|
28
29
|
- examples/sidekiq_tracing.rb
|
|
30
|
+
- lib/logbrew-sdk.rb
|
|
29
31
|
- lib/logbrew.rb
|
|
30
32
|
- lib/logbrew/automatic_delivery.rb
|
|
31
33
|
- lib/logbrew/bounded_event_queue.rb
|
|
32
34
|
- lib/logbrew/event_batcher.rb
|
|
33
35
|
- lib/logbrew/faraday_tracing.rb
|
|
34
36
|
- lib/logbrew/http_client_tracing.rb
|
|
37
|
+
- lib/logbrew/issue_diagnostics.rb
|
|
35
38
|
- lib/logbrew/operation_tracing.rb
|
|
36
39
|
- lib/logbrew/persistent_event_store.rb
|
|
37
40
|
- lib/logbrew/product_timeline.rb
|
|
41
|
+
- lib/logbrew/rails.rb
|
|
42
|
+
- lib/logbrew/rails_integration.rb
|
|
38
43
|
- lib/logbrew/sidekiq.rb
|
|
39
44
|
- lib/logbrew/span_events.rb
|
|
40
45
|
- lib/logbrew/support_ticket.rb
|
|
46
|
+
- lib/logbrew/telemetry.rb
|
|
47
|
+
- lib/logbrew/telemetry_context.rb
|
|
48
|
+
- lib/logbrew/telemetry_context_value.rb
|
|
49
|
+
- lib/logbrew/telemetry_resource.rb
|
|
41
50
|
- lib/logbrew/trace.rb
|
|
42
51
|
- lib/logbrew/traceparent.rb
|
|
52
|
+
- lib/logbrew/version.rb
|
|
43
53
|
- lib/logbrew/worker_lifecycle.rb
|
|
44
54
|
homepage: https://github.com/LogBrewCo/sdk
|
|
45
55
|
licenses:
|