Skip to content

Commit 229d980

Browse files
authored
feat: extend logging (#119)
Extends debug logging to the rest of the backends
1 parent eec5a9c commit 229d980

File tree

10 files changed

+182
-94
lines changed

10 files changed

+182
-94
lines changed

crates/pixi-build-backend/src/protocol.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::{Path, PathBuf};
2+
13
use pixi_build_types::procedures::{
24
conda_build::{CondaBuildParams, CondaBuildResult},
35
conda_metadata::{CondaMetadataParams, CondaMetadataResult},
@@ -9,6 +11,10 @@ use pixi_build_types::procedures::{
911
/// and endpoint that can handle the RPC calls.
1012
#[async_trait::async_trait]
1113
pub trait ProtocolInstantiator: Send + Sync + 'static {
14+
/// Get the debug directory
15+
/// If set, internal state will be logged as files in that directory
16+
fn debug_dir(configuration: Option<serde_json::Value>) -> Option<PathBuf>;
17+
1218
/// Called when negotiating capabilities with the client.
1319
/// This is determine how the rest of the initialization will proceed.
1420
async fn negotiate_capabilities(
@@ -28,6 +34,10 @@ pub trait ProtocolInstantiator: Send + Sync + 'static {
2834
/// server as an endpoint for the RPC calls.
2935
#[async_trait::async_trait]
3036
pub trait Protocol {
37+
/// Get the debug directory
38+
/// If set, internal state will be logged as files in that directory
39+
fn debug_dir(&self) -> Option<&Path>;
40+
3141
/// Called when the client requests metadata for a Conda package.
3242
async fn conda_get_metadata(
3343
&self,

crates/pixi-build-backend/src/server.rs

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
use std::{net::SocketAddr, sync::Arc};
1+
use std::{net::SocketAddr, path::Path, sync::Arc};
22

3+
use fs_err::tokio as tokio_fs;
34
use jsonrpc_core::{Error, IoHandler, Params, serde_json, to_value};
4-
use miette::{IntoDiagnostic, JSONReportHandler};
5+
use miette::{Context, IntoDiagnostic, JSONReportHandler};
6+
use pixi_build_types::VersionedProjectModel;
57
use pixi_build_types::procedures::{
68
self, conda_build::CondaBuildParams, conda_metadata::CondaMetadataParams,
79
initialize::InitializeParams, negotiate_capabilities::NegotiateCapabilitiesParams,
810
};
11+
912
use tokio::sync::RwLock;
1013

1114
use crate::protocol::{Protocol, ProtocolInstantiator};
@@ -85,6 +88,10 @@ impl<T: ProtocolInstantiator> Server<T> {
8588
return Err(Error::invalid_request());
8689
};
8790

91+
let debug_dir = T::debug_dir(params.configuration.clone());
92+
let _ =
93+
log_initialize(debug_dir.as_deref(), params.project_model.clone()).await;
94+
8895
let (protocol_endpoint, result) = initializer
8996
.initialize(params)
9097
.await
@@ -105,8 +112,14 @@ impl<T: ProtocolInstantiator> Server<T> {
105112
async move {
106113
let params: CondaMetadataParams = params.parse()?;
107114
let state = state.read().await;
108-
state
109-
.as_endpoint()?
115+
let endpoint = state.as_endpoint()?;
116+
117+
let debug_dir = endpoint.debug_dir();
118+
log_conda_get_metadata(debug_dir, &params)
119+
.await
120+
.map_err(convert_error)?;
121+
122+
endpoint
110123
.conda_get_metadata(params)
111124
.await
112125
.map(|value| to_value(value).expect("failed to convert to json"))
@@ -124,8 +137,14 @@ impl<T: ProtocolInstantiator> Server<T> {
124137
async move {
125138
let params: CondaBuildParams = params.parse()?;
126139
let state = state.read().await;
127-
state
128-
.as_endpoint()?
140+
let endpoint = state.as_endpoint()?;
141+
142+
let debug_dir = endpoint.debug_dir();
143+
log_conda_build(debug_dir, &params)
144+
.await
145+
.map_err(convert_error)?;
146+
147+
endpoint
129148
.conda_build(params)
130149
.await
131150
.map(|value| to_value(value).expect("failed to convert to json"))
@@ -151,3 +170,78 @@ fn convert_error(err: miette::Report) -> jsonrpc_core::Error {
151170
data: Some(data),
152171
}
153172
}
173+
174+
async fn log_initialize(
175+
debug_dir: Option<&Path>,
176+
project_model: Option<VersionedProjectModel>,
177+
) -> miette::Result<()> {
178+
let Some(debug_dir) = debug_dir else {
179+
return Ok(());
180+
};
181+
182+
let project_model = project_model
183+
.ok_or_else(|| miette::miette!("project model is required if debug_dir is given"))?
184+
.into_v1()
185+
.ok_or_else(|| miette::miette!("project model needs to be v1"))?;
186+
187+
let project_model_json = serde_json::to_string_pretty(&project_model)
188+
.into_diagnostic()
189+
.context("failed to serialize project model to JSON")?;
190+
191+
let project_model_path = debug_dir.join("project_model.json");
192+
tokio_fs::write(&project_model_path, project_model_json)
193+
.await
194+
.into_diagnostic()
195+
.context("failed to write project model JSON to file")?;
196+
Ok(())
197+
}
198+
199+
async fn log_conda_get_metadata(
200+
debug_dir: Option<&Path>,
201+
params: &CondaMetadataParams,
202+
) -> miette::Result<()> {
203+
let Some(debug_dir) = debug_dir else {
204+
return Ok(());
205+
};
206+
207+
let json = serde_json::to_string_pretty(&params)
208+
.into_diagnostic()
209+
.context("failed to serialize parameters to JSON")?;
210+
211+
tokio_fs::create_dir_all(&debug_dir)
212+
.await
213+
.into_diagnostic()
214+
.context("failed to create data directory")?;
215+
216+
let path = debug_dir.join("conda_metadata_params.json");
217+
tokio_fs::write(&path, json)
218+
.await
219+
.into_diagnostic()
220+
.context("failed to write JSON to file")?;
221+
Ok(())
222+
}
223+
224+
async fn log_conda_build(
225+
debug_dir: Option<&Path>,
226+
params: &CondaBuildParams,
227+
) -> miette::Result<()> {
228+
let Some(debug_dir) = debug_dir else {
229+
return Ok(());
230+
};
231+
232+
let json = serde_json::to_string_pretty(&params)
233+
.into_diagnostic()
234+
.context("failed to serialize parameters to JSON")?;
235+
236+
tokio_fs::create_dir_all(&debug_dir)
237+
.await
238+
.into_diagnostic()
239+
.context("failed to create data directory")?;
240+
241+
let path = debug_dir.join("conda_build_params.json");
242+
tokio_fs::write(&path, json)
243+
.await
244+
.into_diagnostic()
245+
.context("failed to write JSON to file")?;
246+
Ok(())
247+
}

crates/pixi-build-cmake/src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::PathBuf;
2+
13
use indexmap::IndexMap;
24
use serde::Deserialize;
35

@@ -10,6 +12,8 @@ pub struct CMakeBackendConfig {
1012
/// Environment Variables
1113
#[serde(default)]
1214
pub env: IndexMap<String, String>,
15+
/// If set, internal state will be logged as files in that directory
16+
pub debug_dir: Option<PathBuf>,
1317
}
1418

1519
#[cfg(test)]

crates/pixi-build-cmake/src/protocol.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use std::{str::FromStr, sync::Arc};
1+
use std::{
2+
path::{Path, PathBuf},
3+
str::FromStr,
4+
sync::Arc,
5+
};
26

37
use miette::{Context, IntoDiagnostic};
48
use pixi_build_backend::{
@@ -60,6 +64,10 @@ impl CMakeBuildBackendInstantiator {
6064
}
6165
#[async_trait::async_trait]
6266
impl Protocol for CMakeBuildBackend<ProjectModelV1> {
67+
fn debug_dir(&self) -> Option<&Path> {
68+
self.config.debug_dir.as_deref()
69+
}
70+
6371
async fn conda_get_metadata(
6472
&self,
6573
params: CondaMetadataParams,
@@ -372,6 +380,12 @@ impl Protocol for CMakeBuildBackend<ProjectModelV1> {
372380

373381
#[async_trait::async_trait]
374382
impl ProtocolInstantiator for CMakeBuildBackendInstantiator {
383+
fn debug_dir(configuration: Option<serde_json::Value>) -> Option<PathBuf> {
384+
configuration
385+
.and_then(|config| serde_json::from_value::<CMakeBackendConfig>(config).ok())
386+
.and_then(|config| config.debug_dir)
387+
}
388+
375389
async fn initialize(
376390
&self,
377391
params: InitializeParams,

crates/pixi-build-python/src/config.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use indexmap::IndexMap;
22
use serde::Deserialize;
3-
use std::convert::identity;
3+
use std::{convert::identity, path::PathBuf};
44

55
#[derive(Debug, Default, Deserialize)]
66
#[serde(rename_all = "kebab-case")]
@@ -9,10 +9,11 @@ pub struct PythonBackendConfig {
99
/// to `true`.
1010
#[serde(default)]
1111
pub noarch: Option<bool>,
12-
1312
/// Environment Variables
1413
#[serde(default)]
1514
pub env: IndexMap<String, String>,
15+
/// If set, internal state will be logged as files in that directory
16+
pub debug_dir: Option<PathBuf>,
1617
}
1718

1819
impl PythonBackendConfig {

crates/pixi-build-python/src/protocol.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use std::{str::FromStr, sync::Arc};
1+
use std::{
2+
path::{Path, PathBuf},
3+
str::FromStr,
4+
sync::Arc,
5+
};
26

37
use miette::{Context, IntoDiagnostic};
48
use pixi_build_backend::{
@@ -38,6 +42,10 @@ use crate::{
3842

3943
#[async_trait::async_trait]
4044
impl<P: ProjectModel + Sync> Protocol for PythonBuildBackend<P> {
45+
fn debug_dir(&self) -> Option<&Path> {
46+
self.config.debug_dir.as_deref()
47+
}
48+
4149
async fn conda_get_metadata(
4250
&self,
4351
params: CondaMetadataParams,
@@ -424,6 +432,12 @@ impl PythonBuildBackendInstantiator {
424432

425433
#[async_trait::async_trait]
426434
impl ProtocolInstantiator for PythonBuildBackendInstantiator {
435+
fn debug_dir(configuration: Option<serde_json::Value>) -> Option<PathBuf> {
436+
configuration
437+
.and_then(|config| serde_json::from_value::<PythonBackendConfig>(config.clone()).ok())
438+
.and_then(|config| config.debug_dir)
439+
}
440+
427441
async fn initialize(
428442
&self,
429443
params: InitializeParams,

crates/pixi-build-rattler-build/src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::path::PathBuf;
44
#[derive(Debug, Default, Deserialize)]
55
#[serde(rename_all = "kebab-case")]
66
pub struct RattlerBuildBackendConfig {
7+
/// If set, internal state will be logged as files in that directory
78
pub debug_dir: Option<PathBuf>,
89
}
910

0 commit comments

Comments
 (0)