cargo/util/
log_message.rs

1//! Messages for logging.
2
3use std::io::Write;
4use std::path::PathBuf;
5
6use cargo_util_schemas::core::PackageIdSpec;
7use jiff::Timestamp;
8use serde::Serialize;
9
10use crate::core::Target;
11use crate::core::compiler::CompilationSection;
12use crate::core::compiler::CompileMode;
13
14/// A log message.
15///
16/// Each variant represents a different type of event.
17#[derive(Serialize)]
18#[serde(tag = "reason", rename_all = "kebab-case")]
19pub enum LogMessage {
20    /// Emitted when a build starts.
21    BuildStarted {
22        cwd: PathBuf,
23        host: String,
24        jobs: u32,
25        profile: String,
26        rustc_version: String,
27        rustc_version_verbose: String,
28        target_dir: PathBuf,
29        workspace_root: PathBuf,
30    },
31    /// Emitted when a compilation unit finishes.
32    TimingInfo {
33        package_id: PackageIdSpec,
34        target: Target,
35        mode: CompileMode,
36        duration: f64,
37        #[serde(skip_serializing_if = "Option::is_none")]
38        rmeta_time: Option<f64>,
39        #[serde(skip_serializing_if = "Vec::is_empty")]
40        sections: Vec<(String, CompilationSection)>,
41    },
42}
43
44impl LogMessage {
45    /// Serializes this message as a JSON log line directly to the writer.
46    pub fn write_json_log<W: Write>(&self, writer: &mut W, run_id: &str) -> std::io::Result<()> {
47        #[derive(Serialize)]
48        struct LogEntry<'a> {
49            run_id: &'a str,
50            timestamp: Timestamp,
51            #[serde(flatten)]
52            msg: &'a LogMessage,
53        }
54
55        let entry = LogEntry {
56            run_id,
57            timestamp: Timestamp::now(),
58            msg: self,
59        };
60
61        serde_json::to_writer(&mut *writer, &entry)?;
62        writer.write_all(b"\n")?;
63        Ok(())
64    }
65}