fxfs/
metrics.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::object_store::ObjectStore;
6use fuchsia_inspect::Node;
7use fuchsia_sync::Mutex;
8use futures::FutureExt;
9use once_cell::sync::Lazy;
10use rustc_hash::FxHashMap as HashMap;
11use std::sync::Weak;
12
13/// Root node to which the filesystem Inspect tree will be attached.
14fn root() -> Node {
15    #[cfg(target_os = "fuchsia")]
16    static FXFS_ROOT_NODE: Lazy<Mutex<fuchsia_inspect::Node>> =
17        Lazy::new(|| Mutex::new(fuchsia_inspect::component::inspector().root().clone_weak()));
18    #[cfg(not(target_os = "fuchsia"))]
19    static FXFS_ROOT_NODE: Lazy<Mutex<Node>> = Lazy::new(|| Mutex::new(Node::default()));
20
21    FXFS_ROOT_NODE.lock().clone_weak()
22}
23
24/// `fs.detail` node for holding fxfs-specific metrics.
25pub fn detail() -> Node {
26    static DETAIL_NODE: Lazy<Mutex<Node>> =
27        Lazy::new(|| Mutex::new(root().create_child("fs.detail")));
28
29    DETAIL_NODE.lock().clone_weak()
30}
31
32/// This is held to support unmounting and remounting of an object store. Nodes cannot be recreated,
33/// so hold onto them and simply replace what they point at instead.
34pub struct ObjectStoresTracker {
35    stores: Mutex<HashMap<String, Weak<ObjectStore>>>,
36}
37
38impl ObjectStoresTracker {
39    /// Add a store to be tracked in inspect.
40    pub fn register_store(&self, name: &str, store: Weak<ObjectStore>) {
41        self.stores.lock().insert(name.to_owned(), store);
42    }
43
44    /// Stop tracking a store in inspect.
45    pub fn unregister_store(&self, name: &str) {
46        self.stores.lock().remove(name);
47    }
48}
49
50/// Holder of lazy nodes for the object stores list.
51pub fn object_stores_tracker() -> &'static ObjectStoresTracker {
52    static OBJECT_STORES_TRACKER: Lazy<ObjectStoresTracker> = Lazy::new(|| {
53        let root = root();
54        let node = root.create_lazy_child("stores", || {
55            async {
56                let inspector = fuchsia_inspect::Inspector::default();
57                let root = inspector.root();
58                for (name, store) in object_stores_tracker().stores.lock().iter() {
59                    let store_arc = match store.upgrade() {
60                        Some(store) => store,
61                        None => continue,
62                    };
63                    root.record_child(name.clone(), move |n| store_arc.record_data(n));
64                }
65                Ok(inspector)
66            }
67            .boxed()
68        });
69        root.record(node);
70        ObjectStoresTracker { stores: Mutex::new(HashMap::default()) }
71    });
72
73    &OBJECT_STORES_TRACKER
74}