below_dump/
cgroup.rs

1// Copyright (c) Facebook, Inc. and its affiliates.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use model::CgroupModelFieldId;
16use model::SingleCgroupModelFieldId;
17
18use super::*;
19
20pub struct Cgroup {
21    opts: GeneralOpt,
22    select: Option<SingleCgroupModelFieldId>,
23    fields: Vec<CgroupField>,
24}
25
26impl Cgroup {
27    pub fn new(
28        opts: &GeneralOpt,
29        select: Option<SingleCgroupModelFieldId>,
30        fields: Vec<CgroupField>,
31    ) -> Self {
32        Self {
33            opts: opts.to_owned(),
34            select,
35            fields,
36        }
37    }
38}
39
40impl Dumper for Cgroup {
41    fn dump_model(
42        &self,
43        ctx: &CommonFieldContext,
44        model: &model::Model,
45        output: &mut dyn Write,
46        round: &mut usize,
47        comma_flag: bool,
48    ) -> Result<IterExecResult> {
49        fn output_cgroup(
50            handle: &Cgroup,
51            ctx: &CommonFieldContext,
52            model: &model::CgroupModel,
53            output: &mut dyn Write,
54            round: &mut usize,
55            json: bool,
56            jval: &mut Value,
57        ) -> Result<()> {
58            let cgroup = &model.data;
59            //filter
60            let should_print = match (handle.select.as_ref(), handle.opts.filter.as_ref()) {
61                (Some(field_id), Some(filter)) => filter.is_match(
62                    &cgroup
63                        .query(field_id)
64                        .map_or("?".to_owned(), |v| v.to_string()),
65                ),
66                _ => true,
67            };
68
69            if should_print {
70                match handle.opts.output_format {
71                    Some(OutputFormat::Raw) | None => write!(
72                        output,
73                        "{}",
74                        print::dump_raw_indented(
75                            &handle.fields,
76                            ctx,
77                            cgroup,
78                            *round,
79                            handle.opts.repeat_title,
80                            handle.opts.disable_title,
81                            handle.opts.raw,
82                        )
83                    )?,
84                    Some(OutputFormat::Csv) => write!(
85                        output,
86                        "{}",
87                        print::dump_csv(
88                            &handle.fields,
89                            ctx,
90                            cgroup,
91                            *round,
92                            handle.opts.disable_title,
93                            handle.opts.raw,
94                        )
95                    )?,
96                    Some(OutputFormat::Tsv) => write!(
97                        output,
98                        "{}",
99                        print::dump_tsv(
100                            &handle.fields,
101                            ctx,
102                            cgroup,
103                            *round,
104                            handle.opts.disable_title,
105                            handle.opts.raw,
106                        )
107                    )?,
108                    Some(OutputFormat::KeyVal) => write!(
109                        output,
110                        "{}",
111                        print::dump_kv(&handle.fields, ctx, cgroup, handle.opts.raw)
112                    )?,
113                    Some(OutputFormat::Json) => {
114                        *jval = print::dump_json(&handle.fields, ctx, cgroup, handle.opts.raw);
115                        jval["children"] = json!([]);
116                    }
117                    Some(OutputFormat::OpenMetrics) => write!(
118                        output,
119                        "{}",
120                        print::dump_openmetrics(&handle.fields, ctx, cgroup)
121                    )?,
122                };
123                *round += 1;
124            }
125
126            let mut children = Vec::from_iter(&model.children);
127            //sort
128            if let Some(field_id) = &handle.select {
129                // field_id that queries its own data
130                let field_id = CgroupModelFieldId::new(
131                    Some(model::CgroupPath { path: vec![] }),
132                    field_id.to_owned(),
133                );
134                if handle.opts.sort {
135                    model::sort_queriables(&mut children, &field_id, false);
136                }
137
138                if handle.opts.rsort {
139                    model::sort_queriables(&mut children, &field_id, false);
140                }
141
142                if (handle.opts.sort || handle.opts.rsort) && handle.opts.top != 0 {
143                    children.truncate(handle.opts.top as usize);
144                }
145            }
146
147            for child_cgroup in &children {
148                let mut child = json!({});
149                output_cgroup(handle, ctx, child_cgroup, output, round, json, &mut child)?;
150                if json && child["children"].is_array() {
151                    // Parent does not match, but child does, we should also render parent.
152                    if !jval["children"].is_array() {
153                        *jval = print::dump_json(&handle.fields, ctx, cgroup, handle.opts.raw);
154                        jval["children"] = json!([]);
155                    }
156                    jval["children"].as_array_mut().unwrap().push(child);
157                }
158            }
159
160            Ok(())
161        }
162        let json = self.opts.output_format == Some(OutputFormat::Json);
163        let mut jval = json!({});
164        output_cgroup(self, ctx, &model.cgroup, output, round, json, &mut jval)?;
165        match (json, comma_flag) {
166            (true, true) => write!(output, ",{}", jval)?,
167            (true, false) => write!(output, "{}", jval)?,
168            _ => {}
169        };
170
171        Ok(IterExecResult::Success)
172    }
173}