class GreenHat::Report

Report Generator Helper rubocop:disable Metrics/ClassLength

Attributes

api_log[RW]
application_log[RW]
archive[RW]
cpu[RW]
disk_free[RW]
free_m[RW]
gitlab_manifest[RW]
gitlab_status[RW]
host[RW]
meminfo[RW]
os_release[RW]
production_log[RW]
selinux_status[RW]
sidekiq_log[RW]
timedatectl[RW]
uname[RW]
uptime[RW]

Public Class Methods

new(archive) click to toggle source

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

# File lib/greenhat/shell/report.rb, line 26
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

Public Instance Methods

api_errors() click to toggle source
# File lib/greenhat/shell/report.rb, line 103
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_errors() click to toggle source
# File lib/greenhat/shell/report.rb, line 113
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
arch() click to toggle source
# File lib/greenhat/shell/report.rb, line 178
def arch
  [
    title('Arch'),
    cpu.data.Architecture
  ].join
end
disks() click to toggle source
# File lib/greenhat/shell/report.rb, line 296
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
distro() click to toggle source
# File lib/greenhat/shell/report.rb, line 157
def distro
  [
    title('Distro'),
    "[#{os_release.data.ID}] ".pastel(:bright_black),
    os_release.data.PRETTY_NAME
  ].join
end
gitlab_services() click to toggle source
# File lib/greenhat/shell/report.rb, line 133
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_version() click to toggle source
# File lib/greenhat/shell/report.rb, line 143
def gitlab_version
  [
    title('Version'),
    gitlab_manifest.data.build_version
  ].join
end
hostname() click to toggle source
# File lib/greenhat/shell/report.rb, line 150
def hostname
  [
    title('Hostname'),
    host.data.first
  ].join
end
kernel() click to toggle source
# File lib/greenhat/shell/report.rb, line 185
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_average() click to toggle source
# File lib/greenhat/shell/report.rb, line 234
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_free() click to toggle source
# File lib/greenhat/shell/report.rb, line 272
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_perc() click to toggle source
# File lib/greenhat/shell/report.rb, line 257
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_keys() click to toggle source

Helper for finding if NTP is enabled

# File lib/greenhat/shell/report.rb, line 196
def ntp_keys
  [
    'Network time on', 'NTP enabled', 'NTP service', 'System clock synchronized'
  ]
end
percent(value, total) click to toggle source

Helpers


# File lib/greenhat/shell/report.rb, line 313
def percent(value, total)
  ((value / total.to_f) * 100).round
end
production_errors() click to toggle source

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

# File lib/greenhat/shell/report.rb, line 93
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
selinux() click to toggle source
# File lib/greenhat/shell/report.rb, line 165
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
show() click to toggle source
# File lib/greenhat/shell/report.rb, line 46
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_errors() click to toggle source
# File lib/greenhat/shell/report.rb, line 123
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_time() click to toggle source
# File lib/greenhat/shell/report.rb, line 202
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_uptime() click to toggle source

Strip/Simplify Uptime

# File lib/greenhat/shell/report.rb, line 225
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) click to toggle source

Helper to Make Cyan Titles

# File lib/greenhat/shell/report.rb, line 318
def title(name, color = :cyan, ljust = 12)
  "  #{name}:".ljust(ljust).pastel(color)
end