greenhat 0.4.0 → 0.6.1

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/bin/greenhat +1 -2
  3. data/lib/greenhat/accessors/disk.rb +1 -1
  4. data/lib/greenhat/accessors/gitlab.rb +4 -2
  5. data/lib/greenhat/archive.rb +7 -1
  6. data/lib/greenhat/cli.rb +24 -11
  7. data/lib/greenhat/entrypoint.rb +37 -34
  8. data/lib/greenhat/host.rb +1 -1
  9. data/lib/greenhat/logbot.rb +1 -1
  10. data/lib/greenhat/paper/flag_helper.rb +18 -0
  11. data/lib/greenhat/paper/paper_helper.rb +118 -0
  12. data/lib/greenhat/paper.rb +34 -0
  13. data/lib/greenhat/reports/builder.rb +98 -0
  14. data/lib/greenhat/reports/helpers.rb +101 -0
  15. data/lib/greenhat/reports/internal_methods.rb +156 -0
  16. data/lib/greenhat/reports/reports/errors.rb +49 -0
  17. data/lib/greenhat/reports/reports/faststats.rb +42 -0
  18. data/lib/greenhat/reports/reports/full.rb +143 -0
  19. data/lib/greenhat/reports/runner.rb +58 -0
  20. data/lib/greenhat/reports/shared.rb +37 -0
  21. data/lib/greenhat/reports/shell_helper.rb +34 -0
  22. data/lib/greenhat/reports.rb +79 -0
  23. data/lib/greenhat/settings.rb +35 -8
  24. data/lib/greenhat/shell/args.rb +9 -9
  25. data/lib/greenhat/shell/color_string.rb +1 -1
  26. data/lib/greenhat/shell/faststats.rb +24 -5
  27. data/lib/greenhat/shell/field_helper.rb +1 -1
  28. data/lib/greenhat/shell/filter_help.rb +65 -185
  29. data/lib/greenhat/shell/gitlab.rb +1 -0
  30. data/lib/greenhat/shell/log.rb +24 -30
  31. data/lib/greenhat/shell/markdown.rb +355 -352
  32. data/lib/greenhat/shell/process.rb +11 -5
  33. data/lib/greenhat/shell/query.rb +534 -0
  34. data/lib/greenhat/shell/report.rb +415 -410
  35. data/lib/greenhat/shell/reports.rb +41 -0
  36. data/lib/greenhat/shell/shell_helper.rb +95 -387
  37. data/lib/greenhat/shell.rb +22 -3
  38. data/lib/greenhat/thing/file_types.rb +30 -1
  39. data/lib/greenhat/thing/formatters/api_json.rb +4 -2
  40. data/lib/greenhat/thing/formatters/bracket_log.rb +1 -1
  41. data/lib/greenhat/thing/formatters/clean_raw.rb +1 -1
  42. data/lib/greenhat/thing/formatters/colon_split_strip.rb +2 -2
  43. data/lib/greenhat/thing/formatters/dotenv.rb +1 -1
  44. data/lib/greenhat/thing/formatters/format.rb +0 -11
  45. data/lib/greenhat/thing/formatters/free_m.rb +2 -2
  46. data/lib/greenhat/thing/formatters/json.rb +41 -17
  47. data/lib/greenhat/thing/formatters/json_shellwords.rb +3 -2
  48. data/lib/greenhat/thing/formatters/kube_json.rb +3 -2
  49. data/lib/greenhat/thing/formatters/multiline_json.rb +1 -1
  50. data/lib/greenhat/thing/formatters/nginx.rb +5 -1
  51. data/lib/greenhat/thing/formatters/runner_log.rb +70 -0
  52. data/lib/greenhat/thing/formatters/table.rb +17 -3
  53. data/lib/greenhat/thing/formatters/time_json.rb +12 -1
  54. data/lib/greenhat/thing/helpers.rb +0 -11
  55. data/lib/greenhat/thing/info_format.rb +4 -4
  56. data/lib/greenhat/thing/kind.rb +1 -1
  57. data/lib/greenhat/thing.rb +21 -25
  58. data/lib/greenhat/version.rb +1 -1
  59. data/lib/greenhat.rb +6 -8
  60. metadata +32 -4
  61. data/lib/greenhat/pry_helpers.rb +0 -51
  62. data/lib/greenhat/thing/super_log.rb +0 -102
@@ -3,7 +3,7 @@ module GreenHat
3
3
  # Helper to colorize and make outtput easier to read
4
4
  module StringColor
5
5
  def self.do(key, entry)
6
- LogBot.debug('Unknown Format', entry.class) if ENV['DEBUG'] && !entry.instance_of?(String)
6
+ LogBot.debug('Unknown Format', entry.class) if ENV.fetch('DEBUG', nil) && !entry.instance_of?(String)
7
7
 
8
8
  # Other Helpful colorizers
9
9
  if pastel?(key)
@@ -100,6 +100,13 @@ module GreenHat
100
100
  puts "- #{log.name.pastel(:yellow)}"
101
101
  end
102
102
  end
103
+
104
+ return unless all
105
+
106
+ puts "\n#{'Other / Unknown'.pastel(:red)}"
107
+ (Thing.all - files).each do |file|
108
+ puts "- #{file.name.pastel(:yellow)}"
109
+ end
103
110
  end
104
111
 
105
112
  def self.ls(args = [])
@@ -117,15 +124,23 @@ module GreenHat
117
124
 
118
125
  LogBot.debug('FastStats CMD', cmd) if ENV['DEBUG']
119
126
 
127
+ # binding.pry
128
+
129
+ # Ignore Unknown Errors
120
130
  results = ShellHelper.file_process(files) do |file|
131
+ output = `fast-stats #{cmd} #{file.file} 2>&1`
132
+ result = $CHILD_STATUS.success?
133
+
134
+ next unless result
135
+
121
136
  [
122
137
  file.friendly_name,
123
- `fast-stats #{cmd} #{file.file}`.split("\n"),
138
+ output.split("\n"),
124
139
  "\n"
125
140
  ]
126
141
  end
127
142
 
128
- ShellHelper.show(results.flatten, flags)
143
+ ShellHelper.show(results.compact.flatten, flags)
129
144
  end
130
145
 
131
146
  # ========================================================================
@@ -219,11 +234,15 @@ module GreenHat
219
234
  end
220
235
  end.join(' ')
221
236
 
222
- # Prepare Log List
223
- file_list = ShellHelper.prepare_list(file_list, ShellHelper::Faststats.things, flags)
237
+ # Prepare Log List / Allow attempting of parsing everything
238
+ file_list = if file_list == ['*']
239
+ Thing.all.map(&:name)
240
+ else
241
+ ShellHelper.prepare_list(file_list, ShellHelper::Faststats.things)
242
+ end
224
243
 
225
244
  # Convert to Things
226
- files = ShellHelper.find_things(file_list)
245
+ files = ShellHelper.find_things(file_list, fuzzy_file_match: true)
227
246
 
228
247
  [files, flags, cmd]
229
248
  end
@@ -34,7 +34,7 @@ module GreenHat
34
34
  %w[
35
35
  archive case combine end exact except exists json limit or page pluck
36
36
  raw reverse round slice sort start stats table_style text time_zone
37
- total truncate uniq
37
+ total truncate uniq percentile transform
38
38
  ]
39
39
  end
40
40
 
@@ -2,181 +2,20 @@ module GreenHat
2
2
  # CLI Helper
3
3
  module ShellHelper
4
4
  # Unify Filter / Filter Help
5
- # rubocop:disable Metrics/MethodLength,Metrics/ModuleLength,Layout/LineLength
5
+ # rubocop:disable Metrics/MethodLength,Layout/LineLength,Metrics/ModuleLength
6
6
  module Filter
7
- def self.help
8
- puts "\u2500".pastel(:cyan) * 20
9
- puts 'Filter'.pastel(:yellow)
10
- puts "\u2500".pastel(:cyan) * 20
11
-
12
- puts 'Options'.pastel(:blue)
13
- puts '--raw'.pastel(:green)
14
- puts ' Disable formatting and page/less'
15
- puts
16
-
17
- puts '--page'.pastel(:green)
18
- puts ' Specifically enable or disable paging'
19
- puts ' E.g. --page (default to true), --page=true, --page=false'
20
- puts
21
-
22
- puts '--round'.pastel(:green)
23
- puts ' Attempt to round all integers. Default: 2.'
24
- puts ' E.g. --round, --round=3, --round=0'
25
- puts
26
-
27
- puts '--limit'.pastel(:green)
28
- puts ' Limit total output lines. Disabled by default. Default without value is based on screen height'
29
- puts ' E.g. --limit, --limit=5'
30
- puts
31
-
32
- puts '--json'.pastel(:green)
33
- puts ' Print output back into JSON'
34
- puts
35
-
36
- puts '--or'.pastel(:green)
37
- puts ' Filters will use OR instead of AND (all match vs any match)'
38
- puts
39
-
40
- puts '--total'.pastel(:green)
41
- puts ' Show total count, duration, start/end time for matching entries'
42
- puts
43
-
44
- puts '--fields'.pastel(:green)
45
- puts ' Print only Available fields for selected files'
46
- puts
47
-
48
- puts '--slice'.pastel(:green)
49
- puts ' Extract specific fields from entries (slice multiple with comma)'
50
- puts ' Ex: --slice=path or --slice=path,params'
51
- puts
52
-
53
- puts '--except'.pastel(:green)
54
- puts ' Exclude specific fields (except multiple with comma)'
55
- puts ' Ex: --except=params --except=params,path'
56
- puts
57
-
58
- puts '--exists'.pastel(:green)
59
- puts ' Ensure field exists regardless of contents'
60
- puts ' Ex: --exists=params --exists=params,path'
61
- puts
62
-
63
- puts '--stats'.pastel(:green)
64
- puts ' Order/Count occurrances by field. Combine with `truncate` for key names'
65
- puts ' Ex: --stats=params --except=params,path'
66
- puts
67
-
68
- puts '--uniq'.pastel(:green)
69
- puts ' Show unique values only'
70
- puts ' Ex: --uniq=params --uniq=params,path'
71
- puts
72
-
73
- puts '--pluck'.pastel(:green)
74
- puts ' Extract values from entries'
75
- puts ' Ex: --pluck=params --pluck=params,path'
76
- puts
77
-
78
- puts '--archive'.pastel(:green)
79
- puts ' Limit to specific archvie name (partial matching /inclusive). Matching SOS tar.gz name'
80
- puts ' Ex: --archive=dev-gitlab_20210622154626, --archive=202106,202107'
81
- puts
82
-
83
- puts '--sort'.pastel(:green)
84
- puts ' Sort by multiple fields'
85
- puts ' Ex: --sort=duration_s,db_duration_s'
86
- puts
87
-
88
- puts '--reverse'.pastel(:green)
89
- puts ' Reverse all results'
90
- puts ' Ex: --reverse'
91
- puts
92
-
93
- puts '--combine'.pastel(:green)
94
- puts ' Omit archive identifier dividers. Useful with sort or time filters'
95
- puts ' Ex: --combine'
96
- puts
97
-
98
- puts '--case'.pastel(:green)
99
- puts ' Exact case match. Defaults to case insensitive'
100
- puts ' Ex: --case; --name=Jon, --name=jane --case'
101
- puts
102
-
103
- puts '--exact'.pastel(:green)
104
- puts ' Exact parameter/value match. Defaults to partial match'
105
- puts ' Ex: --field=CommonPartial --exact'
106
- puts
107
-
108
- puts '--start'.pastel(:green)
109
- puts ' Show events after specified time. Filtered by the `time` field'
110
- puts ' Use with `--end` for between selections'
111
- puts ' Ex: log filter --start="2021-06-22 14:44 UTC" --end="2021-06-22 14:45 UTC"'
112
- puts
113
-
114
- puts '--end'.pastel(:green)
115
- puts ' Show events before specified time. Filtered by the `time` field'
116
- puts ' Use with `--start` for between selections'
117
- puts ' Ex: log filter --end="2021-06-22"'
118
- puts
119
-
120
- puts '--time_zone'.pastel(:green)
121
- puts ' Manipulate the `time` field into a specific timezone'
122
- puts ' Ex: log filter --time_zone=EDT'
123
- puts
124
-
125
- puts '--text'.pastel(:green)
126
- puts ' Full entry text searching (slow)'
127
- puts ' --text="anything here"'
128
- puts
129
-
130
- puts '--table_style'.pastel(:green)
131
- puts ' Renderer used for formatted output. basic, ascii, or unicode(default)'
132
- puts ' Ex: log filter --table_style=base'
133
- puts
134
-
135
- puts '--truncate'.pastel(:green)
136
- puts ' Truncate field length. On by default (4 rows). Performance issues!'
137
- puts ' Disable with --truncate=0'.pastel(:bright_red)
138
- puts ' Ex: --truncate=200, --truncate=2048"'
139
- puts
140
-
141
- puts 'Search specific logs'.pastel(:blue)
142
- puts ' Any non dash parameters will be the log list to search from'
143
- puts " Ex: log filter --path=api sidekiq/current (hint: use `#{'ls'.pastel(:yellow)}` for log names"
144
- puts
145
-
146
- puts 'General (Field) Searching'.pastel(:blue)
147
- puts " There are different ways filter within specific keys/fields within log. The baseline is #{'--[key]=[value]'.pastel(:green)}"
148
- puts ' This will, by default, select any entries with any partial match (case insensitive) of [value] in the entry [key]'
149
- puts ' Example: --path=mirror/pull'
150
- puts
151
-
152
- puts " You can modify logic with params like: #{'case'.pastel(:green)}, #{'exact'.pastel(:green)}"
153
- puts ' Ex Case turn on case sensitivity, exact will change from the inclusive to only exact matching.'
154
- puts
155
-
156
- puts " You can also use multiple #{'--[key]=[value]'.pastel(:green)} to narrow down, or combine it with #{'or'.pastel(:green)} to be more inclusive"
157
- puts ' Ex nginx/gitlab_access.log --http_user_agent=gitlab-runner --path=/api/v4/jobs/request'
158
- puts ' This will look through the access logs for anything that is a runner (user agent) and hitting the request endpoint'
159
- puts
160
-
161
- puts " You can also modify whether a field search excluded or a integer (and technically string) comparison by changing the operator: #{'(!= >= <=)'.pastel(:green)}"
162
- puts ' Ex "nginx/gitlab_access.log --http_user_agent=gitlab-runner --http_user_agent!=13.12.0" will exclude any entries with 13.12.0/13.12 runners'
163
- puts ' Ex "sidekiq/current --duration_s>=5 --class!=LdapSyncWorker" Duration over 5 that is not an ldap job'
164
- puts
165
-
166
- puts 'Pipe to Shell'.pastel(:blue)
167
- puts ' This is very experimental! The idea is to take all the output from the search and allow a pipe into a traditional shell command.'
168
- puts ' Due to the arg parsing its not a straight send to the terminal. You may need to escape quotes.'
169
- puts ' Order is relevant, no arguments after the pipe'
170
- puts
171
- puts ' <files> <params> | grep path'
172
- puts
173
-
174
- puts 'Example Queries'.pastel(:blue)
175
- puts " Also see #{'examples'.pastel(:bright_blue)} for even more examples"
176
- puts ' log filter --class=BuildFinishedWorker sidekiq/current --slice=time,message'
177
- puts ' log filter gitlab-rails/api_json.log --slice=ua --uniq=ua --ua=gitlab-runner'
178
-
179
- puts
7
+ def self.help(args = '')
8
+ output = if args.blank?
9
+ help_index.values.map { |x| x.push '' }
10
+ else
11
+ list = help_index.select do |k, _v|
12
+ k.to_s.include? args
13
+ end
14
+
15
+ list.values
16
+ end
17
+
18
+ output.flatten(2)
180
19
  end
