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