Class: GreenHat::Report

Inherits:
Object
  • Object
show all
Includes:
ActionView::Helpers::NumberHelper
Defined in:
lib/greenhat/shell/report.rb

Overview

Report Generator Helper rubocop:disable Metrics/ClassLength

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(archive) ⇒ Report

Find Needed Files for Report rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/greenhat/shell/report.rb', line 32

def initialize(archive)
  self.archive = archive
  self.host = archive.things.find { |x| x.name == 'hostname' }
  self.os_release = archive.things.find { |x| x.name == 'etc/os-release' }
  self.selinux_status = archive.things.find { |x| x.name == 'sestatus' }
  self.cpu = archive.things.find { |x| x.name == 'lscpu' }
  self.uname = archive.things.find { |x| x.name == 'uname' }
  self.timedatectl = archive.things.find { |x| x.name == 'timedatectl' }
  self.uptime = archive.things.find { |x| x.name == 'uptime' }
  self.meminfo = archive.things.find { |x| x.name == 'meminfo' }
  self.free_m = archive.things.find { |x| x.name == 'free_m' }
  self.gitlab_manifest = archive.things.find { |x| x.name == 'gitlab/version-manifest.json' }
  self.gitlab_status = archive.things.find { |x| x.name == 'gitlab_status' }
  self.production_log = archive.things.find { |x| x.name == 'gitlab-rails/production_json.log' }
  self.api_log = archive.things.find { |x| x.name == 'gitlab-rails/api_json.log' }
  self.application_log = archive.things.find { |x| x.name == 'gitlab-rails/application_json.log' }
  self.sidekiq_log = archive.things.find { |x| x.name == 'sidekiq/current' }
  self.disk_free = archive.things.find { |x| x.name == 'df_h' }
end

Instance Attribute Details

#api_logObject

Returns the value of attribute api_log.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def api_log
  @api_log
end

#application_logObject

Returns the value of attribute application_log.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def application_log
  @application_log
end

#archiveObject

Returns the value of attribute archive.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def archive
  @archive
end

#cpuObject

Returns the value of attribute cpu.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def cpu
  @cpu
end

#disk_freeObject

Returns the value of attribute disk_free.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def disk_free
  @disk_free
end

#free_mObject

Returns the value of attribute free_m.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def free_m
  @free_m
end

#gitlab_manifestObject

Returns the value of attribute gitlab_manifest.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def gitlab_manifest
  @gitlab_manifest
end

#gitlab_statusObject

Returns the value of attribute gitlab_status.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def gitlab_status
  @gitlab_status
end

#hostObject

Returns the value of attribute host.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def host
  @host
end

#meminfoObject

Returns the value of attribute meminfo.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def meminfo
  @meminfo
end

#os_releaseObject

Returns the value of attribute os_release.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def os_release
  @os_release
end

#production_logObject

Returns the value of attribute production_log.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def production_log
  @production_log
end

#selinux_statusObject

Returns the value of attribute selinux_status.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def selinux_status
  @selinux_status
end

#sidekiq_logObject

Returns the value of attribute sidekiq_log.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def sidekiq_log
  @sidekiq_log
end

#timedatectlObject

Returns the value of attribute timedatectl.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def timedatectl
  @timedatectl
end

#unameObject

Returns the value of attribute uname.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def uname
  @uname
end

#uptimeObject

Returns the value of attribute uptime.



26
27
28
# File 'lib/greenhat/shell/report.rb', line 26

def uptime
  @uptime
end

Instance Method Details

#api_errorsObject



109
110
111
112
113
114
115
116
117
# File 'lib/greenhat/shell/report.rb', line 109

def api_errors
  count = api_log.data.count { |x| x.status == 500 }
  color = count.zero? ? :green : :red

  [
    title('  API', :bright_red, 18),
    count.to_s.pastel(color)
  ].join
end

#application_errorsObject



119
120
121
122
123
124
125
126
127
# File 'lib/greenhat/shell/report.rb', line 119

def application_errors
  count = application_log.data.count { |x| x&.severity == 'ERROR' }
  color = count.zero? ? :green : :red

  [
    title('  Application', :bright_red, 18),
    count.to_s.pastel(color)
  ].join
