greenhat 0.6.7 → 0.7.0

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: 562e92d64d65ccb2791a5602855d0fb9de79b443e4116f2a906fa34d07f7d0ae
4
- data.tar.gz: 23040e75b3c4ea72b9363aab2f5db85d420a7e990dfab120e550890b29755413
3
+ metadata.gz: efdb641c3ae684fcaf175c79aca027340e28bca4baeb97d2760f879709cbf511
4
+ data.tar.gz: 04a8a25c0e5f3ffd1fb3f4de4b1c65856c90d902418725cabe87aca9c1fbbfa8
5
5
  SHA512:
6
- metadata.gz: 4b4e2da3672c747354ac630d3347be6ac49a1ddec84f034ffecef51528f1277fd3e079fea742cfe1a55762ed99f4ddd74d1b2166a6ef55a24e8d2eb2ccbaa9bf
7
- data.tar.gz: 594011521f46b879c5c3636828263577411810d30d49b7b8dc811fcb50260c692e45cf3884bed31ca45a482503324a51085280226668e8bd3d94d729d49be361
6
+ metadata.gz: af18184676b26aaff2c24ed85a18902fc06f08939755f9698d2fd43664fd5727a1b464aafd5b4c879a8c6065af856fb733c69022b6b2ec73389913468ce21c00
7
+ data.tar.gz: c0442ebaeb59941d09f4b413fcb36431a7975153ad4f5ff56d4e9c3cc29ad20c62836ec201f6de1b9e94a3f50d28d76973440c91b0f3d6f1a69347f00daf97c0
@@ -45,6 +45,9 @@ module GreenHat
45
45
  ].join
46
46
 
47
47
  disks.map do |disk|
48
+ # Safety
49
+ next if disk.nil? || disk.use.nil?
50
+
48
51
  # Pretty Disk Use
49
52
  use = [
50
53
  disk.use.rjust(5).ljust(5).pastel(:green),
data/lib/greenhat/host.rb CHANGED
@@ -148,7 +148,7 @@ class Host < Teron
148
148
 
149
149
  headers = file.raw.first.split(' ', 11)
150
150
  list = file.raw[1..].each.map do |row|
151
- row.split(' ', 11).each_with_index.each_with_object({}) do |(v, i), obj|
151
+ row.split(' ', 11).each_with_index.with_object({}) do |(v, i), obj|
152
152
  obj[headers[i]] = v
153
153
  end
154
154
  end
@@ -63,7 +63,13 @@ module GreenHat
63
63
  flags[arg.field] = arg.value
64
64
 
65
65
  true
66
- # Ignore Good Entries
66
+ # Special Flags -- Send Full Thing
67
+ elsif arg_to_flag_raw_list.include?(arg.field)
68
+ flags[arg.field] ||= []
69
+ flags[arg.field].push arg
70
+
71
+ true
72
+ # Ignore Good Entries
67
73
  else
68
74
  false
69
75
  end
@@ -85,6 +91,13 @@ module GreenHat
85
91
  ]
86
92
  end
87
93
 
94
+ # Don't parse the flag value, just give it to the flag
95
+ def self.arg_to_flag_raw_list
96
+ %i[
97
+ stats_limit
98
+ ]
99
+ end
100
+
88
101
  # Arg Scan (Split -- values into keys)
89
102
  def self.arg_scan(arg)
90
103
  arg.scan(/^-+([^=]+)=(.*)/).map do |field, value|
@@ -105,6 +105,15 @@ module GreenHat
105
105
 
106
106
  ],
107
107
 
