class Labkit::Context
A context can be used to provide structured information on what resources GitLab is working on within a service. The currently supported keys are defined in the `KNOWN_KEYS` constant.
Values can be provided by passing a hash. If one of the values is a Proc the proc will only be called when the value is actually needed.
Multiple contexts can be nested, the nested context will inherit the values from the closest outer one. All contexts will have the same correlation id.
Usage:
Labkit::Context.with_context(user: 'username', root_namespace: -> { get_root_namespace } do |context| logger.info(context.to_h) end
Constants
- CORRELATION_ID_KEY
- HEADER_PREFIX
- KNOWN_KEYS
- LOG_KEY
- RAW_KEYS
Attributes
data[R]
Public Class Methods
correlation_id()
click to toggle source
# File lib/labkit/context.rb, line 57 def correlation_id contexts.last&.correlation_id end
current()
click to toggle source
# File lib/labkit/context.rb, line 61 def current contexts.last end
header_name(name)
click to toggle source
# File lib/labkit/context.rb, line 77 def header_name(name) HEADER_PREFIX + log_key(name).titlecase(keep_id_suffix: true).gsub(/\W/, "-") end
known_log_keys()
click to toggle source
# File lib/labkit/context.rb, line 73 def known_log_keys @known_log_keys ||= (KNOWN_KEYS.map(&method(:log_key)) + RAW_KEYS).freeze end
log_key(key)
click to toggle source
# File lib/labkit/context.rb, line 65 def log_key(key) key = key.to_s return key if RAW_KEYS.include?(key) return key if key.starts_with?("#{LOG_KEY}.") "#{LOG_KEY}.#{key}" end
new(values = {})
click to toggle source
# File lib/labkit/context.rb, line 88 def initialize(values = {}) @data = {} assign_attributes(values) end
pop(context)
click to toggle source
# File lib/labkit/context.rb, line 53 def pop(context) contexts.pop while contexts.include?(context) end
push(new_attributes = {})
click to toggle source
# File lib/labkit/context.rb, line 45 def push(new_attributes = {}) new_context = current&.merge(new_attributes) || new(new_attributes) contexts.push(new_context) new_context end
with_context(attributes = {}) { |context| ... }
click to toggle source
# File lib/labkit/context.rb, line 35 def with_context(attributes = {}) context = push(attributes) begin yield(context) ensure pop(context) end end
Private Class Methods
contexts()
click to toggle source
# File lib/labkit/context.rb, line 83 def contexts Thread.current[:labkit_contexts] ||= [] end
Public Instance Methods
correlation_id()
click to toggle source
# File lib/labkit/context.rb, line 105 def correlation_id data[CORRELATION_ID_KEY] end
get_attribute(attribute)
click to toggle source
# File lib/labkit/context.rb, line 115 def get_attribute(attribute) raw = call_or_value(data[log_key(attribute)]) call_or_value(raw) end
merge(new_attributes)
click to toggle source
# File lib/labkit/context.rb, line 94 def merge(new_attributes) new_context = self.class.new(data.dup) new_context.assign_attributes(new_attributes) new_context end
to_h()
click to toggle source
# File lib/labkit/context.rb, line 101 def to_h expand_data end
to_headers()
click to toggle source
# File lib/labkit/context.rb, line 109 def to_headers to_h.except(CORRELATION_ID_KEY).transform_keys do |key| self.class.header_name(key) end end
Protected Instance Methods
assign_attributes(attributes)
click to toggle source
# File lib/labkit/context.rb, line 123 def assign_attributes(attributes) attributes = attributes.transform_keys(&method(:log_key)) attributes = attributes.slice(*known_log_keys) data.merge!(attributes) # Remove keys that had their values set to `nil` in the new attributes data.keep_if { |_, value| value.present? } # Assign a correlation if it was missing in the first context or when # explicitly removed data[CORRELATION_ID_KEY] ||= new_id data end
Private Instance Methods
call_or_value(value)
click to toggle source
# File lib/labkit/context.rb, line 145 def call_or_value(value) value.respond_to?(:call) ? value.call : value end
expand_data()
click to toggle source
# File lib/labkit/context.rb, line 149 def expand_data data.transform_values do |value| value = call_or_value(value) value.presence end.compact end
new_id()
click to toggle source
# File lib/labkit/context.rb, line 157 def new_id SecureRandom.hex end