Module: Labkit::Logging::FieldValidator

Defined in:
lib/labkit/logging/field_validator.rb,
lib/labkit/logging/field_validator/config.rb,
lib/labkit/logging/field_validator/registry.rb,
lib/labkit/logging/field_validator/log_interceptor.rb

Overview

Runtime validator for logging fields. Validates logged fields against standard and deprecated field lists. This validator is automatically injected in non-production environments. Offenses are collected during test runs and development.

Defined Under Namespace

Modules: Config, LogInterceptor Classes: Registry

Class Method Summary collapse

Class Method Details

.clear_offenses!Object



63
64
65
# File 'lib/labkit/logging/field_validator.rb', line 63

def clear_offenses!
  Registry.instance.clear!
end

.initialize_todo_fileObject



33
34
35
36
37
38
39
40
41
42
# File 'lib/labkit/logging/field_validator.rb', line 33

def initialize_todo_file
  Config.init_file!
  warn "Created .labkit_logging_todo.yml with skip_ci_failure enabled."
  warn ""
  warn "Next steps:"
  warn "1. Commit this file to source control"
  warn "2. Push and let CI run to generate offense logs"
  warn "3. Run: bundle exec labkit-logging fetch <project> <pipeline_id>"
  warn "4. Commit the populated todo file (skip_ci_failure will be removed automatically)"
end

.inject!Object

Inject the validator into JsonLogger



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/labkit/logging/field_validator.rb', line 21

def inject!
  return if @injected

  # If the config file does not exist, we don't inject the validator.
  # To enable field validation in a repository, a config file must exist.
  return unless Config.config_file_exists?

  ::Labkit::Logging::JsonLogger.prepend(LogInterceptor)
  Kernel.at_exit { FieldValidator.process_violations }
  @injected = true
end

.process_violationsObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/labkit/logging/field_validator.rb', line 44

def process_violations
  detected_offenses, new_offenses, removed_offenses = Registry.instance.finalize

  return if detected_offenses.empty? && new_offenses.empty? && removed_offenses.empty?

  in_ci = ENV['CI'] == 'true'

  output_ndjson(detected_offenses) if in_ci

  # Auto-remove fixed offenses (not in CI to avoid race conditions)
  handle_removed_offenses(removed_offenses) if removed_offenses.any? && !in_ci

  if ENV['LABKIT_LOGGING_TODO_UPDATE'] == 'true'
    handle_update(new_offenses)
  elsif new_offenses.any?
    handle_new_offenses(new_offenses)
  end
end