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