8

The other day, I was sitting in a coffee shop working, when I looked down to find that 25% of my battery was left.

I looked at my Activity Monitor and saw that the time machine process was going at 90% for a while (as long as I was watching it).

Are there any apps that can notify me if a process is at a certain level for a certain amount of time?

5

You could run a script like this every minute with cron or launchd:

#!/bin/bash

cpulimit=50
prefix=${TMPDIR}cron_cpu
current=$(ps -erco %cpu,command | tail -n+2 | sed 's/^ *//')
echo "$current" > $prefix$(date +%s)
a=($prefix*); for ((i=0;i<=${#a[@]}-3;i++)); do rm "${a[i]}"; done
[[ $(awk '{s+=$1}END{printf "%i",s}' <<< "$current") -lt $cpulimit ]] && exit
averages=$(awk '{cpu=$1;sub(/[^ ]+ /,"");a[$0]+=cpu;c[$0]++}END{for(i in a){printf "%.1f %s\n",a[i]/c[$0],i}}' $prefix* | sort -rn)
if [[ $(awk '{s+=$1}END{printf "%i",s}' <<< "$averages") -ge $cpulimit ]]; then
    terminal-notifier -title "CPU use" -message "$(head -n5 <<< "$averages" | paste -sd / -)"
fi

If the average CPU use in the last three samples is over 50%, it uses terminal-notifier to display the processes that used the most CPU.

You could also use MenuMeters to display total CPU use in the menu bar:

Or run a script like this with GeekTool:

for i in {1..4}; do ps -erco %cpu,command | tail -n+2; sleep 1; done | sed 's/^ *//' | grep -v GeekTool | awk '{cpu=$1;sub(/[^ ]+ /,"");a[$0]+=cpu;c[$0]++}END{for(i in a){printf "%.1f %s\n",a[i]/c[$0],i}}' | sort -rn

0

This is a variant built off of the answer from @Lri. It will stay silent if there are no processes above a threshold (set to 60 here) but does not do averaging across samples, so may give more one-off noise. Like the other answer, you will need to install terminal-notifier.

Save the script below to a file (called, e.g., /Users/goldberg/cpu_notify and made executable):

#!/bin/bash
# Post a notification if a process is over a CPU limit

# see ~/Library/LaunchAgents/goldberg.cpu_notify.plist

notify=/usr/local/bin/terminal-notifier

cpulimit=60
active=$(ps -erco %cpu,command \
    | head -3 \
    | grep -vE -e '\b(CPU COMMAND|bash|sed|awk|ps|grep|head)\b' \
    | awk "\$1 > $cpulimit")

# Skip if empty.
[ -z "${active}" ] || $notify  -title "CPU use" -message "$active"

...and for launchd, save the file below with a name like ~/Library/LaunchAgents/goldberg.cpu_notify.plist.

It's set to 300 seconds (5 minutes) interval, and you will need to fix the line that points to the script.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>goldberg.cpu_notify</string>
    <key>Program</key>
    <string>/Users/goldberg/bin/cpu_notify</string>
    <key>ServiceDescription</key>
    <string>High CPU process notification</string>
    <key>StartInterval</key>
    <integer>300</integer>
    <key>ThrottleInterval</key>
    <integer>0</integer>
</dict>
</plist>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .