Skip to content

Commit cf32394

Browse files
committed
feat: ram power & limit samples count in pipe command
1 parent ef1b90e commit cf32394

File tree

6 files changed

+73
-10
lines changed

6 files changed

+73
-10
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
- uses: softprops/action-gh-release@v2
4040
with:
4141
files: macmon-${{ github.ref_name }}.tar.gz
42+
generate_release_notes: true
4243
env:
4344
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4445

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "macmon"
3-
version = "0.4.1"
3+
version = "0.4.2"
44
edition = "2021"
55

66
[lints.rust]

readme.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ sudo cp target/release/macmon /usr/local/bin
6767
Usage: macmon [OPTIONS] [COMMAND]
6868

6969
Commands:
70-
raw Print metrics in JSON format – can be used for piping
70+
pipe Output metrics in JSON format
7171
debug Print debug information
7272
help Print this message or the help of the given subcommand(s)
7373

@@ -82,6 +82,51 @@ Controls:
8282
q - quit
8383
```
8484

85+
## Piping
86+
87+
You can use the pipe subcommand to output metrics in JSON format, which is suitable for piping into other tools or scripts. For example:
88+
89+
```sh
90+
macmon pipe | jq
91+
```
92+
93+
This command runs `macmon` in "pipe" mode and navigate output to `jq` for pretty-printing.
94+
95+
You can also specify the number of samples to run using `-s` or `--samples` parameter (default: `0`, which runs indefinitely), and set update interval in milliseconds using the `-i` or `--interval` parameter (default: `1000` ms). For example:
96+
97+
```sh
98+
macmon pipe -s 10 -i 500 | jq
99+
```
100+
101+
This will collect 10 samples with an update interval of 500 milliseconds.
102+
103+
### Output
104+
105+
```json
106+
{
107+
"temp": {
108+
"cpu_temp_avg": 43.73614, // Celsius
109+
"gpu_temp_avg": 36.95167 // Celsius
110+
},
111+
"memory": {
112+
"ram_total": 25769803776, // Bytes
113+
"ram_usage": 20985479168, // Bytes
114+
"swap_total": 4294967296, // Bytes
115+
"swap_usage": 2602434560 // Bytes
116+
},
117+
"ecpu_usage": [1181, 0.082656614], // (Frequency MHz, Usage %)
118+
"pcpu_usage": [1974, 0.015181795], // (Frequency MHz, Usage %)
119+
"gpu_usage": [461, 0.021497859], // (Frequency MHz, Usage %)
120+
"cpu_power": 0.20486385, // Watts
121+
"gpu_power": 0.017451683, // Watts
122+
"ane_power": 0.0, // Watts
123+
"all_power": 0.22231553, // Watts
124+
"sys_power": 5.876533, // Watts
125+
"ram_power": 0.11635789, // Watts
126+
"gpu_ram_power": 0.0009615385 // Watts
127+
}
128+
```
129+
85130
## 🤝 Contributing
86131
We love contributions! Whether you have ideas, suggestions, or bug reports, feel free to open an issue or submit a pull request. Your input is essential in helping us improve `macmon` 💪
87132

src/main.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ use std::error::Error;
1111

1212
#[derive(Debug, Subcommand)]
1313
enum Commands {
14-
/// Print metrics in JSON format – can be used for piping
15-
Raw,
14+
/// Output metrics in JSON format (suitable for piping)
15+
#[command(alias = "raw")]
16+
Pipe {
17+
/// Number of samples to run for. Set to 0 to run indefinitely
18+
#[arg(short, long, default_value_t = 0)]
19+
samples: u32,
20+
},
1621

1722
/// Print debug information
1823
Debug,
@@ -36,13 +41,19 @@ fn main() -> Result<(), Box<dyn Error>> {
3641
let msec = args.interval.max(100);
3742

3843
match &args.command {
39-
Some(Commands::Raw) => {
44+
Some(Commands::Pipe { samples }) => {
4045
let mut sampler = Sampler::new()?;
46+
let mut counter = 0u32;
4147

4248
loop {
4349
let doc = sampler.get_metrics(msec)?;
4450
let doc = serde_json::to_string(&doc)?;
4551
println!("{}", doc);
52+
53+
counter += 1;
54+
if *samples > 0 && counter >= *samples {
55+
break;
56+
}
4657
}
4758
}
4859
Some(Commands::Debug) => debug::print_debug()?,

src/metrics.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ pub struct Metrics {
3939
pub ane_power: f32, // Watts
4040
pub all_power: f32, // Watts
4141
pub sys_power: f32, // Watts
42+
pub ram_power: f32, // Watts
43+
pub gpu_ram_power: f32, // Watts
4244
}
4345

4446
// MARK: Helpers
@@ -220,7 +222,7 @@ impl Sampler {
220222

221223
// do several samples to smooth metrics
222224
// see: https://github.com/vladkens/macmon/issues/10
223-
for (sample, sample_dt) in self.ior.get_samples(duration, measures) {
225+
for (sample, dt) in self.ior.get_samples(duration, measures) {
224226
let mut ecpu_usages = Vec::new();
225227
let mut pcpu_usages = Vec::new();
226228
let mut rs = Metrics::default();
@@ -247,9 +249,11 @@ impl Sampler {
247249

248250
if x.group == "Energy Model" {
249251
match x.channel.as_str() {
250-
"CPU Energy" => rs.cpu_power += cfio_watts(x.item, &x.unit, sample_dt)?,
251-
"GPU Energy" => rs.gpu_power += cfio_watts(x.item, &x.unit, sample_dt)?,
252-
c if c.starts_with("ANE") => rs.ane_power += cfio_watts(x.item, &x.unit, sample_dt)?,
252+
"CPU Energy" => rs.cpu_power += cfio_watts(x.item, &x.unit, dt)?,
253+
"GPU Energy" => rs.gpu_power += cfio_watts(x.item, &x.unit, dt)?,
254+
c if c.starts_with("ANE") => rs.ane_power += cfio_watts(x.item, &x.unit, dt)?,
255+
c if c.starts_with("DRAM") => rs.ram_power += cfio_watts(x.item, &x.unit, dt)?,
256+
c if c.starts_with("GPU SRAM") => rs.gpu_ram_power += cfio_watts(x.item, &x.unit, dt)?,
253257
_ => {}
254258
}
255259
}
@@ -270,6 +274,8 @@ impl Sampler {
270274
rs.cpu_power = zero_div(results.iter().map(|x| x.cpu_power).sum(), measures as _);
271275
rs.gpu_power = zero_div(results.iter().map(|x| x.gpu_power).sum(), measures as _);
272276
rs.ane_power = zero_div(results.iter().map(|x| x.ane_power).sum(), measures as _);
277+
rs.ram_power = zero_div(results.iter().map(|x| x.ram_power).sum(), measures as _);
278+
rs.gpu_ram_power = zero_div(results.iter().map(|x| x.gpu_ram_power).sum(), measures as _);
273279
rs.all_power = rs.cpu_power + rs.gpu_power + rs.ane_power;
274280

275281
rs.memory = self.get_mem()?;

0 commit comments

Comments
 (0)