1use crate::error_from_metrics_error;
6use anyhow::Result;
7use attribution_processing::digest::{BucketDefinition, Digest};
8use cobalt_client::traits::{AsEventCode, AsEventCodes};
9use cobalt_registry::MemoryLeakMigratedMetricDimensionTimeSinceBoot as TimeSinceBoot;
10use memory_metrics_registry::cobalt_registry;
11use std::collections::HashMap;
12use {fidl_fuchsia_kernel as fkernel, fidl_fuchsia_metrics as fmetrics};
13
14const UPTIME_LEVEL_INDEX: &[(zx::BootDuration, TimeSinceBoot)] = &[
16 (zx::BootDuration::from_minutes(1), TimeSinceBoot::Up),
17 (zx::BootDuration::from_minutes(30), TimeSinceBoot::UpOneMinute),
18 (zx::BootDuration::from_hours(1), TimeSinceBoot::UpThirtyMinutes),
19 (zx::BootDuration::from_hours(6), TimeSinceBoot::UpOneHour),
20 (zx::BootDuration::from_hours(12), TimeSinceBoot::UpSixHours),
21 (zx::BootDuration::from_hours(24), TimeSinceBoot::UpTwelveHours),
22 (zx::BootDuration::from_hours(48), TimeSinceBoot::UpOneDay),
23 (zx::BootDuration::from_hours(72), TimeSinceBoot::UpTwoDays),
24 (zx::BootDuration::from_hours(144), TimeSinceBoot::UpThreeDays),
25];
26
27fn get_uptime_event_code(capture_time: zx::BootInstant) -> TimeSinceBoot {
29 let uptime = zx::Duration::from_nanos(capture_time.into_nanos());
30 UPTIME_LEVEL_INDEX
31 .into_iter()
32 .find(|&&(time, _)| uptime < time)
33 .map(|(_, code)| *code)
34 .unwrap_or(TimeSinceBoot::UpSixDays)
35}
36
37fn kmem_events(kmem_stats: &fkernel::MemoryStats) -> impl Iterator<Item = fmetrics::MetricEvent> {
38 use cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown as Breakdown;
39 let make_event = |code: Breakdown, value| {
40 Some(fmetrics::MetricEvent {
41 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
42 event_codes: vec![code.as_event_code()],
43 payload: fmetrics::MetricEventPayload::IntegerValue(value? as i64),
44 })
45 };
46 vec![
47 make_event(Breakdown::TotalBytes, kmem_stats.total_bytes),
48 make_event(
49 Breakdown::UsedBytes,
50 (|| Some((kmem_stats.total_bytes? as i64 - kmem_stats.free_bytes? as i64) as u64))(),
51 ),
52 make_event(Breakdown::FreeBytes, kmem_stats.free_bytes),
53 make_event(Breakdown::VmoBytes, kmem_stats.vmo_bytes),
54 make_event(Breakdown::KernelFreeHeapBytes, kmem_stats.free_heap_bytes),
55 make_event(Breakdown::MmuBytes, kmem_stats.mmu_overhead_bytes),
56 make_event(Breakdown::IpcBytes, kmem_stats.ipc_bytes),
57 make_event(Breakdown::KernelTotalHeapBytes, kmem_stats.total_heap_bytes),
58 make_event(Breakdown::WiredBytes, kmem_stats.wired_bytes),
59 make_event(Breakdown::OtherBytes, kmem_stats.other_bytes),
60 ]
61 .into_iter()
62 .flatten()
63}
64
65fn kmem_events_with_uptime(
66 kmem_stats: &fkernel::MemoryStats,
67 capture_time: zx::BootInstant,
68) -> impl Iterator<Item = fmetrics::MetricEvent> {
69 use cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown as Breakdown;
70 let make_event = |code: Breakdown, value| {
71 Some(fmetrics::MetricEvent {
72 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
73 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
74 general_breakdown: code,
75 time_since_boot: get_uptime_event_code(capture_time),
76 }
77 .as_event_codes(),
78 payload: fmetrics::MetricEventPayload::IntegerValue(value? as i64),
79 })
80 };
81 vec![
82 make_event(Breakdown::TotalBytes, kmem_stats.total_bytes),
83 make_event(
84 Breakdown::UsedBytes,
85 (|| Some((kmem_stats.total_bytes? as i64 - kmem_stats.free_bytes? as i64) as u64))(),
86 ),
87 make_event(Breakdown::FreeBytes, kmem_stats.free_bytes),
88 make_event(Breakdown::VmoBytes, kmem_stats.vmo_bytes),
89 make_event(Breakdown::KernelFreeHeapBytes, kmem_stats.free_heap_bytes),
90 make_event(Breakdown::MmuBytes, kmem_stats.mmu_overhead_bytes),
91 make_event(Breakdown::IpcBytes, kmem_stats.ipc_bytes),
92 make_event(Breakdown::KernelTotalHeapBytes, kmem_stats.total_heap_bytes),
93 make_event(Breakdown::WiredBytes, kmem_stats.wired_bytes),
94 make_event(Breakdown::OtherBytes, kmem_stats.other_bytes),
95 ]
96 .into_iter()
97 .flatten()
98}
99
100fn digest_events<'a>(
101 digest: &'a Digest,
102 bucket_name_to_code: &'a HashMap<String, u32>,
103) -> impl 'a + Iterator<Item = fmetrics::MetricEvent> {
104 digest.buckets.iter().filter_map(|bucket| {
105 Some(fmetrics::MetricEvent {
106 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
107 event_codes: vec![*bucket_name_to_code.get(&bucket.name)?],
108 payload: fmetrics::MetricEventPayload::IntegerValue(bucket.populated_size as i64),
109 })
110 })
111}
112
113pub fn prepare_bucket_codes(bucket_definitions: &[BucketDefinition]) -> HashMap<String, u32> {
114 let mut bucket_name_to_code = HashMap::from([
115 (
116 "TotalBytes".to_string(),
117 cobalt_registry::MemoryMigratedMetricDimensionBucket::TotalBytes.as_event_code(),
118 ),
119 (
120 "Free".to_string(),
121 cobalt_registry::MemoryMigratedMetricDimensionBucket::Free.as_event_code(),
122 ),
123 (
124 "Kernel".to_string(),
125 cobalt_registry::MemoryMigratedMetricDimensionBucket::Kernel.as_event_code(),
126 ),
127 (
128 "Orphaned".to_string(),
129 cobalt_registry::MemoryMigratedMetricDimensionBucket::Orphaned.as_event_code(),
130 ),
131 (
132 "Undigested".to_string(),
133 cobalt_registry::MemoryMigratedMetricDimensionBucket::Undigested.as_event_code(),
134 ),
135 (
136 "[Addl]PagerTotal".to_string(),
137 cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_PagerTotal.as_event_code(),
138 ),
139 (
140 "[Addl]PagerNewest".to_string(),
141 cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_PagerNewest
142 .as_event_code(),
143 ),
144 (
145 "[Addl]PagerOldest".to_string(),
146 cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_PagerOldest
147 .as_event_code(),
148 ),
149 (
150 "[Addl]DiscardableLocked".to_string(),
151 cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_DiscardableLocked
152 .as_event_code(),
153 ),
154 (
155 "[Addl]DiscardableUnlocked".to_string(),
156 cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_DiscardableUnlocked
157 .as_event_code(),
158 ),
159 (
160 "[Addl]ZramCompressedBytes".to_string(),
161 cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_ZramCompressedBytes
162 .as_event_code(),
163 ),
164 ]);
165 bucket_definitions.iter().for_each(|bucket_definition| {
166 bucket_name_to_code
167 .entry(bucket_definition.name.clone())
168 .or_insert(bucket_definition.event_code as u32);
169 });
170 bucket_name_to_code
171}
172
173pub async fn upload_metrics(
175 timestamp: zx::BootInstant,
176 kmem_stats: &fkernel::MemoryStats,
177 metric_event_logger: &fmetrics::MetricEventLoggerProxy,
178 digest: &Digest,
179 bucket_codes: &HashMap<String, u32>,
180) -> Result<()> {
181 let events = kmem_events(kmem_stats)
182 .chain(kmem_events_with_uptime(kmem_stats, timestamp))
183 .chain(digest_events(digest, &bucket_codes));
184 metric_event_logger
185 .log_metric_events(&events.collect::<Vec<fmetrics::MetricEvent>>())
186 .await?
187 .map_err(error_from_metrics_error)?;
188 Ok(())
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194 use anyhow::anyhow;
195 use attribution_processing::{
196 Attribution, AttributionData, GlobalPrincipalIdentifier, Principal, PrincipalDescription,
197 PrincipalType, ProcessedAttributionData, Resource, ResourceReference, ZXName,
198 attribute_vmos,
199 };
200 use fidl_fuchsia_memory_attribution_plugin as fplugin;
201 use futures::{TryFutureExt, TryStreamExt, try_join};
202 use regex::bytes::Regex;
203
204 fn get_data() -> ProcessedAttributionData {
205 let attribution_data = AttributionData {
206 principals_vec: vec![Principal {
207 identifier: GlobalPrincipalIdentifier::new_for_test(1),
208 description: Some(PrincipalDescription::Component("principal".to_owned())),
209 principal_type: PrincipalType::Runnable,
210 parent: None,
211 }],
212 resources_vec: vec![
213 Resource {
215 koid: 10,
216 name_index: 0,
217 resource_type: fplugin::ResourceType::Vmo(fplugin::Vmo {
218 parent: None,
219 private_committed_bytes: Some(1024),
220 private_populated_bytes: Some(2048),
221 scaled_committed_bytes: Some(1024),
222 scaled_populated_bytes: Some(2048),
223 total_committed_bytes: Some(1024),
224 total_populated_bytes: Some(2048),
225 ..Default::default()
226 }),
227 },
228 Resource {
230 koid: 20,
231 name_index: 1,
232 resource_type: fplugin::ResourceType::Vmo(fplugin::Vmo {
233 parent: None,
234 private_committed_bytes: Some(1024),
235 private_populated_bytes: Some(2048),
236 scaled_committed_bytes: Some(1024),
237 scaled_populated_bytes: Some(2048),
238 total_committed_bytes: Some(1024),
239 total_populated_bytes: Some(2048),
240 ..Default::default()
241 }),
242 },
243 Resource {
245 koid: 30,
246 name_index: 1,
247 resource_type: fplugin::ResourceType::Process(fplugin::Process {
248 vmos: Some(vec![20]),
249 ..Default::default()
250 }),
251 },
252 ],
253 resource_names: vec![
254 ZXName::from_string_lossy("resource"),
255 ZXName::from_string_lossy("bucket1_resource"),
256 ],
257 attributions: vec![Attribution {
258 source: GlobalPrincipalIdentifier::new_for_test(1),
259 subject: GlobalPrincipalIdentifier::new_for_test(1),
260 resources: vec![ResourceReference::KernelObject(10)],
261 }],
262 };
263 attribute_vmos(attribution_data)
264 }
265
266 fn get_kernel_stats() -> (fkernel::MemoryStats, fkernel::MemoryStatsCompression) {
267 (
268 fkernel::MemoryStats {
269 total_bytes: Some(1),
270 free_bytes: Some(2),
271 wired_bytes: Some(3),
272 total_heap_bytes: Some(4),
273 free_heap_bytes: Some(5),
274 vmo_bytes: Some(6),
275 mmu_overhead_bytes: Some(7),
276 ipc_bytes: Some(8),
277 other_bytes: Some(9),
278 free_loaned_bytes: Some(10),
279 cache_bytes: Some(11),
280 slab_bytes: Some(12),
281 zram_bytes: Some(13),
282 vmo_reclaim_total_bytes: Some(14),
283 vmo_reclaim_newest_bytes: Some(15),
284 vmo_reclaim_oldest_bytes: Some(16),
285 vmo_reclaim_disabled_bytes: Some(17),
286 vmo_discardable_locked_bytes: Some(18),
287 vmo_discardable_unlocked_bytes: Some(19),
288 ..Default::default()
289 },
290 fkernel::MemoryStatsCompression {
291 uncompressed_storage_bytes: Some(20),
292 compressed_storage_bytes: Some(21),
293 compressed_fragmentation_bytes: Some(22),
294 compression_time: Some(23),
295 decompression_time: Some(24),
296 total_page_compression_attempts: Some(25),
297 failed_page_compression_attempts: Some(26),
298 total_page_decompressions: Some(27),
299 compressed_page_evictions: Some(28),
300 eager_page_compressions: Some(29),
301 memory_pressure_page_compressions: Some(30),
302 critical_memory_page_compressions: Some(31),
303 pages_decompressed_unit_ns: Some(32),
304 pages_decompressed_within_log_time: Some([40, 41, 42, 43, 44, 45, 46, 47]),
305 ..Default::default()
306 },
307 )
308 }
309
310 #[fuchsia::test]
311 async fn test_upload_metrics() -> anyhow::Result<()> {
312 let bucket_definitions = [BucketDefinition {
313 name: "bucket1".to_string(),
314 vmo: Some(Regex::new("bucket1.*")?),
315 event_code: 1,
316 process: None,
317 principal: None,
318 }];
319
320 let (metric_event_logger, mut metric_event_request_stream) =
321 fidl::endpoints::create_proxy_and_stream::<fmetrics::MetricEventLoggerMarker>();
322
323 let (kmem_stats, kmem_stats_compression) = get_kernel_stats();
324 let digest = Digest::compute(
325 &get_data(),
326 &kmem_stats,
327 &kmem_stats_compression,
328 &bucket_definitions,
329 false,
330 )?;
331 let bucket_codes = prepare_bucket_codes(&bucket_definitions);
332 let upload = upload_metrics(
333 zx::BootInstant::get(),
334 &kmem_stats,
335 &metric_event_logger,
336 &digest,
337 &bucket_codes,
338 );
339 let uptime = get_uptime_event_code(zx::BootInstant::get());
340 try_join!(metric_event_request_stream.try_next().and_then(|event| async {
341 match event.unwrap() {
342 fmetrics::MetricEventLoggerRequest::LogMetricEvents { events, responder } => {
343 responder.send(Ok(()))?;
344 assert_eq!(
346 &events[0..10],
347 vec![
348 fmetrics::MetricEvent {
349 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
350 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::TotalBytes.as_event_code()],
351 payload: fmetrics::MetricEventPayload::IntegerValue(1)
352 },
353 fmetrics::MetricEvent {
354 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
355 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::UsedBytes.as_event_code()],
356 payload: fmetrics::MetricEventPayload::IntegerValue(-1)
357 },
358 fmetrics::MetricEvent {
359 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
360 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::FreeBytes.as_event_code()],
361 payload: fmetrics::MetricEventPayload::IntegerValue(2)
362 },
363 fmetrics::MetricEvent {
364 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
365 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::VmoBytes.as_event_code()],
366 payload: fmetrics::MetricEventPayload::IntegerValue(6)
367 },
368 fmetrics::MetricEvent {
369 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
370 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::KernelFreeHeapBytes.as_event_code()],
371 payload: fmetrics::MetricEventPayload::IntegerValue(5)
372 },
373 fmetrics::MetricEvent {
374 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
375 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::MmuBytes.as_event_code()],
376 payload: fmetrics::MetricEventPayload::IntegerValue(7)
377 },
378 fmetrics::MetricEvent {
379 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
380 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::IpcBytes.as_event_code()],
381 payload: fmetrics::MetricEventPayload::IntegerValue(8)
382 },
383 fmetrics::MetricEvent {
384 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
385 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::KernelTotalHeapBytes.as_event_code()],
386 payload: fmetrics::MetricEventPayload::IntegerValue(4)
387 },
388 fmetrics::MetricEvent {
389 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
390 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::WiredBytes.as_event_code()],
391 payload: fmetrics::MetricEventPayload::IntegerValue(3)
392 },
393 fmetrics::MetricEvent {
394 metric_id: cobalt_registry::MEMORY_GENERAL_BREAKDOWN_MIGRATED_METRIC_ID,
395 event_codes: vec![cobalt_registry::MemoryGeneralBreakdownMigratedMetricDimensionGeneralBreakdown::OtherBytes.as_event_code()],
396 payload: fmetrics::MetricEventPayload::IntegerValue(9)
397 },]);
398 assert_eq!(
400 &events[10..20],
401 vec![
402 fmetrics::MetricEvent {
403 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
404 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
405 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::TotalBytes, time_since_boot: uptime}.as_event_codes(),
406 payload: fmetrics::MetricEventPayload::IntegerValue(1)
407 },
408 fmetrics::MetricEvent {
409 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
410 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
411 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::UsedBytes, time_since_boot:uptime}.as_event_codes(),
412 payload: fmetrics::MetricEventPayload::IntegerValue(-1)
413 },
414 fmetrics::MetricEvent {
415 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
416 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
417 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::FreeBytes, time_since_boot:uptime}.as_event_codes(),
418 payload: fmetrics::MetricEventPayload::IntegerValue(2)
419 },
420 fmetrics::MetricEvent {
421 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
422 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
423 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::VmoBytes, time_since_boot:uptime}.as_event_codes(),
424 payload: fmetrics::MetricEventPayload::IntegerValue(6)
425 },
426 fmetrics::MetricEvent {
427 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
428 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
429 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::KernelFreeHeapBytes, time_since_boot:uptime}.as_event_codes(),
430 payload: fmetrics::MetricEventPayload::IntegerValue(5)
431 },
432 fmetrics::MetricEvent {
433 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
434 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
435 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::MmuBytes, time_since_boot:uptime}.as_event_codes(),
436 payload: fmetrics::MetricEventPayload::IntegerValue(7)
437 },
438 fmetrics::MetricEvent {
439 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
440 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
441 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::IpcBytes, time_since_boot:uptime}.as_event_codes(),
442 payload: fmetrics::MetricEventPayload::IntegerValue(8)
443 },
444 fmetrics::MetricEvent {
445 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
446 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
447 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::KernelTotalHeapBytes, time_since_boot:uptime}.as_event_codes(),
448 payload: fmetrics::MetricEventPayload::IntegerValue(4)
449 },
450 fmetrics::MetricEvent {
451 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
452 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
453 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::WiredBytes, time_since_boot:uptime}.as_event_codes(),
454 payload: fmetrics::MetricEventPayload::IntegerValue(3)
455 },
456 fmetrics::MetricEvent {
457 metric_id: cobalt_registry::MEMORY_LEAK_MIGRATED_METRIC_ID,
458 event_codes: cobalt_registry::MemoryLeakMigratedEventCodes {
459 general_breakdown: cobalt_registry::MemoryLeakMigratedMetricDimensionGeneralBreakdown::OtherBytes, time_since_boot:uptime}.as_event_codes(),
460 payload: fmetrics::MetricEventPayload::IntegerValue(9)
461 },
462 ]
463 );
464 assert_eq!(
466 &events[20..],
467 vec![
468 fmetrics::MetricEvent {
470 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
471 event_codes: vec![1], payload: fmetrics::MetricEventPayload::IntegerValue(2048)
473 },
474 fmetrics::MetricEvent {
476 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
477 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::Undigested.as_event_code()],
478 payload: fmetrics::MetricEventPayload::IntegerValue(2048)
479 },
480 fmetrics::MetricEvent {
481 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
482 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::Orphaned.as_event_code()],
483 payload: fmetrics::MetricEventPayload::IntegerValue(0)
484 },
485 fmetrics::MetricEvent {
486 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
487 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::Kernel.as_event_code()],
488 payload: fmetrics::MetricEventPayload::IntegerValue(31)
489 },
490 fmetrics::MetricEvent {
491 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
492 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::Free.as_event_code()],
493 payload: fmetrics::MetricEventPayload::IntegerValue(2)
494 },
495 fmetrics::MetricEvent {
496 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
497 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_PagerTotal.as_event_code()],
498 payload: fmetrics::MetricEventPayload::IntegerValue(14)
499 },
500 fmetrics::MetricEvent {
501 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
502 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_PagerNewest.as_event_code()],
503 payload: fmetrics::MetricEventPayload::IntegerValue(15)
504 },
505 fmetrics::MetricEvent {
506 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
507 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_PagerOldest.as_event_code()],
508 payload: fmetrics::MetricEventPayload::IntegerValue(16)
509 },
510 fmetrics::MetricEvent {
511 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
512 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_DiscardableLocked.as_event_code()],
513 payload: fmetrics::MetricEventPayload::IntegerValue(18)
514 },
515 fmetrics::MetricEvent {
516 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
517 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_DiscardableUnlocked.as_event_code()],
518 payload: fmetrics::MetricEventPayload::IntegerValue(19)
519 },
520 fmetrics::MetricEvent {
521 metric_id: cobalt_registry::MEMORY_MIGRATED_METRIC_ID,
522 event_codes: vec![cobalt_registry::MemoryMigratedMetricDimensionBucket::__Addl_ZramCompressedBytes.as_event_code()],
523 payload: fmetrics::MetricEventPayload::IntegerValue(21)
524 }
525 ]
526 )
527 }
528 _ => panic!("Unexpected metric event"),
529 }
530 Ok(())}).map_err(|err| anyhow!(err)), upload)?;
531 Ok(())
532 }
533}