ALPHA: wire is a tool to deploy nixos systems wire.althaea.zone/
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

switch to snix for log parsing (#414)

authored by

marshmallow and committed by
GitHub
64f8fb8b b152eac2

+27 -63
-7
Cargo.lock
··· 864 864 checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 865 865 866 866 [[package]] 867 - name = "gjson" 868 - version = "0.8.1" 869 - source = "registry+https://github.com/rust-lang/crates.io-index" 870 - checksum = "43503cc176394dd30a6525f5f36e838339b8b5619be33ed9a7783841580a97b6" 871 - 872 - [[package]] 873 867 name = "hashbrown" 874 868 version = "0.15.5" 875 869 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3209 3203 "enum_dispatch", 3210 3204 "futures", 3211 3205 "gethostname", 3212 - "gjson", 3213 3206 "im", 3214 3207 "itertools", 3215 3208 "miette",
-1
crates/core/Cargo.toml
··· 35 35 strip-ansi-escapes = "0.2.1" 36 36 aho-corasick = "1.1.4" 37 37 num_enum = "0.7.5" 38 - gjson = "0.8.1" 39 38 owo-colors = { workspace = true } 40 39 termion = "4.0.6" 41 40 sqlx = { version = "0.8", features = ["runtime-tokio", "sqlite"] }
+27 -55
crates/core/src/commands/mod.rs
··· 7 7 }; 8 8 use std::{ 9 9 collections::HashMap, 10 - str::from_utf8, 11 10 sync::{Arc, LazyLock}, 12 11 }; 13 12 14 13 use aho_corasick::AhoCorasick; 15 - use gjson::Value; 16 14 use itertools::Itertools; 17 - use nix_compat::log::{AT_NIX_PREFIX, VerbosityLevel}; 18 - use num_enum::TryFromPrimitive; 15 + use nix_compat::log::{AT_NIX_PREFIX, LogMessage, VerbosityLevel}; 19 16 use tracing::{debug, error, info, trace, warn}; 20 17 21 18 use crate::{ ··· 156 153 } 157 154 } 158 155 159 - fn trace_gjson_str<'a>(log: &'a Value<'a>, msg: &'a str) -> Option<String> { 160 - if msg.is_empty() { 161 - return None; 162 - } 163 - 164 - let level = log.get("level"); 165 - 166 - if !level.exists() { 167 - return None; 168 - } 169 - 170 - let level = match VerbosityLevel::try_from_primitive(level.u64()) { 171 - Ok(level) => level, 172 - Err(err) => { 173 - error!("nix log `level` did not match to a VerbosityLevel: {err:?}"); 174 - return None; 175 - } 176 - }; 177 - 178 - let msg = strip_ansi_escapes::strip_str(msg); 179 - 180 - match level { 181 - VerbosityLevel::Info => info!("{msg}"), 182 - VerbosityLevel::Warn | VerbosityLevel::Notice => warn!("{msg}"), 183 - VerbosityLevel::Error => error!("{msg}"), 184 - VerbosityLevel::Debug => debug!("{msg}"), 185 - VerbosityLevel::Vomit | VerbosityLevel::Talkative | VerbosityLevel::Chatty => { 186 - trace!("{msg}"); 187 - } 188 - } 189 - 190 - if matches!( 191 - level, 192 - VerbosityLevel::Error | VerbosityLevel::Warn | VerbosityLevel::Notice 193 - ) { 194 - return Some(msg); 195 - } 196 - 197 - None 198 - } 199 - 200 156 impl ChildOutputMode { 201 157 /// this function is by far the biggest hotspot in the whole tree 202 158 /// Returns a string if this log is notable to be stored as an error message ··· 221 177 } 222 178 }; 223 179 224 - let Ok(str) = from_utf8(slice) else { 225 - error!("nix log was not valid utf8!"); 180 + let Ok(log_message) = serde_json::from_slice::<LogMessage>(slice) else { 181 + // failed to parse, print the string regardless as a backup 182 + warn!("{}", String::from_utf8_lossy(slice)); 226 183 return None; 227 184 }; 228 185 229 - let log = gjson::parse(str); 230 - 231 - let text = log.get("text"); 186 + let (msg, level) = match log_message { 187 + LogMessage::Start { text, level, .. } => (text, level), 188 + LogMessage::Msg { msg, level, .. } => (msg, level), 189 + _ => return None, 190 + }; 232 191 233 - if text.exists() { 234 - return trace_gjson_str(&log, text.str()); 192 + if msg.is_empty() { 193 + return None; 235 194 } 236 195 237 - let text = log.get("msg"); 196 + let msg = strip_ansi_escapes::strip_str(msg); 197 + 198 + match level { 199 + VerbosityLevel::Info => info!("{msg}"), 200 + VerbosityLevel::Warn | VerbosityLevel::Notice => warn!("{msg}"), 201 + VerbosityLevel::Error => error!("{msg}"), 202 + VerbosityLevel::Debug => debug!("{msg}"), 203 + VerbosityLevel::Vomit | VerbosityLevel::Talkative | VerbosityLevel::Chatty => { 204 + trace!("{msg}"); 205 + } 206 + } 238 207 239 - if text.exists() { 240 - return trace_gjson_str(&log, text.str()); 208 + if matches!( 209 + level, 210 + VerbosityLevel::Error | VerbosityLevel::Warn | VerbosityLevel::Notice 211 + ) { 212 + return Some(msg); 241 213 } 242 214 243 215 None