181
20
 
182
21
  def self.help_index
@@ -184,9 +23,8 @@ module GreenHat
184
23
  title: [
185
24
  "\u2500".pastel(:cyan) * 20,
186
25
  'Filter'.pastel(:yellow),
187
- "\u2500".pastel(:cyan) * 20
188
- ],
189
- options: [
26
+ "\u2500".pastel(:cyan) * 20,
27
+ '',
190
28
  'Options'.pastel(:blue)
191
29
  ],
192
30
 
@@ -224,7 +62,8 @@ module GreenHat
224
62
 
225
63
  total: [
226
64
  '--total'.pastel(:green),
227
- ' Show total count, duration, start/end time for matching entries'
65
+ ' Show total count, duration, start/end time for matching entries',
66
+ ' Add `simple` to only return counts. e.g. --total=simple'
228
67
  ],
229
68
 
230
69
  fields: [
@@ -236,14 +75,20 @@ module GreenHat
236
75
  '--slice'.pastel(:green),
237
76
  ' Extract specific fields from entries (slice multiple with comma)',
238
77
  ' Ex: --slice=path or --slice=path,params'
239
-
240
78
  ],
241
79
 
242
80
  except: [
243
81
  '--except'.pastel(:green),
244
82
  ' Exclude specific fields (except multiple with comma)',
245
83
  ' Ex: --except=params --except=params,path'
84
+ ],
246
85
 
