first commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
2430
Cargo.lock
generated
Normal file
2430
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "nodeinfo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rocket = "0.5.0"
|
||||||
|
serde = "1.0.200"
|
||||||
|
sysinfo = "0.30.12"
|
||||||
|
readable = "0.16.0"
|
||||||
|
|
||||||
|
[dependencies.rocket_dyn_templates]
|
||||||
|
version = "0.1.0"
|
||||||
|
features = ["tera"]
|
||||||
2
Rocket.toml
Normal file
2
Rocket.toml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[default]
|
||||||
|
template_dir = "templates"
|
||||||
103
src/main.rs
Normal file
103
src/main.rs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
extern crate rocket;
|
||||||
|
use rocket::serde::Serialize;
|
||||||
|
use rocket::{get, launch, routes};
|
||||||
|
use rocket_dyn_templates::{context, Template};
|
||||||
|
use readable::byte::Byte;
|
||||||
|
use readable::up::UptimeFull;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use sysinfo::{Components, Disks, Networks, System};
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
struct ComponentInfo {
|
||||||
|
name: String,
|
||||||
|
temperature: u8, // Surely nothing's getting higher than 256 degrees
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
struct DiskInfo {
|
||||||
|
name: String,
|
||||||
|
total_space: String,
|
||||||
|
available_space: String,
|
||||||
|
mount_point: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
struct RamInfo {
|
||||||
|
total_memory: String,
|
||||||
|
used_memory: String,
|
||||||
|
total_swap: String,
|
||||||
|
used_swap: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
struct SysInfo {
|
||||||
|
ram: RamInfo,
|
||||||
|
disks: Vec<DiskInfo>,
|
||||||
|
components: Vec<ComponentInfo>,
|
||||||
|
hostname: Option<String>,
|
||||||
|
operating_system: Option<String>,
|
||||||
|
uptime: String,
|
||||||
|
average_load: (String, String, String),
|
||||||
|
restart_needed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_system_info() -> SysInfo {
|
||||||
|
let mut sys = System::new_all();
|
||||||
|
sys.refresh_all();
|
||||||
|
let cpu_load = System::load_average();
|
||||||
|
let cpu_load = (format!("{:.3}", cpu_load.one), format!("{:.3}", cpu_load.five), format!("{:.3}", cpu_load.fifteen));
|
||||||
|
|
||||||
|
let disks = Disks::new_with_refreshed_list();
|
||||||
|
let mut disks_context = Vec::new();
|
||||||
|
for disk in disks.list() {
|
||||||
|
disks_context.push(DiskInfo {
|
||||||
|
name: disk.name().to_str().unwrap().to_string(),
|
||||||
|
total_space: Byte::from(disk.total_space()).to_string(),
|
||||||
|
available_space: Byte::from(disk.available_space()).to_string(),
|
||||||
|
mount_point: disk.mount_point().display().to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let components = Components::new_with_refreshed_list();
|
||||||
|
let mut components_context = Vec::new();
|
||||||
|
for component in &components {
|
||||||
|
components_context.push(ComponentInfo {
|
||||||
|
name: component.label().to_string(),
|
||||||
|
temperature: component.temperature() as u8,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SysInfo {
|
||||||
|
disks: disks_context,
|
||||||
|
components: components_context,
|
||||||
|
ram: RamInfo {
|
||||||
|
total_memory: Byte::from(sys.total_memory()).to_string(),
|
||||||
|
used_memory: Byte::from(sys.used_memory()).to_string(),
|
||||||
|
total_swap: Byte::from(sys.total_swap()).to_string(),
|
||||||
|
used_swap: Byte::from(sys.used_swap()).to_string()
|
||||||
|
},
|
||||||
|
hostname: System::host_name(),
|
||||||
|
operating_system: System::long_os_version(),
|
||||||
|
uptime: UptimeFull::from(System::uptime()).to_string(),
|
||||||
|
average_load: cpu_load,
|
||||||
|
restart_needed: Path::new("/var/run/reboot-required").exists(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
fn index() -> Template {
|
||||||
|
let system_context = get_system_info();
|
||||||
|
let context = context! {
|
||||||
|
system: system_context,
|
||||||
|
};
|
||||||
|
Template::render("index", &context)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[launch]
|
||||||
|
fn rocket() -> _ {
|
||||||
|
rocket::build()
|
||||||
|
.mount("/", routes![index])
|
||||||
|
.attach(Template::fairing())
|
||||||
|
}
|
||||||
64
templates/index.html.tera
Normal file
64
templates/index.html.tera
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>XMR Node Info</title>
|
||||||
|
<style>
|
||||||
|
.infocards {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.infocard {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
p.subheading {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
p.restart {
|
||||||
|
font-weight: bold;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Node Device Info</h1>
|
||||||
|
<div class="infocards">
|
||||||
|
<div class="infocard">
|
||||||
|
<h2>Sys Info</h2>
|
||||||
|
<p>Hostname: {{ system.hostname }}</p>
|
||||||
|
<p>Uptime: {{ system.uptime }}</p>
|
||||||
|
<p>OS: {{ system.operating_system }}</p>
|
||||||
|
<p>Average Load: {{ system.average_load.0 }} {{ system.average_load.1 }} {{ system.average_load.2 }}</p>
|
||||||
|
{% if system.restart_needed %}
|
||||||
|
<p class="restart">RESTART NEEDED</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="infocard">
|
||||||
|
<h2>HDD Info</h2>
|
||||||
|
{% for disk in system.disks %}
|
||||||
|
<h3>{{disk.name}}</h3>
|
||||||
|
<p class="subheading">Mounted at: {{disk.mount_point}}</p>
|
||||||
|
<p>{{disk.available_space}} used of {{disk.total_space}}</p>
|
||||||
|
{% if not loop.last %}
|
||||||
|
<hr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="infocard">
|
||||||
|
<h2>Temperatures</h2>
|
||||||
|
{% for comp in system.components %}
|
||||||
|
<p class="temperature">{{ comp.name }} - {{ comp.temperature }}°C</p>
|
||||||
|
{% if not loop.last %}
|
||||||
|
<hr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="infocard">
|
||||||
|
<h2>RAM</h2>
|
||||||
|
<p>{{ system.ram.used_memory }} of {{ system.ram.total_memory }} RAM current in use</p>
|
||||||
|
<p>{{ system.ram.used_swap }} of {{ system.ram.total_swap }} swap currently in use</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{__tera_context}}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user