Skip to content

Commit 4e454b4

Browse files
authored
chore: add more instrumentation (#293)
`#[instrument]` and clean up. No functional changes intended.
1 parent e8a2e02 commit 4e454b4

File tree

10 files changed

+58
-21
lines changed

10 files changed

+58
-21
lines changed

crates/artifacts/solc/src/sources.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl Source {
124124
}
125125

126126
/// Reads the file's content
127-
#[instrument(name = "read_source", level = "debug", skip_all, err)]
127+
#[instrument(name = "Source::read", skip_all, err)]
128128
pub fn read(file: &Path) -> Result<Self, SolcIoError> {
129129
trace!(file=%file.display());
130130
let mut content = fs::read_to_string(file).map_err(|err| SolcIoError::new(err, file))?;
@@ -162,6 +162,7 @@ impl Source {
162162
}
163163

164164
/// Reads all files
165+
#[instrument(name = "Source::read_all", skip_all)]
165166
pub fn read_all<T, I>(files: I) -> Result<Sources, SolcIoError>
166167
where
167168
I: IntoIterator<Item = T>,
@@ -211,7 +212,7 @@ impl Source {
211212
#[cfg(feature = "async")]
212213
impl Source {
213214
/// async version of `Self::read`
214-
#[instrument(name = "async_read_source", level = "debug", skip_all, err)]
215+
#[instrument(name = "Source::async_read", skip_all, err)]
215216
pub async fn async_read(file: &Path) -> Result<Self, SolcIoError> {
216217
let mut content =
217218
tokio::fs::read_to_string(file).await.map_err(|err| SolcIoError::new(err, file))?;

crates/compilers/src/cache.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ impl<S: CompilerSettings> CompilerCache<S> {
118118
/// cache.join_artifacts_files(project.artifacts_path());
119119
/// # Ok::<_, Box<dyn std::error::Error>>(())
120120
/// ```
121-
#[instrument(skip_all, name = "sol-files-cache::read")]
121+
#[instrument(name = "CompilerCache::read", skip_all)]
122122
pub fn read(path: &Path) -> Result<Self> {
123123
trace!("reading solfiles cache at {}", path.display());
124124
let cache: Self = utils::read_json_file(path)?;
@@ -149,6 +149,7 @@ impl<S: CompilerSettings> CompilerCache<S> {
149149
}
150150

151151
/// Write the cache as json file to the given path
152+
#[instrument(name = "CompilerCache::write", skip_all)]
152153
pub fn write(&self, path: &Path) -> Result<()> {
153154
trace!("writing cache with {} entries to json file: \"{}\"", self.len(), path.display());
154155
utils::create_parent_dir_all(path)?;
@@ -158,6 +159,7 @@ impl<S: CompilerSettings> CompilerCache<S> {
158159
}
159160

160161
/// Removes build infos which don't have any artifacts linked to them.
162+
#[instrument(skip_all)]
161163
pub fn remove_outdated_builds(&mut self) {
162164
let mut outdated = Vec::new();
163165
for build_id in &self.builds {
@@ -180,6 +182,7 @@ impl<S: CompilerSettings> CompilerCache<S> {
180182
}
181183

182184
/// Sets the `CacheEntry`'s file paths to `root` adjoined to `self.file`.
185+
#[instrument(skip_all)]
183186
pub fn join_entries(&mut self, root: &Path) -> &mut Self {
184187
self.files = std::mem::take(&mut self.files)
185188
.into_iter()
@@ -189,6 +192,7 @@ impl<S: CompilerSettings> CompilerCache<S> {
189192
}
190193

191194
/// Removes `base` from all `CacheEntry` paths
195+
#[instrument(skip_all)]
192196
pub fn strip_entries_prefix(&mut self, base: &Path) -> &mut Self {
193197
self.files = std::mem::take(&mut self.files)
194198
.into_iter()
@@ -198,12 +202,14 @@ impl<S: CompilerSettings> CompilerCache<S> {
198202
}
199203

200204
/// Sets the artifact files location to `base` adjoined to the `CachEntries` artifacts.
205+
#[instrument(skip_all)]
201206
pub fn join_artifacts_files(&mut self, base: &Path) -> &mut Self {
202207
self.files.values_mut().for_each(|entry| entry.join_artifacts_files(base));
203208
self
204209
}
205210

206211
/// Removes `base` from all artifact file paths
212+
#[instrument(skip_all)]
207213
pub fn strip_artifact_files_prefixes(&mut self, base: &Path) -> &mut Self {
208214
self.files.values_mut().for_each(|entry| entry.strip_artifact_files_prefixes(base));
209215
self
@@ -212,6 +218,7 @@ impl<S: CompilerSettings> CompilerCache<S> {
212218
/// Removes all `CacheEntry` which source files don't exist on disk
213219
///
214220
/// **NOTE:** this assumes the `files` are absolute
221+
#[instrument(skip_all)]
215222
pub fn remove_missing_files(&mut self) {
216223
trace!("remove non existing files from cache");
217224
self.files.retain(|file, _| {
@@ -292,6 +299,7 @@ impl<S: CompilerSettings> CompilerCache<S> {
292299
///
293300
/// **NOTE**: unless the cache's `files` keys were modified `contract_file` is expected to be
294301
/// absolute.
302+
#[instrument(skip_all)]
295303
pub fn read_artifact<Artifact: DeserializeOwned>(
296304
&self,
297305
contract_file: &Path,
@@ -318,6 +326,7 @@ impl<S: CompilerSettings> CompilerCache<S> {
318326
/// let artifacts = cache.read_artifacts::<CompactContractBytecode>()?;
319327
/// # Ok::<_, Box<dyn std::error::Error>>(())
320328
/// ```
329+
#[instrument(skip_all)]
321330
pub fn read_artifacts<Artifact: DeserializeOwned + Send + Sync>(
322331
&self,
323332
) -> Result<Artifacts<Artifact>> {
@@ -335,6 +344,7 @@ impl<S: CompilerSettings> CompilerCache<S> {
335344
/// objects, so we are basically just partially deserializing build infos here.
336345
///
337346
/// [BuildContext]: crate::buildinfo::BuildContext
347+
#[instrument(skip_all)]
338348
pub fn read_builds<L: Language>(&self, build_info_dir: &Path) -> Result<Builds<L>> {
339349
use rayon::prelude::*;
340350

@@ -491,6 +501,7 @@ impl CacheEntry {
491501
/// Reads all artifact files associated with the `CacheEntry`
492502
///
493503
/// **Note:** all artifact file paths should be absolute.
504+
#[instrument(skip_all)]
494505
fn read_artifact_files<Artifact: DeserializeOwned>(
495506
&self,
496507
) -> Result<BTreeMap<String, Vec<ArtifactFile<Artifact>>>> {
@@ -514,6 +525,7 @@ impl CacheEntry {
514525
Ok(artifacts)
515526
}
516527

528+
#[instrument(skip_all)]
517529
pub(crate) fn merge_artifacts<'a, A, I, T: 'a>(&mut self, artifacts: I)
518530
where
519531
I: IntoIterator<Item = (&'a String, A)>,
@@ -1017,6 +1029,7 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
10171029
ArtifactsCache<'a, T, C>
10181030
{
10191031
/// Create a new cache instance with the given files
1032+
#[instrument(name = "ArtifactsCache::new", skip(project, edges))]
10201033
pub fn new(
10211034
project: &'a Project<C, T>,
10221035
edges: GraphEdges<C::ParsedSource>,
@@ -1042,6 +1055,8 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
10421055
}
10431056
}
10441057

1058+
trace!(invalidate_cache, "cache invalidated");
1059+
10451060
// new empty cache
10461061
CompilerCache::new(Default::default(), paths, preprocessed)
10471062
}
@@ -1135,6 +1150,7 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
11351150
}
11361151

11371152
/// Adds the file's hashes to the set if not set yet
1153+
#[instrument(skip_all)]
11381154
pub fn remove_dirty_sources(&mut self) {
11391155
match self {
11401156
ArtifactsCache::Ephemeral(..) => {}
@@ -1161,6 +1177,7 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
11611177
}
11621178

11631179
/// Filters out those sources that don't need to be compiled
1180+
#[instrument(name = "ArtifactsCache::filter", skip_all)]
11641181
pub fn filter(&mut self, sources: &mut Sources, version: &Version, profile: &str) {
11651182
match self {
11661183
ArtifactsCache::Ephemeral(..) => {}
@@ -1173,6 +1190,7 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
11731190
/// compiled and written to disk `written_artifacts`.
11741191
///
11751192
/// Returns all the _cached_ artifacts.
1193+
#[instrument(name = "ArtifactsCache::consume", skip_all)]
11761194
pub fn consume<A>(
11771195
self,
11781196
written_artifacts: &Artifacts<A>,

crates/compilers/src/compile/output/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ impl<T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
8787
ProjectCompileOutput<C, T>
8888
{
8989
/// Converts all `\\` separators in _all_ paths to `/`
90+
#[instrument(skip_all)]
9091
pub fn slash_paths(&mut self) {
9192
self.compiler_output.slash_paths();
9293
self.compiled_artifacts.slash_paths();

crates/compilers/src/compile/project.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
171171
///
172172
/// Multiple (`Solc` -> `Sources`) pairs can be compiled in parallel if the `Project` allows
173173
/// multiple `jobs`, see [`crate::Project::set_solc_jobs()`].
174+
#[instrument(name = "ProjectCompiler::new", skip_all)]
174175
pub fn with_sources(project: &'a Project<C, T>, mut sources: Sources) -> Result<Self> {
175176
if let Some(filter) = &project.sparse_output {
176177
sources.retain(|f, _| filter.is_match(f))
@@ -209,6 +210,7 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
209210
/// let output = project.compile()?;
210211
/// # Ok::<(), Box<dyn std::error::Error>>(())
211212
/// ```
213+
#[instrument(name = "compile_project", skip_all)]
212214
pub fn compile(self) -> Result<ProjectCompileOutput<C, T>> {
213215
let slash_paths = self.project.slash_paths;
214216

@@ -226,6 +228,7 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
226228
/// Does basic preprocessing
227229
/// - sets proper source unit names
228230
/// - check cache
231+
#[instrument(skip_all)]
229232
fn preprocess(self) -> Result<PreprocessedState<'a, T, C>> {
230233
trace!("preprocessing");
231234
let Self { edges, project, mut sources, primary_profiles, preprocessor } = self;
@@ -265,6 +268,7 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
265268
PreprocessedState<'a, T, C>
266269
{
267270
/// advance to the next state by compiling all sources
271+
#[instrument(skip_all)]
268272
fn compile(self) -> Result<CompiledState<'a, T, C>> {
269273
trace!("compiling");
270274
let PreprocessedState { sources, mut cache, primary_profiles, preprocessor } = self;
@@ -297,7 +301,7 @@ impl<'a, T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
297301
///
298302
/// Writes all output contracts to disk if enabled in the `Project` and if the build was
299303
/// successful
300-
#[instrument(skip_all, name = "write-artifacts")]
304+
#[instrument(skip_all)]
301305
fn write_artifacts(self) -> Result<ArtifactsState<'a, T, C>> {
302306
let CompiledState { output, cache, primary_profiles } = self;
303307

@@ -365,6 +369,7 @@ impl<T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
365369
/// Writes the cache file
366370
///
367371
/// this concludes the [`Project::compile()`] statemachine
372+
#[instrument(skip_all)]
368373
fn write_cache(self) -> Result<ProjectCompileOutput<C, T>> {
369374
let ArtifactsState { output, cache, compiled_artifacts } = self;
370375
let project = cache.project();
@@ -436,6 +441,7 @@ impl<L: Language, S: CompilerSettings> CompilerSources<'_, L, S> {
436441
}
437442

438443
/// Filters out all sources that don't need to be compiled, see [`ArtifactsCache::filter`]
444+
#[instrument(name = "CompilerSources::filter", skip_all)]
439445
fn filter<
440446
T: ArtifactOutput<CompilerContract = C::CompilerContract>,
441447
C: Compiler<Language = L>,

crates/compilers/src/compilers/mod.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use semver::{Version, VersionReq};
1313
use serde::{de::DeserializeOwned, Deserialize, Serialize};
1414
use std::{
1515
borrow::Cow,
16-
collections::{BTreeMap, BTreeSet, HashMap, HashSet},
16+
collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet},
1717
fmt::{Debug, Display},
1818
hash::Hash,
1919
path::{Path, PathBuf},
@@ -356,20 +356,24 @@ pub(crate) fn cache_version(
356356
f: impl FnOnce(&Path) -> Result<Version>,
357357
) -> Result<Version> {
358358
#[allow(clippy::complexity)]
359-
static VERSION_CACHE: OnceLock<Mutex<HashMap<PathBuf, HashMap<Vec<String>, Version>>>> =
359+
static VERSION_CACHE: OnceLock<Mutex<HashMap<(PathBuf, Vec<String>), Version>>> =
360360
OnceLock::new();
361-
let mut lock = VERSION_CACHE
362-
.get_or_init(|| Mutex::new(HashMap::new()))
361+
362+
let mut cache = VERSION_CACHE
363+
.get_or_init(Default::default)
363364
.lock()
364365
.unwrap_or_else(std::sync::PoisonError::into_inner);
365366

366-
if let Some(version) = lock.get(&path).and_then(|versions| versions.get(args)) {
367-
return Ok(version.clone());
367+
match cache.entry((path, args.to_vec())) {
368+
Entry::Occupied(entry) => Ok(entry.get().clone()),
369+
Entry::Vacant(entry) => {
370+
let path = &entry.key().0;
371+
let _guard =
372+
debug_span!("get_version", path = %path.file_name().map(|n| n.to_string_lossy()).unwrap_or_else(|| path.to_string_lossy()))
373+
.entered();
374+
let version = f(path)?;
375+
entry.insert(version.clone());
376+
Ok(version)
377+
}
368378
}
369-
370-
let version = f(&path)?;
371-
372-
lock.entry(path).or_default().insert(args.to_vec(), version.clone());
373-
374-
Ok(version)
375379
}

crates/compilers/src/compilers/solc/compiler.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ impl Solc {
8989
/// A new instance which points to `solc`. Invokes `solc --version` to determine the version.
9090
///
9191
/// Returns error if `solc` is not found in the system or if the version cannot be retrieved.
92+
#[instrument(name = "Solc::new", skip_all)]
9293
pub fn new(path: impl Into<PathBuf>) -> Result<Self> {
9394
let path = path.into();
9495
let version = Self::version(path.clone())?;
@@ -200,6 +201,7 @@ impl Solc {
200201
///
201202
/// Ok::<_, Box<dyn std::error::Error>>(())
202203
/// ```
204+
#[instrument(skip_all)]
203205
pub fn find_svm_installed_version(version: &Version) -> Result<Option<Self>> {
204206
let version = format!("{}.{}.{}", version.major, version.minor, version.patch);
205207
let solc = Self::svm_home()
@@ -266,6 +268,7 @@ impl Solc {
266268
/// # }
267269
/// ```
268270
#[cfg(feature = "svm-solc")]
271+
#[instrument(name = "Solc::install", skip_all)]
269272
pub async fn install(version: &Version) -> std::result::Result<Self, svm::SvmError> {
270273
trace!("installing solc version \"{}\"", version);
271274
crate::report::solc_installation_start(version);
@@ -283,6 +286,7 @@ impl Solc {
283286

284287
/// Blocking version of `Self::install`
285288
#[cfg(feature = "svm-solc")]
289+
#[instrument(name = "Solc::blocking_install", skip_all)]
286290
pub fn blocking_install(version: &Version) -> std::result::Result<Self, svm::SvmError> {
287291
use foundry_compilers_core::utils::RuntimeOrHandle;
288292

@@ -311,6 +315,7 @@ impl Solc {
311315
/// Verify that the checksum for this version of solc is correct. We check against the SHA256
312316
/// checksum from the build information published by [binaries.soliditylang.org](https://binaries.soliditylang.org/)
313317
#[cfg(feature = "svm-solc")]
318+
#[instrument(name = "Solc::verify_checksum", skip_all)]
314319
pub fn verify_checksum(&self) -> Result<()> {
315320
let version = self.version_short();
316321
let mut version_path = svm::version_path(version.to_string().as_str());
@@ -407,6 +412,7 @@ impl Solc {
407412
}
408413

409414
/// Compiles with `--standard-json` and deserializes the output as the given `D`.
415+
#[instrument(name = "Solc::compile", skip_all)]
410416
pub fn compile_as<T: Serialize, D: DeserializeOwned>(&self, input: &T) -> Result<D> {
411417
let output = self.compile_output(input)?;
412418

@@ -417,7 +423,7 @@ impl Solc {
417423
}
418424

419425
/// Compiles with `--standard-json` and returns the raw `stdout` output.
420-
#[instrument(name = "compile", level = "debug", skip_all)]
426+
#[instrument(name = "Solc::compile_raw", skip_all)]
421427
pub fn compile_output<T: Serialize>(&self, input: &T) -> Result<Vec<u8>> {
422428
let mut cmd = self.configure_cmd();
423429

@@ -447,13 +453,11 @@ impl Solc {
447453
}
448454

449455
/// Invokes `solc --version` and parses the output as a SemVer [`Version`].
450-
#[instrument(level = "debug", skip_all)]
451456
pub fn version(solc: impl Into<PathBuf>) -> Result<Version> {
452457
Self::version_with_args(solc, &[])
453458
}
454459

455460
/// Invokes `solc --version` and parses the output as a SemVer [`Version`].
456-
#[instrument(level = "debug", skip_all)]
457461
pub fn version_with_args(solc: impl Into<PathBuf>, args: &[String]) -> Result<Version> {
458462
crate::cache_version(solc.into(), args, |solc| {
459463
let mut cmd = Command::new(solc);

crates/compilers/src/compilers/vyper/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ impl Vyper {
127127
}
128128

129129
/// Compiles with `--standard-json` and deserializes the output as the given `D`.
130+
#[instrument(name = "Vyper::compile", skip_all)]
130131
pub fn compile_as<T: Serialize, D: DeserializeOwned>(&self, input: &T) -> Result<D> {
131132
let output = self.compile_output(input)?;
132133

@@ -139,7 +140,7 @@ impl Vyper {
139140
}
140141

141142
/// Compiles with `--standard-json` and returns the raw `stdout` output.
142-
#[instrument(name = "compile", level = "debug", skip_all)]
143+
#[instrument(name = "Vyper::compile_raw", skip_all)]
143144
pub fn compile_output<T: Serialize>(&self, input: &T) -> Result<Vec<u8>> {
144145
let mut cmd = Command::new(&self.path);
145146
cmd.arg("--standard-json")
@@ -171,7 +172,6 @@ impl Vyper {
171172
}
172173

173174
/// Invokes `vyper --version` and parses the output as a SemVer [`Version`].
174-
#[instrument(level = "debug", skip_all)]
175175
pub fn version(vyper: impl Into<PathBuf>) -> Result<Version> {
176176
crate::cache_version(vyper.into(), &[], |vyper| {
177177
let mut cmd = Command::new(vyper);

crates/compilers/src/compilers/vyper/parser.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub struct VyperParsedSource {
3636
impl ParsedSource for VyperParsedSource {
3737
type Language = VyperLanguage;
3838

39+
#[instrument(name = "VyperParsedSource::parse", skip_all)]
3940
fn parse(content: &str, file: &Path) -> Result<Self> {
4041
let version_req = capture_outer_and_inner(content, &RE_VYPER_VERSION, &["version"])
4142
.first()

crates/compilers/src/resolver/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ impl<L: Language, D: ParsedSource<Language = L>> Graph<D> {
332332
}
333333

334334
/// Resolves a number of sources within the given config
335+
#[instrument(name = "Graph::resolve_sources", skip_all)]
335336
pub fn resolve_sources(
336337
paths: &ProjectPathsConfig<D::Language>,
337338
sources: Sources,

0 commit comments

Comments
 (0)