86
+ transform: [
87
+ '--transform'.pastel(:green),
88
+ ' Copy key to another key within results. Useful for queries that require (timestamp => time)',
89
+ ' Available Transforms, to_i, default is to copy',
90
+ ' Ex: --transform=timestamp,time',
91
+ ' --transform=cpu,cpu,to_i'
247
92
  ],
248
93
 
249
94
  exists: [
@@ -357,11 +202,46 @@ module GreenHat
357
202
  ' Ex: --truncate=200, --truncate=2048"'
358
203
  ],
359
204
 
360
- field: [
361
- 'Field Searching'.pastel(:blue),
362
- ' --[key]=[value]',
363
- ' Search in key for value',
364
- ' Example: --path=mirror/pull'
205
+ interval: [
206
+ '--interval'.pastel(:green),
207
+ ' Split results down into a interval (based on the time field)',
208
+ ' Example Params: 5m, 1d, 3h, "30 minutes" (chronic duration)',
209
+ ' Ex: --interval=15m, --interval=1h"'
210
+ ],
211
+
212
+ percentile: [
213
+ '--percentile'.pastel(:green),
214
+ ' Stats breakdown on any integer value within the results. No params',
215
+ ' Best when combined with slice/round to limit/filter results',
216
+ ' No parameters, Returns 99,95,mean,min,max and entry count',
217
+ ' Ex: --percentile --round --slice=field',
218
+ ' Query: gitlab-rails/api_json.log --percentile --round=2 --slice=cpu_s'
219
+ ],
220
+
221
+ field_search: [
222
+ 'General (Field) Searching'.pastel(:blue),
223
+ " There are different ways filter within specific keys/fields within log. The baseline is #{'--[key]=[value]'.pastel(:green)}",
224
+ ' This will, by default, select any entries with any partial match (case insensitive) of [value] in the entry [key]',
225
+ ' Example: --path=mirror/pull',
226
+ '',
227
+ " You can modify logic with params like: #{'case'.pastel(:green)}, #{'exact'.pastel(:green)}",
228
+ ' Ex Case turn on case sensitivity, exact will change from the inclusive to only exact matching.',
229
+ '',
230
+ " You can also use multiple #{'--[key]=[value]'.pastel(:green)} to narrow down, or combine it with #{'or'.pastel(:green)} to be more inclusive",
231
+ ' Ex nginx/gitlab_access.log --http_user_agent=gitlab-runner --path=/api/v4/jobs/request',
232
+ ' This will look through the access logs for anything that is a runner (user agent) and hitting the request endpoint',
233
+ '',
234
+ " You can also modify whether a field search excluded or a integer (and technically string) comparison by changing the operator: #{'(!= >= <=)'.pastel(:green)}",
235
+ ' Ex "nginx/gitlab_access.log --http_user_agent=gitlab-runner --http_user_agent!=13.12.0" will exclude any entries with 13.12.0/13.12 runners',
236
+ ' Ex "sidekiq/current --duration_s>=5 --class!=LdapSyncWorker" Duration over 5 that is not an ldap job'
237
+ ],
238
+
239
+ pipe_to_shell: [
240
+ 'Pipe to Shell'.pastel(:blue),
241
+ ' This is very experimental! The idea is to take all the output from the search and allow a pipe into a traditional shell command.',
242
+ ' Due to the arg parsing its not a straight send to the terminal. You may need to escape quotes.',
243
+ ' Order is relevant, no arguments after the pipe',
244
+ ' <files> <params> | grep path'
365
245
  ],
366
246
 
367
247
  ls: [
@@ -379,7 +259,7 @@ module GreenHat
379
259
 
380
260
  }
381
261
  end
382
- # rubocop:enable Metrics/MethodLength,Metrics/ModuleLength,Layout/LineLength
262
+ # rubocop:enable Metrics/MethodLength,Layout/LineLength,Metrics/ModuleLength
383
263
  end
384
264
  end
385
265
  end
@@ -99,6 +99,7 @@ module GreenHat
99
99
  end
100
100
  end
101
101
  end
102
+
102
103
  # -----
103
104
  end
104
105
  end
@@ -20,8 +20,8 @@ module GreenHat
20
20
  elsif matches.count > 1
21
21
  puts "#{'Filter Options:'.pastel(:bright_blue)} #{matches.join(' ').pastel(:bright_green)}"
22
22
  "--#{Cli.common_substr(matches)}"
23
- # -----------------------------------
24
- # TODO: Fix Icky Double Nesting
23
+ # -----------------------------------
24
+ # TODO: Fix Icky Double Nesting
25
25
  elsif files.count.nonzero?
26
26
  matches = FieldHelper.fields_find(files, word, flags)
27
27
 
@@ -76,16 +76,10 @@ module GreenHat
76
76
  puts "See #{'examples'.pastel(:bright_blue)} for query examples"
77
77
  end
78
78
 
79
- def self.filter_help(args = {})
80
- if args.empty?
81
- ShellHelper::Filter.help
82
- else
83
- list = ShellHelper::Filter.help_index.select do |k, _v|
84
- k.to_s.include? args.first
85
- end
79
+ def self.filter_help(raw = {})
80
+ args, flags, _args = Args.parse(raw)
86
81
 
87
- puts list.values.map { |x| x.join("\n") }.join("\n\n")
88
- end
82
+ ShellHelper.show(ShellHelper::Filter.help(args.first), flags)
89
83
  end
90
84
 
91
85
  def self.ls(args = [])
@@ -112,7 +106,7 @@ module GreenHat
112
106
  end
113
107
 
114
108
  name = if raw.empty?
115
- Cli.prompt.ask('Log/name to save the results to? '.pastel(:yellow))
109
+ Cli.prompt.ask('Log entry to save the results to? '.pastel(:yellow))
116
110
  else
117
111
  raw.first
118
112
  end
@@ -145,7 +139,7 @@ module GreenHat
145
139
  end
146
140
 
147
141
  name = if raw.empty?
148
- Cli.prompt.ask('Log/name to save the results to? '.pastel(:yellow))
142
+ Cli.prompt.ask('Filename to save the results to? '.pastel(:yellow))
149
143
  else
150
144
  raw.first
151
145
  end
@@ -201,7 +195,7 @@ module GreenHat
201
195
  def self.filter(raw)
202
196
  # Print Helper
203
197
  if raw == ['help']
204
- filter_help
198
+ filter_help(raw)
205
199
  return true
206
200
  end
207
201
 
@@ -211,15 +205,9 @@ module GreenHat
211
205
  files, flags, args = Args.parse(raw)
212
206
 
213
207
  # Prepare Log List
214
- files = ShellHelper.prepare_list(files, ShellHelper::Log.list, flags)
215
-
216
- results = ShellHelper.filter_start(files, flags, args)
208
+ files = ShellHelper.prepare_list(files, ShellHelper::Log.list)
217
209
 
218
- # Skip and Print Total if set
219
- if flags[:total]
220
- ShellHelper.total_count(results, flags)
221
- return true
222
- end
210
+ results = Query.start(files, flags, args)
223
211
 
224
212
  # Skip and Print Total if set
225
213
  if flags[:fields]
@@ -228,14 +216,15 @@ module GreenHat
228
216
  end
229
217
 
230
218
  # Check Search Results
231
- if results.instance_of?(Hash) && results.values.flatten.empty?
219
+ if results.empty?
232
220
  puts 'No results'.pastel(:red)
233
221
  ShellHelper::Log.no_files_warning(files) if ShellHelper.find_things(files, flags).count.zero?
234
222
  elsif flags[:pipe]
235
223
  Pipe.show(results, flags[:pipe])
236
224
  else
225
+ # Allow for array / multiple table outputs
237
226
  # This causes the key 'colorized' output to also be included
238
- ShellHelper.show(results.to_a.compact.flatten, flags)
227
+ ShellHelper.show(results, flags)
239
228
  end
240
229
  rescue StandardError => e
241
230
  LogBot.fatal('Filter', message: e.message)
@@ -281,6 +270,10 @@ module GreenHat
281
270
  puts 'Show workhorse duration/URI. Filter by duration bounds'.pastel(:bright_green)
282
271
  puts 'gitlab-workhorse/current --duration_ms>=30000 --duration_ms<=45000 --slice=duration_ms,uri'
283
272
  puts
273
+
274
+ puts 'Show runner statistics'.pastel(:bright_green)
275
+ puts 'gitlab-rails/api_json.log --path=/api/v4/jobs/request --percentile --round=2'
276
+ puts
284
277
  end
285
278
  # rubocop:enable Layout/LineLength
286
279
 
@@ -292,7 +285,7 @@ module GreenHat
292
285
  files_list, flags, args = Args.parse(raw)
293
286
 
294
287
  # Prepare Log List
295
- files = ShellHelper.prepare_list(files_list)
288
+ files = ShellHelper.prepare_list(files_list, ShellHelper::Log.list)
296
289
 
297
290
  results = ShellHelper.search_start(files, flags, args)
298
291
 
@@ -306,7 +299,6 @@ module GreenHat
306
299
  if results.values.flatten.empty?
307
300
  puts 'No results'.pastel(:red)
308
301
  ShellHelper::Log.no_files_warning(files) if ShellHelper.find_things(files, flags).count.zero?
309
-
310
302
  else
311
303
  # This causes the key 'colorized' output to also be included
312
304
  ShellHelper.show(results.to_a.compact.flatten, flags)
@@ -390,15 +382,17 @@ module GreenHat
390
382
  @last
391
383
  end
392
384
 
393
- def self.list
394
- Thing.all.select(&:log)
395
- end
396
-
397
385
  def self.no_files_warning(files)
398
386
  puts "No matching files found for pattern #{files.to_s.pastel(:yellow)}"
399
387
  puts "See #{'ls'.pastel(:blue)} for available files"
400
388
  end
389
+
390
+ # Limit to Log Files
391
+ def self.list
392
+ Thing.all.select(&:log)
393
+ end
401
394
  end
395
+
402
396
  # --------
403
397
  end
404
398
  end