end

#archObject



184
185
186
187
188
189
# File 'lib/greenhat/shell/report.rb', line 184

def arch
  [
    title('Arch'),
    cpu.data.Architecture
  ].join
end

#disksObject



302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/greenhat/shell/report.rb', line 302

def disks
  # GreenHat::Disk.df({archive: []})
  file = GreenHat::Disk.df({ archive: [archive.name] })

  disk_list = GreenHat::Disk.format_output(file.first, false, 3)

  # Preapre / Indent List
  [
    'Disks'.pastel(:bright_yellow) + ' (Top % Usage)'.pastel(:bright_black),
    "\n",
    disk_list.each { |x| x.prepend(' ' * 4) }.join("\n")
  ].join
end

#distroObject



163
164
165
166
167
168
169
# File 'lib/greenhat/shell/report.rb', line 163

def distro
  [
    title('Distro'),
    "[#{os_release.data.ID}] ".pastel(:bright_black),
    os_release.data.PRETTY_NAME
  ].join
end

#gitlab_servicesObject



139
140
141
142
143
144
145
146
147
# File 'lib/greenhat/shell/report.rb', line 139

def gitlab_services
  [
    title('Services'),
    "\n   ",
    GitLab.services(archive, 3)
  ].join
rescue StandardError => e
  LogBot.fatal('GitLab Services', message: e.message, backtrace: e.backtrace.first)
end

#gitlab_versionObject



149
150
151
152
153
154
# File 'lib/greenhat/shell/report.rb', line 149

def gitlab_version
  [
    title('Version'),
    gitlab_manifest.data.build_version
  ].join
end

#hostnameObject



156
157
158
159
160
161
# File 'lib/greenhat/shell/report.rb', line 156

def hostname
  [
    title('Hostname'),
    host.data.first
  ].join
end

#kernelObject



191
192
193
194
195
196
197
198
199
# File 'lib/greenhat/shell/report.rb', line 191

def kernel
  # TODO: Better way to consistently get uname info?
  value, build = uname.data.first.split[2].split('-')
  [
    title('Kernel'),
    value,
    " (#{build})".pastel(:bright_black)
  ].join
end

#load_averageObject



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/greenhat/shell/report.rb', line 240

def load_average
  cpu_count = cpu.data['CPU(s)'].to_i
  intervals = uptime.data.first.split('load average: ', 2).last.split(', ').map(&:to_f)

  # Generate Colorized Text for Output
  intervals_text = intervals.map do |interval|
    value = percent(interval, cpu_count)
    color = value > 100 ? :red : :green
    [
      interval,
      ' (',
      "#{value}%".pastel(color),
      ')'
    ].join
  end

  [
    title('LoadAvg'),
    "[CPU #{cpu_count}] ".pastel(:bright_white),
    intervals_text.join(', ')
  ].join
end

#memory_freeObject



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/greenhat/shell/report.rb', line 278

def memory_free
  free = free_m.data.find { |x| x.kind == 'Mem' }

  return unless free

  formatted_mem = free_m.data.map { |x| GreenHat::Memory.memory_row x }

  [
    title('Total', :cyan, 14),
    number_to_human_size(free.total.to_i * 1024**2),
    "\n",
    title('Used', :yellow, 14),
    number_to_human_size(free.used.to_i * 1024**2),
    "\n",
    title('Free', :blue, 14),
    number_to_human_size(free.free.to_i * 1024**2),
    "\n",
    title('Available', :green, 14),
    number_to_human_size(free.available.to_i * 1024**2),
    "\n\n",
    formatted_mem.map { |x| x.prepend ' ' * 2 }.join("\n")
  ].join
end

#memory_percObject



263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/greenhat/shell/report.rb', line 263

def memory_perc
  total = ShellHelper.human_size_to_number(meminfo.data['MemTotal'])
  free = ShellHelper.human_size_to_number(meminfo.data['MemFree'])
  used = percent((total - free), total)

  [
    title('Usage'),
    '  ['.pastel(:bright_black),
    '='.pastel(:green) * (used / 2),
    ' ' * (50 - used / 2),
    ']'.pastel(:bright_black),
    " #{100 - percent(free, total)}%".pastel(:green) # Inverse
  ].join
