julewire-core 1.0.0
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 +7 -0
- data/CHANGELOG.md +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +73 -0
- data/docs/advanced-configuration.md +66 -0
- data/docs/attribute-keys.md +74 -0
- data/docs/configuration.md +327 -0
- data/docs/context-and-propagation.md +353 -0
- data/docs/contracts.md +211 -0
- data/docs/development.md +49 -0
- data/docs/extensions-and-api.md +567 -0
- data/docs/health-schema.md +104 -0
- data/docs/instrumentation-cheatsheet.md +29 -0
- data/docs/internals.md +135 -0
- data/docs/outputs-and-lifecycle.md +206 -0
- data/docs/quickstart.md +133 -0
- data/docs/record-sources.md +17 -0
- data/docs/records-and-data-policy.md +230 -0
- data/docs/security-and-wire.md +45 -0
- data/docs/tail.md +91 -0
- data/exe/julewire +6 -0
- data/julewire-core.gemspec +41 -0
- data/lib/julewire/core/cli/doctor.rb +143 -0
- data/lib/julewire/core/cli/line_helpers.rb +77 -0
- data/lib/julewire/core/cli/log_formats/console_text.rb +25 -0
- data/lib/julewire/core/cli/log_formats/core_json_decoder.rb +46 -0
- data/lib/julewire/core/cli/log_formats/core_json_encoder.rb +21 -0
- data/lib/julewire/core/cli/log_formats/record_decoder.rb +39 -0
- data/lib/julewire/core/cli/log_formats.rb +123 -0
- data/lib/julewire/core/cli/tail.rb +153 -0
- data/lib/julewire/core/cli/transcode.rb +105 -0
- data/lib/julewire/core/cli.rb +73 -0
- data/lib/julewire/core/configuration.rb +99 -0
- data/lib/julewire/core/context_store.rb +384 -0
- data/lib/julewire/core/destinations/chaos_output.rb +91 -0
- data/lib/julewire/core/destinations/collection.rb +177 -0
- data/lib/julewire/core/destinations/definition.rb +125 -0
- data/lib/julewire/core/destinations/destination.rb +268 -0
- data/lib/julewire/core/destinations/registry.rb +81 -0
- data/lib/julewire/core/destinations/sink.rb +35 -0
- data/lib/julewire/core/destinations/synchronized_output.rb +57 -0
- data/lib/julewire/core/destinations/tail_sampling.rb +321 -0
- data/lib/julewire/core/destinations/write_step.rb +119 -0
- data/lib/julewire/core/destinations.rb +33 -0
- data/lib/julewire/core/diagnostics/callback_notifier.rb +63 -0
- data/lib/julewire/core/diagnostics/doctor.rb +114 -0
- data/lib/julewire/core/diagnostics/failure_snapshot.rb +39 -0
- data/lib/julewire/core/diagnostics/health.rb +144 -0
- data/lib/julewire/core/diagnostics/integration_health_store.rb +64 -0
- data/lib/julewire/core/diagnostics/internal_records.rb +61 -0
- data/lib/julewire/core/diagnostics/invalid_severity_reporter.rb +112 -0
- data/lib/julewire/core/diagnostics/meta_observer.rb +161 -0
- data/lib/julewire/core/diagnostics/process_integration_health.rb +26 -0
- data/lib/julewire/core/diagnostics/tail/renderer.rb +36 -0
- data/lib/julewire/core/diagnostics/tail.rb +168 -0
- data/lib/julewire/core/diagnostics.rb +8 -0
- data/lib/julewire/core/error.rb +7 -0
- data/lib/julewire/core/execution/boundary.rb +106 -0
- data/lib/julewire/core/execution/handle.rb +77 -0
- data/lib/julewire/core/execution/lineage.rb +192 -0
- data/lib/julewire/core/execution/measurement_handle.rb +28 -0
- data/lib/julewire/core/execution/no_current_error.rb +9 -0
- data/lib/julewire/core/execution/scope.rb +246 -0
- data/lib/julewire/core/execution/scope_fields.rb +76 -0
- data/lib/julewire/core/execution/scope_identity.rb +71 -0
- data/lib/julewire/core/execution/scope_snapshot.rb +92 -0
- data/lib/julewire/core/execution/summary_state.rb +206 -0
- data/lib/julewire/core/execution/view.rb +56 -0
- data/lib/julewire/core/facade_methods.rb +181 -0
- data/lib/julewire/core/fields/attribute_keys.rb +54 -0
- data/lib/julewire/core/fields/attributes_proxy.rb +11 -0
- data/lib/julewire/core/fields/bags.rb +123 -0
- data/lib/julewire/core/fields/carry_proxy.rb +22 -0
- data/lib/julewire/core/fields/context_proxy.rb +11 -0
- data/lib/julewire/core/fields/field_set.rb +78 -0
- data/lib/julewire/core/fields/field_stack.rb +269 -0
- data/lib/julewire/core/fields/internal/deletion.rb +68 -0
- data/lib/julewire/core/fields/internal.rb +87 -0
- data/lib/julewire/core/fields/lookup.rb +35 -0
- data/lib/julewire/core/fields/section_proxy.rb +88 -0
- data/lib/julewire/core/fields/stack_set.rb +69 -0
- data/lib/julewire/core/fields/static_labels.rb +43 -0
- data/lib/julewire/core/fields/summary_proxy.rb +62 -0
- data/lib/julewire/core/integration/configurable.rb +52 -0
- data/lib/julewire/core/integration/destination_health.rb +43 -0
- data/lib/julewire/core/integration/event_subscriber.rb +62 -0
- data/lib/julewire/core/integration/facade.rb +131 -0
- data/lib/julewire/core/integration/fork_hooks.rb +79 -0
- data/lib/julewire/core/integration/health.rb +41 -0
- data/lib/julewire/core/integration/ivar_state.rb +38 -0
- data/lib/julewire/core/integration/lifecycle.rb +22 -0
- data/lib/julewire/core/integration/scoped.rb +34 -0
- data/lib/julewire/core/integration/settings.rb +92 -0
- data/lib/julewire/core/integration/subscriber_install.rb +39 -0
- data/lib/julewire/core/integration/subscription.rb +29 -0
- data/lib/julewire/core/integration/values.rb +192 -0
- data/lib/julewire/core/lifecycle_error.rb +7 -0
- data/lib/julewire/core/local_storage.rb +91 -0
- data/lib/julewire/core/processing/level_threshold.rb +53 -0
- data/lib/julewire/core/processing/match.rb +74 -0
- data/lib/julewire/core/processing/pipeline.rb +360 -0
- data/lib/julewire/core/processing/processor_chain.rb +69 -0
- data/lib/julewire/core/processing/processor_registry.rb +115 -0
- data/lib/julewire/core/processing/processor_wrapper.rb +44 -0
- data/lib/julewire/core/processing/record_field_transform.rb +124 -0
- data/lib/julewire/core/processing/sampling.rb +109 -0
- data/lib/julewire/core/processing.rb +41 -0
- data/lib/julewire/core/propagation/carrier.rb +93 -0
- data/lib/julewire/core/propagation.rb +50 -0
- data/lib/julewire/core/records/console_formatter.rb +24 -0
- data/lib/julewire/core/records/deconstruct.rb +19 -0
- data/lib/julewire/core/records/display_message.rb +166 -0
- data/lib/julewire/core/records/draft.rb +576 -0
- data/lib/julewire/core/records/formatter.rb +14 -0
- data/lib/julewire/core/records/lazy_emit_input.rb +99 -0
- data/lib/julewire/core/records/metadata.rb +23 -0
- data/lib/julewire/core/records/public_projection.rb +51 -0
- data/lib/julewire/core/records/raw_input.rb +41 -0
- data/lib/julewire/core/records/record.rb +175 -0
- data/lib/julewire/core/records/severity.rb +44 -0
- data/lib/julewire/core/runtime.rb +515 -0
- data/lib/julewire/core/runtime_locator.rb +20 -0
- data/lib/julewire/core/runtime_registry.rb +48 -0
- data/lib/julewire/core/runtime_state.rb +39 -0
- data/lib/julewire/core/scheduling/deadline.rb +24 -0
- data/lib/julewire/core/scheduling/deadline_scheduler.rb +207 -0
- data/lib/julewire/core/scheduling/shared_scheduler.rb +48 -0
- data/lib/julewire/core/sentinel.rb +18 -0
- data/lib/julewire/core/serialization/backtrace_limiter.rb +50 -0
- data/lib/julewire/core/serialization/bounded_transform.rb +55 -0
- data/lib/julewire/core/serialization/bounded_traversal.rb +274 -0
- data/lib/julewire/core/serialization/deep_compact_empty.rb +67 -0
- data/lib/julewire/core/serialization/deep_freeze.rb +63 -0
- data/lib/julewire/core/serialization/encoding_sanitizer.rb +40 -0
- data/lib/julewire/core/serialization/exception_shape.rb +88 -0
- data/lib/julewire/core/serialization/json_encoder.rb +69 -0
- data/lib/julewire/core/serialization/serializer.rb +233 -0
- data/lib/julewire/core/serialization/serializer_pool.rb +21 -0
- data/lib/julewire/core/serialization/text_encoder.rb +147 -0
- data/lib/julewire/core/serialization/value_copy.rb +209 -0
- data/lib/julewire/core/serialization/value_traversal.rb +150 -0
- data/lib/julewire/core/testing/chaos/catalog.rb +72 -0
- data/lib/julewire/core/testing/chaos/core_runtime.rb +120 -0
- data/lib/julewire/core/testing/chaos/destination.rb +55 -0
- data/lib/julewire/core/testing/chaos/emitter.rb +20 -0
- data/lib/julewire/core/testing/chaos/raising_output.rb +42 -0
- data/lib/julewire/core/testing/chaos.rb +80 -0
- data/lib/julewire/core/testing/contracts/component.rb +162 -0
- data/lib/julewire/core/testing/contracts/deadline_scheduler.rb +59 -0
- data/lib/julewire/core/testing/contracts/integration.rb +166 -0
- data/lib/julewire/core/testing/contracts/integration_fields.rb +36 -0
- data/lib/julewire/core/testing/contracts/record_draft.rb +37 -0
- data/lib/julewire/core/testing/contracts/runtime.rb +178 -0
- data/lib/julewire/core/testing/contracts/wire.rb +60 -0
- data/lib/julewire/core/testing/contracts.rb +24 -0
- data/lib/julewire/core/testing/coverage.rb +58 -0
- data/lib/julewire/core/testing/test_reports.rb +78 -0
- data/lib/julewire/core/testing.rb +122 -0
- data/lib/julewire/core/validation.rb +69 -0
- data/lib/julewire/core/version.rb +7 -0
- data/lib/julewire/core.rb +80 -0
- data/lib/julewire/error.rb +5 -0
- data/lib/julewire-core.rb +3 -0
- metadata +237 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Julewire
|
|
4
|
+
module Core
|
|
5
|
+
module Records
|
|
6
|
+
class PublicProjection
|
|
7
|
+
include Enumerable
|
|
8
|
+
|
|
9
|
+
INTERNAL_KEYS = Fields::Bags.hidden_output_sections
|
|
10
|
+
INTERNAL_EXECUTION_KEYS = %i[
|
|
11
|
+
ancestors
|
|
12
|
+
ancestors_truncated
|
|
13
|
+
depth
|
|
14
|
+
parent
|
|
15
|
+
root
|
|
16
|
+
].freeze
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
def public_execution(value)
|
|
20
|
+
return value unless INTERNAL_EXECUTION_KEYS.any? { value.key?(it) }
|
|
21
|
+
|
|
22
|
+
value.except(*INTERNAL_EXECUTION_KEYS)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(record)
|
|
27
|
+
Record.validate_normalized!(record)
|
|
28
|
+
@record = record
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def each
|
|
32
|
+
return enum_for(:each) unless block_given?
|
|
33
|
+
|
|
34
|
+
@record.each do |key, value|
|
|
35
|
+
next if INTERNAL_KEYS.include?(key)
|
|
36
|
+
|
|
37
|
+
yield key, output_value(key, value)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def output_value(key, value)
|
|
44
|
+
return self.class.public_execution(value) if key == :execution && value.is_a?(Hash)
|
|
45
|
+
|
|
46
|
+
value
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Julewire
|
|
4
|
+
module Core
|
|
5
|
+
module Records
|
|
6
|
+
module RawInput
|
|
7
|
+
# Reads user-supplied emit hashes before draft normalization.
|
|
8
|
+
SEVERITY_KEYS = [:severity, "severity"].freeze
|
|
9
|
+
SEVERITY_KEY = SEVERITY_KEYS.fetch(0)
|
|
10
|
+
SEVERITY_STRING_KEY = SEVERITY_KEYS.fetch(1)
|
|
11
|
+
private_constant :SEVERITY_KEYS, :SEVERITY_KEY, :SEVERITY_STRING_KEY
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def explicit_severity?(input)
|
|
15
|
+
hash_input?(input) && (input.key?(SEVERITY_KEY) || input.key?(SEVERITY_STRING_KEY))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def severity_key?(key)
|
|
19
|
+
SEVERITY_KEYS.include?(key)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def without_severity_keys(input)
|
|
23
|
+
input.except(*SEVERITY_KEYS)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def value(input, key, default: nil)
|
|
27
|
+
return default unless hash_input?(input)
|
|
28
|
+
return input[key] if input.key?(key)
|
|
29
|
+
return input[key.to_s] if input.key?(key.to_s)
|
|
30
|
+
|
|
31
|
+
default
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def hash_input?(input)
|
|
35
|
+
input.is_a?(Hash) || LazyEmitInput.input?(input)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "time"
|
|
4
|
+
|
|
5
|
+
module Julewire
|
|
6
|
+
module Core
|
|
7
|
+
module Records
|
|
8
|
+
# @api extension
|
|
9
|
+
class Record
|
|
10
|
+
include Enumerable
|
|
11
|
+
include Deconstruct
|
|
12
|
+
|
|
13
|
+
KINDS = {
|
|
14
|
+
"point" => :point,
|
|
15
|
+
"summary" => :summary
|
|
16
|
+
}.freeze
|
|
17
|
+
HASH_SECTIONS = Fields::Bags.record_hash_sections
|
|
18
|
+
REQUIRED_KEYS = Fields::Bags.required_record_keys
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def from_normalized_hash(record, lineage: nil)
|
|
22
|
+
if record.is_a?(Hash)
|
|
23
|
+
lineage ||= Execution::Lineage.from_execution_hash(record[:execution])
|
|
24
|
+
record = record.merge(execution: Execution::Lineage.clean_lazy_relationship_hash(record[:execution]))
|
|
25
|
+
end
|
|
26
|
+
validate_normalized_hash!(record)
|
|
27
|
+
new(snapshot_hash(record), lineage: lineage)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def from_owned_hash(record, lineage: nil, trust_frozen: false)
|
|
31
|
+
if record.is_a?(Hash)
|
|
32
|
+
lineage ||= Execution::Lineage.from_execution_hash(record.fetch(:execution))
|
|
33
|
+
execution = Execution::Lineage.clean_lazy_relationship_hash(record.fetch(:execution))
|
|
34
|
+
record = record.frozen? ? record.merge(execution: execution) : replace_execution(record, execution)
|
|
35
|
+
end
|
|
36
|
+
validate_normalized_hash!(record)
|
|
37
|
+
new(Serialization::DeepFreeze.call(record, trust_frozen: trust_frozen), lineage: lineage)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def validate_normalized!(record)
|
|
41
|
+
return record if record.is_a?(self)
|
|
42
|
+
|
|
43
|
+
raise TypeError, "expected Julewire::Record"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def validate_normalized_hash!(record)
|
|
47
|
+
validate_hash!(record)
|
|
48
|
+
record
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def replace_execution(record, execution)
|
|
54
|
+
record[:execution] = execution
|
|
55
|
+
record
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def validate_hash!(record)
|
|
59
|
+
raise TypeError, "record must be a normalized Hash" unless record.is_a?(Hash)
|
|
60
|
+
|
|
61
|
+
validate_symbol_keys!(record)
|
|
62
|
+
|
|
63
|
+
validate_required_keys!(record)
|
|
64
|
+
validate_known_keys!(record)
|
|
65
|
+
|
|
66
|
+
validate_kind!(record.fetch(:kind))
|
|
67
|
+
validate_severity!(record.fetch(:severity))
|
|
68
|
+
validate_hash_sections!(record)
|
|
69
|
+
validate_error!(record.fetch(:error))
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def validate_symbol_keys!(record)
|
|
73
|
+
record.each_key do |key|
|
|
74
|
+
raise TypeError, "record must not use string keys" if key.is_a?(String)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def validate_required_keys!(record)
|
|
79
|
+
missing = nil
|
|
80
|
+
REQUIRED_KEYS.each do |key|
|
|
81
|
+
next if record.key?(key)
|
|
82
|
+
|
|
83
|
+
(missing ||= []) << key
|
|
84
|
+
end
|
|
85
|
+
raise TypeError, "record must be complete (missing: #{missing.join(", ")})" if missing
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def validate_known_keys!(record)
|
|
89
|
+
unknown = nil
|
|
90
|
+
record.each_key do |key|
|
|
91
|
+
next if REQUIRED_KEYS.include?(key)
|
|
92
|
+
|
|
93
|
+
(unknown ||= []) << key
|
|
94
|
+
end
|
|
95
|
+
return unless unknown
|
|
96
|
+
|
|
97
|
+
raise TypeError, "record has unknown top-level keys: #{unknown.join(", ")}"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def validate_kind!(value)
|
|
101
|
+
return if KINDS.value?(value)
|
|
102
|
+
|
|
103
|
+
raise TypeError, "record kind must be :point or :summary"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def validate_severity!(value)
|
|
107
|
+
return if Severity::VALUES.include?(value)
|
|
108
|
+
|
|
109
|
+
raise TypeError, "record severity must be one of: #{Severity::VALUES.join(", ")}"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def validate_hash_sections!(record)
|
|
113
|
+
HASH_SECTIONS.each do |section|
|
|
114
|
+
next if record.fetch(section).is_a?(Hash)
|
|
115
|
+
|
|
116
|
+
raise TypeError, "record #{section} must be a Hash"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def validate_error!(value)
|
|
121
|
+
return if value.nil? || value.is_a?(Hash)
|
|
122
|
+
|
|
123
|
+
raise TypeError, "record error must be nil or a Hash"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def snapshot_hash(record)
|
|
127
|
+
Serialization::ValueCopy.call(
|
|
128
|
+
record,
|
|
129
|
+
freeze_values: true
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
attr_reader :lineage
|
|
135
|
+
|
|
136
|
+
def initialize(data, lineage: nil)
|
|
137
|
+
@data = data
|
|
138
|
+
@lineage = (lineage || Execution::Lineage.from_execution_hash(fetch(:execution))).freeze
|
|
139
|
+
freeze
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def [](key) = @data[key]
|
|
143
|
+
|
|
144
|
+
def fetch(...) = @data.fetch(...)
|
|
145
|
+
|
|
146
|
+
def dig(...) = @data.dig(...)
|
|
147
|
+
|
|
148
|
+
def key?(key) = @data.key?(key)
|
|
149
|
+
|
|
150
|
+
def each(&) = @data.each(&)
|
|
151
|
+
|
|
152
|
+
def to_h = Fields::FieldSet.deep_dup(@data)
|
|
153
|
+
|
|
154
|
+
# @api internal
|
|
155
|
+
def serializable_data = @data
|
|
156
|
+
|
|
157
|
+
REQUIRED_KEYS.each do |key|
|
|
158
|
+
define_method(key) { @data[key] }
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def ==(other)
|
|
162
|
+
other.instance_of?(Record) && @data == other.serializable_data
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def eql?(other)
|
|
166
|
+
other.instance_of?(Record) && @data.eql?(other.serializable_data)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def hash = @data.hash
|
|
170
|
+
|
|
171
|
+
def inspect = "#<#{self.class} #{@data}>"
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# shareable_constant_value: literal
|
|
3
|
+
|
|
4
|
+
module Julewire
|
|
5
|
+
module Core
|
|
6
|
+
module Records
|
|
7
|
+
module Severity
|
|
8
|
+
VALUES = %i[debug info warn error fatal unknown].freeze
|
|
9
|
+
STRING_VALUES = VALUES.to_h { [it.name, it] }.freeze
|
|
10
|
+
RANKS = VALUES.each_with_index.to_h.freeze
|
|
11
|
+
LOGGER_INTEGER_VALUES = VALUES.each_with_index.to_h.invert.freeze
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def normalize(value)
|
|
15
|
+
return value if RANKS.key?(value)
|
|
16
|
+
|
|
17
|
+
severity = severity_symbol(value)
|
|
18
|
+
return severity if RANKS.key?(severity)
|
|
19
|
+
|
|
20
|
+
raise ArgumentError, "unsupported severity: #{value.inspect}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def severity_symbol(value)
|
|
24
|
+
case value
|
|
25
|
+
when Symbol
|
|
26
|
+
value.downcase
|
|
27
|
+
when String
|
|
28
|
+
STRING_VALUES[value.downcase]
|
|
29
|
+
when Integer
|
|
30
|
+
LOGGER_INTEGER_VALUES[value]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def rank(value)
|
|
35
|
+
rank = RANKS[value]
|
|
36
|
+
return rank unless rank.nil?
|
|
37
|
+
|
|
38
|
+
RANKS.fetch(normalize(value))
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|