Skip to content

Commit 7bf1c0d

Browse files
committed
feat(core): enhance native cache operations with comprehensive logging (#31652)
## Current Behavior The native cache system has minimal logging, making it difficult to debug issues or understand what's happening during cache operations. When problems occur, there's insufficient visibility into: - File copying operations and their progress - Output expansion and glob pattern matching - Cache PUT operation timing and success/failure details - Directory creation and cleanup processes ## Expected Behavior With these changes, the native cache system provides comprehensive logging that: - Tracks all file operations with sizes and timing - Provides detailed visibility into glob pattern expansion - Logs cache PUT operations with performance metrics - Includes trace-level debugging for troubleshooting - Makes it easier to diagnose cache-related issues ## Related Issue(s) This enhancement improves the observability and debugging capabilities of the native cache system without changing its core functionality. ## Changes Made - **Enhanced cache PUT operations**: Added timing metrics and detailed logging for each step - **Improved file copying**: Added progress tracking, size reporting, and detailed trace logs - **Better output expansion**: Added comprehensive logging for glob pattern analysis and path validation - **Fixed borrow checker error**: Resolved compilation issue in file_ops copy function - **Comprehensive tracing**: Added trace and debug logging throughout the cache operations The logging follows a structured approach: - `trace\!()` for detailed step-by-step operations - `debug\!()` for summary information and timing metrics - Proper error context for debugging issues This makes the native cache system much more observable and easier to debug when issues arise. (cherry picked from commit fca5650)
1 parent f703ac2 commit 7bf1c0d

File tree

3 files changed

+124
-24
lines changed

3 files changed

+124
-24
lines changed

packages/nx/src/native/cache/cache.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::fs::{create_dir_all, read_to_string, write};
22
use std::path::{Path, PathBuf};
33
use std::time::Instant;
4+
use tracing::{debug, trace};
45

56
use fs_extra::remove_items;
67
use napi::bindgen_prelude::*;
78
use regex::Regex;
89
use rusqlite::params;
910
use sysinfo::Disks;
10-
use tracing::trace;
1111

1212
use crate::native::cache::expand_outputs::_expand_outputs;
1313
use crate::native::cache::file_ops::_copy;
@@ -136,37 +136,55 @@ impl NxCache {
136136
outputs: Vec<String>,
137137
code: i16,
138138
) -> anyhow::Result<()> {
139+
let start = Instant::now();
139140
trace!("PUT {}", &hash);
140141
let task_dir = self.cache_path.join(&hash);
141142

142143
// Remove the task directory
143144
//
144145
trace!("Removing task directory: {:?}", &task_dir);
145146
remove_items(&[&task_dir])?;
147+
trace!("Successfully removed task directory: {:?}", &task_dir);
148+
146149
// Create the task directory again
147150
trace!("Creating task directory: {:?}", &task_dir);
148151
create_dir_all(&task_dir)?;
152+
trace!("Successfully created task directory: {:?}", &task_dir);
149153

150154
// Write the terminal outputs into a file
151155
let task_outputs_path = self.get_task_outputs_path_internal(&hash);
152156
trace!("Writing terminal outputs to: {:?}", &task_outputs_path);
153157
let mut total_size: i64 = terminal_output.len() as i64;
154158
write(task_outputs_path, terminal_output)?;
159+
trace!("Successfully wrote terminal outputs ({} bytes)", total_size);
155160

156161
// Expand the outputs
157162
let expanded_outputs = _expand_outputs(&self.workspace_root, outputs)?;
163+
trace!("Successfully expanded {} outputs", expanded_outputs.len());
158164

159165
// Copy the outputs to the cache
166+
let mut copied_files = 0;
160167
for expanded_output in expanded_outputs.iter() {
161168
let p = self.workspace_root.join(expanded_output);
162169
if p.exists() {
163170
let cached_outputs_dir = task_dir.join(expanded_output);
164171
trace!("Copying {:?} -> {:?}", &p, &cached_outputs_dir);
165-
total_size += _copy(p, cached_outputs_dir)?;
172+
let copied_size = _copy(p, cached_outputs_dir)?;
173+
total_size += copied_size;
174+
copied_files += 1;
175+
trace!(
176+
"Successfully copied {} ({} bytes)",
177+
expanded_output, copied_size
178+
);
166179
}
167180
}
181+
trace!(
182+
"Successfully copied {} files, total cache size: {} bytes",
183+
copied_files, total_size
184+
);
168185

169-
self.record_to_cache(hash, code, total_size)?;
186+
self.record_to_cache(hash.clone(), code, total_size)?;
187+
debug!("PUT {} {:?}", &hash, start.elapsed());
170188
Ok(())
171189
}
172190

packages/nx/src/native/cache/expand_outputs.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use hashbrown::HashMap;
22
use std::path::{Path, PathBuf};
3-
use tracing::trace;
3+
use tracing::{debug, trace};
44

55
use crate::native::glob::{build_glob_set, contains_glob_pattern, glob_transform::partition_glob};
66
use crate::native::logger::enable_logger;
@@ -19,18 +19,36 @@ where
1919
P: AsRef<Path>,
2020
{
2121
let directory: PathBuf = directory.as_ref().into();
22+
trace!(
23+
"Expanding {} output entries in directory: {:?}",
24+
entries.len(),
25+
&directory
26+
);
2227

2328
let has_glob_pattern = entries.iter().any(|entry| contains_glob_pattern(entry));
2429

2530
if !has_glob_pattern {
2631
trace!("No glob patterns found, checking if entries exist");
32+
let mut existing_count = 0;
2733
let existing_directories = entries
2834
.into_iter()
2935
.filter(|entry| {
3036
let path = directory.join(entry);
31-
path.exists()
37+
let exists = path.exists();
38+
if exists {
39+
existing_count += 1;
40+
trace!("Found existing entry: {}", entry);
41+
} else {
42+
trace!("Entry does not exist: {}", entry);
43+
}
44+
exists
3245
})
33-
.collect();
46+
.collect::<Vec<_>>();
47+
debug!(
48+
"Expanded outputs: found {} existing entries out of {} total",
49+
existing_count,
50+
existing_directories.len()
51+
);
3452
return Ok(existing_directories);
3553
}
3654

@@ -57,18 +75,33 @@ where
5775
.collect::<Vec<_>>();
5876

5977
trace!(?negated_globs, ?regular_globs, "Expanding globs");
78+
trace!(
79+
"Building glob set for {} regular globs",
80+
regular_globs.len()
81+
);
6082

6183
let glob_set = build_glob_set(&regular_globs)?;
62-
let found_paths = nx_walker_sync(directory, Some(&negated_globs))
84+
trace!("Successfully built glob set");
85+
86+
trace!(
87+
"Walking directory with {} negated globs",
88+
negated_globs.len()
89+
);
90+
let found_paths = nx_walker_sync(&directory, Some(&negated_globs))
6391
.filter_map(|path| {
6492
if glob_set.is_match(&path) {
93+
trace!("Glob match found: {}", path.to_normalized_string());
6594
Some(path.to_normalized_string())
6695
} else {
6796
None
6897
}
6998
})
70-
.collect();
99+
.collect::<Vec<_>>();
71100

101+
debug!(
102+
"Expanded outputs: found {} paths matching glob patterns",
103+
found_paths.len()
104+
);
72105
Ok(found_paths)
73106
}
74107

packages/nx/src/native/cache/file_ops.rs

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::path::{Path, PathBuf};
22
use std::{fs, io};
33

44
use fs_extra::error::ErrorKind;
5-
use tracing::trace;
5+
use tracing::{debug, trace};
66

77
#[napi]
88
pub fn remove(src: String) -> anyhow::Result<()> {
@@ -22,24 +22,41 @@ where
2222
P: AsRef<Path>,
2323
{
2424
let dest: PathBuf = remove_trailing_single_dot(dest);
25-
2625
let dest_parent = dest.parent().unwrap_or(&dest);
27-
2826
let src: PathBuf = src.as_ref().into();
2927

28+
trace!("Copying {:?} -> {:?}", &src, &dest);
29+
3030
if !dest_parent.exists() {
31+
trace!("Creating parent directory: {:?}", dest_parent);
3132
fs::create_dir_all(dest_parent)?;
33+
trace!("Successfully created parent directory: {:?}", dest_parent);
3234
}
3335

3436
let size = if src.is_dir() {
35-
copy_dir_all(&src, dest).map_err(anyhow::Error::new)?
37+
trace!("Copying directory: {:?}", &src);
38+
let copied_size = copy_dir_all(&src, &dest).map_err(anyhow::Error::new)?;
39+
trace!(
40+
"Successfully copied directory: {:?} ({} bytes)",
41+
&src, copied_size
42+
);
43+
copied_size
3644
} else if src.is_symlink() {
37-
symlink(fs::read_link(src)?, dest)?;
45+
trace!("Copying symlink: {:?}", &src);
46+
symlink(fs::read_link(&src)?, &dest)?;
47+
trace!("Successfully copied symlink: {:?}", &src);
3848
0
3949
} else {
40-
fs::copy(src, dest)?
50+
trace!("Copying file: {:?}", &src);
51+
let copied_size = fs::copy(&src, &dest)?;
52+
trace!(
53+
"Successfully copied file: {:?} ({} bytes)",
54+
&src, copied_size
55+
);
56+
copied_size
4157
};
4258

59+
debug!("Copy completed: {:?} -> {:?} ({} bytes)", &src, &dest, size);
4360
Ok(size as i64)
4461
}
4562

@@ -71,27 +88,59 @@ fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<(
7188
}
7289

7390
fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<u64> {
74-
trace!("creating directory: {:?}", dst.as_ref());
91+
trace!("Creating directory: {:?}", dst.as_ref());
7592
fs::create_dir_all(&dst)?;
76-
trace!("reading source directory: {:?}", src.as_ref());
93+
trace!("Successfully created directory: {:?}", dst.as_ref());
94+
95+
trace!("Reading source directory: {:?}", src.as_ref());
7796
let mut total_size = 0;
78-
for entry in fs::read_dir(src)? {
97+
let mut files_copied = 0;
98+
let mut dirs_copied = 0;
99+
let mut symlinks_copied = 0;
100+
101+
for entry in fs::read_dir(&src)? {
79102
let entry = entry?;
80103
let ty = entry.file_type()?;
104+
let entry_name = entry.file_name();
105+
let dest_path = dst.as_ref().join(&entry_name);
106+
81107
let size: u64 = if ty.is_dir() {
82-
copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?
108+
trace!("Copying subdirectory: {:?}", entry.path());
109+
let subdir_size = copy_dir_all(entry.path(), dest_path)?;
110+
dirs_copied += 1;
111+
trace!(
112+
"Successfully copied subdirectory: {:?} ({} bytes)",
113+
entry_name, subdir_size
114+
);
115+
subdir_size
83116
} else if ty.is_symlink() {
84-
symlink(
85-
fs::read_link(entry.path())?,
86-
dst.as_ref().join(entry.file_name()),
87-
)?;
88-
// Handle this
117+
trace!("Copying symlink: {:?}", entry.path());
118+
symlink(fs::read_link(entry.path())?, dest_path)?;
119+
symlinks_copied += 1;
120+
trace!("Successfully copied symlink: {:?}", entry_name);
89121
0
90122
} else {
91-
fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?
123+
trace!("Copying file: {:?}", entry.path());
124+
let file_size = fs::copy(entry.path(), dest_path)?;
125+
files_copied += 1;
126+
trace!(
127+
"Successfully copied file: {:?} ({} bytes)",
128+
entry_name, file_size
129+
);
130+
file_size
92131
};
93132
total_size += size;
94133
}
134+
135+
debug!(
136+
"Directory copy completed: {:?} -> {:?} ({} files, {} dirs, {} symlinks, {} bytes total)",
137+
src.as_ref(),
138+
dst.as_ref(),
139+
files_copied,
140+
dirs_copied,
141+
symlinks_copied,
142+
total_size
143+
);
95144
Ok(total_size)
96145
}
97146

0 commit comments

Comments
 (0)