Skip to content

Commit 34b7eaf

Browse files
Liubov Dmitrievafacebook-github-bot
authored andcommitted
define the named counters
Summary: define the named counters only the types, implementation comes in next diff Reviewed By: MichaelCuevas Differential Revision: D74736096 fbshipit-source-id: 687e6404de3c03f3c730bb1c7e6b94b8a9d31ca6
1 parent 17c52f6 commit 34b7eaf

File tree

1 file changed

+367
-0
lines changed

1 file changed

+367
-0
lines changed

eden/fs/cli_rs/edenfs-client/src/counters.rs

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
use std::collections::BTreeMap;
9+
use std::ops::Sub;
910

1011
use anyhow::Context;
1112
use edenfs_error::EdenFsError;
@@ -14,6 +15,372 @@ use edenfs_error::Result;
1415
use crate::client::Client;
1516
use crate::client::EdenFsClient;
1617

18+
#[derive(Debug, Clone, PartialEq, Eq)]
19+
/// EdenFS filesystem counters
20+
/// The exact VFS implementation depends on the platform
21+
pub struct FilesystemTelemetryCounters {
22+
// The number of successful open filesystem operations.
23+
pub syscall_opens: i64,
24+
// The number of successful read operations.
25+
pub syscall_reads: i64,
26+
// The number of successful readdir operations.
27+
pub syscall_readdirs: i64,
28+
// The number of successful write operations.
29+
pub syscall_writes: i64,
30+
// The number of successful stat operations.
31+
pub syscall_stats: i64,
32+
}
33+
34+
impl Sub for FilesystemTelemetryCounters {
35+
type Output = Self;
36+
37+
fn sub(self, rhs: Self) -> Self::Output {
38+
Self {
39+
syscall_opens: self.syscall_opens - rhs.syscall_opens,
40+
syscall_reads: self.syscall_reads - rhs.syscall_reads,
41+
syscall_readdirs: self.syscall_readdirs - rhs.syscall_readdirs,
42+
syscall_writes: self.syscall_writes - rhs.syscall_writes,
43+
syscall_stats: self.syscall_stats - rhs.syscall_stats,
44+
}
45+
}
46+
}
47+
48+
#[derive(Debug, Clone, PartialEq, Eq)]
49+
pub struct ThriftTelemetryCounters {}
50+
51+
impl Sub for ThriftTelemetryCounters {
52+
type Output = Self;
53+
54+
fn sub(self, _rhs: Self) -> Self::Output {
55+
Self {}
56+
}
57+
}
58+
59+
/// Remote backends
60+
/// EdenAPI backend counters
61+
/// There are no misses as Mononoke is the source of truth for the data
62+
#[derive(Debug, Clone, PartialEq, Eq)]
63+
pub struct EdenApiBackendTelemetryCounters {
64+
/// The number of file content fetches from the EdenAPI backend
65+
pub edenapi_fetches_blobs: i64,
66+
/// The number of tree fetches from the EdenAPI backend
67+
pub edenapi_fetches_trees: i64,
68+
/// Total number of http requests performed to the EdenAPI backend combined for files and trees
69+
pub edenapi_requests: i64,
70+
}
71+
72+
impl Sub for EdenApiBackendTelemetryCounters {
73+
type Output = Self;
74+
75+
fn sub(self, rhs: Self) -> Self::Output {
76+
Self {
77+
edenapi_fetches_blobs: self.edenapi_fetches_blobs - rhs.edenapi_fetches_blobs,
78+
edenapi_fetches_trees: self.edenapi_fetches_trees - rhs.edenapi_fetches_trees,
79+
edenapi_requests: self.edenapi_requests - rhs.edenapi_requests,
80+
}
81+
}
82+
}
83+
84+
/// LFS backend counters
85+
/// There are no misses as Mononoke is the source of truth for the data
86+
#[derive(Debug, Clone, PartialEq, Eq)]
87+
pub struct LfsBackendTelemetryCounters {
88+
/// The number of file content fetches from the LFS backend
89+
pub lfs_fetches_blobs: i64,
90+
/// The number of tree fetches from the LFS backend
91+
pub lfs_fetches_trees: i64,
92+
/// Total number of http requests performed to the LFS backend combined for files and trees
93+
pub lfs_requests: i64,
94+
}
95+
96+
impl Sub for LfsBackendTelemetryCounters {
97+
type Output = Self;
98+
99+
fn sub(self, rhs: Self) -> Self::Output {
100+
Self {
101+
lfs_fetches_blobs: self.lfs_fetches_blobs - rhs.lfs_fetches_blobs,
102+
lfs_fetches_trees: self.lfs_fetches_trees - rhs.lfs_fetches_trees,
103+
lfs_requests: self.lfs_requests - rhs.lfs_requests,
104+
}
105+
}
106+
}
107+
108+
/// CASd backend counters
109+
/// There could be misses as the storage layer is TTL based
110+
#[derive(Debug, Clone, PartialEq, Eq)]
111+
pub struct CASCBackendTelemetryCounters {
112+
/// The number of file content fetches from the CAS backend
113+
pub cas_fetches_blobs: i64,
114+
/// The number of file content fetches from the CAS backend that were not found
115+
pub cas_missing_blobs: i64,
116+
/// The number of tree fetches from the CAS backend
117+
pub cas_fetches_trees: i64,
118+
/// The number of tree fetches from the CAS backend that were not found
119+
pub cas_missing_trees: i64,
120+
}
121+
122+
impl Sub for CASCBackendTelemetryCounters {
123+
type Output = Self;
124+
125+
fn sub(self, rhs: Self) -> Self::Output {
126+
Self {
127+
cas_fetches_blobs: self.cas_fetches_blobs - rhs.cas_fetches_blobs,
128+
cas_missing_blobs: self.cas_missing_blobs - rhs.cas_missing_blobs,
129+
cas_fetches_trees: self.cas_fetches_trees - rhs.cas_fetches_trees,
130+
cas_missing_trees: self.cas_missing_trees - rhs.cas_missing_trees,
131+
}
132+
}
133+
}
134+
135+
/// Remote backend counters to track the number of fetches from the remote backends
136+
/// typically with much higher latency than the local caches
137+
#[derive(Debug, Clone, PartialEq, Eq)]
138+
pub struct RemoteBackendTelemetryCounters {
139+
pub edenapi_backend: Option<EdenApiBackendTelemetryCounters>,
140+
pub casc_backend: Option<CASCBackendTelemetryCounters>,
141+
pub lfs_backend: Option<LfsBackendTelemetryCounters>,
142+
}
143+
144+
impl Sub for RemoteBackendTelemetryCounters {
145+
type Output = Self;
146+
147+
fn sub(self, rhs: Self) -> Self::Output {
148+
Self {
149+
edenapi_backend: match (self.edenapi_backend, rhs.edenapi_backend) {
150+
(Some(lhs), Some(rhs)) => Some(lhs - rhs),
151+
(lhs, None) => lhs,
152+
(None, _) => None,
153+
},
154+
casc_backend: match (self.casc_backend, rhs.casc_backend) {
155+
(Some(lhs), Some(rhs)) => Some(lhs - rhs),
156+
(lhs, None) => lhs,
157+
(None, _) => None,
158+
},
159+
lfs_backend: match (self.lfs_backend, rhs.lfs_backend) {
160+
(Some(lhs), Some(rhs)) => Some(lhs - rhs),
161+
(lhs, None) => lhs,
162+
(None, _) => None,
163+
},
164+
}
165+
}
166+
}
167+
168+
/// Local caches (sapling "local" cache is skipped as it serves only a few fetches only for commits made locally)
169+
#[derive(Debug, Clone, PartialEq, Eq)]
170+
pub struct SaplingCacheTelemetryCounters {
171+
// Blobs
172+
pub sapling_cache_blobs_hits: i64,
173+
pub sapling_cache_blobs_misses: i64,
174+
// Trees
175+
pub sapling_cache_trees_hits: i64,
176+
pub sapling_cache_trees_misses: i64,
177+
}
178+
179+
impl Sub for SaplingCacheTelemetryCounters {
180+
type Output = Self;
181+
182+
fn sub(self, rhs: Self) -> Self::Output {
183+
Self {
184+
sapling_cache_blobs_hits: self.sapling_cache_blobs_hits - rhs.sapling_cache_blobs_hits,
185+
sapling_cache_blobs_misses: self.sapling_cache_blobs_misses
186+
- rhs.sapling_cache_blobs_misses,
187+
sapling_cache_trees_hits: self.sapling_cache_trees_hits - rhs.sapling_cache_trees_hits,
188+
sapling_cache_trees_misses: self.sapling_cache_trees_misses
189+
- rhs.sapling_cache_trees_misses,
190+
}
191+
}
192+
}
193+
194+
#[derive(Debug, Clone, PartialEq, Eq)]
195+
pub struct SaplingLFSCacheTelemetryCounters {
196+
// Blobs
197+
pub sapling_lfs_cache_blobs_hits: i64,
198+
pub sapling_lfs_cache_blobs_misses: i64,
199+
// Trees
200+
pub sapling_lfs_cache_trees_hits: i64,
201+
pub sapling_lfs_cache_trees_misses: i64,
202+
}
203+
impl Sub for SaplingLFSCacheTelemetryCounters {
204+
type Output = Self;
205+
206+
fn sub(self, rhs: Self) -> Self::Output {
207+
Self {
208+
sapling_lfs_cache_blobs_hits: self.sapling_lfs_cache_blobs_hits
209+
- rhs.sapling_lfs_cache_blobs_hits,
210+
sapling_lfs_cache_blobs_misses: self.sapling_lfs_cache_blobs_misses
211+
- rhs.sapling_lfs_cache_blobs_misses,
212+
sapling_lfs_cache_trees_hits: self.sapling_lfs_cache_trees_hits
213+
- rhs.sapling_lfs_cache_trees_hits,
214+
sapling_lfs_cache_trees_misses: self.sapling_lfs_cache_trees_misses
215+
- rhs.sapling_lfs_cache_trees_misses,
216+
}
217+
}
218+
}
219+
220+
#[derive(Debug, Clone, PartialEq, Eq)]
221+
pub struct CASCLocalCacheTelemetryCounters {
222+
// Blobs
223+
/// Total number of blobs fetched from the CAS local cache layers (on-disk cache and lmdb cache layer)
224+
pub cas_local_cache_blobs_hits: i64,
225+
/// Blobs fetched from lmdb cache layer
226+
pub cas_local_cache_blobs_lmdb_hits: i64,
227+
pub cas_local_cache_blobs_misses: i64,
228+
// Trees
229+
/// Total number of trees fetched from the CAS local cache layers (on-disk cache and lmdb cache layer)
230+
pub cas_local_cache_trees_hits: i64,
231+
/// Trees fetched from lmdb cache layer
232+
pub cas_local_cache_trees_lmdb_hits: i64,
233+
pub cas_local_cache_trees_misses: i64,
234+
}
235+
236+
impl Sub for CASCLocalCacheTelemetryCounters {
237+
type Output = Self;
238+
239+
fn sub(self, rhs: Self) -> Self::Output {
240+
Self {
241+
cas_local_cache_blobs_hits: self.cas_local_cache_blobs_hits
242+
- rhs.cas_local_cache_blobs_hits,
243+
cas_local_cache_blobs_lmdb_hits: self.cas_local_cache_blobs_lmdb_hits
244+
- rhs.cas_local_cache_blobs_lmdb_hits,
245+
cas_local_cache_blobs_misses: self.cas_local_cache_blobs_misses
246+
- rhs.cas_local_cache_blobs_misses,
247+
cas_local_cache_trees_hits: self.cas_local_cache_trees_hits
248+
- rhs.cas_local_cache_trees_hits,
249+
cas_local_cache_trees_lmdb_hits: self.cas_local_cache_trees_lmdb_hits
250+
- rhs.cas_local_cache_trees_lmdb_hits,
251+
cas_local_cache_trees_misses: self.cas_local_cache_trees_misses
252+
- rhs.cas_local_cache_trees_misses,
253+
}
254+
}
255+
}
256+
257+
#[derive(Debug, Clone, PartialEq, Eq)]
258+
pub struct LocalStoreCacheTelemetryCounters {
259+
// Blobs
260+
pub local_store_cache_blobs_hits: i64,
261+
pub local_store_cache_blobs_misses: i64,
262+
// Trees
263+
pub local_store_cache_trees_hits: i64,
264+
pub local_store_cache_trees_misses: i64,
265+
}
266+
267+
impl Sub for LocalStoreCacheTelemetryCounters {
268+
type Output = Self;
269+
270+
fn sub(self, rhs: Self) -> Self::Output {
271+
Self {
272+
local_store_cache_blobs_hits: self.local_store_cache_blobs_hits
273+
- rhs.local_store_cache_blobs_hits,
274+
local_store_cache_blobs_misses: self.local_store_cache_blobs_misses
275+
- rhs.local_store_cache_blobs_misses,
276+
local_store_cache_trees_hits: self.local_store_cache_trees_hits
277+
- rhs.local_store_cache_trees_hits,
278+
local_store_cache_trees_misses: self.local_store_cache_trees_misses
279+
- rhs.local_store_cache_trees_misses,
280+
}
281+
}
282+
}
283+
284+
#[derive(Debug, Clone, PartialEq, Eq)]
285+
pub struct InMemoryCacheTelemetryCounters {
286+
// Blobs
287+
pub in_memory_cache_blobs_hits: i64,
288+
pub in_memory_cache_blobs_misses: i64,
289+
// Trees
290+
pub in_memory_cache_trees_hits: i64,
291+
pub in_memory_cache_trees_misses: i64,
292+
}
293+
294+
impl Sub for InMemoryCacheTelemetryCounters {
295+
type Output = Self;
296+
297+
fn sub(self, rhs: Self) -> Self::Output {
298+
Self {
299+
in_memory_cache_blobs_hits: self.in_memory_cache_blobs_hits
300+
- rhs.in_memory_cache_blobs_hits,
301+
in_memory_cache_blobs_misses: self.in_memory_cache_blobs_misses
302+
- rhs.in_memory_cache_blobs_misses,
303+
in_memory_cache_trees_hits: self.in_memory_cache_trees_hits
304+
- rhs.in_memory_cache_trees_hits,
305+
in_memory_cache_trees_misses: self.in_memory_cache_trees_misses
306+
- rhs.in_memory_cache_trees_misses,
307+
}
308+
}
309+
}
310+
311+
#[derive(Debug, Clone, PartialEq, Eq)]
312+
pub struct LocalCacheTelemetryCounters {
313+
/// Shared Sapling Cache counters (known also as hgcache)
314+
pub sapling_cache: Option<SaplingCacheTelemetryCounters>,
315+
/// Shared Sapling LFS Cache counters (known also as hgcache)
316+
pub sapling_lfs_cache: Option<SaplingLFSCacheTelemetryCounters>,
317+
/// CASd local cache counters
318+
pub casc_local_cache: Option<CASCLocalCacheTelemetryCounters>,
319+
/// Local store cache counters (eden rocksdb cache)
320+
pub local_store_cache: Option<LocalStoreCacheTelemetryCounters>,
321+
/// In memory (eden) cache counters
322+
pub in_memory_local_cache: Option<InMemoryCacheTelemetryCounters>,
323+
}
324+
325+
impl Sub for LocalCacheTelemetryCounters {
326+
type Output = Self;
327+
328+
fn sub(self, rhs: Self) -> Self::Output {
329+
Self {
330+
sapling_cache: match (self.sapling_cache, rhs.sapling_cache) {
331+
(Some(lhs), Some(rhs)) => Some(lhs - rhs),
332+
(lhs, None) => lhs,
333+
(None, _) => None,
334+
},
335+
sapling_lfs_cache: match (self.sapling_lfs_cache, rhs.sapling_lfs_cache) {
336+
(Some(lhs), Some(rhs)) => Some(lhs - rhs),
337+
(lhs, None) => lhs,
338+
(None, _) => None,
339+
},
340+
casc_local_cache: match (self.casc_local_cache, rhs.casc_local_cache) {
341+
(Some(lhs), Some(rhs)) => Some(lhs - rhs),
342+
(lhs, None) => lhs,
343+
(None, _) => None,
344+
},
345+
local_store_cache: match (self.local_store_cache, rhs.local_store_cache) {
346+
(Some(lhs), Some(rhs)) => Some(lhs - rhs),
347+
(lhs, None) => lhs,
348+
(None, _) => None,
349+
},
350+
in_memory_local_cache: match (self.in_memory_local_cache, rhs.in_memory_local_cache) {
351+
(Some(lhs), Some(rhs)) => Some(lhs - rhs),
352+
(lhs, None) => lhs,
353+
(None, _) => None,
354+
},
355+
}
356+
}
357+
}
358+
359+
/// EdenFS cummulative counters
360+
/// This is a subset of the counters that are available as part of the EdenFS telemetry
361+
/// Only covers cumulative counters that are incremented on operations during the lifetime of the EdenFS process
362+
/// It is possible to snapshot the counters and compare them to a previous snapshot
363+
#[derive(Debug, Clone, PartialEq, Eq)]
364+
pub struct TelemetryCounters {
365+
pub fs_stats: FilesystemTelemetryCounters,
366+
pub thrift_stats: ThriftTelemetryCounters,
367+
pub backend_stats: RemoteBackendTelemetryCounters,
368+
pub local_cache_stats: LocalCacheTelemetryCounters,
369+
}
370+
371+
impl Sub for TelemetryCounters {
372+
type Output = Self;
373+
374+
fn sub(self, rhs: Self) -> Self::Output {
375+
Self {
376+
fs_stats: self.fs_stats - rhs.fs_stats,
377+
thrift_stats: self.thrift_stats - rhs.thrift_stats,
378+
backend_stats: self.backend_stats - rhs.backend_stats,
379+
local_cache_stats: self.local_cache_stats - rhs.local_cache_stats,
380+
}
381+
}
382+
}
383+
17384
impl EdenFsClient {
18385
pub async fn get_regex_counters(&self, arg_regex: &str) -> Result<BTreeMap<String, i64>> {
19386
self.with_thrift(|thrift| thrift.getRegexCounters(arg_regex))

0 commit comments

Comments
 (0)