greenhat 0.6.7 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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