greenhat 0.5.1 → 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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/greenhat/archive.rb +2 -0
  3. data/lib/greenhat/cli.rb +12 -2
  4. data/lib/greenhat/entrypoint.rb +36 -33
  5. data/lib/greenhat/logbot.rb +1 -1
  6. data/lib/greenhat/paper/flag_helper.rb +18 -0
  7. data/lib/greenhat/paper/paper_helper.rb +118 -0
  8. data/lib/greenhat/paper.rb +34 -0
  9. data/lib/greenhat/reports/builder.rb +98 -0
  10. data/lib/greenhat/reports/helpers.rb +101 -0
  11. data/lib/greenhat/reports/internal_methods.rb +156 -0
  12. data/lib/greenhat/reports/reports/errors.rb +49 -0
  13. data/lib/greenhat/reports/reports/faststats.rb +42 -0
  14. data/lib/greenhat/reports/reports/full.rb +143 -0
  15. data/lib/greenhat/reports/runner.rb +58 -0
  16. data/lib/greenhat/reports/shared.rb +37 -0
  17. data/lib/greenhat/reports/shell_helper.rb +34 -0
  18. data/lib/greenhat/reports.rb +79 -0
  19. data/lib/greenhat/settings.rb +6 -1
  20. data/lib/greenhat/shell/args.rb +9 -9
  21. data/lib/greenhat/shell/color_string.rb +1 -1
  22. data/lib/greenhat/shell/faststats.rb +24 -5
  23. data/lib/greenhat/shell/field_helper.rb +1 -1
  24. data/lib/greenhat/shell/filter_help.rb +36 -189
  25. data/lib/greenhat/shell/log.rb +18 -14
  26. data/lib/greenhat/shell/markdown.rb +355 -352
  27. data/lib/greenhat/shell/process.rb +11 -5
  28. data/lib/greenhat/shell/query.rb +183 -27
  29. data/lib/greenhat/shell/report.rb +415 -412
  30. data/lib/greenhat/shell/reports.rb +41 -0
  31. data/lib/greenhat/shell/shell_helper.rb +92 -34
  32. data/lib/greenhat/shell.rb +13 -2
  33. data/lib/greenhat/thing/file_types.rb +14 -0
  34. data/lib/greenhat/thing/formatters/clean_raw.rb +1 -1
  35. data/lib/greenhat/thing/formatters/runner_log.rb +70 -0
  36. data/lib/greenhat/thing/formatters/time_json.rb +12 -1
  37. data/lib/greenhat/thing/kind.rb +1 -1
  38. data/lib/greenhat/version.rb +1 -1
  39. data/lib/greenhat.rb +6 -8
  40. metadata +31 -4
  41. data/lib/greenhat/pry_helpers.rb +0 -51
  42. data/lib/greenhat/thing/super_log.rb +0 -1
