From 432d07361fab96c3887be8564f7b43c0ed4266a4 Mon Sep 17 00:00:00 2001 From: Lars T Hansen Date: Wed, 3 Apr 2024 11:17:07 +0200 Subject: [PATCH] For #152 - Remove serde_json dependency --- Cargo.lock | 13 ----------- Cargo.toml | 2 -- src/sysinfo.rs | 58 ++++++++++++++++++++------------------------------ src/util.rs | 31 +++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53a77ce..dd2e8ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -394,17 +394,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_json" -version = "1.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" -dependencies = [ - "itoa", - "ryu", - "serde", -] - [[package]] name = "signal-hook" version = "0.3.17" @@ -436,8 +425,6 @@ dependencies = [ "libc", "log", "page_size", - "serde", - "serde_json", "signal-hook", "subprocess", ] diff --git a/Cargo.toml b/Cargo.toml index 758d65d..4c010c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,5 +16,3 @@ env_logger = "0.11" page_size = "0.6" libc = "0.2" signal-hook = "0.3" -serde_json = "1.0.114" -serde = { version = "1.0.197", features = ["derive"] } diff --git a/src/sysinfo.rs b/src/sysinfo.rs index 0561109..34e5fbb 100644 --- a/src/sysinfo.rs +++ b/src/sysinfo.rs @@ -5,8 +5,7 @@ use crate::gpu; use crate::nvidia; use crate::procfs; use crate::procfsapi; - -use serde::Serialize; +use crate::util; use std::io::{self, Write}; @@ -22,21 +21,6 @@ pub fn show_system(timestamp: &str) { const GIB: usize = 1024 * 1024 * 1024; -// Note the field names here are used by decoders developed separately and should be considered set -// in stone. All fields will be serialized; missing numeric values must be zero; consumers must -// deal with that. - -#[derive(Serialize)] -struct NodeConfig { - timestamp: String, - hostname: String, - description: String, - cpu_cores: i32, - mem_gb: i64, // This is GiB despite the name - the name is frozen - gpu_cards: i32, - gpumem_gb: i64, // Ditto -} - fn do_show_system(fs: &dyn procfsapi::ProcfsAPI, timestamp: &str) -> Result<(), String> { let (model, sockets, cores_per_socket, threads_per_core) = procfs::get_cpu_info(fs)?; let mem_by = procfs::get_memtotal_kib(fs)? * 1024; @@ -90,22 +74,26 @@ fn do_show_system(fs: &dyn procfsapi::ProcfsAPI, timestamp: &str) -> Result<(), } else { ("".to_string(), 0, 0) }; - let config = NodeConfig { - timestamp: timestamp.to_string(), - hostname, - description: format!("{sockets}x{cores_per_socket}{ht} {model}, {mem_gib} GiB{gpu_desc}"), - cpu_cores: sockets * cores_per_socket * threads_per_core, - mem_gb: mem_gib, - gpu_cards, - gpumem_gb, - }; - match serde_json::to_string_pretty(&config) { - Ok(s) => { - let _ = io::stdout().write(s.as_bytes()); - let _ = io::stdout().write(b"\n"); - let _ = io::stdout().flush(); - Ok(()) - } - Err(_) => Err("JSON encoding failed".to_string()), - } + let timestamp = util::json_quote(timestamp); + let hostname = util::json_quote(&hostname); + let description = util::json_quote(&format!("{sockets}x{cores_per_socket}{ht} {model}, {mem_gib} GiB{gpu_desc}")); + let cpu_cores = sockets * cores_per_socket * threads_per_core; + + // Note the field names here are used by decoders that are developed separately, and they should + // be considered set in stone. + + let s = format!(r#"{{ + "timestamp": "{timestamp}", + "hostname": "{hostname}", + "description": "{description}", + "cpu_cores": {cpu_cores}, + "mem_gb": {mem_gib}, + "gpu_cards": {gpu_cards}, + "gpumem_gb": {gpumem_gb} +}} +"#); + + let _ = io::stdout().write(s.as_bytes()); + let _ = io::stdout().flush(); + Ok(()) } diff --git a/src/util.rs b/src/util.rs index e07e5b5..1262865 100644 --- a/src/util.rs +++ b/src/util.rs @@ -71,3 +71,34 @@ pub fn chunks(input: &str) -> (Vec, Vec<&str>) { pub fn three_places(n: f64) -> f64 { (n * 1000.0).round() / 1000.0 } + +// Insert \ before " and \ +// Insert escape sequences for well-known control chars. +// Translate all other control chars to spaces (it's possible to do better). +pub fn json_quote(s: &str) -> String { + let mut t = "".to_string(); + for c in s.chars() { + match c { + '"' | '\\' => { + t.push('\\'); + t.push(c); + } + '\n' => { + t.push_str("\\n"); + } + '\r' => { + t.push_str("\\r"); + } + '\t' => { + t.push_str("\\t"); + } + _ctl if c < ' ' => { + t.push(' '); + } + _ => { + t.push(c); + } + } + } + t +}