|  | 
| 1 |  | -#[cfg(feature = "display")] | 
| 2 |  | -use std::fmt::Write; | 
| 3 |  | - | 
| 4 | 1 | use chrono::{DateTime, Utc}; | 
| 5 | 2 | #[cfg(feature = "display")] | 
| 6 | 3 | use crossterm::style::{StyledContent, Stylize}; | 
| 7 | 4 | use serde::{Deserialize, Serialize}; | 
|  | 5 | +use strum::EnumString; | 
| 8 | 6 | #[cfg(feature = "openapi")] | 
| 9 | 7 | use utoipa::ToSchema; | 
| 10 | 8 | use uuid::Uuid; | 
| 11 | 9 | 
 | 
| 12 |  | -use crate::deployment::State; | 
| 13 |  | - | 
| 14 |  | -pub const STATE_MESSAGE: &str = "NEW STATE"; | 
|  | 10 | +#[derive(Clone, Debug, EnumString, Eq, PartialEq, Deserialize, Serialize)] | 
|  | 11 | +#[cfg_attr(feature = "display", derive(strum::Display))] | 
|  | 12 | +#[cfg_attr(feature = "openapi", derive(ToSchema))] | 
|  | 13 | +pub enum InternalLogOrigin { | 
|  | 14 | +    Unknown, | 
|  | 15 | +    Deployer, | 
|  | 16 | +    // Builder, | 
|  | 17 | +    // ResourceRecorder, | 
|  | 18 | +} | 
| 15 | 19 | 
 | 
|  | 20 | +impl Default for InternalLogOrigin { | 
|  | 21 | +    fn default() -> Self { | 
|  | 22 | +        Self::Unknown | 
|  | 23 | +    } | 
|  | 24 | +} | 
| 16 | 25 | #[derive(Clone, Debug, Deserialize, Serialize)] | 
| 17 | 26 | #[cfg_attr(feature = "openapi", derive(ToSchema))] | 
| 18 | 27 | #[cfg_attr(feature = "openapi", schema(as = shuttle_common::log::Item))] | 
| 19 | 28 | pub struct Item { | 
| 20 | 29 |     #[cfg_attr(feature = "openapi", schema(value_type = KnownFormat::Uuid))] | 
| 21 | 30 |     pub id: Uuid, | 
|  | 31 | +    #[cfg_attr(feature = "openapi", schema(value_type = shuttle_common::log::InternalLogOrigin))] | 
|  | 32 | +    pub internal_origin: InternalLogOrigin, | 
| 22 | 33 |     #[cfg_attr(feature = "openapi", schema(value_type = KnownFormat::DateTime))] | 
| 23 | 34 |     pub timestamp: DateTime<Utc>, | 
| 24 |  | -    #[cfg_attr(feature = "openapi", schema(value_type = shuttle_common::deployment::State))] | 
| 25 |  | -    pub state: State, | 
| 26 |  | -    #[cfg_attr(feature = "openapi", schema(value_type = shuttle_common::log::Level))] | 
| 27 |  | -    pub level: Level, | 
| 28 |  | -    pub file: Option<String>, | 
| 29 |  | -    pub line: Option<u32>, | 
| 30 |  | -    pub target: String, | 
| 31 |  | -    pub fields: Vec<u8>, | 
|  | 35 | +    pub line: String, | 
|  | 36 | +    // #[cfg_attr(feature = "openapi", schema(value_type = shuttle_common::deployment::State))] | 
|  | 37 | +    // pub state: State, | 
|  | 38 | +    // #[cfg_attr(feature = "openapi", schema(value_type = shuttle_common::log::Level))] | 
|  | 39 | +    // pub level: Level, | 
|  | 40 | +    // pub file: Option<String>, | 
|  | 41 | +    // pub line: Option<u32>, | 
|  | 42 | +    // pub target: String, | 
|  | 43 | +    // pub fields: Vec<u8>, | 
| 32 | 44 | } | 
| 33 | 45 | 
 | 