@@ -1,412 +1,415 @@
1
- module GreenHat
2
- # Root Level Shell / Report Helper
3
- module Shell
4
- def self.report(raw)
5
- _files, flags, _args = Args.parse(raw)
6
-
7
- archives = if flags.archive
8
- Archive.all.select do |archive|
9
- flags.archive.any? { |x| archive.name.include? x.to_s }
10
- end
11
- else
12
- Archive.all
13
- end
14
-
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)
20
- end
21
- end
22
- end
23
-
24
- module GreenHat
25
- # Report Generator Helper
26
- # rubocop:disable Metrics/ClassLength
27
- class Report
28
- include ActionView::Helpers::NumberHelper
29
-
30
- attr_accessor :archive, :flags, :host, :os_release, :selinux_status, :cpu, :uname,
31
- :timedatectl, :uptime, :meminfo, :gitlab_manifest, :gitlab_status,
32
- :production_log, :api_log, :sidekiq_log,
33
- :exceptions_log, :gitaly_log, :free_m, :disk_free
34
-
35
- # Find Needed Files for Report
36
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
37
- def initialize(archive, flags)
38
- self.archive = archive
39
- self.flags = flags
40
- self.host = archive.things.find { |x| x.name == 'hostname' }
41
- self.os_release = archive.things.find { |x| x.name == 'etc/os-release' }
42
- self.selinux_status = archive.things.find { |x| x.name == 'sestatus' }
43
- self.cpu = archive.things.find { |x| x.name == 'lscpu' }
44
- self.uname = archive.things.find { |x| x.name == 'uname' }
45
- self.timedatectl = archive.things.find { |x| x.name == 'timedatectl' }
46
- self.uptime = archive.things.find { |x| x.name == 'uptime' }
47
- self.meminfo = archive.things.find { |x| x.name == 'meminfo' }
48
- self.free_m = archive.things.find { |x| x.name == 'free_m' }
49
- self.gitlab_manifest = archive.things.find { |x| x.name == 'gitlab/version-manifest.json' }
50
- self.gitlab_status = archive.things.find { |x| x.name == 'gitlab_status' }
51
- self.production_log = archive.things.find { |x| x.name == 'gitlab-rails/production_json.log' }
52
- self.api_log = archive.things.find { |x| x.name == 'gitlab-rails/api_json.log' }
53
- self.exceptions_log = archive.things.find { |x| x.name == 'gitlab-rails/exceptions_json.log' }
54
- self.gitaly_log = archive.things.find { |x| x.name == 'gitaly/current' }
55
- self.sidekiq_log = archive.things.find { |x| x.name == 'sidekiq/current' }
56
- self.disk_free = archive.things.find { |x| x.name == 'df_hT' }
57
- end
58
-
59
- def show
60
- output = [
61
- archive.friendly_name.pastel(:blue)
62
- ]
63
-
64
- # OS
65
- output << 'OS'.pastel(:bright_yellow)
66
- output << hostname if host
67
- output << distro if os_release
68
- output << selinux if selinux_status
69
- # output << arch if cpu
70
- output << kernel if uname
71
- output << sys_time if timedatectl
72
- output << sys_uptime if uptime
73
- output << load_average if uptime && cpu
74
- output << ''
75
-
76
- # Memory
77
- if meminfo || free_m
78
- output << 'Memory'.pastel(:bright_yellow)
79
- output << memory_perc if meminfo
80
- output << memory_free if free_m
81
- output << ''
82
- end
83
-
84
- # Disk
85
- if disk_free
86
- output << disks
87
- output << ''
88
- end
89
-
90
- # Gitlab
91
- output << 'GitLab'.pastel(:bright_yellow) if gitlab_manifest
92
- output << gitlab_version if gitlab_manifest
93
- output << gitlab_services if gitlab_status
94
- output << title('Errors') if production_log || api_log || sidekiq_log
95
- output << production_errors if production_log
96
- output << application_errors if archive.thing?('gitlab-rails/application_json.log')
97
- output << sidekiq_errors if sidekiq_log
98
- output << api_errors if api_log
99
- output << exception_errors if exceptions_log
100
- output << gitaly_errors if gitaly_log
101
- output << workhorse_errors if archive.thing?('gitlab-workhorse/current')
102
-
103
- full(output) if flags.full
104
-
105
- # Final Space / Return
106
- output << ''
107
- output
108
- end
109
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
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
-
122
- def exception_errors
123
- count = exceptions_log.data.count
124
- color = count.zero? ? :green : :red
125
-
126
- [
127
- title(' Exception', :bright_red, 18),
128
- count.to_s.pastel(color)
129
- ].join
130
- end
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
-
147
- def gitaly_errors
148
- count = gitaly_log.data.count { |x| x.level == 'error' }
149
- color = count.zero? ? :green : :red
150
-
151
- [
152
- title(' Gitaly', :bright_red, 18),
153
- count.to_s.pastel(color)
154
- ].join
155
- end
156
-
157
- def production_errors
158
- count = production_log.data.count { |x| x.status == 500 }
159
- color = count.zero? ? :green : :red
160
-
161
- [
162
- title(' Production', :bright_red, 18),
163
- count.to_s.pastel(color)
164
- ].join
165
- end
166
-
167
- def api_errors
168
- count = api_log.data.count { |x| x.status == 500 }
169
- color = count.zero? ? :green : :red
170
-
171
- [
172
- title(' API', :bright_red, 18),
173
- count.to_s.pastel(color)
174
- ].join
175
- end
176
-
177
- def application_errors
178
- results = ShellHelper.filter_internal([
179
- 'gitlab-rails/application_json.log',
180
- '--message!="Cannot obtain an exclusive lease"',
181
- '--severity=error',
182
- "--archive=#{archive.name}"
183
- ].join(' '))
184
-
185
- count = results.count { |x| x&.severity == 'ERROR' }
186
- color = count.zero? ? :green : :red
187
-
188
- [
189
- title(' Application', :bright_red, 18),
190
- count.to_s.pastel(color)
191
- ].join
192
- end
193
-
194
- def sidekiq_errors
195
- count = sidekiq_log.data.count { |x| x&.severity == 'ERROR' }
196
- color = count.zero? ? :green : :red
197
-
198
- [
199
- title(' Sidekiq', :bright_red, 18),
200
- count.to_s.pastel(color)
201
- ].join
202
- end
203
-
204
- def gitlab_services
205
- [
206
- title('Services'),
207
- "\n ",
208
- GitLab.services(archive, 3)
209
- ].join
210
- rescue StandardError => e
211
- LogBot.fatal('GitLab Services', message: e.message, backtrace: e.backtrace.first)
212
- end
213
-
214
- def gitlab_version
215
- [
216
- title('Version'),
217
- gitlab_manifest.data.build_version
218
- ].join
219
- end
220
-
221
- def hostname
222
- [
223
- title('Hostname'),
224
- host.data.first
225
- ].join
226
- end
227
-
228
- def distro
229
- [
230
- title('Distro'),
231
- "[#{os_release.data.ID}] ".pastel(:bright_black),
232
- os_release.data.PRETTY_NAME
233
- ].join
234
- end
235
-
236
- def selinux
237
- return nil if selinux_status.data.nil?
238
-
239
- status = selinux_status.data['SELinux status']
240
- status_color = status == 'enabled' ? :green : :red
241
-
242
- [
243
- title('SeLinux'),
244
- status.pastel(status_color),
245
- ' (',
246
- selinux_status.data['Current mode'],
247
- ')'
248
- ].join
249
- end
250
-
251
- def arch
252
- [
253
- title('Arch'),
254
- cpu.data.Architecture
255
- ].join
256
- end
257
-
258
- def kernel
259
- # TODO: Better way to consistently get uname info?
260
- value, build = uname.data.first.split[2].split('-')
261
- [
262
- title('Kernel'),
263
- value,
264
- " (#{build})".pastel(:bright_black)
265
- ].join
266
- end
267
-
268
- # Helper for finding if NTP is enabled
269
- def ntp_keys
270
- [
271
- 'Network time on', 'NTP enabled', 'NTP service', 'System clock synchronized'
272
- ]
273
- end
274
-
275
- def sys_time
276
- # Ignore if Empty
277
- return false if timedatectl.data.nil?
278
-
279
- ntp_statuses = timedatectl.data.slice(*ntp_keys).values.compact
280
-
281
- enabled = %w[active yes] & ntp_statuses
282
- ntp_status = ntp_statuses.first
283
- ntp_color = enabled.empty? ? :red : :green
284
-
285
- # Fall Back
286
- ntp_status ||= 'unknown'
287
-
288
- [
289
- title('Sys Time'),
290
- timedatectl.data['Local time'],
291
- ' (ntp: '.pastel(:bright_black),
292
- ntp_status.pastel(ntp_color),
293
- ')'.pastel(:bright_black)
294
- ].join
295
- end
296
-
297
- # Strip/Simplify Uptime
298
- def sys_uptime
299
- init = uptime.data.first.split(', load average').first.strip
300
-
301
- [
302
- title('Uptime'),
303
- init.split('up ', 2).last
304
- ].join
305
- end
306
-
307
- def load_average
308
- cpu_count = cpu.data['CPU(s)'].to_i
309
- intervals = uptime.data.first.split('load average: ', 2).last.split(', ').map(&:to_f)
310
-
311
- # Generate Colorized Text for Output
312
- intervals_text = intervals.map do |interval|
313
- value = percent(interval, cpu_count)
314
- color = value > 100 ? :red : :green
315
- [
316
- interval,
317
- ' (',
318
- "#{value}%".pastel(color),
319
- ')'
320
- ].join
321
- end
322
-
323
- [
324
- title('LoadAvg'),
325
- "[CPU #{cpu_count}] ".pastel(:bright_white),
326
- intervals_text.join(', ')
327
- ].join
328
- end
329
-
330
- def memory_perc
331
- total = ShellHelper.human_size_to_number(meminfo.data['MemTotal'])
332
- free = ShellHelper.human_size_to_number(meminfo.data['MemFree'])
333
- used = percent((total - free), total)
334
-
335
- [
336
- title('Usage'),
337
- ' ['.pastel(:bright_black),
338
- '='.pastel(:green) * (used / 2),
339
- ' ' * (50 - (used / 2)),
340
- ']'.pastel(:bright_black),
341
- " #{100 - percent(free, total)}%".pastel(:green) # Inverse
342
- ].join
343
- end
344
-
345
- def memory_free
346
- free = free_m.data.find { |x| x.kind == 'Mem' }
347
-
348
- return unless free
349
-
350
- formatted_mem = free_m.data.map { |x| GreenHat::Memory.memory_row x }
351
-
352
- output = []
353
- unless free.total.blank?
354
- output << title('Total', :cyan, 14)
355
- output << number_to_human_size(free.total.to_i * (1024**2))
356
- output << "\n"
357
- end
358
-
359
- unless free.total.blank?
360
- output << title('Used', :yellow, 14)
361
- output << number_to_human_size(free.used.to_i * (1024**2))
362
- output << "\n"
363
- end
364
-
365
- unless free.total.blank?
366
- output << title('Free', :blue, 14)
367
- output << number_to_human_size(free.free.to_i * (1024**2))
368
- output << "\n"
369
- end
370
-
371
- unless free.total.blank?
372
- output << title('Available', :green, 14)
373
- output << number_to_human_size(free.available.to_i * (1024**2))
374
- output << "\n"
375
- end
376
-
377
- output << "\n"
378
- output << formatted_mem.map { |x| x.prepend ' ' * 2 }.join("\n")
379
-
380
- output.join
381
- rescue StandardError => e
382
- LogBot.fatal('Memory', message: e.message, backtrace: e.backtrace.first)
383
- end
384
-
385
- def disks
386
- # GreenHat::Disk.df({archive: []})
387
- file = GreenHat::Disk.df({ archive: [archive.name] })
388
-
389
- disk_list = GreenHat::Disk.format_output(file.first, false, 3)
390
-
391
- # Preapre / Indent List
392
- [
393
- 'Disks'.pastel(:bright_yellow) + ' (Top % Usage)'.pastel(:bright_black),
394
- "\n",
395
- disk_list.each { |x| x.prepend(' ' * 4) }.join("\n")
396
- ].join
397
- end
398
-
399
- # ----------------------------
400
- # Helpers
401
- # ----------------------------
402
- def percent(value, total)
403
- ((value / total.to_f) * 100).round
404
- end
405
-
406
- # Helper to Make Cyan Titles
407
- def title(name, color = :cyan, ljust = 12)
408
- " #{name}:".ljust(ljust).pastel(color)
409
- end
410
- end
411
- # rubocop:enable Metrics/ClassLength
412
- end
1
+ # Deprecated in favor of reports module
2
+ # TODO: Remove
3
+ # module GreenHat
4
+ # # Root Level Shell / Report Helper
5
+ # module Shell
6
+ # def self.report(raw)
7
+
8
+ # _files, flags, _args = Args.parse(raw)
9
+
10
+ # archives = if flags.archive
11
+ # Archive.all.select do |archive|
12
+ # flags.archive.any? { |x| archive.name.include? x.to_s }
13
+ # end
14
+ # else
15
+ # Archive.all
16
+ # end
17
+
18
+ # output = archives.map { |x| x.report(flags) }.map(&:show).flatten
19
+
20
+ # flags[:page] = true if flags.full && !flags.raw
21
+
22
+ # ShellHelper.show(output, flags)
23
+ # end
24
+ # end
25
+ # end
26
+
27
+ # module GreenHat
28
+ # # Report Generator Helper
29
+ #
30
+ # class Report
31
+ # include ActionView::Helpers::NumberHelper
32
+
33
+ # attr_accessor :archive, :flags, :host, :os_release, :selinux_status, :cpu, :uname,
34
+ # :timedatectl, :uptime, :meminfo, :gitlab_manifest, :gitlab_status,
35
+ # :production_log, :api_log, :sidekiq_log,
36
+ # :exceptions_log, :gitaly_log, :free_m, :disk_free
37
+
38
+ # # Find Needed Files for Report
39
+ #
40
+ # def initialize(archive, flags)
41
+ # self.archive = archive
42
+ # self.flags = flags
43
+ # self.host = archive.things.find { |x| x.name == 'hostname' }
44
+ # self.os_release = archive.things.find { |x| x.name == 'etc/os-release' }
45
+ # self.selinux_status = archive.things.find { |x| x.name == 'sestatus' }
46
+ # self.cpu = archive.things.find { |x| x.name == 'lscpu' }
47
+ # self.uname = archive.things.find { |x| x.name == 'uname' }
48
+ # self.timedatectl = archive.things.find { |x| x.name == 'timedatectl' }
49
+ # self.uptime = archive.things.find { |x| x.name == 'uptime' }
50
+ # self.meminfo = archive.things.find { |x| x.name == 'meminfo' }
51
+ # self.free_m = archive.things.find { |x| x.name == 'free_m' }
52
+ # self.gitlab_manifest = archive.things.find { |x| x.name == 'gitlab/version-manifest.json' }
53
+ # self.gitlab_status = archive.things.find { |x| x.name == 'gitlab_status' }
54
+ # self.production_log = archive.things.find { |x| x.name == 'gitlab-rails/production_json.log' }
55
+ # self.api_log = archive.things.find { |x| x.name == 'gitlab-rails/api_json.log' }
56
+ # self.exceptions_log = archive.things.find { |x| x.name == 'gitlab-rails/exceptions_json.log' }
57
+ # self.gitaly_log = archive.things.find { |x| x.name == 'gitaly/current' }
58
+ # self.sidekiq_log = archive.things.find { |x| x.name == 'sidekiq/current' }
59
+ # self.disk_free = archive.things.find { |x| x.name == 'df_hT' }
60
+ # end
61
+
62
+ # def show
63
+ # output = [
64
+ # archive.friendly_name.pastel(:blue)
65
+ # ]
66
+
67
+ # # OS
68
+ # output << 'OS'.pastel(:bright_yellow)
69
+ # output << hostname if host
70
+ # output << distro if os_release
71
+ # output << selinux if selinux_status
72
+ # # output << arch if cpu
73
+ # output << kernel if uname
74
+ # output << sys_time if timedatectl
75
+ # output << sys_uptime if uptime
76
+ # output << load_average if uptime && cpu
77
+ # output << ''
78
+
79
+ # # Memory
80
+ # if meminfo || free_m
81
+ # output << 'Memory'.pastel(:bright_yellow)
82
+ # output << memory_perc if meminfo
83
+ # output << memory_free if free_m
84
+ # output << ''
85
+ # end
86
+
87
+ # # Disk
88
+ # if disk_free
89
+ # output << disks
90
+ # output << ''
91
+ # end
92
+
93
+ # # Gitlab
94
+ # output << 'GitLab'.pastel(:bright_yellow) if gitlab_manifest
95
+ # output << gitlab_version if gitlab_manifest
96
+ # output << gitlab_services if gitlab_status
97
+ # output << title('Errors') if production_log || api_log || sidekiq_log
98
+ # output << production_errors if production_log
99
+ # output << application_errors if archive.thing?('gitlab-rails/application_json.log')
100
+ # output << sidekiq_errors if sidekiq_log
101
+ # output << api_errors if api_log
102
+ # output << exception_errors if exceptions_log
103
+ # output << gitaly_errors if gitaly_log
104
+ # output << workhorse_errors if archive.thing?('gitlab-workhorse/current')
105
+
106
+ # full(output) if flags.full
107
+
108
+ # # Final Space / Return
109
+ # output << ''
110
+ # output
111
+ # end
112
+ # # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
113
+
114
+ # def full(output)
115
+ # output << ''
116
+ # output << 'FastStats Top'
117
+ # Shell::Faststats.top(['--raw'], true).each { |x| output << x } # Page Row Helper
118
+ # output << ''
119
+
120
+ # output << 'FastStats Errors'
121
+ # Shell::Faststats.errors(['--raw'], true).each { |x| output << x } # Page Row Helper
122
+ # output << ''
123
+ # end
124
+
125
+ # def exception_errors
126
+ # count = exceptions_log.data.count
127
+ # color = count.zero? ? :green : :red
128
+
129
+ # [
130
+ # title(' Exception', :bright_red, 18),
131
+ # count.to_s.pastel(color)
132
+ # ].join
133
+ # end
134
+
135
+ # def workhorse_errors
136
+ # results = ShellHelper.filter_internal([
137
+ # 'gitlab-workhorse/current',
138
+ # '--level=error',
139
+ # "--archive=#{archive.name}"
140
+ # ].join(' '))
141
+
142
+ # color = results.count.zero? ? :green : :red
143
+
144
+ # [
145
+ # title(' Workhorse', :bright_red, 18),
146
+ # results.count.to_s.pastel(color)
147
+ # ].join
148
+ # end
149
+
150
+ # def gitaly_errors
151
+ # count = gitaly_log.data.count { |x| x.level == 'error' }
152
+ # color = count.zero? ? :green : :red
153
+
154
+ # [
155
+ # title(' Gitaly', :bright_red, 18),
156
+ # count.to_s.pastel(color)
157
+ # ].join
158
+ # end
159
+
160
+ # def production_errors
161
+ # count = production_log.data.count { |x| x.status == 500 }
162
+ # color = count.zero? ? :green : :red
163
+
164
+ # [
165
+ # title(' Production', :bright_red, 18),
166
+ # count.to_s.pastel(color)
167
+ # ].join
168
+ # end
169
+
170
+ # def api_errors
171
+ # count = api_log.data.count { |x| x.status == 500 }
172
+ # color = count.zero? ? :green : :red
173
+
174
+ # [
175
+ # title(' API', :bright_red, 18),
176
+ # count.to_s.pastel(color)
177
+ # ].join
178
+ # end
179
+
180
+ # def application_errors
181
+ # results = ShellHelper.filter_internal([
182
+ # 'gitlab-rails/application_json.log',
183
+ # '--message!="Cannot obtain an exclusive lease"',
184
+ # '--severity=error',
185
+ # "--archive=#{archive.name}"
186
+ # ].join(' '))
187
+
188
+ # count = results.count { |x| x&.severity == 'ERROR' }
189
+ # color = count.zero? ? :green : :red
190
+
191
+ # [
192
+ # title(' Application', :bright_red, 18),
193
+ # count.to_s.pastel(color)
194
+ # ].join
195
+ # end
196
+
197
+ # def sidekiq_errors
198
+ # count = sidekiq_log.data.count { |x| x&.severity == 'ERROR' }
199
+ # color = count.zero? ? :green : :red
200
+
201
+ # [
202
+ # title(' Sidekiq', :bright_red, 18),
203
+ # count.to_s.pastel(color)
204
+ # ].join
205
+ # end
206
+
207
+ # def gitlab_services
208
+ # [
209
+ # title('Services'),
210
+ # "\n ",
211
+ # GitLab.services(archive, 3)
212
+ # ].join
213
+ # rescue StandardError => e
214
+ # LogBot.fatal('GitLab Services', message: e.message, backtrace: e.backtrace.first)
215
+ # end
216
+
217
+ # def gitlab_version
218
+ # [
219
+ # title('Version'),
220
+ # gitlab_manifest.data.build_version
221
+ # ].join
222
+ # end
223
+
224
+ # def hostname
225
+ # [
226
+ # title('Hostname'),
227
+ # host.data.first
228
+ # ].join
229
+ # end
230
+
231
+ # def distro
232
+ # [
233
+ # title('Distro'),
234
+ # "[#{os_release.data.ID}] ".pastel(:bright_black),
235
+ # os_release.data.PRETTY_NAME
236
+ # ].join
237
+ # end
238
+
239
+ # def selinux
240
+ # return nil if selinux_status.data.nil?
241
+
242
+ # status = selinux_status.data['SELinux status']
243
+ # status_color = status == 'enabled' ? :green : :red
244
+
245
+ # [
246
+ # title('SeLinux'),
247
+ # status.pastel(status_color),
248
+ # ' (',
249
+ # selinux_status.data['Current mode'],
250
+ # ')'
251
+ # ].join
252
+ # end
253
+
254
+ # def arch
255
+ # [
256
+ # title('Arch'),
257
+ # cpu.data.Architecture
258
+ # ].join
259
+ # end
260
+
261
+ # def kernel
262
+ # # TODO: Better way to consistently get uname info?
263
+ # value, build = uname.data.first.split[2].split('-')
264
+ # [
265
+ # title('Kernel'),
266
+ # value,
267
+ # " (#{build})".pastel(:bright_black)
268
+ # ].join
269
+ # end
270
+
271
+ # # Helper for finding if NTP is enabled
272
+ # def ntp_keys
273
+ # [
274
+ # 'Network time on', 'NTP enabled', 'NTP service', 'System clock synchronized'
275
+ # ]
276
+ # end
277
+
278
+ # def sys_time
279
+ # # Ignore if Empty
280
+ # return false if timedatectl.data.nil?
281
+
282
+ # ntp_statuses = timedatectl.data.slice(*ntp_keys).values.compact
283
+
284
+ # enabled = %w[active yes] & ntp_statuses
285
+ # ntp_status = ntp_statuses.first
286
+ # ntp_color = enabled.empty? ? :red : :green
287
+
288
+ # # Fall Back
289
+ # ntp_status ||= 'unknown'
290
+
291
+ # [
292
+ # title('Sys Time'),
293
+ # timedatectl.data['Local time'],
294
+ # ' (ntp: '.pastel(:bright_black),
295
+ # ntp_status.pastel(ntp_color),
296
+ # ')'.pastel(:bright_black)
297
+ # ].join
298
+ # end
299
+
300
+ # # Strip/Simplify Uptime
301
+ # def sys_uptime
302
+ # init = uptime.data.first.split(', load average').first.strip
303
+
304
+ # [
305
+ # title('Uptime'),
306
+ # init.split('up ', 2).last
307
+ # ].join
308
+ # end
309
+
310
+ # def load_average
311
+ # cpu_count = cpu.data['CPU(s)'].to_i
312
+ # intervals = uptime.data.first.split('load average: ', 2).last.split(', ').map(&:to_f)
313
+
314
+ # # Generate Colorized Text for Output
315
+ # intervals_text = intervals.map do |interval|
316
+ # value = percent(interval, cpu_count)
317
+ # color = value > 100 ? :red : :green
318
+ # [
319
+ # interval,
320
+ # ' (',
321
+ # "#{value}%".pastel(color),
322
+ # ')'
323
+ # ].join
324
+ # end
325
+
326
+ # [
327
+ # title('LoadAvg'),
328
+ # "[CPU #{cpu_count}] ".pastel(:bright_white),
329
+ # intervals_text.join(', ')
330
+ # ].join
331
+ # end
332
+
333
+ # def memory_perc
334
+ # total = ShellHelper.human_size_to_number(meminfo.data['MemTotal'])
335
+ # free = ShellHelper.human_size_to_number(meminfo.data['MemFree'])
336
+ # used = percent((total - free), total)
337
+
338
+ # [
339
+ # title('Usage'),
340
+ # ' ['.pastel(:bright_black),
341
+ # '='.pastel(:green) * (used / 2),
342
+ # ' ' * (50 - (used / 2)),
343
+ # ']'.pastel(:bright_black),
344
+ # " #{100 - percent(free, total)}%".pastel(:green) # Inverse
345
+ # ].join
346
+ # end
347
+
348
+ # def memory_free
349
+ # free = free_m.data.find { |x| x.kind == 'Mem' }
350
+
351
+ # return unless free
352
+
353
+ # formatted_mem = free_m.data.map { |x| GreenHat::Memory.memory_row x }
354
+
355
+ # output = []
356
+ # unless free.total.blank?
357
+ # output << title('Total', :cyan, 14)
358
+ # output << number_to_human_size(free.total.to_i * (1024**2))
359
+ # output << "\n"
360
+ # end
361
+
362
+ # unless free.total.blank?
363
+ # output << title('Used', :yellow, 14)
364
+ # output << number_to_human_size(free.used.to_i * (1024**2))
365
+ # output << "\n"
366
+ # end
367
+
368
+ # unless free.total.blank?
369
+ # output << title('Free', :blue, 14)
370
+ # output << number_to_human_size(free.free.to_i * (1024**2))
371
+ # output << "\n"
372
+ # end
373
+
374
+ # unless free.total.blank?
375
+ # output << title('Available', :green, 14)
376
+ # output << number_to_human_size(free.available.to_i * (1024**2))
377
+ # output << "\n"
378
+ # end
379
+
380
+ # output << "\n"
381
+ # output << formatted_mem.map { |x| x.prepend ' ' * 2 }.join("\n")
382
+
383
+ # output.join
384
+ # rescue StandardError => e
385
+ # LogBot.fatal('Memory', message: e.message, backtrace: e.backtrace.first)
386
+ # end
387
+
388
+ # def disks
389
+ # # GreenHat::Disk.df({archive: []})
390
+ # file = GreenHat::Disk.df({ archive: [archive.name] })
391
+
392
+ # disk_list = GreenHat::Disk.format_output(file.first, false, 3)
393
+
394
+ # # Preapre / Indent List
395
+ # [
396
+ # 'Disks'.pastel(:bright_yellow) + ' (Top % Usage)'.pastel(:bright_black),
397
+ # "\n",
398
+ # disk_list.each { |x| x.prepend(' ' * 4) }.join("\n")
399
+ # ].join
400
+ # end
401
+
402
+ # # ----------------------------
403
+ # # Helpers
404
+ # # ----------------------------
405
+ # def percent(value, total)
406
+ # ((value / total.to_f) * 100).round
407
+ # end
408
+
409
+ # # Helper to Make Cyan Titles
410
+ # def title(name, color = :cyan, ljust = 12)
411
+ # " #{name}:".ljust(ljust).pastel(color)
412
+ # end
413
+ # end
414
+ # # rubocop:enable Metrics/ClassLength
415
+ # end