| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use { |
| diagnostics_reader::{ArchiveReader, DiagnosticsHierarchy, Inspect}, |
| std::fmt::{Display, Formatter, Result}, |
| }; |
| |
| struct BlobFrequency { |
| pub hash: String, |
| pub frequencies: Vec<(u64, u64)>, |
| } |
| |
| impl Display for BlobFrequency { |
| fn fmt(&self, f: &mut Formatter<'_>) -> Result { |
| write!(f, "{}", self.hash)?; |
| for (index, frequency) in &self.frequencies { |
| write!(f, ",{}:{}", index, frequency)?; |
| } |
| Ok(()) |
| } |
| } |
| |
| async fn get_blobfs_tree(reader: ArchiveReader) -> Option<DiagnosticsHierarchy<String>> { |
| let mut response = reader.snapshot::<Inspect>().await.unwrap(); |
| |
| for data in response.drain(..) { |
| if data.metadata.filename == "blobfs/fuchsia.inspect.Tree" { |
| return data.payload; |
| } |
| } |
| |
| panic!("Could not find blobfs inspect tree!"); |
| } |
| |
| pub struct BlobFrequencies { |
| blobs: Vec<BlobFrequency>, |
| } |
| |
| impl BlobFrequencies { |
| pub async fn collect() -> BlobFrequencies { |
| let mut blobs = vec![]; |
| let reader = |
| ArchiveReader::new().add_selector("bootstrap/fshost:root/page_in_frequency_stats"); |
| let result = get_blobfs_tree(reader).await; |
| |
| if let Some(hierarchy) = result { |
| let blob_nodes = hierarchy.get_child("page_in_frequency_stats").unwrap(); |
| |
| for blob_node in &blob_nodes.children { |
| let mut frequencies = vec![]; |
| for property in &blob_node.properties { |
| let index = property.name().parse().unwrap(); |
| let frequency = property.uint().unwrap(); |
| frequencies.push((index, *frequency)); |
| } |
| |
| blobs.push(BlobFrequency { hash: blob_node.name.clone(), frequencies }); |
| } |
| } |
| |
| BlobFrequencies { blobs } |
| } |
| } |
| |
| impl Display for BlobFrequencies { |
| fn fmt(&self, f: &mut Formatter<'_>) -> Result { |
| if self.blobs.is_empty() { |
| writeln!( |
| f, |
| "There is no data in the Inspect tree. Check that page-in metrics \ |
| recording is enabled for blobfs. Enable the page-in metrics flag in \ |
| src/storage/blobfs/BUILD.gn" |
| )?; |
| } else { |
| for blob in &self.blobs { |
| writeln!(f, "{}", blob)?; |
| } |
| } |
| Ok(()) |
| } |
| } |