k_log 0.0.20 → 0.0.31

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5ce4190206d26b326f0295241cf8c087c3c56bfc0bb11b4e8dbb6f8d401447f
4
- data.tar.gz: 3ed6be809644377525a00658e5f010b32e3979bb031e4d10037a4393c67c47d1
3
+ metadata.gz: f1791ddbcf6769e1e472c511dd52b4f1d4ddda87c9fba038f8abe17e24bff934
4
+ data.tar.gz: 511ec8d2758769bdc54822f96390f15764e3055f71d96f84db0085b3a8c70a60
5
5
  SHA512:
6
- metadata.gz: 133ea34980568cb38ecf8e3b1d9efdf4aa292005b5a67ad9f8282da82200bf42611bb95dfe25bc2f1ee78b7b845cf9af4e65fbf136e0f73867cb07e092699419
7
- data.tar.gz: 3606bca839c257f596f6ca6a0fb1e1b6cda1da58c3735ce0857236523c47e8ca13c0ce656936239ea0ffb2ce1c435e62dbd6b68b9f67a3677f1239c9ff0038ca
6
+ metadata.gz: 680b73d54409a72018e0cbf1ea07df828a86713654afd98fa78739e0b83a8e685eefa14ef56a181529404144b4706c902644a5f96dbf31f79af2abaf893e38e2
7
+ data.tar.gz: 4e855ad037c22b16a3a6ef8bfbbec6b5b3dfee33a35078d4b2f29cc8a2b62ec9d06ae0ea332c8b58f73d19439e5a5e690d18afb62ec4ff3dee4d39d7dc6b27e0
data/.rubocop.yml CHANGED
@@ -40,6 +40,8 @@ Layout/LineLength:
40
40
  # Ignores annotate output
41
41
  IgnoredPatterns: ['\A# \*\*']
42
42
  IgnoreCopDirectives: true
43
+ Exclude:
44
+ - "**/spec/**/*"
43
45
 
44
46
  Lint/UnusedMethodArgument:
45
47
  AllowUnusedKeywordArguments: true
@@ -61,6 +63,16 @@ Metrics/ClassLength:
61
63
  Metrics/ModuleLength:
62
64
  Exclude:
63
65
  - "**/spec/**/*"
66
+ Metrics/CyclomaticComplexity:
67
+ Exclude:
68
+ - "lib/k_log/log_structure.rb"
69
+ Metrics/PerceivedComplexity:
70
+ Exclude:
71
+ - "lib/k_log/log_structure.rb"
72
+ Metrics/AbcSize:
73
+ Exclude:
74
+ - "lib/k_log/log_structure.rb"
75
+
64
76
  Naming/MemoizedInstanceVariableName:
65
77
  Enabled: false
66
78
  Naming/VariableNumber:
data/Gemfile CHANGED
@@ -2,23 +2,18 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- # Specify your gem's dependencies in handlebars_helpers.gemspec
6
5
  gemspec
7
6
 
8
- # group :development do
9
- # # Currently conflicts with GitHub actions and so I remove it on push
10
- # # pry on steroids
11
- # gem 'jazz_fingers'
12
- # gem 'pry-coolline', github: 'owst/pry-coolline', branch: 'support_new_pry_config_api'
13
- # end
14
-
15
7
  group :development, :test do
8
+ gem 'dry-struct', '~> 1'
9
+
16
10
  gem 'guard-bundler'
17
11
  gem 'guard-rspec'
18
12
  gem 'guard-rubocop'
19
13
  gem 'rake', '~> 12.0'
20
14
  gem 'rake-compiler', require: false
21
15
  gem 'rspec', '~> 3.0'
16
+ gem 'rspec-collection_matchers'
22
17
  gem 'rubocop'
23
18
  gem 'rubocop-rake', require: false
24
19
  gem 'rubocop-rspec', require: false
@@ -20,8 +20,10 @@ module KLog
20
20
 
