greenhat 0.3.5 → 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 +1 -3
- data/lib/greenhat/accessors/gitlab.rb +5 -2
- data/lib/greenhat/archive.rb +7 -2
- data/lib/greenhat/cli.rb +36 -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 +32 -10
- data/lib/greenhat/shell/log.rb +142 -7
- data/lib/greenhat/shell/markdown.rb +16 -8
- 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 +47 -15
- data/lib/greenhat/shell/shell_helper.rb +92 -101
- data/lib/greenhat/shell.rb +7 -0
- data/lib/greenhat/thing/file_types.rb +28 -0
- data/lib/greenhat/thing/formatters/json.rb +4 -0
- data/lib/greenhat/thing/formatters/nginx.rb +6 -2
- 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 +68 -2
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
|
@@ -58,6 +59,18 @@ module GreenHat
|
|
58
59
|
puts " General full text by file searching. See #{'search_help'.pastel(:blue)}"
|
59
60
|
puts
|
60
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
|
+
|
61
74
|
puts ShellHelper::List.help
|
62
75
|
|
63
76
|
puts "See #{'examples'.pastel(:bright_blue)} for query examples"
|
@@ -89,6 +102,95 @@ module GreenHat
|
|
89
102
|
ShellHelper.show files.map(&:data).flatten
|
90
103
|
end
|
91
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
|
+
|
92
194
|
# ========================================================================
|
93
195
|
# Filter (See Filter Help)
|
94
196
|
# ========================================================================
|
@@ -103,6 +205,8 @@ module GreenHat
|
|
103
205
|
return true
|
104
206
|
end
|
105
207
|
|
208
|
+
ShellHelper::Log.last = raw
|
209
|
+
|
106
210
|
# Argument Parsing
|
107
211
|
files, flags, args = Args.parse(raw)
|
108
212
|
|
@@ -113,7 +217,7 @@ module GreenHat
|
|
113
217
|
|
114
218
|
# Skip and Print Total if set
|
115
219
|
if flags[:total]
|
116
|
-
ShellHelper.total_count(results)
|
220
|
+
ShellHelper.total_count(results, flags)
|
117
221
|
return true
|
118
222
|
end
|
119
223
|
|
@@ -126,13 +230,13 @@ module GreenHat
|
|
126
230
|
# Check Search Results
|
127
231
|
if results.instance_of?(Hash) && results.values.flatten.empty?
|
128
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])
|
129
236
|
else
|
130
237
|
# This causes the key 'colorized' output to also be included
|
131
238
|
ShellHelper.show(results.to_a.compact.flatten, flags)
|
132
239
|
end
|
133
|
-
|
134
|
-
# log filter --path='cloud/gitlab-automation' --path='/pull' --all
|
135
|
-
# log filter --project=thingy --other_filter=asdf *
|
136
240
|
rescue StandardError => e
|
137
241
|
LogBot.fatal('Filter', message: e.message)
|
138
242
|
ap e.backtrace
|
@@ -161,9 +265,25 @@ module GreenHat
|
|
161
265
|
puts 'Count/% occurences for both user and remote ip fields'.pastel(:bright_green)
|
162
266
|
puts 'gitlab-rails/api_json.log --stats=meta.user,meta.remote_ip --exists=meta.user'
|
163
267
|
puts
|
164
|
-
end
|
165
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
|
166
285
|
# rubocop:enable Layout/LineLength
|
286
|
+
|
167
287
|
# ========================================================================
|
168
288
|
# Search (Full Text / String Search)
|
169
289
|
# ========================================================================
|
@@ -178,13 +298,15 @@ module GreenHat
|
|
178
298
|
|
179
299
|
# Skip and Print Total if set
|
180
300
|
if flags[:total]
|
181
|
-
ShellHelper.total_count(results)
|
301
|
+
ShellHelper.total_count(results, flags)
|
182
302
|
return true
|
183
303
|
end
|
184
304
|
|
185
305
|
# Check Search Results
|
186
306
|
if results.values.flatten.empty?
|
187
307
|
puts 'No results'.pastel(:red)
|
308
|
+
ShellHelper::Log.no_files_warning(files) if ShellHelper.find_things(files, flags).count.zero?
|
309
|
+
|
188
310
|
else
|
189
311
|
# This causes the key 'colorized' output to also be included
|
190
312
|
ShellHelper.show(results.to_a.compact.flatten, flags)
|
@@ -249,7 +371,7 @@ module GreenHat
|
|
249
371
|
puts 'log search --text=BuildHooksWorker --text!=start --slice=enqueued_at sidekiq/current'
|
250
372
|
puts
|
251
373
|
end
|
252
|
-
# rubocop:enable Metrics/MethodLength
|
374
|
+
# rubocop:enable Metrics/MethodLength,Metrics/ModuleLength
|
253
375
|
|
254
376
|
# ------------------------------------------------------------------------
|
255
377
|
end
|
@@ -260,9 +382,22 @@ module GreenHat
|
|
260
382
|
module ShellHelper
|
261
383
|
# Log Helpers
|
262
384
|
module Log
|
385
|
+
def self.last=(value)
|
386
|
+
@last = value.join(' ')
|
387
|
+
end
|
388
|
+
|
389
|
+
def self.last
|
390
|
+
@last
|
391
|
+
end
|
392
|
+
|
263
393
|
def self.list
|
264
394
|
Thing.all.select(&:log)
|
265
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
|
266
401
|
end
|
267
402
|
# --------
|
268
403
|
end
|
@@ -58,6 +58,9 @@ module GreenHat
|
|
58
58
|
''
|
59
59
|
]
|
60
60
|
|
61
|
+
# GitLab Version
|
62
|
+
output << "**GitLab #{gitlab_version}**\n" if gitlab_manifest || gitlab_status
|
63
|
+
|
61
64
|
# OS
|
62
65
|
output << "**OS**\n"
|
63
66
|
|
@@ -79,8 +82,6 @@ module GreenHat
|
|
79
82
|
end
|
80
83
|
|
81
84
|
# Gitlab
|
82
|
-
output << "**GitLab**\n" if gitlab_manifest || gitlab_status
|
83
|
-
output << gitlab_version if gitlab_manifest
|
84
85
|
output << gitlab_services if gitlab_status
|
85
86
|
|
86
87
|
output << ''
|
@@ -172,7 +173,8 @@ module GreenHat
|
|
172
173
|
results = ShellHelper.filter_internal([
|
173
174
|
'gitlab-rails/application_json.log',
|
174
175
|
'--message!="Cannot obtain an exclusive lease"',
|
175
|
-
'--severity=error'
|
176
|
+
'--severity=error',
|
177
|
+
"--archive=#{archive.name}"
|
176
178
|
].join(' '))
|
177
179
|
|
178
180
|
"Application: #{results.count}"
|
@@ -195,7 +197,13 @@ module GreenHat
|
|
195
197
|
end
|
196
198
|
|
197
199
|
def gitlab_version
|
198
|
-
|
200
|
+
txt = gitlab_manifest.data.dig(:software, :'gitlab-rails', :display_version) || gitlab_manifest.data.build_version
|
201
|
+
|
202
|
+
if txt.include? '-ce'
|
203
|
+
txt += ' - [😱 CE](https://about.gitlab.com/support/statement-of-support.html#free-and-community-edition-users)!'
|
204
|
+
end
|
205
|
+
|
206
|
+
"Version: #{txt}"
|
199
207
|
end
|
200
208
|
|
201
209
|
def hostname
|
@@ -295,10 +303,10 @@ module GreenHat
|
|
295
303
|
|
296
304
|
pad = 6
|
297
305
|
list = [
|
298
|
-
"#{title('Total', pad)} #{number_to_human_size(free.total.to_i * 1024**2)}",
|
299
|
-
"#{title('Used', pad)} #{number_to_human_size(free.used.to_i * 1024**2)}",
|
300
|
-
"#{title('Free', pad)} #{number_to_human_size(free.free.to_i * 1024**2)}",
|
301
|
-
"#{title('Avail', pad)} #{number_to_human_size(free.available.to_i * 1024**2)}"
|
306
|
+
"#{title('Total', pad)} #{number_to_human_size(free.total.to_i * (1024**2))}",
|
307
|
+
"#{title('Used', pad)} #{number_to_human_size(free.used.to_i * (1024**2))}",
|
308
|
+
"#{title('Free', pad)} #{number_to_human_size(free.free.to_i * (1024**2))}",
|
309
|
+
"#{title('Avail', pad)} #{number_to_human_size(free.available.to_i * (1024**2))}"
|
302
310
|
]
|
303
311
|
|
304
312
|
# Keep Alphabetical Sort
|
@@ -0,0 +1,54 @@
|
|
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
|
data/lib/greenhat/shell/page.rb
CHANGED
@@ -8,7 +8,7 @@ module GreenHat
|
|
8
8
|
# Pass if Explicitly Set / Inverse for skip
|
9
9
|
return !flags[:page] if flags.key? :page
|
10
10
|
|
11
|
-
LogBot.debug('Page', count_rows(data, flags)) if ENV['DEBUG']
|
11
|
+
LogBot.debug('Page Skip', count_rows(data, flags)) if ENV['DEBUG']
|
12
12
|
|
13
13
|
count_rows(data, flags)
|
14
14
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module GreenHat
|
2
|
+
# Helper for piping arguments
|
3
|
+
module Pipe
|
4
|
+
def self.show(results, arg)
|
5
|
+
uuid = SecureRandom.uuid # File Placeholder
|
6
|
+
write(results, uuid)
|
7
|
+
command(uuid, arg)
|
8
|
+
delete(uuid)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Final execution into pipe
|
12
|
+
def self.command(uuid, arg)
|
13
|
+
puts `cat "#{file(uuid)}" | #{arg}`
|
14
|
+
end
|
15
|
+
|
16
|
+
# File path helper
|
17
|
+
def self.file(uuid)
|
18
|
+
"#{$TMP}/#{uuid}.txt"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Helper to write all into split lines for pipe
|
22
|
+
def self.write(results, uuid)
|
23
|
+
File.write(file(uuid), results.map(&:flatten).flatten.join("\n"))
|
24
|
+
end
|
25
|
+
|
26
|
+
# Clean up created file
|
27
|
+
def self.delete(uuid)
|
28
|
+
File.delete file(uuid)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module GreenHat
|
2
|
+
# Common Helpers
|
3
|
+
module Platform
|
4
|
+
def self.platform
|
5
|
+
if @platform
|
6
|
+
@platform
|
7
|
+
else
|
8
|
+
require 'tty-platform'
|
9
|
+
@platform ||= TTY::Platform.new
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.open(url = 'http://localhost:4567/chart/time')
|
15
|
+
cmd = if platform.linux? || platform.unix?
|
16
|
+
'xdg-open'
|
17
|
+
elsif platform.mac?
|
18
|
+
'open'
|
19
|
+
end
|
20
|
+
|
21
|
+
# platform.windows? # => false
|
22
|
+
# platform.unix? # => true
|
23
|
+
# platform.linux? # => false
|
24
|
+
# platform.mac? # => true
|
25
|
+
system("#{cmd} '#{url}'")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -12,7 +12,11 @@ module GreenHat
|
|
12
12
|
Archive.all
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
output = archives.map { |x| x.report(flags) }.map(&:show).flatten
|
16
|
+
|
17
|
+
flags[:page] = true if flags.full && !flags.raw
|
18
|
+
|
19
|
+
ShellHelper.show(output, flags)
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -23,15 +27,16 @@ module GreenHat
|
|
23
27
|
class Report
|
24
28
|
include ActionView::Helpers::NumberHelper
|
25
29
|
|
26
|
-
attr_accessor :archive, :host, :os_release, :selinux_status, :cpu, :uname,
|
30
|
+
attr_accessor :archive, :flags, :host, :os_release, :selinux_status, :cpu, :uname,
|
27
31
|
:timedatectl, :uptime, :meminfo, :gitlab_manifest, :gitlab_status,
|
28
|
-
:production_log, :api_log, :
|
32
|
+
:production_log, :api_log, :sidekiq_log,
|
29
33
|
:exceptions_log, :gitaly_log, :free_m, :disk_free
|
30
34
|
|
31
35
|
# Find Needed Files for Report
|
32
36
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
33
|
-
def initialize(archive)
|
37
|
+
def initialize(archive, flags)
|
34
38
|
self.archive = archive
|
39
|
+
self.flags = flags
|
35
40
|
self.host = archive.things.find { |x| x.name == 'hostname' }
|
36
41
|
self.os_release = archive.things.find { |x| x.name == 'etc/os-release' }
|
37
42
|
self.selinux_status = archive.things.find { |x| x.name == 'sestatus' }
|
@@ -45,7 +50,6 @@ module GreenHat
|
|
45
50
|
self.gitlab_status = archive.things.find { |x| x.name == 'gitlab_status' }
|
46
51
|
self.production_log = archive.things.find { |x| x.name == 'gitlab-rails/production_json.log' }
|
47
52
|
self.api_log = archive.things.find { |x| x.name == 'gitlab-rails/api_json.log' }
|
48
|
-
self.application_log = archive.things.find { |x| x.name == 'gitlab-rails/application_json.log' }
|
49
53
|
self.exceptions_log = archive.things.find { |x| x.name == 'gitlab-rails/exceptions_json.log' }
|
50
54
|
self.gitaly_log = archive.things.find { |x| x.name == 'gitaly/current' }
|
51
55
|
self.sidekiq_log = archive.things.find { |x| x.name == 'sidekiq/current' }
|
@@ -87,13 +91,16 @@ module GreenHat
|
|
87
91
|
output << 'GitLab'.pastel(:bright_yellow) if gitlab_manifest
|
88
92
|
output << gitlab_version if gitlab_manifest
|
89
93
|
output << gitlab_services if gitlab_status
|
90
|
-
output << title('Errors') if production_log || api_log ||
|
94
|
+
output << title('Errors') if production_log || api_log || sidekiq_log
|
91
95
|
output << production_errors if production_log
|
92
|
-
output << application_errors if
|
96
|
+
output << application_errors if archive.thing?('gitlab-rails/application_json.log')
|
93
97
|
output << sidekiq_errors if sidekiq_log
|
94
98
|
output << api_errors if api_log
|
95
99
|
output << exception_errors if exceptions_log
|
96
100
|
output << gitaly_errors if gitaly_log
|
101
|
+
output << workhorse_errors if archive.thing?('gitlab-workhorse/current')
|
102
|
+
|
103
|
+
full(output) if flags.full
|
97
104
|
|
98
105
|
# Final Space / Return
|
99
106
|
output << ''
|
@@ -101,6 +108,17 @@ module GreenHat
|
|
101
108
|
end
|
102
109
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
103
110
|
|
111
|
+
def full(output)
|
112
|
+
output << ''
|
113
|
+
output << 'FastStats Top'
|
114
|
+
Shell::Faststats.top(['--raw'], true).each { |x| output << x } # Page Row Helper
|
115
|
+
output << ''
|
116
|
+
|
117
|
+
output << 'FastStats Errors'
|
118
|
+
Shell::Faststats.errors(['--raw'], true).each { |x| output << x } # Page Row Helper
|
119
|
+
output << ''
|
120
|
+
end
|
121
|
+
|
104
122
|
def exception_errors
|
105
123
|
count = exceptions_log.data.count
|
106
124
|
color = count.zero? ? :green : :red
|
@@ -111,6 +129,21 @@ module GreenHat
|
|
111
129
|
].join
|
112
130
|
end
|
113
131
|
|
132
|
+
def workhorse_errors
|
133
|
+
results = ShellHelper.filter_internal([
|
134
|
+
'gitlab-workhorse/current',
|
135
|
+
'--level=error',
|
136
|
+
"--archive=#{archive.name}"
|
137
|
+
].join(' '))
|
138
|
+
|
139
|
+
color = results.count.zero? ? :green : :red
|
140
|
+
|
141
|
+
[
|
142
|
+
title(' Workhorse', :bright_red, 18),
|
143
|
+
results.count.to_s.pastel(color)
|
144
|
+
].join
|
145
|
+
end
|
146
|
+
|
114
147
|
def gitaly_errors
|
115
148
|
count = gitaly_log.data.count { |x| x.level == 'error' }
|
116
149
|
color = count.zero? ? :green : :red
|
@@ -145,7 +178,8 @@ module GreenHat
|
|
145
178
|
results = ShellHelper.filter_internal([
|
146
179
|
'gitlab-rails/application_json.log',
|
147
180
|
'--message!="Cannot obtain an exclusive lease"',
|
148
|
-
'--severity=error'
|
181
|
+
'--severity=error',
|
182
|
+
"--archive=#{archive.name}"
|
149
183
|
].join(' '))
|
150
184
|
|
151
185
|
count = results.count { |x| x&.severity == 'ERROR' }
|
@@ -300,13 +334,12 @@ module GreenHat
|
|
300
334
|
title('Usage'),
|
301
335
|
' ['.pastel(:bright_black),
|
302
336
|
'='.pastel(:green) * (used / 2),
|
303
|
-
' ' * (50 - used / 2),
|
337
|
+
' ' * (50 - (used / 2)),
|
304
338
|
']'.pastel(:bright_black),
|
305
339
|
" #{100 - percent(free, total)}%".pastel(:green) # Inverse
|
306
340
|
].join
|
307
341
|
end
|
308
342
|
|
309
|
-
# rubocop:disable Metrics/MethodLength
|
310
343
|
def memory_free
|
311
344
|
free = free_m.data.find { |x| x.kind == 'Mem' }
|
312
345
|
|
@@ -317,25 +350,25 @@ module GreenHat
|
|
317
350
|
output = []
|
318
351
|
unless free.total.blank?
|
319
352
|
output << title('Total', :cyan, 14)
|
320
|
-
output << number_to_human_size(free.total.to_i * 1024**2)
|
353
|
+
output << number_to_human_size(free.total.to_i * (1024**2))
|
321
354
|
output << "\n"
|
322
355
|
end
|
323
356
|
|
324
357
|
unless free.total.blank?
|
325
358
|
output << title('Used', :yellow, 14)
|
326
|
-
output << number_to_human_size(free.used.to_i * 1024**2)
|
359
|
+
output << number_to_human_size(free.used.to_i * (1024**2))
|
327
360
|
output << "\n"
|
328
361
|
end
|
329
362
|
|
330
363
|
unless free.total.blank?
|
331
364
|
output << title('Free', :blue, 14)
|
332
|
-
output << number_to_human_size(free.free.to_i * 1024**2)
|
365
|
+
output << number_to_human_size(free.free.to_i * (1024**2))
|
333
366
|
output << "\n"
|
334
367
|
end
|
335
368
|
|
336
369
|
unless free.total.blank?
|
337
370
|
output << title('Available', :green, 14)
|
338
|
-
output << number_to_human_size(free.available.to_i * 1024**2)
|
371
|
+
output << number_to_human_size(free.available.to_i * (1024**2))
|
339
372
|
output << "\n"
|
340
373
|
end
|
341
374
|
|
@@ -346,7 +379,6 @@ module GreenHat
|
|
346
379
|
rescue StandardError => e
|
347
380
|
LogBot.fatal('Memory', message: e.message, backtrace: e.backtrace.first)
|
348
381
|
end
|
349
|
-
# rubocop:enable Metrics/MethodLength
|
350
382
|
|
351
383
|
def disks
|
352
384
|
# GreenHat::Disk.df({archive: []})
|