Module: LogBrew::TelemetryContextValue
- Defined in:
- lib/logbrew/telemetry_context_value.rb
Overview
Shared validation and detachment rules for schema-v1 telemetry context.
Constant Summary collapse
- MAX_CONTEXT_STRING =
256- MAX_CONTEXT_ID =
200- MAX_TAGS =
32- MAX_TAG_KEY =
64- TAG_KEY =
/\A[A-Za-z][A-Za-z0-9_.-]*\z/.freeze
- CONTROL_CHARACTERS =
/[\u0000-\u001f\u007f-\u009f]/.freeze
- LOWER_HEX =
/\A[0-9a-f]+\z/.freeze
Class Method Summary collapse
- .deep_copy(value) ⇒ Object
- .deep_freeze(value) ⇒ Object
- .invalid(message) ⇒ Object
- .object(value, label) ⇒ Object
- .optional_id(value, label) ⇒ Object
- .optional_span_id(value, label) ⇒ Object
- .optional_string(value, label, maximum = MAX_CONTEXT_STRING) ⇒ Object
- .reject_unknown_fields(value, allowed, label) ⇒ Object
- .require_tag_count(count) ⇒ Object
- .required_id(value, label) ⇒ Object
- .required_string(value, label, maximum = MAX_CONTEXT_STRING) ⇒ Object
- .span_id(value, label) ⇒ Object
- .tag_key(value) ⇒ Object
- .trace_id(value, label = "traceId") ⇒ Object
Class Method Details
.deep_copy(value) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/logbrew/telemetry_context_value.rb', line 101 def deep_copy(value) case value when Hash value.each_with_object({}) { |(key, item), copy| copy[key.dup] = deep_copy(item) } when Array value.map { |item| deep_copy(item) } when String value.dup else value end end |
.deep_freeze(value) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/logbrew/telemetry_context_value.rb', line 114 def deep_freeze(value) case value when Hash value.each do |key, item| key.freeze deep_freeze(item) end when Array value.each { |item| deep_freeze(item) } end value.freeze end |
.invalid(message) ⇒ Object
127 128 129 |
# File 'lib/logbrew/telemetry_context_value.rb', line 127 def invalid() SdkError.new("validation_error", ) end |
.object(value, label) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/logbrew/telemetry_context_value.rb', line 16 def object(value, label) raise invalid("#{label} must be an object") unless value.is_a?(Hash) value.each_with_object({}) do |(key, item), normalized| unless key.is_a?(String) || key.is_a?(Symbol) raise invalid("#{label} keys must be strings") end normalized_key = key.to_s if normalized.key?(normalized_key) raise invalid("#{label} contains duplicate field #{normalized_key}") end normalized[normalized_key] = item end end |
.optional_id(value, label) ⇒ Object
64 65 66 67 68 |
# File 'lib/logbrew/telemetry_context_value.rb', line 64 def optional_id(value, label) return nil if value.nil? required_id(value, label) end |
.optional_span_id(value, label) ⇒ Object
78 79 80 81 82 |
# File 'lib/logbrew/telemetry_context_value.rb', line 78 def optional_span_id(value, label) return nil if value.nil? span_id(value, label) end |
.optional_string(value, label, maximum = MAX_CONTEXT_STRING) ⇒ Object
54 55 56 57 58 |
# File 'lib/logbrew/telemetry_context_value.rb', line 54 def optional_string(value, label, maximum = MAX_CONTEXT_STRING) return nil if value.nil? required_string(value, label, maximum) end |
.reject_unknown_fields(value, allowed, label) ⇒ Object
32 33 34 35 36 37 |
# File 'lib/logbrew/telemetry_context_value.rb', line 32 def reject_unknown_fields(value, allowed, label) unknown = value.keys - allowed return if unknown.empty? raise invalid("#{label} has unknown field #{unknown.sort.first}") end |
.require_tag_count(count) ⇒ Object
95 96 97 98 99 |
# File 'lib/logbrew/telemetry_context_value.rb', line 95 def require_tag_count(count) unless count.between?(1, MAX_TAGS) raise invalid("telemetry context must contain 1 to at most #{MAX_TAGS} tags") end end |
.required_id(value, label) ⇒ Object
60 61 62 |
# File 'lib/logbrew/telemetry_context_value.rb', line 60 def required_id(value, label) required_string(value, label, MAX_CONTEXT_ID) end |
.required_string(value, label, maximum = MAX_CONTEXT_STRING) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/logbrew/telemetry_context_value.rb', line 39 def required_string(value, label, maximum = MAX_CONTEXT_STRING) raise invalid("#{label} must be a string") unless value.is_a?(String) normalized = utf8_string(value, label).strip raise invalid("#{label} must not be empty") if normalized.empty? || !normalized.match?(/\S/) if normalized.length > maximum raise invalid("#{label} must contain at most #{maximum} characters") end if normalized.match?(CONTROL_CHARACTERS) raise invalid("#{label} must not contain control characters") end normalized end |
.span_id(value, label) ⇒ Object
74 75 76 |
# File 'lib/logbrew/telemetry_context_value.rb', line 74 def span_id(value, label) normalized_hex_id(value, 16, "0" * 16, label) end |
.tag_key(value) ⇒ Object
84 85 86 87 88 89 90 91 92 93 |
# File 'lib/logbrew/telemetry_context_value.rb', line 84 def tag_key(value) raise invalid("tag key must be a string") unless value.is_a?(String) normalized = utf8_string(value, "tag key") unless normalized.length <= MAX_TAG_KEY && normalized.match?(TAG_KEY) raise invalid("tag key #{normalized} must start with a letter and contain only letters, numbers, _, ., or -") end normalized end |
.trace_id(value, label = "traceId") ⇒ Object
70 71 72 |
# File 'lib/logbrew/telemetry_context_value.rb', line 70 def trace_id(value, label = "traceId") normalized_hex_id(value, 32, "0" * 32, label) end |