Class: ClassMetrix::Utils::DebugLogger

Inherits:
Object
  • Object
show all
Defined in:
lib/class_metrix/utils/debug_logger.rb

Overview

Debug logging utility for ClassMetrix Provides safe, consistent debug output across all components

Constant Summary collapse

LEVELS =

Debug levels: :basic, :detailed, :verbose

{ basic: 1, detailed: 2, verbose: 3 }.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(component_name, debug_mode = false, level = :basic) ⇒ DebugLogger

Returns a new instance of DebugLogger.



11
12
13
14
15
# File 'lib/class_metrix/utils/debug_logger.rb', line 11

def initialize(component_name, debug_mode = false, level = :basic)
  @component_name = component_name
  @debug_mode = debug_mode
  @level = LEVELS[level] || LEVELS[:basic]
end

Instance Attribute Details

#levelObject (readonly)

Returns the value of attribute level.



152
153
154
# File 'lib/class_metrix/utils/debug_logger.rb', line 152

def level
  @level
end

Instance Method Details

#enabled?Boolean

Returns:

  • (Boolean)


148
149
150
# File 'lib/class_metrix/utils/debug_logger.rb', line 148

def enabled?
  @debug_mode
end

#log(message, level = :basic) ⇒ Object



17
18
19
20
21
# File 'lib/class_metrix/utils/debug_logger.rb', line 17

def log(message, level = :basic)
  return unless @debug_mode && LEVELS[level] <= @level

  puts "[DEBUG #{@component_name}] #{message}"
end

#log_anomaly(description) ⇒ Object



49
50
51
# File 'lib/class_metrix/utils/debug_logger.rb', line 49

def log_anomaly(description)
  log("⚠️ Anomaly: #{description}")
end

#log_decision(decision, reason, level = :basic) ⇒ Object



45
46
47
# File 'lib/class_metrix/utils/debug_logger.rb', line 45

def log_decision(decision, reason, level = :basic)
  log("Decision: #{decision} - #{reason}", level)
end

#log_hash_detection(value, index = nil, level = :detailed) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/class_metrix/utils/debug_logger.rb', line 103

def log_hash_detection(value, index = nil, level = :detailed)
  return unless @debug_mode && @level >= LEVELS[level]

  prefix = index ? "Value #{index}" : "Value"
  is_hash = value.is_a?(Hash)
  is_real_hash = value.is_a?(Hash) && value.instance_of?(Hash)

  return unless is_hash

  log("#{prefix} hash detection:")
  log("  is_a?(Hash): #{is_hash}, class == Hash: #{is_real_hash}")
  log("  respond_to?(:keys): #{value.respond_to?(:keys)}")

  if is_hash && is_real_hash
    log("  keys: #{safe_keys(value)}")
  elsif is_hash
    log_anomaly("Hash-like object (#{safe_class(value)}) but not real Hash - will be skipped")
  end
end

#log_hash_detection_summary(values) ⇒ Object

Smart hash detection summary



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/class_metrix/utils/debug_logger.rb', line 124

def log_hash_detection_summary(values)
  return unless @debug_mode

  hash_count = 0
  real_hash_count = 0
  anomaly_count = 0

  values.each do |value|
    next unless value.is_a?(Hash)

    hash_count += 1
    if value.instance_of?(Hash)
      real_hash_count += 1
    else
      anomaly_count += 1
    end
  end

  return unless hash_count.positive?

  log("Hash detection summary: #{real_hash_count} real hashes, #{anomaly_count} hash-like objects")
  log_anomaly("Found #{anomaly_count} hash-like proxy objects") if anomaly_count.positive?
end

#log_safe_operation(operation_name, level = :detailed, &block) ⇒ Object



23
24
25
26
27
28
29
30
31
# File 'lib/class_metrix/utils/debug_logger.rb', line 23

def log_safe_operation(operation_name, level = :detailed, &block)
  log("Starting #{operation_name}", level)
  result = block.call
  log("Completed #{operation_name} successfully", level)
  result
rescue StandardError => e
  log("Error in #{operation_name}: #{e.class.name}: #{e.message}")
  raise
end

#log_summary(operation, items, &block) ⇒ Object

Summary logging for groups of similar operations



34
35
36
37
38
39
40
41
42
43
# File 'lib/class_metrix/utils/debug_logger.rb', line 34

def log_summary(operation, items, &block)
  return unless @debug_mode

  if @level >= LEVELS[:detailed]
    log("#{operation} (#{items.length} items)")
    items.each_with_index { |item, i| block.call(item, i) } if block_given?
  else
    log("#{operation} (#{items.length} items)")
  end
end

#log_value_details(value, index = nil, level = :verbose) ⇒ Object



96
97
98
99
100
101
# File 'lib/class_metrix/utils/debug_logger.rb', line 96

def log_value_details(value, index = nil, level = :verbose)
  return unless @debug_mode && @level >= LEVELS[level]

  prefix = index ? "Value #{index}" : "Value"
  log("#{prefix}: #{safe_inspect(value)} (#{safe_class(value)})", level)
end

#safe_class(value) ⇒ Object



60
61
62
63
64
# File 'lib/class_metrix/utils/debug_logger.rb', line 60

def safe_class(value)
  value.class
rescue StandardError => e
  "[class failed: #{e.class.name}]"
end

#safe_inspect(value) ⇒ Object

Safe inspection methods to handle problematic objects



54
55
56
57
58
# File 'lib/class_metrix/utils/debug_logger.rb', line 54

def safe_inspect(value)
  value.inspect
rescue StandardError => e
  "[inspect failed: #{e.class.name}]"
end

#safe_keys(value) ⇒ Object



66
67
68
69
70
# File 'lib/class_metrix/utils/debug_logger.rb', line 66

def safe_keys(value)
  value.keys
rescue StandardError => e
  "[keys failed: #{e.class.name}]"
end

#safe_length(value) ⇒ Object



72
73
74
75
76
# File 'lib/class_metrix/utils/debug_logger.rb', line 72

def safe_length(value)
  value.length
rescue StandardError
  "[length failed]"
end

#safe_to_s(value) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/class_metrix/utils/debug_logger.rb', line 86

def safe_to_s(value)
  value.to_s
rescue StandardError => e
  begin
    value.class.name
  rescue StandardError => e2
    "[to_s failed: #{e.class.name}, class failed: #{e2.class.name}]"
  end
end

#safe_truncate(str, max_length) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/class_metrix/utils/debug_logger.rb', line 78

def safe_truncate(str, max_length)
  return str unless str.respond_to?(:length) && str.respond_to?(:[])

  str.length > max_length ? "#{str[0...max_length]}..." : str
rescue StandardError => e
  "[truncate failed: #{e.class.name}]"
end

#set_level(level) ⇒ Object



154
155
156
# File 'lib/class_metrix/utils/debug_logger.rb', line 154

def set_level(level)
  @level = LEVELS[level] || LEVELS[:basic]
end