1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
// Copyright (c) Facebook, Inc. and its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::BTreeMap;
use std::fmt;

use serde::Deserialize;
use serde::Serialize;

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct CpuStat {
    pub user_usec: Option<u64>,
    pub nice_usec: Option<u64>,
    pub system_usec: Option<u64>,
    pub idle_usec: Option<u64>,
    pub iowait_usec: Option<u64>,
    pub irq_usec: Option<u64>,
    pub softirq_usec: Option<u64>,
    pub stolen_usec: Option<u64>,
    pub guest_usec: Option<u64>,
    pub guest_nice_usec: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct Stat {
    pub total_cpu: Option<CpuStat>,
    pub cpus_map: Option<BTreeMap<u32, CpuStat>>,
    pub total_interrupt_count: Option<u64>,
    pub context_switches: Option<u64>,
    pub boot_time_epoch_secs: Option<u64>,
    pub total_processes: Option<u64>,
    pub running_processes: Option<u32>,
    pub blocked_processes: Option<u32>,
}

// In kilobytes unless specified otherwise
#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct MemInfo {
    pub total: Option<u64>,
    pub free: Option<u64>,
    pub available: Option<u64>,
    pub buffers: Option<u64>,
    pub cached: Option<u64>,
    pub swap_cached: Option<u64>,
    pub active: Option<u64>,
    pub inactive: Option<u64>,
    pub active_anon: Option<u64>,
    pub inactive_anon: Option<u64>,
    pub active_file: Option<u64>,
    pub inactive_file: Option<u64>,
    pub unevictable: Option<u64>,
    pub mlocked: Option<u64>,
    pub swap_total: Option<u64>,
    pub swap_free: Option<u64>,
    pub dirty: Option<u64>,
    pub writeback: Option<u64>,
    pub anon_pages: Option<u64>,
    pub mapped: Option<u64>,
    pub shmem: Option<u64>,
    pub kreclaimable: Option<u64>,
    pub slab: Option<u64>,
    pub slab_reclaimable: Option<u64>,
    pub slab_unreclaimable: Option<u64>,
    pub kernel_stack: Option<u64>,
    pub page_tables: Option<u64>,
    pub anon_huge_pages: Option<u64>,
    pub shmem_huge_pages: Option<u64>,
    pub file_huge_pages: Option<u64>,
    // This is in number of pages: not kilobytes
    pub total_huge_pages: Option<u64>,
    // This is in number of pages: not kilobytes
    pub free_huge_pages: Option<u64>,
    pub huge_page_size: Option<u64>,
    pub cma_total: Option<u64>,
    pub cma_free: Option<u64>,
    pub vmalloc_total: Option<u64>,
    pub vmalloc_used: Option<u64>,
    pub vmalloc_chunk: Option<u64>,
    pub direct_map_4k: Option<u64>,
    pub direct_map_2m: Option<u64>,
    pub direct_map_1g: Option<u64>,
    pub hugetlb: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct InterfaceStat {
    pub collisions: Option<u64>,
    pub multicast: Option<u64>,
    pub rx_bytes: Option<u64>,
    pub rx_compressed: Option<u64>,
    pub rx_crc_errors: Option<u64>,
    pub rx_dropped: Option<u64>,
    pub rx_errors: Option<u64>,
    pub rx_fifo_errors: Option<u64>,
    pub rx_frame_errors: Option<u64>,
    pub rx_length_errors: Option<u64>,
    pub rx_missed_errors: Option<u64>,
    pub rx_nohandler: Option<u64>,
    pub rx_over_errors: Option<u64>,
    pub rx_packets: Option<u64>,
    pub tx_aborted_errors: Option<u64>,
    pub tx_bytes: Option<u64>,
    pub tx_carrier_errors: Option<u64>,
    pub tx_compressed: Option<u64>,
    pub tx_dropped: Option<u64>,
    pub tx_errors: Option<u64>,
    pub tx_fifo_errors: Option<u64>,
    pub tx_heartbeat_errors: Option<u64>,
    pub tx_packets: Option<u64>,
    pub tx_window_errors: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct TcpStat {
    pub active_opens: Option<u64>,
    pub passive_opens: Option<u64>,
    pub attempt_fails: Option<u64>,
    pub estab_resets: Option<u64>,
    pub curr_estab: Option<u64>,
    pub in_segs: Option<u64>,
    pub out_segs: Option<u64>,
    pub retrans_segs: Option<u64>,
    pub in_errs: Option<u64>,
    pub out_rsts: Option<u64>,
    pub in_csum_errors: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct TcpExtStat {
    pub syncookies_sent: Option<u64>,
    pub syncookies_recv: Option<u64>,
    pub syncookies_failed: Option<u64>,
    pub embryonic_rsts: Option<u64>,
    pub prune_called: Option<u64>,
    pub tw: Option<u64>,
    pub paws_estab: Option<u64>,
    pub delayed_acks: Option<u64>,
    pub delayed_ack_locked: Option<u64>,
    pub delayed_ack_lost: Option<u64>,
    pub listen_overflows: Option<u64>,
    pub listen_drops: Option<u64>,
    pub tcp_hp_hits: Option<u64>,
    pub tcp_pure_acks: Option<u64>,
    pub tcp_hp_acks: Option<u64>,
    pub tcp_reno_recovery: Option<u64>,
    pub tcp_reno_reorder: Option<u64>,
    pub tcp_ts_reorder: Option<u64>,
    pub tcp_full_undo: Option<u64>,
    pub tcp_partial_undo: Option<u64>,
    pub tcp_dsack_undo: Option<u64>,
    pub tcp_loss_undo: Option<u64>,
    pub tcp_lost_retransmit: Option<u64>,
    pub tcp_reno_failures: Option<u64>,
    pub tcp_loss_failures: Option<u64>,
    pub tcp_fast_retrans: Option<u64>,
    pub tcp_slow_start_retrans: Option<u64>,
    pub tcp_timeouts: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct IpExtStat {
    pub in_mcast_pkts: Option<u64>,
    pub out_mcast_pkts: Option<u64>,
    pub in_bcast_pkts: Option<u64>,
    pub out_bcast_pkts: Option<u64>,
    pub in_octets: Option<u64>,
    pub out_octets: Option<u64>,
    pub in_mcast_octets: Option<u64>,
    pub out_mcast_octets: Option<u64>,
    pub in_bcast_octets: Option<u64>,
    pub out_bcast_octets: Option<u64>,
    pub in_no_ect_pkts: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct IpStat {
    pub forwarding: Option<u64>,
    pub in_receives: Option<u64>,
    pub forw_datagrams: Option<u64>,
    pub in_discards: Option<u64>,
    pub in_delivers: Option<u64>,
    pub out_requests: Option<u64>,
    pub out_discards: Option<u64>,
    pub out_no_routes: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct Ip6Stat {
    pub in_receives: Option<u64>,
    pub in_hdr_errors: Option<u64>,
    pub in_no_routes: Option<u64>,
    pub in_addr_errors: Option<u64>,
    pub in_discards: Option<u64>,
    pub in_delivers: Option<u64>,
    pub out_forw_datagrams: Option<u64>,
    pub out_requests: Option<u64>,
    pub out_no_routes: Option<u64>,
    pub in_mcast_pkts: Option<u64>,
    pub out_mcast_pkts: Option<u64>,
    pub in_octets: Option<u64>,
    pub out_octets: Option<u64>,
    pub in_mcast_octets: Option<u64>,
    pub out_mcast_octets: Option<u64>,
    pub in_bcast_octets: Option<u64>,
    pub out_bcast_octets: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct IcmpStat {
    pub in_msgs: Option<u64>,
    pub in_errors: Option<u64>,
    pub in_dest_unreachs: Option<u64>,
    pub out_msgs: Option<u64>,
    pub out_errors: Option<u64>,
    pub out_dest_unreachs: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct Icmp6Stat {
    pub in_msgs: Option<u64>,
    pub in_errors: Option<u64>,
    pub out_msgs: Option<u64>,
    pub out_errors: Option<u64>,
    pub in_dest_unreachs: Option<u64>,
    pub out_dest_unreachs: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct UdpStat {
    pub in_datagrams: Option<u64>,
    pub no_ports: Option<u64>,
    pub in_errors: Option<u64>,
    pub out_datagrams: Option<u64>,
    pub rcvbuf_errors: Option<u64>,
    pub sndbuf_errors: Option<u64>,
    pub ignored_multi: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct Udp6Stat {
    pub in_datagrams: Option<u64>,
    pub no_ports: Option<u64>,
    pub in_errors: Option<u64>,
    pub out_datagrams: Option<u64>,
    pub rcvbuf_errors: Option<u64>,
    pub sndbuf_errors: Option<u64>,
    pub in_csum_errors: Option<u64>,
    pub ignored_multi: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct VmStat {
    pub pgpgin: Option<u64>,
    pub pgpgout: Option<u64>,
    pub pswpin: Option<u64>,
    pub pswpout: Option<u64>,
    pub pgsteal_kswapd: Option<u64>,
    pub pgsteal_direct: Option<u64>,
    pub pgscan_kswapd: Option<u64>,
    pub pgscan_direct: Option<u64>,
    pub oom_kill: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct SlabInfo {
    pub name: Option<String>,
    pub active_objs: Option<u64>,
    pub num_objs: Option<u64>,
    pub obj_size: Option<u64>,
    pub obj_per_slab: Option<u64>,
    pub pages_per_slab: Option<u64>,
    pub active_slabs: Option<u64>,
    pub num_slabs: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct MountInfo {
    pub mnt_id: Option<i32>,
    pub parent_mnt_id: Option<i32>,
    pub majmin: Option<String>,
    pub root: Option<String>,
    pub mount_point: Option<String>,
    pub mount_options: Option<String>,
    pub fs_type: Option<String>,
    pub mount_source: Option<String>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct DiskStat {
    pub major: Option<u64>,
    pub minor: Option<u64>,
    pub name: Option<String>,
    pub read_completed: Option<u64>,
    pub read_merged: Option<u64>,
    pub read_sectors: Option<u64>,
    pub time_spend_read_ms: Option<u64>,
    pub write_completed: Option<u64>,
    pub write_merged: Option<u64>,
    pub write_sectors: Option<u64>,
    pub time_spend_write_ms: Option<u64>,
    pub discard_completed: Option<u64>,
    pub discard_merged: Option<u64>,
    pub discard_sectors: Option<u64>,
    pub time_spend_discard_ms: Option<u64>,
    pub disk_usage: Option<f32>,
    pub partition_size: Option<u64>,
    pub filesystem_type: Option<String>,
}

#[derive(Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)]
pub enum PidState {
    Running,
    Sleeping,
    UninterruptibleSleep,
    Stopped,
    TracingStopped,
    Zombie,
    Dead,
    Idle,
    Parked,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct PidStat {
    pub pid: Option<i32>,
    pub comm: Option<String>,
    pub state: Option<PidState>,
    pub ppid: Option<i32>,
    pub pgrp: Option<i32>,
    pub session: Option<i32>,
    pub minflt: Option<u64>,
    pub majflt: Option<u64>,
    pub user_usecs: Option<u64>,
    pub system_usecs: Option<u64>,
    pub num_threads: Option<u64>,
    pub running_secs: Option<u64>,
    pub rss_bytes: Option<u64>,
    pub processor: Option<i32>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct PidStatus {
    pub ns_tgid: Option<Vec<u32>>,
    pub vm_size: Option<u64>,
    pub lock: Option<u64>,
    pub pin: Option<u64>,
    pub anon: Option<u64>,
    pub file: Option<u64>,
    pub shmem: Option<u64>,
    pub pte: Option<u64>,
    pub swap: Option<u64>,
    pub huge_tlb: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct PidIo {
    pub rbytes: Option<u64>,
    pub wbytes: Option<u64>,
}

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct PidInfo {
    pub stat: PidStat,
    pub io: PidIo,
    pub cgroup: String,
    // Optional b/c cmdline may be sanitized or redacted based on security policy
    pub cmdline_vec: Option<Vec<String>>,
    pub exe_path: Option<String>,
    // TODO: Remove alias
    // This field was previously called "mem"
    #[serde(alias = "mem")]
    pub status: PidStatus,
}

pub type PidMap = BTreeMap<i32, PidInfo>;
pub type NetMap = BTreeMap<String, InterfaceStat>;
pub type DiskMap = BTreeMap<String, DiskStat>;
pub type SlabInfoMap = BTreeMap<String, SlabInfo>;

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct NetStat {
    pub interfaces: Option<NetMap>,
    pub tcp: Option<TcpStat>,
    pub tcp_ext: Option<TcpExtStat>,
    pub ip: Option<IpStat>,
    pub ip_ext: Option<IpExtStat>,
    pub ip6: Option<Ip6Stat>,
    pub icmp: Option<IcmpStat>,
    pub icmp6: Option<Icmp6Stat>,
    pub udp: Option<UdpStat>,
    pub udp6: Option<Udp6Stat>,
}

impl fmt::Display for PidState {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            PidState::Running => write!(f, "RUNNING"),
            PidState::Sleeping => write!(f, "SLEEPING"),
            PidState::UninterruptibleSleep => write!(f, "UNINTERRUPTIBLE_SLEEP"),
            PidState::Stopped => write!(f, "STOPPED"),
            PidState::TracingStopped => write!(f, "TRACING_STOPPED"),
            PidState::Zombie => write!(f, "ZOMBIE"),
            PidState::Dead => write!(f, "DEAD"),
            PidState::Idle => write!(f, "IDLE"),
            PidState::Parked => write!(f, "PARKED"),
        }
    }
}