| 34 | 46 | #[cfg(feature = "display")] | 
| 35 | 47 | impl std::fmt::Display for Item { | 
| 36 | 48 |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 
| 37 | 49 |         let datetime: chrono::DateTime<chrono::Local> = DateTime::from(self.timestamp); | 
| 38 | 50 | 
 | 
| 39 |  | -        let message = match serde_json::from_slice(&self.fields).unwrap() { | 
| 40 |  | -            serde_json::Value::String(str_value) if str_value == STATE_MESSAGE => { | 
| 41 |  | -                writeln!(f)?; | 
| 42 |  | -                format!("Entering {} state", self.state) | 
| 43 |  | -                    .bold() | 
| 44 |  | -                    .blue() | 
| 45 |  | -                    .to_string() | 
| 46 |  | -            } | 
| 47 |  | -            serde_json::Value::Object(map) => { | 
| 48 |  | -                let mut simple = None; | 
| 49 |  | -                let mut extra = vec![]; | 
| 50 |  | - | 
| 51 |  | -                for (key, value) in map.iter() { | 
| 52 |  | -                    match key.as_str() { | 
| 53 |  | -                        "message" => simple = value.as_str(), | 
| 54 |  | -                        _ => extra.push(format!("{key}={value}")), | 
| 55 |  | -                    } | 
| 56 |  | -                } | 
| 57 |  | - | 
| 58 |  | -                let mut output = if extra.is_empty() { | 
| 59 |  | -                    String::new() | 
| 60 |  | -                } else { | 
| 61 |  | -                    format!("{{{}}} ", extra.join(" ")) | 
| 62 |  | -                }; | 
| 63 |  | - | 
| 64 |  | -                if !self.target.is_empty() { | 
| 65 |  | -                    let target = format!("{}:", self.target).dim(); | 
| 66 |  | -                    write!(output, "{target} ")?; | 
| 67 |  | -                } | 
| 68 |  | - | 
| 69 |  | -                if let Some(msg) = simple { | 
| 70 |  | -                    write!(output, "{msg}")?; | 
| 71 |  | -                } | 
| 72 |  | - | 
| 73 |  | -                output | 
| 74 |  | -            } | 
| 75 |  | -            other => other.to_string(), | 
| 76 |  | -        }; | 
| 77 |  | - | 
| 78 | 51 |         write!( | 
| 79 | 52 |             f, | 
| 80 |  | -            "{} {} {}", | 
|  | 53 | +            "{} [{}] {}", | 
| 81 | 54 |             datetime.to_rfc3339().dim(), | 
| 82 |  | -            self.level.get_colored(), | 
| 83 |  | -            message | 
|  | 55 | +            self.internal_origin, | 
|  | 56 | +            self.line, | 
| 84 | 57 |         ) | 
| 85 | 58 |     } | 
| 86 | 59 | } | 
| @@ -139,16 +112,9 @@ mod tests { | 
| 139 | 112 |     fn test_timezone_formatting() { | 
| 140 | 113 |         let item = Item { | 
| 141 | 114 |             id: Uuid::new_v4(), | 
|  | 115 | +            internal_origin: InternalLogOrigin::Deployer, | 
| 142 | 116 |             timestamp: Utc::now(), | 
| 143 |  | -            state: State::Building, | 
| 144 |  | -            level: Level::Info, | 
| 145 |  | -            file: None, | 
| 146 |  | -            line: None, | 
| 147 |  | -            target: "shuttle::build".to_string(), | 
| 148 |  | -            fields: serde_json::to_vec(&serde_json::json!({ | 
| 149 |  | -                "message": "Building", | 
| 150 |  | -            })) | 
| 151 |  | -            .unwrap(), | 
|  | 117 | +            line: r#"{"message": "Building"}"#.to_owned(), | 
| 152 | 118 |         }; | 
| 153 | 119 | 
 | 
| 154 | 120 |         with_tz("CEST", || { | 
|  | 
0 commit comments