greenhat 0.3.2 → 0.3.6
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 +4 -4
- data/lib/greenhat/accessors/disk.rb +42 -3
- data/lib/greenhat/accessors/gitlab.rb +30 -1
- data/lib/greenhat/accessors/memory.rb +1 -1
- data/lib/greenhat/archive.rb +11 -2
- data/lib/greenhat/cli.rb +37 -0
- data/lib/greenhat/host.rb +25 -37
- data/lib/greenhat/shell/args.rb +22 -9
- data/lib/greenhat/shell/faststats.rb +23 -3
- data/lib/greenhat/shell/field_helper.rb +1 -1
- data/lib/greenhat/shell/filter_help.rb +232 -9
- data/lib/greenhat/shell/log.rb +153 -9
- data/lib/greenhat/shell/markdown.rb +352 -0
- data/lib/greenhat/shell/old_search_helper.rb +54 -0
- data/lib/greenhat/shell/page.rb +1 -1
- data/lib/greenhat/shell/pipe.rb +31 -0
- data/lib/greenhat/shell/platform.rb +28 -0
- data/lib/greenhat/shell/report.rb +106 -25
- data/lib/greenhat/shell/shell_helper.rb +114 -106
- data/lib/greenhat/shell.rb +7 -0
- data/lib/greenhat/thing/file_types.rb +126 -7
- data/lib/greenhat/thing/formatters/json.rb +4 -0
- data/lib/greenhat/thing/formatters/kube_json.rb +36 -0
- data/lib/greenhat/thing/formatters/kube_nginx.rb +48 -0
- data/lib/greenhat/thing/formatters/kube_webservice.rb +51 -0
- data/lib/greenhat/thing/formatters/nginx.rb +6 -2
- data/lib/greenhat/thing/formatters/registry.rb +47 -0
- data/lib/greenhat/thing/formatters/time_space.rb +0 -16
- data/lib/greenhat/thing/helpers.rb +12 -0
- data/lib/greenhat/thing.rb +10 -0
- data/lib/greenhat/version.rb +1 -1
- data/lib/greenhat/views/api.slim +55 -0
- data/lib/greenhat/views/chart.slim +42 -0
- data/lib/greenhat/views/chart_template.slim +31 -0
- data/lib/greenhat/views/chartkick.js +21 -0
- data/lib/greenhat/views/css.slim +47 -0
- data/lib/greenhat/views/gitaly.slim +53 -0
- data/lib/greenhat/views/headers.slim +16 -0
- data/lib/greenhat/views/index-old.slim +51 -0
- data/lib/greenhat/views/index.slim +14 -14
- data/lib/greenhat/views/info.slim +17 -18
- data/lib/greenhat/views/production.slim +55 -0
- data/lib/greenhat/views/sidekiq.slim +55 -0
- data/lib/greenhat/views/time.slim +63 -0
- data/lib/greenhat/views/workhorse.slim +16 -0
- data/lib/greenhat/web/api.rb +94 -0
- data/lib/greenhat/web/chartkick_shim.rb +14 -0
- data/lib/greenhat/web/faststats.rb +44 -0
- data/lib/greenhat/web/gitaly.rb +65 -0
- data/lib/greenhat/web/helpers.rb +198 -0
- data/lib/greenhat/web/production.rb +104 -0
- data/lib/greenhat/web/sidekiq.rb +73 -0
- data/lib/greenhat/web/stats_helpers.rb +74 -0
- data/lib/greenhat/web/time.rb +36 -0
- data/lib/greenhat/web/workhorse.rb +43 -0
- data/lib/greenhat/web.rb +63 -19
- data/lib/greenhat.rb +1 -0
- metadata +73 -2
@@ -2,8 +2,8 @@ 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
6
|
module Filter
|
6
|
-
# rubocop:disable Metrics/MethodLength
|
7
7
|
def self.help
|
8
8
|
puts "\u2500".pastel(:cyan) * 20
|
9
9
|
puts 'Filter'.pastel(:yellow)
|
@@ -38,7 +38,7 @@ module GreenHat
|
|
38
38
|
puts
|
39
39
|
|
40
40
|
puts '--total'.pastel(:green)
|
41
|
-
puts '
|
41
|
+
puts ' Show total count, duration, start/end time for matching entries'
|
42
42
|
puts
|
43
43
|
|
44
44
|
puts '--fields'.pastel(:green)
|
@@ -138,17 +138,39 @@ module GreenHat
|
|
138
138
|
puts ' Ex: --truncate=200, --truncate=2048"'
|
139
139
|
puts
|
140
140
|
|
141
|
-
puts 'Field Searching'.pastel(:blue)
|
142
|
-
puts ' --[key]=[value]'
|
143
|
-
puts ' Search in key for value'
|
144
|
-
puts ' Example: --path=mirror/pull'
|
145
|
-
puts
|
146
|
-
|
147
141
|
puts 'Search specific logs'.pastel(:blue)
|
148
142
|
puts ' Any non dash parameters will be the log list to search from'
|
149
143
|
puts " Ex: log filter --path=api sidekiq/current (hint: use `#{'ls'.pastel(:yellow)}` for log names"
|
150
144
|
puts
|
151
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
|
+
|
152
174
|
puts 'Example Queries'.pastel(:blue)
|
153
175
|
puts " Also see #{'examples'.pastel(:bright_blue)} for even more examples"
|
154
176
|
puts ' log filter --class=BuildFinishedWorker sidekiq/current --slice=time,message'
|
@@ -156,7 +178,208 @@ module GreenHat
|
|
156
178
|
|
157
179
|
puts
|
158
180
|
end
|
159
|
-
|
181
|
+
|
182
|
+
def self.help_index
|
183
|
+
{
|
184
|
+
title: [
|
185
|
+
"\u2500".pastel(:cyan) * 20,
|
186
|
+
'Filter'.pastel(:yellow),
|
187
|
+
"\u2500".pastel(:cyan) * 20
|
188
|
+
],
|
189
|
+
options: [
|
190
|
+
'Options'.pastel(:blue)
|
191
|
+
],
|
192
|
+
|
193
|
+
raw: [
|
194
|
+
'--raw'.pastel(:green),
|
195
|
+
' Disable formatting and page/less'
|
196
|
+
],
|
197
|
+
|
198
|
+
page: [
|
199
|
+
'--page'.pastel(:green),
|
200
|
+
' Specifically enable or disable paging',
|
201
|
+
' E.g. --page (default to true), --page=true, --page=false'
|
202
|
+
],
|
203
|
+
|
204
|
+
round: ['--round'.pastel(:green),
|
205
|
+
' Attempt to round all integers. Default: 2.',
|
206
|
+
' E.g. --round, --round=3, --round=0'],
|
207
|
+
|
208
|
+
limit: [
|
209
|
+
|
210
|
+
'--limit'.pastel(:green),
|
211
|
+
' Limit total output lines. Disabled by default. Default without value is based on screen height',
|
212
|
+
' E.g. --limit, --limit=5'
|
213
|
+
],
|
214
|
+
|
215
|
+
json: [
|
216
|
+
'--json'.pastel(:green),
|
217
|
+
' Print output back into JSON'
|
218
|
+
],
|
219
|
+
|
220
|
+
or: [
|
221
|
+
'--or'.pastel(:green),
|
222
|
+
' Filters will use OR instead of AND (all match vs any match)'
|
223
|
+
],
|
224
|
+
|
225
|
+
total: [
|
226
|
+
'--total'.pastel(:green),
|
227
|
+
' Show total count, duration, start/end time for matching entries'
|
228
|
+
],
|
229
|
+
|
230
|
+
fields: [
|
231
|
+
'--fields'.pastel(:green),
|
232
|
+
' Print only Available fields for selected files'
|
233
|
+
],
|
234
|
+
|
235
|
+
slice: [
|
236
|
+
'--slice'.pastel(:green),
|
237
|
+
' Extract specific fields from entries (slice multiple with comma)',
|
238
|
+
' Ex: --slice=path or --slice=path,params'
|
239
|
+
|
240
|
+
],
|
241
|
+
|
242
|
+
except: [
|
243
|
+
'--except'.pastel(:green),
|
244
|
+
' Exclude specific fields (except multiple with comma)',
|
245
|
+
' Ex: --except=params --except=params,path'
|
246
|
+
|
247
|
+
],
|
248
|
+
|
249
|
+
exists: [
|
250
|
+
'--exists'.pastel(:green),
|
251
|
+
' Ensure field exists regardless of contents',
|
252
|
+
' Ex: --exists=params --exists=params,path'
|
253
|
+
|
254
|
+
],
|
255
|
+
|
256
|
+
stats: [
|
257
|
+
'--stats'.pastel(:green),
|
258
|
+
' Order/Count occurrances by field. Combine with `truncate` for key names',
|
259
|
+
' Ex: --stats=params --except=params,path'
|
260
|
+
|
261
|
+
],
|
262
|
+
|
263
|
+
uniq: [
|
264
|
+
'--uniq'.pastel(:green),
|
265
|
+
' Show unique values only',
|
266
|
+
' Ex: --uniq=params --uniq=params,path'
|
267
|
+
|
268
|
+
],
|
269
|
+
|
270
|
+
pluck: [
|
271
|
+
'--pluck'.pastel(:green),
|
272
|
+
' Extract values from entries',
|
273
|
+
' Ex: --pluck=params --pluck=params,path'
|
274
|
+
|
275
|
+
],
|
276
|
+
|
277
|
+
archive: [
|
278
|
+
'--archive'.pastel(:green),
|
279
|
+
' Limit to specific archvie name (partial matching /inclusive). Matching SOS tar.gz name',
|
280
|
+
' Ex: --archive=dev-gitlab_20210622154626, --archive=202106,202107'
|
281
|
+
|
282
|
+
],
|
283
|
+
|
284
|
+
sort: [
|
285
|
+
'--sort'.pastel(:green),
|
286
|
+
' Sort by multiple fields',
|
287
|
+
' Ex: --sort=duration_s,db_duration_s'
|
288
|
+
|
289
|
+
],
|
290
|
+
|
291
|
+
reverse: [
|
292
|
+
'--reverse'.pastel(:green),
|
293
|
+
' Reverse all results',
|
294
|
+
' Ex: --reverse'
|
295
|
+
|
296
|
+
],
|
297
|
+
|
298
|
+
combine: [
|
299
|
+
'--combine'.pastel(:green),
|
300
|
+
' Omit archive identifier dividers. Useful with sort or time filters',
|
301
|
+
' Ex: --combine'
|
302
|
+
|
303
|
+
],
|
304
|
+
|
305
|
+
case: [
|
306
|
+
'--case'.pastel(:green),
|
307
|
+
' Exact case match. Defaults to case insensitive',
|
308
|
+
' Ex: --case; --name=Jon, --name=jane --case'
|
309
|
+
|
310
|
+
],
|
311
|
+
|
312
|
+
exact: [
|
313
|
+
'--exact'.pastel(:green),
|
314
|
+
' Exact parameter/value match. Defaults to partial match',
|
315
|
+
' Ex: --field=CommonPartial --exact'
|
316
|
+
|
317
|
+
],
|
318
|
+
|
319
|
+
start: [
|
320
|
+
'--start'.pastel(:green),
|
321
|
+
' Show events after specified time. Filtered by the `time` field',
|
322
|
+
' Use with `--end` for between selections',
|
323
|
+
' Ex: log filter --start="2021-06-22 14:44 UTC" --end="2021-06-22 14:45 UTC"'
|
324
|
+
|
325
|
+
],
|
326
|
+
|
327
|
+
end: [
|
328
|
+
'--end'.pastel(:green),
|
329
|
+
' Show events before specified time. Filtered by the `time` field',
|
330
|
+
' Use with `--start` for between selections',
|
331
|
+
' Ex: log filter --end="2021-06-22"'
|
332
|
+
],
|
333
|
+
|
334
|
+
time_zone: [
|
335
|
+
'--time_zone'.pastel(:green),
|
336
|
+
' Manipulate the `time` field into a specific timezone',
|
337
|
+
' Ex: log filter --time_zone=EDT'
|
338
|
+
|
339
|
+
],
|
340
|
+
|
341
|
+
text: [
|
342
|
+
'--text'.pastel(:green),
|
343
|
+
' Full entry text searching (slow)',
|
344
|
+
' --text="anything here"'
|
345
|
+
],
|
346
|
+
|
347
|
+
table_style: [
|
348
|
+
'--table_style'.pastel(:green),
|
349
|
+
' Renderer used for formatted output. basic, ascii, or unicode(default)',
|
350
|
+
' Ex: log filter --table_style=base'
|
351
|
+
],
|
352
|
+
|
353
|
+
truncate: [
|
354
|
+
'--truncate'.pastel(:green),
|
355
|
+
' Truncate field length. On by default (4 rows). Performance issues!',
|
356
|
+
' Disable with --truncate=0'.pastel(:bright_red),
|
357
|
+
' Ex: --truncate=200, --truncate=2048"'
|
358
|
+
],
|
359
|
+
|
360
|
+
field: [
|
361
|
+
'Field Searching'.pastel(:blue),
|
362
|
+
' --[key]=[value]',
|
363
|
+
' Search in key for value',
|
364
|
+
' Example: --path=mirror/pull'
|
365
|
+
],
|
366
|
+
|
367
|
+
ls: [
|
368
|
+
'Search specific logs'.pastel(:blue),
|
369
|
+
' Any non dash parameters will be the log list to search from',
|
370
|
+
" Ex: log filter --path=api sidekiq/current (hint: use `#{'ls'.pastel(:yellow)}` for log names"
|
371
|
+
],
|
372
|
+
|
373
|
+
examples: [
|
374
|
+
'Example Queries'.pastel(:blue),
|
375
|
+
" Also see #{'examples'.pastel(:bright_blue)} for even more examples",
|
376
|
+
' log filter --class=BuildFinishedWorker sidekiq/current --slice=time,message',
|
377
|
+
' log filter gitlab-rails/api_json.log --slice=ua --uniq=ua --ua=gitlab-runner'
|
378
|
+
]
|
379
|
+
|
380
|
+
}
|
381
|
+
end
|
382
|
+
# rubocop:enable Metrics/MethodLength,Metrics/ModuleLength,Layout/LineLength
|
160
383
|
end
|
161
384
|
end
|
162
385
|
end
|
data/lib/greenhat/shell/log.rb
CHANGED
@@ -2,6 +2,7 @@ module GreenHat
|
|
2
2
|
# CLI Helper
|
3
3
|
module Shell
|
4
4
|
# Logs
|
5
|
+
# rubocop:disable Metrics/ModuleLength
|
5
6
|
module Log
|
6
7
|
def self.auto_complete(list, word)
|
7
8
|
# Argument Parsing
|
@@ -47,6 +48,7 @@ module GreenHat
|
|
47
48
|
puts ' filter'.pastel(:green)
|
48
49
|
puts " Primary way for log searching within greenhat. See #{'filter_help'.pastel(:blue)}"
|
49
50
|
puts ' Time, round, slice/except, and/or, stats, uniq, sort'
|
51
|
+
puts " #{'filter_help'.pastel(:blue)} supports filtering Ex: #{'filter_help stats'.pastel(:blue)}"
|
50
52
|
puts
|
51
53
|
|
52
54
|
puts ' show'.pastel(:green)
|
@@ -57,13 +59,33 @@ module GreenHat
|
|
57
59
|
puts " General full text by file searching. See #{'search_help'.pastel(:blue)}"
|
58
60
|
puts
|
59
61
|
|
62
|
+
puts ' save'.pastel(:green)
|
63
|
+
puts ' Save the last query result into a new searchable object'
|
64
|
+
puts
|
65
|
+
|
66
|
+
puts ' write'.pastel(:green)
|
67
|
+
puts ' Write the last query result into a local file'
|
68
|
+
puts
|
69
|
+
|
70
|
+
puts ' visualize'.pastel(:green)
|
71
|
+
puts ' Load web services and formulate last query for the UI'
|
72
|
+
puts
|
73
|
+
|
60
74
|
puts ShellHelper::List.help
|
61
75
|
|
62
76
|
puts "See #{'examples'.pastel(:bright_blue)} for query examples"
|
63
77
|
end
|
64
78
|
|
65
|
-
def self.filter_help
|
66
|
-
|
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
|
86
|
+
|
87
|
+
puts list.values.map { |x| x.join("\n") }.join("\n\n")
|
88
|
+
end
|
67
89
|
end
|
68
90
|
|
69
91
|
def self.ls(args = [])
|
@@ -80,6 +102,95 @@ module GreenHat
|
|
80
102
|
ShellHelper.show files.map(&:data).flatten
|
81
103
|
end
|
82
104
|
|
105
|
+
def self.save(raw = [])
|
106
|
+
if ShellHelper::Log.last.nil?
|
107
|
+
puts 'No previous query found'.pastel(:red)
|
108
|
+
puts 'Run a query first then save to store as a new log'
|
109
|
+
puts
|
110
|
+
puts "Try #{'nginx/gitlab_access.log --status!=200'.pastel(:green)} then #{'save'.pastel(:green)}"
|
111
|
+
true
|
112
|
+
end
|
113
|
+
|
114
|
+
name = if raw.empty?
|
115
|
+
Cli.prompt.ask('Log/name to save the results to? '.pastel(:yellow))
|
116
|
+
else
|
117
|
+
raw.first
|
118
|
+
end
|
119
|
+
|
120
|
+
if name.blank?
|
121
|
+
puts 'Name required'.pastel(:red)
|
122
|
+
return true
|
123
|
+
end
|
124
|
+
|
125
|
+
results = ShellHelper.filter_internal ShellHelper::Log.last
|
126
|
+
|
127
|
+
# Don't save empty results
|
128
|
+
if results.empty?
|
129
|
+
puts 'No results'.pastel(:red)
|
130
|
+
ShellHelper::Log.no_files_warning(files) if ShellHelper.find_things(files, flags).count.zero?
|
131
|
+
return false
|
132
|
+
end
|
133
|
+
|
134
|
+
Thing.new.query_save(results, name)
|
135
|
+
puts "#{name.pastel(:green)} Saved!"
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.write(raw = [])
|
139
|
+
if ShellHelper::Log.last.nil?
|
140
|
+
puts 'No previous query found'.pastel(:red)
|
141
|
+
puts 'Run a query first then write'
|
142
|
+
puts
|
143
|
+
puts "Try #{'nginx/gitlab_access.log --status!=200'.pastel(:green)} then #{'save'.pastel(:green)}"
|
144
|
+
true
|
145
|
+
end
|
146
|
+
|
147
|
+
name = if raw.empty?
|
148
|
+
Cli.prompt.ask('Log/name to save the results to? '.pastel(:yellow))
|
149
|
+
else
|
150
|
+
raw.first
|
151
|
+
end
|
152
|
+
|
153
|
+
if name.blank?
|
154
|
+
puts 'Name required'.pastel(:red)
|
155
|
+
return true
|
156
|
+
end
|
157
|
+
|
158
|
+
results = ShellHelper.filter_internal ShellHelper::Log.last
|
159
|
+
|
160
|
+
# Don't save empty results
|
161
|
+
if results.empty?
|
162
|
+
puts 'No results'.pastel(:red)
|
163
|
+
ShellHelper::Log.no_files_warning(files) if ShellHelper.find_things(files, flags).count.zero?
|
164
|
+
return false
|
165
|
+
end
|
166
|
+
|
167
|
+
all = results.map { |row| Oj.dump(row) }
|
168
|
+
File.write(name, all.join("\n"))
|
169
|
+
puts "#{name.pastel(:green)} File Written!"
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.visualize
|
173
|
+
if ShellHelper::Log.last.nil?
|
174
|
+
puts 'No previous query found'.pastel(:red)
|
175
|
+
puts 'Run a query first then visualize to load it in the chart web page'
|
176
|
+
puts
|
177
|
+
puts "Try #{'nginx/gitlab_access.log --status!=200'.pastel(:green)} then #{'visualize'.pastel(:green)}"
|
178
|
+
return true
|
179
|
+
end
|
180
|
+
|
181
|
+
# Load Required Files
|
182
|
+
require 'greenhat/web'
|
183
|
+
|
184
|
+
unless GreenHat::Web.alive?
|
185
|
+
GreenHat::Web.start
|
186
|
+
sleep 0.2
|
187
|
+
end
|
188
|
+
|
189
|
+
url = "http://localhost:4567/chart/time?query=#{CGI.escape(ShellHelper::Log.last)}"
|
190
|
+
|
191
|
+
GreenHat::Platform.open url
|
192
|
+
end
|
193
|
+
|
83
194
|
# ========================================================================
|
84
195
|
# Filter (See Filter Help)
|
85
196
|
# ========================================================================
|
@@ -94,6 +205,8 @@ module GreenHat
|
|
94
205
|
return true
|
95
206
|
end
|
96
207
|
|
208
|
+
ShellHelper::Log.last = raw
|
209
|
+
|
97
210
|
# Argument Parsing
|
98
211
|
files, flags, args = Args.parse(raw)
|
99
212
|
|
@@ -104,7 +217,7 @@ module GreenHat
|
|
104
217
|
|
105
218
|
# Skip and Print Total if set
|
106
219
|
if flags[:total]
|
107
|
-
ShellHelper.total_count(results)
|
220
|
+
ShellHelper.total_count(results, flags)
|
108
221
|
return true
|
109
222
|
end
|
110
223
|
|
@@ -117,13 +230,13 @@ module GreenHat
|
|
117
230
|
# Check Search Results
|
118
231
|
if results.instance_of?(Hash) && results.values.flatten.empty?
|
119
232
|
puts 'No results'.pastel(:red)
|
233
|
+
ShellHelper::Log.no_files_warning(files) if ShellHelper.find_things(files, flags).count.zero?
|
234
|
+
elsif flags[:pipe]
|
235
|
+
Pipe.show(results, flags[:pipe])
|
120
236
|
else
|
121
237
|
# This causes the key 'colorized' output to also be included
|
122
238
|
ShellHelper.show(results.to_a.compact.flatten, flags)
|
123
239
|
end
|
124
|
-
|
125
|
-
# log filter --path='cloud/gitlab-automation' --path='/pull' --all
|
126
|
-
# log filter --project=thingy --other_filter=asdf *
|
127
240
|
rescue StandardError => e
|
128
241
|
LogBot.fatal('Filter', message: e.message)
|
129
242
|
ap e.backtrace
|
@@ -152,9 +265,25 @@ module GreenHat
|
|
152
265
|
puts 'Count/% occurences for both user and remote ip fields'.pastel(:bright_green)
|
153
266
|
puts 'gitlab-rails/api_json.log --stats=meta.user,meta.remote_ip --exists=meta.user'
|
154
267
|
puts
|
155
|
-
end
|
156
268
|
|
269
|
+
puts 'Sidekiq jobs that took over 5 seconds excluding LdapSyncWorker jobs'.pastel(:bright_green)
|
270
|
+
puts 'sidekiq/current --duration_s>=5 --class!=LdapSyncWorker'
|
271
|
+
puts
|
272
|
+
|
273
|
+
puts 'Search access logs for runner requests, exclude specific runner version'.pastel(:bright_green)
|
274
|
+
puts 'nginx/gitlab_access.log --http_user_agent=gitlab-runner --http_user_agent!=13.12.0'
|
275
|
+
puts
|
276
|
+
|
277
|
+
puts 'Get a list of unique Gitaly error messages for a specific project'.pastel(:bright_green)
|
278
|
+
puts 'filter --level=error --grpc.request.glProjectPath=path/to/project gitaly/current --slice=error --uniq=error'
|
279
|
+
puts
|
280
|
+
|
281
|
+
puts 'Show workhorse duration/URI. Filter by duration bounds'.pastel(:bright_green)
|
282
|
+
puts 'gitlab-workhorse/current --duration_ms>=30000 --duration_ms<=45000 --slice=duration_ms,uri'
|
283
|
+
puts
|
284
|
+
end
|
157
285
|
# rubocop:enable Layout/LineLength
|
286
|
+
|
158
287
|
# ========================================================================
|
159
288
|
# Search (Full Text / String Search)
|
160
289
|
# ========================================================================
|
@@ -169,13 +298,15 @@ module GreenHat
|
|
169
298
|
|
170
299
|
# Skip and Print Total if set
|
171
300
|
if flags[:total]
|
172
|
-
ShellHelper.total_count(results)
|
301
|
+
ShellHelper.total_count(results, flags)
|
173
302
|
return true
|
174
303
|
end
|
175
304
|
|
176
305
|
# Check Search Results
|
177
306
|
if results.values.flatten.empty?
|
178
307
|
puts 'No results'.pastel(:red)
|
308
|
+
ShellHelper::Log.no_files_warning(files) if ShellHelper.find_things(files, flags).count.zero?
|
309
|
+
|
179
310
|
else
|
180
311
|
# This causes the key 'colorized' output to also be included
|
181
312
|
ShellHelper.show(results.to_a.compact.flatten, flags)
|
@@ -240,7 +371,7 @@ module GreenHat
|
|
240
371
|
puts 'log search --text=BuildHooksWorker --text!=start --slice=enqueued_at sidekiq/current'
|
241
372
|
puts
|
242
373
|
end
|
243
|
-
# rubocop:enable Metrics/MethodLength
|
374
|
+
# rubocop:enable Metrics/MethodLength,Metrics/ModuleLength
|
244
375
|
|
245
376
|
# ------------------------------------------------------------------------
|
246
377
|
end
|
@@ -251,9 +382,22 @@ module GreenHat
|
|
251
382
|
module ShellHelper
|
252
383
|
# Log Helpers
|
253
384
|
module Log
|
385
|
+
def self.last=(value)
|
386
|
+
@last = value.join(' ')
|
387
|
+
end
|
388
|
+
|
389
|
+
def self.last
|
390
|
+
@last
|
391
|
+
end
|
392
|
+
|
254
393
|
def self.list
|
255
394
|
Thing.all.select(&:log)
|
256
395
|
end
|
396
|
+
|
397
|
+
def self.no_files_warning(files)
|
398
|
+
puts "No matching files found for pattern #{files.to_s.pastel(:yellow)}"
|
399
|
+
puts "See #{'ls'.pastel(:blue)} for available files"
|
400
|
+
end
|
257
401
|
end
|
258
402
|
# --------
|
259
403
|
end
|