end

#ntp_keysObject

Helper for finding if NTP is enabled



202
203
204
205
206
# File 'lib/greenhat/shell/report.rb', line 202

def ntp_keys
  [
    'Network time on', 'NTP enabled', 'NTP service', 'System clock synchronized'
  ]
end

#percent(value, total) ⇒ Object


Helpers




319
320
321
# File 'lib/greenhat/shell/report.rb', line 319

def percent(value, total)
  ((value / total.to_f) * 100).round
end

#production_errorsObject

rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength



99
100
101
102
103
104
105
106
107
# File 'lib/greenhat/shell/report.rb', line 99

def production_errors
  count = production_log.data.count { |x| x.status == 500 }
  color = count.zero? ? :green : :red

  [
    title('  Production', :bright_red, 18),
    count.to_s.pastel(color)
  ].join
end

#selinuxObject



171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/greenhat/shell/report.rb', line 171

def selinux
  status = selinux_status.data['SELinux status']
  status_color = status == 'enabled' ?  :green : :red

  [
    title('SeLinux'),
    status.pastel(status_color),
    ' (',
    selinux_status.data['Current mode'],
    ')'
  ].join
end

#showObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/greenhat/shell/report.rb', line 52

def show
  output = [
    archive.friendly_name.pastel(:blue)
  ]

  # OS
  output << 'OS'.pastel(:bright_yellow)
  output << hostname if host
  output << distro if os_release
  output << selinux if selinux_status
  # output << arch if cpu
  output << kernel if uname
  output << sys_time if timedatectl
  output << sys_uptime if uptime
  output << load_average if uptime && cpu
  output << ''

  # Memory
  if meminfo || free_m
    output << 'Memory'.pastel(:bright_yellow)
    output << memory_perc if meminfo
    output << memory_free if free_m
    output << ''
  end

  # Disk
  if disk_free
    output << disks
    output << ''
  end

  # Gitlab
  output << 'GitLab'.pastel(:bright_yellow) if gitlab_manifest
  output << gitlab_version if gitlab_manifest
  output << gitlab_services if gitlab_status
  output << title('Errors') if production_log || api_log || application_log || sidekiq_log
  output << production_errors if production_log
  output << api_errors if api_log
  output << application_errors if application_log
  output << sidekiq_errors if sidekiq_log

  # Final Space / Return
  output << ''
  output
end

#sidekiq_errorsObject



129
130
131
132
133
134
135
136
137
# File 'lib/greenhat/shell/report.rb', line 129

def sidekiq_errors
  count = sidekiq_log.data.count { |x| x&.severity == 'ERROR' }
  color = count.zero? ? :green : :red

  [
    title('  Sidekiq', :bright_red, 18),
    count.to_s.pastel(color)
  ].join
end

#sys_timeObject



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/greenhat/shell/report.rb', line 208

def sys_time
  # Ignore if Empty
  return false if timedatectl.data.nil?

  ntp_statuses = timedatectl.data.slice(*ntp_keys).values.compact

  enabled = %w[active yes] & ntp_statuses
  ntp_status = ntp_statuses.first
  ntp_color = enabled.empty? ? :red : :green

  # Fall Back
  ntp_status ||= 'unknown'

  [
    title('Sys Time'),
    timedatectl.data['Local time'],
    ' (ntp: '.pastel(:bright_black),
    ntp_status.pastel(ntp_color),
    ')'.pastel(:bright_black)
  ].join
end

#sys_uptimeObject

Strip/Simplify Uptime



231
232
233
234
235
236
237
238
# File 'lib/greenhat/shell/report.rb', line 231

def sys_uptime
  init = uptime.data.first.split(',  load average').first.strip

  [
    title('Uptime'),
    init.split('up ', 2).last
  ].join
end

#title(name, color = :cyan, ljust = 12) ⇒ Object

Helper to Make Cyan Titles



324
325
326
# File 'lib/greenhat/shell/report.rb', line 324

def title(name, color = :cyan, ljust = 12)
  "  #{name}:".ljust(ljust).pastel(color)
end