21
21
  msg = msg.is_a?(String) ? msg : msg.inspect
22
22
 
23
+ # "%<time>s %<severity>s %<message>s\n", {
24
+
23
25
  format(
24
- "%<time>s %<severity>s %<message>s\n", {
26
+ "%<severity>s %<message>s\n", {
25
27
  time: Time.now.strftime('%d|%H:%M:%S'),
26
28
  severity: severity_value,
27
29
  message: msg
@@ -43,6 +43,14 @@ module KLog
43
43
  green(character * size)
44
44
  end
45
45
 
46
+ def self.dynamic_heading(heading, size: 70, type: :heading)
47
+ return heading(heading, size) if type == :heading
48
+ return subheading(heading, size) if type == :subheading
49
+ return [section_heading(heading, size)] if %i[section_heading section].include?(type)
50
+
51
+ []
52
+ end
53
+
46
54
  def self.heading(heading, size = 70)
47
55
  line = line(size)
48
56
 
@@ -69,7 +77,8 @@ module KLog
69
77
  def self.section_heading(heading, size = 70)
70
78
  brace_open = green('[ ')
71
79
  brace_close = green(' ]')
72
- line = line(size - heading.length - 4, '-')
80
+ line_length = size - heading.length - 4
81
+ line = line_length.positive? ? line(line_length, '-') : ''
73
82
 
74
83
  # It is important that you set the colour after you have calculated the size
75
84
  "#{brace_open}#{heading}#{brace_close}#{green(line)}"
@@ -106,8 +115,60 @@ module KLog
106
115
  end
107
116
  # rubocop:enable Metrics/CyclomaticComplexity
108
117
 
118
+ def self.red(value)
119
+ "\033[31m#{value}\033[0m"
120
+ end
121
+
109
122
  def self.green(value)
110
123
  "\033[32m#{value}\033[0m"
111
124
  end
125
+
126
+ def self.yellow(value)
127
+ "\033[33m#{value}\033[0m"
128
+ end
129
+
130
+ def self.blue(value)
131
+ "\033[34m#{value}\033[0m"
132
+ end
133
+
134
+ def self.purple(value)
135
+ "\033[35m#{value}\033[0m"
136
+ end
137
+
138
+ def self.cyan(value)
139
+ "\033[36m#{value}\033[0m"
140
+ end
141
+
142
+ def self.grey(value)
143
+ "\033[37m#{value}\033[0m"
144
+ end
145
+
146
+ def self.bg_red(value)
147
+ "\033[41m#{value}\033[0m"
148
+ end
149
+
150
+ def self.bg_green(value)
151
+ "\033[42m#{value}\033[0m"
152
+ end
153
+
154
+ def self.bg_yellow(value)
155
+ "\033[43m#{value}\033[0m"
156
+ end
157
+
158
+ def self.bg_blue(value)
159
+ "\033[44m#{value}\033[0m"
160
+ end
161
+
162
+ def self.bg_purple(value)
163
+ "\033[45m#{value}\033[0m"
164
+ end
165
+
166
+ def self.bg_cyan(value)
167
+ "\033[46m#{value}\033[0m"
168
+ end
169
+
170
+ def self.bg_grey(value)
171
+ "\033[47m#{value}\033[0m"
172
+ end
112
173
  end
113
174
  end
@@ -5,15 +5,26 @@ require 'k_util'
5
5
  module KLog
6
6
  # Log Structure is flexible logger for working through a complex object graph
7
7
  class LogStructure
8
- attr_accessor :indent
9
- attr_accessor :heading
10
- attr_accessor :heading_type
11
- attr_accessor :line_width
12
- attr_accessor :formatter
13
- attr_accessor :skip_array
14
-
15
- attr_accessor :recursion_depth
16
- attr_accessor :key_format
8
+ attr_reader :indent
9
+ attr_reader :title
10
+ attr_reader :title_type
11
+ attr_reader :heading
12
+ attr_reader :heading_type
13
+ attr_reader :line_width
14
+ attr_reader :key_width
15
+ attr_reader :show_array_count
16
+ attr_reader :graph
17
+ attr_reader :formatter
18
+ attr_reader :convert_data_to
19
+
20
+ attr_reader :recursion_depth
21
+ attr_reader :key_format
22
+ attr_reader :graph_path
23
+ attr_reader :graph_node
24
+
25
+ attr_reader :lines
26
+ attr_reader :output_as
27
+ attr_reader :output_file
17
28
 
18
29
  # Log a structure
19
30
  #
@@ -23,71 +34,135 @@ module KLog
23
34
  # @option opts [String] :heading Log heading using logger.dynamic_heading
24
35
  # @option opts [String] :heading_type :heading, :subheading, :section_heading
25
36
  # @option opts [String] :line_width line width defaults to 80, but can be overridden here
37
+ # @option opts [String] :key_width key width defaults to 30, but can be overridden here
26
38
  # @option opts [String] :formatter is a complex configuration for formatting different data within the structure
39
+ # @option opts [Symbol] :convert_data_to (:raw, open_struct)
27
40
  def initialize(opts)
28
41
  @indent = opts[:indent] || ' '
42
+ @title = opts[:title]
43
+ @title_type = opts[:title_type] || :heading
44
+
29
45
  @heading = opts[:heading]
30
46
  @heading_type = opts[:heading_type] || :heading
31
- @formatter = opts[:formatter] || {}
47
+ puts ':heading should be :title' if opts[:heading]
48
+ puts ':heading_type should be :title_type' if opts[:heading_type]
49
+
50
+ @formatter = opts[:formatter] || {}
51
+ @graph = parse_graph(opts[:graph] || {})
52
+ @convert_data_to = opts[:convert_data_to] || :raw # by default leave data as is
32
53
 
33
- @line_width = opts[:line_width] || 80
34
- # @skip_array = opts[:skip_array]
54
+ @line_width = opts[:line_width] || 80
55
+ @key_width = opts[:key_width] || 30
56
+ @show_array_count = opts[:show_array_count] || false
57
+ @output_as = opts[:output_as] || [:console]
58
+ @output_as = [@output_as] unless @output_as.is_a?(Array)
59
+ @output_file = opts[:output_file]
35
60
 
36
61
  @recursion_depth = 0
37
62
  @key_format = nil
63
+ @graph_path = []
64
+ @lines = []
65
+
38
66
  update_indent_label
39
67
  end
40
68
 
69
+ def l
70
+ @l ||= KLog::LogUtil.new(KLog.logger)
71
+ end
72
+
41
73
  def log(data)
42
- log_heading(heading, heading_type)
74
+ log_heading(title, title_type) if title
43
75
 
44
- open_struct_data = KUtil.data.to_open_struct(data)
76
+ data = convert_data(data)
45
77
 
46
- log_data(open_struct_data)
78
+ log_data(data)
79
+
80
+ add_line(KLog::LogHelper.line(line_width))
81
+
82
+ render_output
83
+ end
84
+
85
+ def content
86
+ @content ||= lines.join("\n")
87
+ end
47
88
 
48
- KLog.logger.line(line_width)
89
+ def clean_content
90
+ # remove color escape codes
91
+ @clean_content ||= content.gsub(/\x1B\[\d*m/, '')
49
92
  end
50
93
 
51
- # Build a sample configuration based on the structure (move to own class)
52
- def build_sample_config(_data)
53
- # open_struct_data = KUtil.data.to_open_struct(data)
54
- {
55
- to: :do
56
- }
94
+ def clean_lines
95
+ # remove color escape codes
96
+ lines.flat_map { |line| line.gsub(/\x1B\[\d*m/, '').split("\n") }
97
+ end
98
+
99
+ def add_lines(lines)
100
+ @lines += lines
101
+ end
102
+
103
+ def add_line(line)
104
+ @lines << line
57
105
  end
58
106
 
59
107
  private
60
108
 
61
- def build_key_format(key)
62
- format_config = @formatter[key]
63
- format_config = @formatter[:_root] if format_config.nil? && @recursion_depth.zero?
64
- @key_format = KeyFormat.new(format_config)
109
+ # format_config = @formatter[:_root] if format_config.nil? && @recursion_depth.zero?
110
+
111
+ def data_enumerator(data)
112
+ return data.attributes if data.respond_to?(:attributes)
113
+
114
+ data
65
115
  end
66
116
 
67
117
  def log_data(data)
68
- data.each_pair do |key, value|
69
- build_key_format(key)
70
- case value
71
- when OpenStruct
72
- log_structure(key, value) unless @key_format.ignore?
73
- when Array
74
- log_array(key, value) unless @key_format.ignore?
118
+ data_enumerator(data).each_pair do |k, v|
119
+ key = k.is_a?(String) ? k.to_sym : k
120
+
121
+ graph_path.push(key)
122
+ @graph_node = GraphNode.for(self, graph, graph_path)
123
+ # @graph_node.debug
124
+ # l.kv 'key', "#{key.to_s.ljust(15)}#{graph_node.skip?.to_s.ljust(6)}#{@recursion_depth}"
125
+
126
+ if graph_node.skip?
127
+ # l.kv 'key', 'skipping...'
128
+ @graph_path.pop
129
+ next
130
+ end
131
+
132
+ # xxxx.pry if graph_node.pry_at?(:before_value) # 'puts xmen'
133
+
134
+ value = graph_node.transform? ? graph_node.transform(v) : v
135
+
136
+ # xxxx.pry if graph_node.pry_at?(:after_value) # 'puts xmen'
137
+ if value.is_a?(OpenStruct) || value.respond_to?(:attributes)
138
+
139
+ # l.kv 'go', 'open struct ->'
140
+ # xxxx.pry if graph_node.pry_at?(:before_structure) # 'puts xmen'
141
+ log_structure(key, value)
142
+ # l.kv 'go', 'open struct <-'
143
+ elsif value.is_a?(Array)
144
+ # l.kv 'go', 'array ->'
145
+ log_array(key, value)
146
+ # l.kv 'go', 'array <-'
75
147
  else
76
- KLog.logger.kv "#{@indent_label}#{key}", value
148
+ # l.kv 'go', 'value ->'
149
+ # xxxx.pry if graph_node.pry_at?(:before_kv) # 'puts xmen'
150
+ log_heading(graph_node.heading, graph_node.heading_type) if graph_node.heading
151
+ add_line KLog::LogHelper.kv("#{@indent_label}#{key}", value, key_width)
152
+ # l.kv 'go', 'value <-'
77
153
  end
154
+
155
+ # l.line
156
+ # @graph_node = graph.for_path(graph_path)
157
+ # l.line
158
+ @graph_path.pop
78
159
  end
79
160
  nil
80
161
  end
81
162
 
82
163
  def log_structure(key, value)
83
- # This is specifically for k_doc, I should use a configuration instead of this technique
84
- if value['rows'].is_a?(Array)
85
- # KLog.logger.subheading(key)
86
- # opts[:subheading] = key
87
- # opts.delete(:subheading)
88
- else
89
- KLog.logger.kv "#{@indent_label}#{key}", ''
90
- end
164
+ log_heading(graph_node.heading, graph_node.heading_type) if graph_node.heading
165
+ add_line(KLog::LogHelper.green("#{@indent_label}#{key}"))
91
166
  log_child_data(value)
92
167
  end
93
168
 
@@ -97,22 +172,39 @@ module KLog
97
172
  depth_up
98
173
  end
99
174
 
100
- # rubocop:disable Metrics/AbcSize
101
175
  def log_array(key, array)
102
- # next unless opts[:skip_array].nil?
103
- return unless array.length.positive?
176
+ # xxxx.pry if graph_node.pry_at?(:before_array) # 'puts xmen'
177
+
178
+ items = array.clone
179
+ items.select! { |item| graph_node.filter(item) } if graph_node.filter?
180
+ items = items.take(graph_node.take) if graph_node.limited?
181
+ items.sort!(&graph_node.sort) if graph_node.sort?
182
+
183
+ # xxxx.pry if graph_node.pry_at?(:before_array_print) # 'puts xmen'
104
184
 
105
- log_heading(key_format.heading, key_format.heading_type)
185
+ return if items.length.zero? && graph_node.skip_empty?
106
186
 
107
- filter_items = key_format.take_all ? array : array.take(key_format.take)
187
+ log_heading(graph_node.heading, graph_node.heading_type) if graph_node.heading
108
188
 
109
- if primitive?(filter_items)
110
- KLog.logger.kv "#{indent}#{key}", filter_items.map(&:to_s).join(', ')
189
+ if primitive?(items)
190
+ add_line KLog::LogHelper.kv "#{@indent_label}#{key}", items.map(&:to_s).join(', ')
111
191
  else
112
- tp filter_items, tp_columns(filter_items)
192
+ table_print items, tp_columns(items)
193
+
194
+ # NEED SUPPORT FOR A configured ARRAY COUNT with width and label
195
+ add_line KLog::LogHelper.kv key.to_s, items.count if show_array_count
113
196
  end
197
+ rescue StandardError => e
198
+ KLog.logger.exception(e)
199
+ end
200
+
201
+ def table_print(items, columns)
202
+ io = TablePrintIo.new(self)
203
+
204
+ tp.set :io, io
205
+ tp items, columns
206
+ tp.clear :io
114
207
  end
115
- # rubocop:enable Metrics/AbcSize
116
208
 
117
209
  def primitive?(items)
118
210
  item = items.first
@@ -120,14 +212,12 @@ module KLog
120
212
  end
121
213
 
122
214
  def log_heading(heading, heading_type)
123
- return unless heading
124
-
125
- KLog.logger.dynamic_heading(heading, size: line_width, type: heading_type)
215
+ add_lines(KLog::LogHelper.dynamic_heading(heading, size: line_width, type: heading_type))
126
216
  end
127
217
 
128
218
  def tp_columns(items)
129
219
  # Use configured array columns
130
- return key_format.array_columns if key_format.array_columns
220
+ return graph_node.columns if graph_node.columns
131
221
 
132
222
  # Slow but complete list of keys
133
223
  # items.flat_map { |v| v.to_h.keys }.uniq
@@ -136,6 +226,7 @@ module KLog
136
226
  end
137
227
 
138
228
  def update_indent_label
229
+ # puts "indent_label: #{indent} - #{@recursion_depth} - #{(indent * @recursion_depth)}"
139
230
  @indent_label = (indent * @recursion_depth)
140
231
  end
141
232
 
@@ -153,10 +244,56 @@ module KLog
153
244
  end
154
245
 
155
246
  def depth_up
156
- update_indent_label
157
247
  @recursion_depth = recursion_depth - 1
248
+ update_indent_label
249
+ end
250
+
251
+ def render_output
252
+ puts content if output_as.include?(:console)
253
+ File.write(output_file, clean_content) if output_as.include?(:file) && output_file
254
+ # content
255
+ end
256
+
257
+ # convert_data_to: :open_struct
258
+ def convert_data(data)
259
+ return KUtil.data.to_open_struct(data) if convert_data_to == :open_struct
260
+
261
+ data
158
262
  end
159
263
 
264
+ def parse_graph(data)
265
+ if data.is_a?(Hash)
266
+ transform_hash = data.each_with_object({}) do |(key, value), new_hash|
267
+ new_hash[key] = if key == :columns && value.is_a?(Array)
268
+ # Don't transform the table_print GEM columns definition as it must stay as a hash
269
+ value
270
+ else
271
+ parse_graph(value)
272
+ end
273
+ end
274
+
275
+ return OpenStruct.new(transform_hash.to_h)
276
+ end
277
+
278
+ return data.map { |o| parse_graph(o) } if data.is_a?(Array)
279
+ return parse_graph(data.to_h) if data.respond_to?(:to_h) # hash_convertible?(data)
280
+
281
+ # Some primitave type: String, True/False or an ObjectStruct
282
+ data
283
+ end
284
+
285
+ # def hash_convertible?(value)
286
+ # # Nil is a special case, it responds to :to_h but generally
287
+ # # you only want to convert nil to {} in specific scenarios
288
+ # return false if value.nil?
289
+
290
+ # value.is_a?(Array) ||
291
+ # value.is_a?(Hash) ||
292
+ # value.is_a?(Struct) ||
293
+ # value.is_a?(OpenStruct) ||
294
+ # value.respond_to?(:to_h)
295
+ # end
296
+
160
297
  # Format configuration for a specific key
161
298
  #
162
299
  # @example Example configuration for key: tables
@@ -165,7 +302,7 @@ module KLog
165
302
  # tables: {
166
303
  # heading: 'Database Tables',
167
304
  # take: :all,
168
- # array_columns: [
305
+ # columns: [
169
306
  # :name,
170
307
  # :force,
171
308
  # :primary_key,
@@ -178,36 +315,139 @@ module KLog
178
315
  # }
179
316
  # }
180
317
  #
181
- # format = KeyFormat.new(configuration[:tables])
182
- class KeyFormat
318
+
319
+ # Override table_print IO stream so that it writes into the structure
320
+ class TablePrintIo
321
+ def initialize(log_structure)
322
+ @log_structure = log_structure
323
+ end
324
+
325
+ def puts(line)
326
+ @log_structure.add_line(line)
327
+ end
328
+ end
329
+
330
+ class GraphNode
331
+ attr_reader :log_structure
183
332
  attr_accessor :config
184
333
 
185
- def initialize(config)
186
- @config = OpenStruct.new(config)
334
+ class << self
335
+ def null
336
+ @null ||= OpenStruct.new
337
+ end
338
+
339
+ def for(log_structure, graph, graph_path)
340
+ # node_config = graph_path.inject(graph, :send) # (uses deep nesting, but fails when nil is returned) https://stackoverflow.com/questions/15862455/ruby-nested-send
341
+ # node.nil? ? null : node.send(name) || null
342
+ node_config = graph_path.reduce(graph) do |node, name|
343
+ result = node.send(name)
344
+
345
+ break null if result.nil?
346
+
347
+ result
348
+ end
349
+ # puts node_config
350
+
351
+ new(log_structure, node_config)
352
+ end
187
353
  end
188
354
 
189
- def array_columns
190
- config.array_columns
355
+ def initialize(log_structure, config)
356
+ @log_structure = log_structure
357
+ @config = config || OpenStruct.new
191
358
  end
192
359
 
360
+ # table_print compatible configuration for displaying columns for an array
361
+ def columns
362
+ config.columns
363
+ end
364
+
365
+ # Optional heading for the node
193
366
  def heading
194
367
  config.heading
195
368
  end
196
369
 
370
+ # Type of heading [:heading, :subheading, :section]
197
371
  def heading_type
198
- config.heading_type || :section_heading
372
+ config.heading_type || :section
199
373
  end
200
374
 
375
+ # Node data is to be transformed
376
+ def transform?
377
+ config&.transform.respond_to?(:call)
378
+ end
379
+
380
+ # Transform node value
381
+ def transform(value)
382
+ config.transform.call(value)
383
+ end
384
+
385
+ # Array rows are filtered
386
+ def filter?
387
+ config&.filter.respond_to?(:call)
388
+ end
389
+
390
+ # Array rows are filtered via this predicate
391
+ def filter(value)
392
+ config.filter.call(value)
393
+ end
394
+
395
+ # How any array rows to take
201
396
  def take
202
397
  config.take
203
398
  end
204
399
 
205
- def take_all
206
- config.take.nil? || config.take == :all
400
+ # Array rows are limited, see take
401
+ def limited?
402
+ config.take&.is_a?(Integer)
403
+ end
404
+
405
+ # Array rows are sorted using .sort
406
+ def sort?
407
+ config&.sort.respond_to?(:call)
408
+ end
409
+
410
+ # Use array.sort?
411
+ def sort
412
+ config.sort
413
+ end
414
+
415
+ # Skip this node
416
+ def skip?
417
+ config.skip == true
418
+ end
419
+
420
+ # Useful in complex debug scenarios
421
+ def pry_at
422
+ config.pry_at || []
207
423
  end
208
424
 
209
- def ignore?
210
- config.ignore == true
425
+ def pry_at?(section)
426
+ pry_at.include?(section)
427
+ end
428
+
429
+ # Skip empty array node (my be useful for other nodes, but not yet)
430
+ def skip_empty?
431
+ config.skip_empty == true
432
+ end
433
+
434
+ def show_array_count
435
+ log_structure.show_array_count
436
+ end
437
+
438
+ def debug
439
+ l = KLog::LogUtil.new(KLog.logger)
440
+ l.kv('columns', columns) if columns
441
+ l.kv('heading', heading) if heading
442
+ l.kv('heading_type', heading_type) if heading_type
443
+ l.kv('filter?', filter?)
444
+ l.kv('take', take)
445
+ l.kv('limited?', limited?)
446
+ l.kv('sort?', sort?)
447
+ l.kv('sort', sort)
448
+ l.kv('skip?', skip?)
449
+ l.kv('pry_at', pry_at)
450
+ l.kv('skip_empty?', skip_empty?)
211
451
  end
212
452
  end
213
453
  end
@@ -75,7 +75,7 @@ module KLog
75
75
  def dynamic_heading(heading, size: 70, type: :heading)
76
76
  KLog.logger.heading(heading, size) if type == :heading
77
77
  KLog.logger.subheading(heading, size) if type == :subheading
78
- KLog.logger.section_heading(heading, size) if type == :section_heading
78
+ KLog.logger.section_heading(heading, size) if %i[section_heading section].include?(type)
79
79
  end
80
80
 
81
81
  def heading(heading, size = 70)
@@ -148,7 +148,7 @@ module KLog
148
148
  # @option opts [String] :heading_type :heading, :subheading, :section_heading
149
149
  # @option opts [Boolean] :skip_array Arrays items can be skipped
150
150
  def structure(data, **opts)
151
- structure = LogStructure.new(**opts)
151
+ structure = LogStructure.new(opts)
152
152
  structure.log(data)
153
153
  end
154
154
 
@@ -195,11 +195,17 @@ module KLog
195
195
  alias ostruct open_struct
196
196
  alias o open_struct
197
197
 
198
- def exception(exception)
198
+ def exception(exception, short: false, method_info: nil)
199
199
  line
200
200
 
201
- @logger.info(exception.message)
202
- @logger.info(exception.backtrace.join("\n"))
201
+ @logger.info(KLog::LogHelper.bg_red(exception.message))
202
+
203
+ @logger.info([method_info.owner.name, method_info.name].join('#')) if method_info
204
+
205
+ trace_items = short ? exception.backtrace.select { |row| row.start_with?(Dir.pwd) } : exception.backtrace
206
+ trace_items = trace_items.map { |row| row.start_with?(Dir.pwd) ? KLog::LogHelper.yellow(row) : KLog::LogHelper.red(row) }
207
+
208
+ @logger.info(KLog::LogHelper.yellow(trace_items.join("\n")))
203
209
 
204
210
  line
205
211
  end
data/lib/k_log/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KLog
4
- VERSION = '0.0.20'
4
+ VERSION = '0.0.31'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: k_log
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20
4
+ version: 0.0.31
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-08 00:00:00.000000000 Z
11
+ date: 2021-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: k_util