class KLog::LogStructure
Log Structure is flexible logger for working through a complex object graph
Attributes
Public Class Methods
Log a structure
Can handle Hash, Array, OpenStruct, Struct, DryStruct, Hash convertible custom classes
@option opts [String] :indent Indent with string, defaults to ' ' @option opts [String] :heading Log heading using logger.dynamic_heading @option opts [String] :heading_type :heading, :subheading, :section_heading @option opts [String] :line_width line width defaults to 80, but can be overridden here @option opts [String] :key_width key width defaults to 30, but can be overridden here @option opts [String] :formatter is a complex configuration for formatting different data within the structure
# File lib/k_log/log_structure.rb, line 39 def initialize(opts) @indent = opts[:indent] || ' ' @title = opts[:title] @title_type = opts[:title_type] || :heading @heading = opts[:heading] @heading_type = opts[:heading_type] || :heading puts ':heading should be :title' if opts[:heading] puts ':heading_type should be :title_type' if opts[:heading_type] @formatter = opts[:formatter] || {} @graph = parse_graph(opts[:graph] || {}) @convert_data_to = opts[:convert_data_to] || :raw # by default leave data as is @line_width = opts[:line_width] || 80 @key_width = opts[:key_width] || 30 @show_array_count = opts[:show_array_count] || false @output_as = opts[:output_as] || [:console] @output_as = [@output_as] unless @output_as.is_a?(Array) @output_file = opts[:output_file] @recursion_depth = 0 @key_format = nil @graph_path = [] @lines = [] update_indent_label end
Public Instance Methods
# File lib/k_log/log_structure.rb, line 102 def add_line(line) @lines << line end
# File lib/k_log/log_structure.rb, line 98 def add_lines(lines) @lines += lines end
# File lib/k_log/log_structure.rb, line 88 def clean_content # remove color escape codes @clean_content ||= content.gsub(/\x1B\[\d*m/, '') end
# File lib/k_log/log_structure.rb, line 93 def clean_lines # remove color escape codes lines.flat_map { |line| line.gsub(/\x1B\[\d*m/, '').split("\n") } end
# File lib/k_log/log_structure.rb, line 84 def content @content ||= lines.join("\n") end
# File lib/k_log/log_structure.rb, line 68 def l @l ||= KLog::LogUtil.new(KLog.logger) end
# File lib/k_log/log_structure.rb, line 72 def log(data) log_heading(title, title_type) if title data = convert_data(data) log_data(data) add_line(KLog::LogHelper.line(line_width)) render_output end
Private Instance Methods
convert_data_to
: :open_struct
# File lib/k_log/log_structure.rb, line 256 def convert_data(data) return KUtil.data.to_open_struct(data) if convert_data_to == :open_struct data end
format_config = @formatter if format_config.nil? && @recursion_depth.zero?
# File lib/k_log/log_structure.rb, line 110 def data_enumerator(data) return data.attributes if data.respond_to?(:attributes) data end
# File lib/k_log/log_structure.rb, line 239 def depth_down @recursion_depth = recursion_depth + 1 update_indent_label end
# File lib/k_log/log_structure.rb, line 244 def depth_up @recursion_depth = recursion_depth - 1 update_indent_label end
# File lib/k_log/log_structure.rb, line 231 def indent_in @indent = "#{@indent} " end
# File lib/k_log/log_structure.rb, line 235 def indent_out @indent = indent.chomp(' ') end
# File lib/k_log/log_structure.rb, line 173 def log_array(key, array) 'puts xmen' if graph_node.pry_at?(:before_array) items = array.clone items.select! { |item| graph_node.filter(item) } if graph_node.filter? items = items.take(graph_node.take) if graph_node.limited? items.sort!(&graph_node.sort) if graph_node.sort? 'puts xmen' if graph_node.pry_at?(:before_array_print) return if items.length.zero? && graph_node.skip_empty? log_heading(graph_node.heading, graph_node.heading_type) if graph_node.heading if primitive?(items) add_line KLog::LogHelper.kv "#{@indent_label}#{key}", items.map(&:to_s).join(', ') else table_print items, tp_columns(items) # NEED SUPPORT FOR A configured ARRAY COUNT with width and label add_line KLog::LogHelper.kv key.to_s, items.count if show_array_count end rescue StandardError => e KLog.logger.exception(e) end
# File lib/k_log/log_structure.rb, line 167 def log_child_data(value) depth_down log_data(value) depth_up end
# File lib/k_log/log_structure.rb, line 116 def log_data(data) data_enumerator(data).each_pair do |k, v| key = k.is_a?(String) ? k.to_sym : k graph_path.push(key) @graph_node = GraphNode.for(self, graph, graph_path) # l.kv 'key', "#{key.to_s.ljust(15)}#{graph_node.skip?.to_s.ljust(6)}#{@recursion_depth}" if graph_node.skip? # l.kv 'key', 'skipping...' @graph_path.pop next end 'puts xmen' if graph_node.pry_at?(:before_value) value = graph_node.transform? ? graph_node.transform(v) : v 'puts xmen' if graph_node.pry_at?(:after_value) if value.is_a?(OpenStruct) || value.respond_to?(:attributes) # l.kv 'go', 'open struct ->' 'puts xmen' if graph_node.pry_at?(:before_structure) log_structure(key, value) # l.kv 'go', 'open struct <-' elsif value.is_a?(Array) # l.kv 'go', 'array ->' log_array(key, value) # l.kv 'go', 'array <-' else # l.kv 'go', 'value ->' 'puts xmen' if graph_node.pry_at?(:before_kv) log_heading(graph_node.heading, graph_node.heading_type) if graph_node.heading add_line KLog::LogHelper.kv("#{@indent_label}#{key}", value, key_width) # l.kv 'go', 'value <-' end # l.line # @graph_node = graph.for_path(graph_path) # l.line @graph_path.pop end nil end
# File lib/k_log/log_structure.rb, line 212 def log_heading(heading, heading_type) add_lines(KLog::LogHelper.dynamic_heading(heading, size: line_width, type: heading_type)) end
# File lib/k_log/log_structure.rb, line 161 def log_structure(key, value) log_heading(graph_node.heading, graph_node.heading_type) if graph_node.heading add_line(KLog::LogHelper.green("#{@indent_label}#{key}")) log_child_data(value) end
# File lib/k_log/log_structure.rb, line 262 def parse_graph(data) if data.is_a?(Hash) transform_hash = data.each_with_object({}) do |(key, value), new_hash| new_hash[key] = if key == :columns && value.is_a?(Array) # Don't transform the table_print GEM columns definition as it must stay as a hash value else parse_graph(value) end end return OpenStruct.new(transform_hash.to_h) end return data.map { |o| parse_graph(o) } if data.is_a?(Array) return parse_graph(data.to_h) if data.respond_to?(:to_h) # hash_convertible?(data) # Some primitave type: String, True/False or an ObjectStruct data end
# File lib/k_log/log_structure.rb, line 207 def primitive?(items) item = items.first KUtil.data.basic_type?(item) end
# File lib/k_log/log_structure.rb, line 249 def render_output puts content if output_as.include?(:console) File.write(output_file, clean_content) if output_as.include?(:file) && output_file # content end
# File lib/k_log/log_structure.rb, line 199 def table_print(items, columns) io = TablePrintIo.new(self) tp.set :io, io tp items, columns tp.clear :io end
# File lib/k_log/log_structure.rb, line 216 def tp_columns(items) # Use configured array columns return graph_node.columns if graph_node.columns # Slow but complete list of keys # items.flat_map { |v| v.to_h.keys }.uniq items.first.to_h.keys end
# File lib/k_log/log_structure.rb, line 226 def update_indent_label # puts "indent_label: #{indent} - #{@recursion_depth} - #{(indent * @recursion_depth)}" @indent_label = (indent * @recursion_depth) end