108
+ stats_limit: [
109
+ '--stats_limit'.pastel(:green),
110
+ ' Companion to the `stats` and used to filters total output percentages. Supports multiple and logic params',
111
+ ' Ex: --stats_limit>=1 will only show stats results with higher than 1% frequency',
112
+ ' Ex: --stats_limit<=15 --stats_limit>=10 slice >10% and <15% frequency',
113
+ ' Ex: --stats_limit=1, filter for greater than %1'
114
+
115
+ ],
116
+
108
117
  uniq: [
109
118
  '--uniq'.pastel(:green),
110
119
  ' Show unique values only',
@@ -2,7 +2,6 @@ module GreenHat
2
2
  # CLI Helper
3
3
  module Shell
4
4
  # Logs
5
- # rubocop:disable Metrics/ModuleLength
6
5
  module Log
7
6
  def self.auto_complete(list, word)
8
7
  # Argument Parsing
@@ -56,7 +55,7 @@ module GreenHat
56
55
  puts
57
56
 
58
57
  puts ' search'.pastel(:green)
59
- puts " General full text by file searching. See #{'search_help'.pastel(:blue)}"
58
+ puts " Deprecated! Use the #{'filter --text="search"'.pastel(:blue)} instead"
60
59
  puts
61
60
 
62
61
  puts ' save'.pastel(:green)
@@ -288,33 +287,35 @@ module GreenHat
288
287
  # ========================================================================
289
288
  # Search (Full Text / String Search)
290
289
  # ========================================================================
291
- def self.search(raw)
292
- # Extract Args
293
- files_list, flags, args = Args.parse(raw)
294
-
295
- # Prepare Log List
296
- files = ShellHelper.prepare_list(files_list, ShellHelper::Log.list)
297
-
298
- results = ShellHelper.search_start(files, flags, args)
299
-
300
- # Skip and Print Total if set
301
- if flags[:total]
302
- ShellHelper.total_count(results, flags)
303
- return true
304
- end
305
-
306
- # Check Search Results
307
- if results.values.flatten.empty?
308
- puts 'No results'.pastel(:red)
309
- ShellHelper::Log.no_files_warning(files) if ShellHelper.find_things(files, flags).count.zero?
310
- else
311
- # This causes the key 'colorized' output to also be included
312
- ShellHelper.show(results.to_a.compact.flatten, flags)
313
- end
314
- rescue StandardError => e
315
- LogBot.fatal('Search', message: e.message)
316
- ap e.backtrace
317
- end
290
+ # Deprecated
291
+ # TODO: Remove
292
+ # def self.search(raw)
293
+ # # Extract Args
294
+ # files_list, flags, args = Args.parse(raw)
295
+
296
+ # # Prepare Log List
297
+ # files = ShellHelper.prepare_list(files_list, ShellHelper::Log.list)
298
+
299
+ # results = ShellHelper.search_start(files, flags, args)
300
+
301
+ # # Skip and Print Total if set
302
+ # if flags[:total]
303
+ # ShellHelper.total_count(results, flags)
304
+ # return true
305
+ # end
306
+
307
+ # # Check Search Results
308
+ # if results.values.flatten.empty?
309
+ # puts 'No results'.pastel(:red)
310
+ # ShellHelper::Log.no_files_warning(files) if ShellHelper.find_things(files, flags).count.zero?
311
+ # else
312
+ # # This causes the key 'colorized' output to also be included
313
+ # ShellHelper.show(results.to_a.compact.flatten, flags)
314
+ # end
315
+ # rescue StandardError => e
316
+ # LogBot.fatal('Search', message: e.message)
317
+ # ap e.backtrace
318
+ # end
318
319
  # ========================================================================
319
320
 
320
321
  # Supported Params
@@ -323,56 +324,53 @@ module GreenHat
323
324
  # --slice=time,path (E.g. log filter --path='mirror/pull' --slice=path,time )
324
325
  # --except: Exclude specific fields (except multiple with comma)
325
326
 
326
- # rubocop:disable Metrics/MethodLength
327
- def self.search_help
328
- puts "\u2500".pastel(:cyan) * 20
329
- puts 'Log Search'.pastel(:yellow)
330
- puts "\u2500".pastel(:cyan) * 20
331
-
332
- puts 'Search will do a full line include or exclude text search'
333
-
334
- puts 'Options'.pastel(:blue)
335
- puts '--text'.pastel(:green)
336
- puts ' Primary parameter for searching. Include or ! to exclude'
337
- puts ' Ex: --text=BuildHooksWorker --text!=start sidekiq/current'
338
- puts
339
-
340
- puts '--total'.pastel(:green)
341
- puts ' Print only total count of matching entries'
342
- puts
343
-
344
- puts '--slice'.pastel(:green)
345
- puts ' Extract specific fields from entries (slice multiple with comma)'
346
- puts ' Ex: --slice=path or --slice=path,params'
347
- puts
348
-
349
- puts '--except'.pastel(:green)
350
- puts ' Exclude specific fields (except multiple with comma)'
351
- puts ' Ex: --except=params --except=params,path'
352
- puts
353
-
354
- puts '--archive'.pastel(:green)
355
- puts ' Limit to specific archive name (inclusive). Matching SOS tar.gz name'
356
- puts ' Ex: --archive=dev-gitlab_20210622154626, --archive=202106,202107'
357
- puts
358
-
359
- puts '--limit'.pastel(:green)
360
- puts ' Limit total number of results. Default to half total screen size'
361
- puts ' Ex: --limit; --limit=10'
362
- puts
363
-
364
- puts 'Search specific logs'.pastel(:blue)
365
- puts ' Any non dash parameters will be the log list to search from'
366
- puts " Ex: log filter --path=api sidekiq/current (hint: use `#{'ls'.pastel(:yellow)}` for log names)"
367
- puts
368
-
369
- puts 'Example Queries'.pastel(:blue)
370
- puts 'log search --text=BuildHooksWorker --text!=start sidekiq/current --total'
371
- puts 'log search --text=BuildHooksWorker --text!=start --slice=enqueued_at sidekiq/current'
372
- puts
373
- end
374
- # rubocop:enable Metrics/MethodLength,Metrics/ModuleLength
375
-
327
+ # def self.search_help
328
+ # puts "\u2500".pastel(:cyan) * 20
329
+ # puts 'Log Search'.pastel(:yellow)
330
+ # puts "\u2500".pastel(:cyan) * 20
331
+
332
+ # puts 'Search will do a full line include or exclude text search'
333
+
334
+ # puts 'Options'.pastel(:blue)
335
+ # puts '--text'.pastel(:green)
336
+ # puts ' Primary parameter for searching. Include or ! to exclude'
337
+ # puts ' Ex: --text=BuildHooksWorker --text!=start sidekiq/current'
338
+ # puts
339
+
340
+ # puts '--total'.pastel(:green)
341
+ # puts ' Print only total count of matching entries'
342
+ # puts
343
+
344
+ # puts '--slice'.pastel(:green)
345
+ # puts ' Extract specific fields from entries (slice multiple with comma)'
346
+ # puts ' Ex: --slice=path or --slice=path,params'
347
+ # puts
348
+
349
+ # puts '--except'.pastel(:green)
350
+ # puts ' Exclude specific fields (except multiple with comma)'
351
+ # puts ' Ex: --except=params --except=params,path'
352
+ # puts
353
+
354
+ # puts '--archive'.pastel(:green)
355
+ # puts ' Limit to specific archive name (inclusive). Matching SOS tar.gz name'
356
+ # puts ' Ex: --archive=dev-gitlab_20210622154626, --archive=202106,202107'
357
+ # puts
358
+
359
+ # puts '--limit'.pastel(:green)
360
+ # puts ' Limit total number of results. Default to half total screen size'
361
+ # puts ' Ex: --limit; --limit=10'
362
+ # puts
363
+
364
+ # puts 'Search specific logs'.pastel(:blue)
365
+ # puts ' Any non dash parameters will be the log list to search from'
366
+ # puts " Ex: log filter --path=api sidekiq/current (hint: use `#{'ls'.pastel(:yellow)}` for log names)"
367
+ # puts
368
+
369
+ # puts 'Example Queries'.pastel(:blue)
370
+ # puts 'log search --text=BuildHooksWorker --text!=start sidekiq/current --total'
371
+ # puts 'log search --text=BuildHooksWorker --text!=start --slice=enqueued_at sidekiq/current'
372
+ # puts
373
+ # end
376
374
  # ------------------------------------------------------------------------
377
375
  end
378
376
  end
@@ -1,54 +1,56 @@
1
- module GreenHat
2
- # Deprecating search stuff
3
- module ShellHelper
4
- # Main Entry Point for Searching
5
- # def self.search_start(log_list, filter_type, args, opts)
6
- def self.search_start(files, flags, args)
7
- # Convert to Things
8
- logs = ShellHelper.find_things(files, flags)
9
-
10
- logs.each_with_object({}) do |log, obj|
11
- # Ignore Empty Results / No Thing
12
- next if log&.data.blank?
13
-
14
- obj[log.friendly_name] = ShellHelper.search(log.data, flags, args)
15
-
16
- obj
17
- end
18
- end
19
-
20
- # Generic Search Helper / String/Regex
21
- def self.search(data, flags = {}, args = {})
22
- results = data.clone.flatten.compact
23
- results.select! do |row|
24
- args.send(flags.logic) do |arg|
25
- search_row(row, arg, flags)
26
- end
27
- end
28
-
29
- # Strip Results if Slice is defined
30
- results.map! { |row| row.slice(*flags[:slice]) } if flags[:slice]
31
-
32
- # Strip Results if Except is defined
33
- results.map! { |row| row.except(*flags[:except]) } if flags[:except]
34
-
35
- # Remove Blank from either slice or except
36
- results.reject!(&:empty?)
37
-
38
- results
39
- end
40
-
41
- # Break out filter row logic into separate method
42
- def self.search_row(row, arg, flags)
43
- # Sensitivity Check / Check for Match
44
- included = filter_row_entry(row.to_s, arg, flags)
45
-
46
- # Pivot of off include vs exclude
47
- if arg.bang
48
- !included
49
- else
50
- included
51
- end
52
- end
53
- end
54
- end
1
+ # Deprecated
2
+ # TODO: Remove
3
+ # module GreenHat
4
+ # # Deprecating search stuff
5
+ # module ShellHelper
6
+ # # Main Entry Point for Searching
7
+ # # def self.search_start(log_list, filter_type, args, opts)
8
+ # def self.search_start(files, flags, args)
9
+ # # Convert to Things
10
+ # logs = ShellHelper.find_things(files, flags)
11
+
12
+ # logs.each_with_object({}) do |log, obj|
13
+ # # Ignore Empty Results / No Thing
14
+ # next if log&.data.blank?
15
+
16
+ # obj[log.friendly_name] = ShellHelper.search(log.data, flags, args)
17
+
18
+ # obj
19
+ # end
20
+ # end
21
+
22
+ # # Generic Search Helper / String/Regex
23
+ # def self.search(data, flags = {}, args = {})
24
+ # results = data.clone.flatten.compact
25
+ # results.select! do |row|
26
+ # args.send(flags.logic) do |arg|
27
+ # search_row(row, arg, flags)
28
+ # end
29
+ # end
30
+
31
+ # # Strip Results if Slice is defined
32
+ # results.map! { |row| row.slice(*flags[:slice]) } if flags[:slice]
33
+
34
+ # # Strip Results if Except is defined
35
+ # results.map! { |row| row.except(*flags[:except]) } if flags[:except]
36
+
37
+ # # Remove Blank from either slice or except
38
+ # results.reject!(&:empty?)
39
+
40
+ # results
41
+ # end
42
+
43
+ # # Break out filter row logic into separate method
44
+ # def self.search_row(row, arg, flags)
45
+ # # Sensitivity Check / Check for Match
46
+ # included = filter_row_entry(row.to_s, arg, flags)
47
+
48
+ # # Pivot of off include vs exclude
49
+ # if arg.bang
50
+ # !included
51
+ # else
52
+ # included
53
+ # end
54
+ # end
55
+ # end
56
+ # end
@@ -252,7 +252,7 @@ module GreenHat
252
252
  next unless x.key? :time
253
253
 
254
254
  x = x.clone # Prevent Top Level Modification
255
- x[:time] = x[:time].in_time_zone time_zone
255
+ x[:time] = x[:time].in_time_zone time_zone.upcase
256
256
 
257
257
  x
258
258
  end
@@ -406,6 +406,9 @@ module GreenHat
406
406
  # Total Occurences
407
407
  total = occurrences.values.sum
408
408
 
409
+ # Limit Output
410
+ filter_stats_limiter(occurrences, total, flags[:stats_limit]) if flags.key?(:stats_limit)
411
+
409
412
  # Percs
410
413
  occurrences.transform_values! do |count|
411
414
  [
@@ -450,6 +453,21 @@ module GreenHat
450
453
  end
451
454
  end
452
455
 
456
+ # Additional Filtering through stats_limit
457
+ def self.filter_stats_limiter(results, total, limits)
458
+ results.select! do |_k, v|
459
+ limits.all? do |limit|
460
+ # Shim for Integers
461
+ if limit.logic == :include?
462
+ percent(v, total).send(:>=, limit.value)
463
+ else
464
+ percent(v, total).send(limit.logic, limit.value)
465
+ end
466
+ # ------------
467
+ end
468
+ end
469
+ end
470
+
453
471
  def self.filter_empty_arg(arg)
454
472
  puts [
455
473
  'Ignoring'.pastel(:bright_yellow),
@@ -460,7 +478,7 @@ module GreenHat
460
478
 
461
479
  # Break out filter row logic into separate method
462
480
  def self.filter_row_key(row, arg, flags)
463
- return false if row.nil? # Nothing to filter if row empty
481
+ return false if row.nil? || row.zero? # Nothing to filter if row empty
464
482
 
465
483
  # Ignore Other Logic if Field isn't even included / Full Text Searching
466
484
  return false unless row.key?(arg[:field]) || arg[:field] == :text
@@ -475,6 +493,9 @@ module GreenHat
475
493
  else
476
494
  match
477
495
  end
496
+ rescue StandardError => e
497
+ LogBot.fatal('[Query] Filter Row Failure', message: e.message, backtrace: e.backtrace.first, row: row)
498
+ false
478
499
  end
479
500
 
480
501
  # Field Partial / Case / Exact search
@@ -284,7 +284,7 @@ module GreenHat
284
284
  end
285
285
 
286
286
  def self.field_table(list, columns = 4)
287
- return nil if list.size.zero?
287
+ return nil if list.empty?
288
288
 
289
289
  # Keep Alphabetical Sort
290
290
  groups = list.each_slice((list.size / columns.to_f).round).to_a
@@ -115,6 +115,54 @@ module GreenHat
115
115
  %r{geo-logcursor/current}
116
116
  ]
117
117
  },
118
+ 'elastic_info' => {
119
+ format: :raw,
120
+ pattern: [
121
+ /elastic_info/
122
+ ]
123
+ },
124
+ 'fast-stats/api' => {
125
+ format: :raw,
126
+ pattern: [
127
+ %r{fast-stats/api}
128
+ ]
129
+ },
130
+ 'fast-stats/gitaly' => {
131
+ format: :raw,
132
+ pattern: [
133
+ %r{fast-stats/gitaly}
134
+ ]
135
+ },
136
+ 'fast-stats/production' => {
137
+ format: :raw,
138
+ pattern: [
139
+ %r{fast-stats/production}
140
+ ]
141
+ },
142
+ 'fast-stats/sidekiq' => {
143
+ format: :raw,
144
+ pattern: [
145
+ %r{fast-stats/sidekiq}
146
+ ]
147
+ },
148
+ 'non_analyzed_tables' => {
149
+ format: :raw,
150
+ pattern: [
151
+ /non_analyzed_tables/
152
+ ]
153
+ },
154
+ 'schema_dump_result' => {
155
+ format: :raw,
156
+ pattern: [
157
+ /schema_dump_result/
158
+ ]
159
+ },
160
+ 'log/mail.log' => {
161
+ format: :raw,
162
+ pattern: [
163
+ %r{log/mail.log}
164
+ ]
165
+ },
118
166
  'gitaly/current' => {
119
167
  format: :json_shell,
120
168
  log: true,
@@ -99,7 +99,7 @@ module GreenHat
99
99
  def ps_format
100
100
  headers = info.ps.first.split(' ', 11)
101
101
  list = info.ps[1..].each.map do |row|
102
- row.split(' ', 11).each_with_index.each_with_object({}) do |(v, i), obj|
102
+ row.split(' ', 11).each_with_index.with_object({}) do |(v, i), obj|
103
103
  obj[headers[i]] = v
104
104
  end
105
105
  end
@@ -1,3 +1,3 @@
1
1
  module GreenHat
2
- VERSION = '0.6.7'.freeze
2
+ VERSION = '0.7.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: greenhat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.7
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davin Walker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-19 00:00:00.000000000 Z
11
+ date: 2023-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: amazing_print