Add Server Info card
This commit is contained in:
parent
5687d8a4e7
commit
49a20a946f
48
bin/malpd
48
bin/malpd
@ -166,6 +166,52 @@ def read_virtual_machines
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def read_server_info
|
||||||
|
info = { "type" => "server" }
|
||||||
|
|
||||||
|
if File.exist?("/etc/os-release")
|
||||||
|
File.readlines("/etc/os-release").each do |line|
|
||||||
|
if line =~ /^PRETTY_NAME="(.+)"$/
|
||||||
|
info["os_name"] = $1
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
out = `stat -c %W / 2>/dev/null`.strip
|
||||||
|
if out =~ /^\d+$/ && out.to_i > 0
|
||||||
|
info["install_date"] = Time.at(out.to_i).strftime("%Y-%m-%d")
|
||||||
|
elsif File.exist?("/etc/machine-id")
|
||||||
|
info["install_date"] = File.mtime("/etc/machine-id").strftime("%Y-%m-%d")
|
||||||
|
end
|
||||||
|
|
||||||
|
if File.exist?("/proc/cpuinfo")
|
||||||
|
cpuinfo = File.read("/proc/cpuinfo")
|
||||||
|
if cpuinfo =~ /^model name\s*:\s*(.+)$/
|
||||||
|
info["cpu_model"] = $1.strip
|
||||||
|
end
|
||||||
|
cores = cpuinfo.scan(/^processor\s*:/).size
|
||||||
|
info["cpu_cores"] = cores if cores > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if File.exist?("/proc/meminfo")
|
||||||
|
mem = {}
|
||||||
|
File.read("/proc/meminfo").each_line do |line|
|
||||||
|
if line =~ /^(\w+):\s+(\d+)/
|
||||||
|
mem[$1] = $2.to_i * 1024
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (total = mem["MemTotal"])
|
||||||
|
available = mem["MemAvailable"] ||
|
||||||
|
(mem["MemFree"].to_i + mem["Buffers"].to_i + mem["Cached"].to_i)
|
||||||
|
info["mem_total"] = total
|
||||||
|
info["mem_used"] = total - available
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
info
|
||||||
|
end
|
||||||
|
|
||||||
def read_ups
|
def read_ups
|
||||||
out = `apcaccess 2>/dev/null`
|
out = `apcaccess 2>/dev/null`
|
||||||
return nil unless $?.success? && !out.empty?
|
return nil unless $?.success? && !out.empty?
|
||||||
@ -232,6 +278,8 @@ def handle_info(conn)
|
|||||||
info.concat(read_filesystems)
|
info.concat(read_filesystems)
|
||||||
info.concat(read_virtual_machines)
|
info.concat(read_virtual_machines)
|
||||||
|
|
||||||
|
info << read_server_info
|
||||||
|
|
||||||
if (ups = read_ups)
|
if (ups = read_ups)
|
||||||
info << ups
|
info << ups
|
||||||
end
|
end
|
||||||
|
|||||||
@ -112,9 +112,67 @@ if cgi.params.key?("content")
|
|||||||
drives = info.select { |e| e["type"] == "drive" }
|
drives = info.select { |e| e["type"] == "drive" }
|
||||||
filesystems = info.select { |e| e["type"] == "filesystem" }
|
filesystems = info.select { |e| e["type"] == "filesystem" }
|
||||||
vms = info.select { |e| e["type"] == "vm" }
|
vms = info.select { |e| e["type"] == "vm" }
|
||||||
|
server = info.find { |e| e["type"] == "server" }
|
||||||
|
|
||||||
html << %(<div class="span-3">)
|
html << %(<div class="span-3">)
|
||||||
|
|
||||||
|
if server
|
||||||
|
html << %(<div class="section-label">Server</div>)
|
||||||
|
html << %(<div class="card ok"><div class="card-header"><span class="card-title">Server Info</span></div><div class="subitems">)
|
||||||
|
|
||||||
|
if server["os_name"]
|
||||||
|
html << <<~HTML
|
||||||
|
<div class="subitem">
|
||||||
|
<div class="subitem-left"><div class="dot ok"></div><span class="subitem-name">OS</span></div>
|
||||||
|
<span class="subitem-value ok">#{CGI.escapeHTML(server["os_name"])}</span>
|
||||||
|
</div>
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
if server["install_date"]
|
||||||
|
html << <<~HTML
|
||||||
|
<div class="subitem">
|
||||||
|
<div class="subitem-left"><div class="dot ok"></div><span class="subitem-name">Installed</span></div>
|
||||||
|
<span class="subitem-value ok">#{CGI.escapeHTML(server["install_date"])}</span>
|
||||||
|
</div>
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
cpu_model = server["cpu_model"]
|
||||||
|
cpu_cores = server["cpu_cores"]
|
||||||
|
if cpu_model || cpu_cores
|
||||||
|
cpu_text = [
|
||||||
|
cpu_model,
|
||||||
|
cpu_cores ? "#{cpu_cores} thread#{cpu_cores == 1 ? "" : "s"}" : nil
|
||||||
|
].compact.join(" · ")
|
||||||
|
html << <<~HTML
|
||||||
|
<div class="subitem">
|
||||||
|
<div class="subitem-left"><div class="dot ok"></div><span class="subitem-name">CPU</span></div>
|
||||||
|
<span class="subitem-value ok">#{CGI.escapeHTML(cpu_text)}</span>
|
||||||
|
</div>
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
mem_total = server["mem_total"].to_i
|
||||||
|
mem_used = server["mem_used"].to_i
|
||||||
|
if mem_total > 0
|
||||||
|
mem_pct_f = mem_used * 100.0 / mem_total
|
||||||
|
mem_pct = mem_pct_f.round
|
||||||
|
mem_cls = mem_pct_f >= 90 ? "bad" : mem_pct_f >= 75 ? "warn" : "ok"
|
||||||
|
html << <<~HTML
|
||||||
|
<div class="subitem" style="flex-direction:column;align-items:stretch;gap:0.35rem;">
|
||||||
|
<div style="display:flex;justify-content:space-between;align-items:center;">
|
||||||
|
<div class="subitem-left"><div class="dot #{mem_cls}"></div><span class="subitem-name">Memory</span></div>
|
||||||
|
<span class="subitem-value #{mem_cls}">#{mem_pct}% · #{CGI.escapeHTML(human_capacity(mem_used))} / #{CGI.escapeHTML(human_capacity(mem_total))}</span>
|
||||||
|
</div>
|
||||||
|
<div class="bar-track"><div class="bar-fill #{mem_cls}" style="width:#{mem_pct}%"></div></div>
|
||||||
|
</div>
|
||||||
|
HTML
|
||||||
|
end
|
||||||
|
|
||||||
|
html << %(</div></div>)
|
||||||
|
end
|
||||||
|
|
||||||
if vms.any?
|
if vms.any?
|
||||||
running = vms.count { |v| v["state"].to_s == "running" }
|
running = vms.count { |v| v["state"].to_s == "running" }
|
||||||
total = vms.size
|
total = vms.size
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user