Igneum Miner: the app log reaches the intake (the uploader sends the file main.rs named instead of guessing a stamp); every upload starts with 'IGNEUM-APP version=<v> machine=<id8> platform=<os> node=<igneumd version>', logged again at every engine start so an OTA-applied restart carries it; token redaction kept
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
3f23df38b7
commit
0dd587d31a
4 changed files with 23 additions and 8 deletions
|
|
@ -73,11 +73,13 @@ pub struct Shared {
|
|||
cmd_tx: Mutex<Sender<Cmd>>,
|
||||
pub started: Instant,
|
||||
engine_log: Mutex<Option<std::fs::File>>,
|
||||
/// the app log's path: the one the uploader sends (main.rs names it; the engine must not guess the stamp)
|
||||
pub log_path: PathBuf,
|
||||
port: std::sync::atomic::AtomicU16,
|
||||
}
|
||||
|
||||
impl Shared {
|
||||
pub fn new(token: String, runtime: Runtime, packaged: Packaged, settings: Settings, cmd_tx: Sender<Cmd>, engine_log: Option<std::fs::File>) -> Shared {
|
||||
pub fn new(token: String, runtime: Runtime, packaged: Packaged, settings: Settings, cmd_tx: Sender<Cmd>, engine_log: Option<std::fs::File>, log_path: PathBuf) -> Shared {
|
||||
let settings_path = runtime.app_dir.join("settings.json");
|
||||
let wallet_path = runtime.app_dir.join("wallet.json");
|
||||
let mut st = State { version: VERSION.into(), ..Default::default() };
|
||||
|
|
@ -113,10 +115,19 @@ impl Shared {
|
|||
cmd_tx: Mutex::new(cmd_tx),
|
||||
started: Instant::now(),
|
||||
engine_log: Mutex::new(engine_log),
|
||||
log_path,
|
||||
port: std::sync::atomic::AtomicU16::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
/// The first line of every upload, so the console's Machines tab parses it without guessing:
|
||||
/// IGNEUM-APP version=<v> machine=<id8> platform=<os> node=<igneumd version>. Logged at every engine start too,
|
||||
/// so the restart after an OTA apply carries it again.
|
||||
pub fn upload_header(&self) -> String {
|
||||
let node = self.state.lock().unwrap().node.version.clone();
|
||||
format!("IGNEUM-APP version={} machine={} platform={} node={}", VERSION, self.runtime.id8(), crate::manifest::platform_name(), if node.is_empty() { "unknown".to_string() } else { node.replace(' ', "_") })
|
||||
}
|
||||
|
||||
pub fn set_port(&self, p: u16) {
|
||||
self.port.store(p, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
|
@ -504,6 +515,7 @@ impl Engine {
|
|||
));
|
||||
let v = crate::detect::node_version(&self.bins.node);
|
||||
self.st().node.version = v.clone();
|
||||
self.shared.log(&self.shared.upload_header());
|
||||
// the prover service (proving v0): its own thread, idle until the setting is on
|
||||
crate::prover::start(self.shared.clone(), self.bins.dir.clone());
|
||||
self.shared.log(&format!("node binary: {} ({v})", self.bins.node.display()));
|
||||
|
|
@ -2106,7 +2118,7 @@ impl Engine {
|
|||
}
|
||||
}
|
||||
let mut files: Vec<(String, PathBuf)> = Vec::new();
|
||||
files.push((self.label_base.clone(), self.shared.runtime.log_dir.join(format!("app-{}.log", self.stamp))));
|
||||
files.push((self.label_base.clone(), self.shared.log_path.clone()));
|
||||
if let Some(n) = &self.node_log {
|
||||
files.push((format!("nodelog-{}", self.label_base), n.clone()));
|
||||
}
|
||||
|
|
@ -2117,9 +2129,10 @@ impl Engine {
|
|||
}
|
||||
// machine = "<hostname>-<id8>": readable in tools/logs.mjs and distinct for cloned PCs
|
||||
let (url, key, machine, run_id) = (p.log_intake_url.clone(), p.log_intake_key.clone(), format!("{}-{}", self.shared.runtime.host, self.shared.runtime.id8()), format!("{}-{}", self.label_base, self.stamp));
|
||||
let header = self.shared.upload_header();
|
||||
let t = std::thread::spawn(move || {
|
||||
for (label, path) in files {
|
||||
crate::update::upload_log(&url, &key, &label, &machine, &run_id, &path);
|
||||
crate::update::upload_log(&url, &key, &label, &machine, &run_id, &path, &header);
|
||||
}
|
||||
});
|
||||
if wait {
|
||||
|
|
|
|||
|
|
@ -533,7 +533,7 @@ fn report(shared: &Arc<Shared>, job: &Job, sink: &Sink, status: &str, exit: i64,
|
|||
return false;
|
||||
}
|
||||
let machine = format!("{}-{}", shared.runtime.host, shared.runtime.id8());
|
||||
crate::update::upload_log(&p.log_intake_url, &p.log_intake_key, &format!("job-{}", job.kind), &machine, &job.run_id(&shared.runtime.machine_id), &path)
|
||||
crate::update::upload_log(&p.log_intake_url, &p.log_intake_key, &format!("job-{}", job.kind), &machine, &job.run_id(&shared.runtime.machine_id), &path, &shared.upload_header())
|
||||
}
|
||||
|
||||
/// One file to the intake under the job's run id, labelled file-<name>. The intake keeps the last 256 KB.
|
||||
|
|
@ -545,7 +545,7 @@ fn upload_file(shared: &Arc<Shared>, job: &Job, path: &Path, label_prefix: &str)
|
|||
let name = path.file_name().map(|n| n.to_string_lossy().into_owned()).unwrap_or_default();
|
||||
let label: String = format!("{label_prefix}-{name}").chars().take(80).collect();
|
||||
let machine = format!("{}-{}", shared.runtime.host, shared.runtime.id8());
|
||||
crate::update::upload_log(&p.log_intake_url, &p.log_intake_key, &label, &machine, &job.run_id(&shared.runtime.machine_id), path)
|
||||
crate::update::upload_log(&p.log_intake_url, &p.log_intake_key, &label, &machine, &job.run_id(&shared.runtime.machine_id), path, &shared.upload_header())
|
||||
}
|
||||
|
||||
// ---- fetching the jobs file and probing requirements -----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ fn main() {
|
|||
let stamp_file = runtime.log_dir.join(format!("app-{}.log", stamp_now()));
|
||||
let engine_log = std::fs::File::create(&stamp_file).ok();
|
||||
let (tx, rx) = channel();
|
||||
let shared = Arc::new(engine::Shared::new(token.clone(), runtime, packaged, settings, tx, engine_log));
|
||||
let shared = Arc::new(engine::Shared::new(token.clone(), runtime, packaged, settings, tx, engine_log, stamp_file.clone()));
|
||||
let port = match server::start(shared.clone()) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ mod tests {
|
|||
}
|
||||
|
||||
/// Posts the last 256 KB of a log file as {label, machine, run_id, lines}, as site/api/log.mjs expects.
|
||||
pub fn upload_log(url: &str, key: &str, label: &str, machine: &str, run_id: &str, path: &std::path::Path) -> bool {
|
||||
pub fn upload_log(url: &str, key: &str, label: &str, machine: &str, run_id: &str, path: &std::path::Path, header: &str) -> bool {
|
||||
if url.is_empty() || key.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -76,7 +76,9 @@ pub fn upload_log(url: &str, key: &str, label: &str, machine: &str, run_id: &str
|
|||
data = data.split_off(data.len() - 262_144);
|
||||
}
|
||||
// second guard (R4.3.8): no line that carries a dashboard token leaves the machine
|
||||
let text: String = String::from_utf8_lossy(&data).lines().filter(|l| !crate::platform::carries_token(l)).map(|l| crate::platform::redact(l)).collect::<Vec<_>>().join("\n");
|
||||
let tail: String = String::from_utf8_lossy(&data).lines().filter(|l| !crate::platform::carries_token(l)).map(|l| crate::platform::redact(l)).collect::<Vec<_>>().join("\n");
|
||||
// the first line of every upload names the app, the machine and the node (the console parses it)
|
||||
let text = format!("{header}\n{tail}");
|
||||
let body = serde_json::json!({ "label": label, "machine": machine, "run_id": run_id, "lines": text });
|
||||
let tmp = std::env::temp_dir().join(format!("igneum-upload-{}-{}.json", std::process::id(), label));
|
||||
if std::fs::write(&tmp, body.to_string()).is_err() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue