Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

status-interval not respected #15

Open
akiross opened this issue Jan 27, 2017 · 16 comments
Open

status-interval not respected #15

akiross opened this issue Jan 27, 2017 · 16 comments

Comments

@akiross
Copy link

akiross commented Jan 27, 2017

So, after installing the plugin I noticed that my status bar was updated too frequently. Apparently, the presence of tmux-cpu influences the update and status-interval is ignored.

For example, if I set

tmux set -g status-right "%H:%M:%S"
tmux set -g status-interval 5

I can see the seconds updated every 5 seconds. On the other hand, if I add the tmux_cpu plugin:

tmux set -g status-right "%H:%M:%S #(/path/to/plugin/scripts/cpu_percentage.sh)"
tmux set -g status-interval 5

I will see the seconds and the CPU percentage updated almost every second, disregarding the value of status-interval. I think status-interval should be taken into account, and I see this behaviour as buggy.

I can help with the debug, but not being familiar with tmux-plugins in any way I don't know where to start.

@ctjhoa
Copy link
Member

ctjhoa commented Jan 27, 2017

I'm not sure if this is something related to tmux-cpu or if this is something related to tpm or tmux in general.
Have you try the same thing with tmux-plugins/tmux-battery?

@ctjhoa
Copy link
Member

ctjhoa commented Jan 27, 2017

ctjhoa@cl-mackbook ~ % time .tmux/plugins/tmux-cpu/scripts/cpu_percentage.sh
  8.3%
.tmux/plugins/tmux-cpu/scripts/cpu_percentage.sh  0.00s user 0.00s system 0% cpu 1.007 total

As you can see get cpu percentage is very slow because you can only get CPU from a time frame of 1 second (thanks to iostat). So maybe it have impact on the status-interval

@ctjhoa
Copy link
Member

ctjhoa commented Jan 27, 2017

In theory, it should be something like this:

     0                  1                                                              5                6                                                             10
   start-interval                                                                    start-interval
      |------------------------------------------------------------------------------->|------------------------------------------------------------------------------->|

 start-cpu           end-cpu                                                          start-cpu           end-cpu 
      |---------------->                                                               |---------------->

@akiross
Copy link
Author

akiross commented Jan 27, 2017

cpu_percentage.sh is slow here as well because it uses an interval of 1, but it can be omitted: iostat -c is sufficient to get an immediate CPU usage statistic, instead of iostat -c 1 2 as it is now in the script.

In fact, replacing iostat -c 1 2 with iostat -c in the cpu_percentage.sh, the issue appears to be fixed and start-interval is honoured.

With the battery plugin it appears not to have this issue, at least using battery_remain.sh... Not knowing how tmux-plugins is implemented, I can't tell, but I think it's something structural causing this issue (i.e. in tpm).

EDIT: just to clarify, I'm on linux.

@ctjhoa
Copy link
Member

ctjhoa commented Jan 27, 2017

From linux iostat man page:

The first report generated by the iostat command provides statistics concerning the time since the system was booted

so I cannot use the first report

@ctjhoa
Copy link
Member

ctjhoa commented Jan 27, 2017

Same from BSD iostat man page:

The first statistics that are printed are averaged over the system uptime.

@akiross
Copy link
Author

akiross commented Jan 27, 2017

Right... So, another way has to be found :)

@ncdc
Copy link

ncdc commented Sep 15, 2017

FYI with the iostat in sysstat-11.5.4-2.fc26.x86_64, you can do iostat -c -y 1 1 to get the current cpu utilization. The docs for -y: Omit first report with statistics since system boot, if displaying multiple records at given interval.. I also had to change it to tail -n 3 instead of 2, FWIW.

@BrainMaestro
Copy link

I have this issue as well, and I think it's related to tmux/tmux#797 (comment). Maybe, as a way to fix this, the status-interval is checked, and if that number of seconds since the last time have not passed, just return the last value to avoid a redraw. Not the nicest solution since we have to keep track of two variables between draws, but it should work

cdanis added a commit to cdanis/dotfiles that referenced this issue Jul 13, 2019
previously we invoked vmstat and parsed its output to report on
supposedly 'recent' CPU consumption.  however, as invoked, vmstat
outputs cumulative-since-boot CPU numbers, as that's all the kernel
interface supplies.  having vmstat wait a few seconds to report
last-few-seconds numbers is possible, but is not recommended
(see tmux/tmux#797 (comment) )
and results in status line updates at rapid and irregular intervals
(see tmux-plugins/tmux-cpu#15 ).  this is
distracting, and also makes tmux create high load on an ancient raspi.

so instead, we kludge using tmux as a sort of background job manager,
launching vmstat on a high-numbered window and parsing its output
into a file underneath our systemd-created session tmpfs, from which
the tmux status line reads it.

vmstat is used over iostat/mpstat/etc as it should be always available
(at least on Debian systems where procps is Priority: important).
@lonix1
Copy link

lonix1 commented Oct 8, 2019

Is this still an issue in the latest bits, and what is the current recommended workaround (OP was a few years ago).

@ctjhoa
Copy link
Member

ctjhoa commented Oct 8, 2019

@lonix1 iostat versions are very different across OSes and even depending on the version used. If you really care about the update frequency of your status bar, an alternative could be to add an option to customize the command used to compute CPU.

@lonix1
Copy link

lonix1 commented Oct 8, 2019

@ctjhoa Since you know much more about this than I do, what approach do you take/recommend? (I'm on latest ubuntu BTW).

@ctjhoa
Copy link
Member

ctjhoa commented Oct 11, 2019

@lonix1 What I mean is, if we cannot guess what iostat version is used and there is a faster way to compute cpu percentage, we could let the user specify the command specific to his system through a tmux-cpu option.
Using eval or such should be straightforward but I have doubt that a faster command exist for the majority of OSes.

casperdcl added a commit that referenced this issue Jul 9, 2020
- fixes #27
- fixes #15
- fixes #5
casperdcl added a commit that referenced this issue Jul 9, 2020
- fixes #27
- related #15
- related #5
@casperdcl casperdcl changed the title Update frequency too high (and status-interval not respected) status-interval not respected Jul 9, 2020
@casperdcl
Copy link
Collaborator

Is this still an issue? To be clear, this should not be the case:

For example, if I set

tmux set -g status-right "%H:%M:%S"
tmux set -g status-interval 5

I can see the seconds updated every 5 seconds. On the other hand, if I add the tmux_cpu plugin:

tmux set -g status-right "%H:%M:%S #(/path/to/plugin/scripts/cpu_percentage.sh)"
tmux set -g status-interval 5

I will see the seconds and the CPU percentage updated almost every second, disregarding the value of status-interval. I think status-interval should be taken into account, and I see this behaviour as buggy.

Seems like it was an upstream bug but isn't a thing any more? My local tests show status-interval is loosely respected even with just tmux set -g status-right "%H:%M:%S".

casperdcl added a commit that referenced this issue Jul 9, 2020
- fixes #27
- related #15
- related #5
@casperdcl
Copy link
Collaborator

While testing this, I think I've found an upstream problem (with tmux or tpm). Basically

set -g status-right "%H:%M:%S #(sleep 1)"
set -g status-interval 5

will ignore status-interval and result in one update per second (!)

@ofdeath
Copy link

ofdeath commented Jul 19, 2020

I have another solution. I know this is ugly because

  • It requires that the user needs to set up a cron job manually.
  • It doesn't check whether the stat file is updating
  • It can get inaccurate values while the stat file is rotating

But it's faster than running the iostat command directly and it can get the cpu percentage with longer interval (ex: 5s)
Anyway you can consider to add this optional method if you want :)

my cronjob
* * * * * root mkdir -p /dev/shm/tmux-cpu && mpstat 1 59 > /dev/shm/tmux-cpu/mpstat

my tmux.conf
set -g @cpu-stat-file '/dev/shm/tmux-cpu/mpstat'

modified cpu_percentage.sh
cpu_percentage.sh.txt


CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

source "$CURRENT_DIR/helpers.sh"

cpu_stat_file="${TMPDIR:-/tmp}/tmux-$EUID-cpu/iostat"
cpu_stat_interval=5

get_time() {
        date +"%s.%N"
}

get_stat_stat() {
        local stat_file=$1
        local stat_stat="$stat_file.stat"
        if [ -f "$stat_stat" ]; then
                local now=$(get_time)
                local time=""
                while read line; do
                        if [ -z "$time" ]; then
                                time=$line
                        else
                                if (( $now - $time < 1 )); then
                                        printf "%s" "$line"
                                        break
                                fi
                        fi
                done < $stat_stat
        fi
}

print_cpu_stat() {
        local stat_file=$1
        local stat_stat="$stat_file.stat"
        local value=$(get_stat_stat $stat_file)
        if [ -z "$value" ]; then
                local stat_interval=$(get_tmux_option "@cpu-stat-interval" "$cpu_stat_interval")
                local stat_dir=$(dirname $stat_stat)
                local time=$(get_time)
                value=$(awk '$NF~/[0-9.]+/ {print 100-$NF}' $stat_file | tail -n $stat_interval | awk '{n+=1;sum+=$1} END{printf("%3.1f%%",n>0?sum/n:0)}')
                [ ! -d "$stat_dir" ] && mkdir -p "$stat_dir" && chmod 0700 "$stat_dir"
                printf "%s\n%s" "$time" "$value" > $stat_stat
        fi
        printf "%s" "$value"
}

print_cpu_percentage() {
        stat_file=$(get_tmux_option "@cpu-stat-file" "$cpu_stat_file")

        if [ -f $stat_file ]; then
                print_cpu_stat $stat_file

        elif command_exists "iostat"; then
                if is_linux_iostat; then
                        iostat -c 1 2 | sed '/^\s*$/d' | tail -n 1 | awk '{usage=100-$NF} END {printf("%3.1f%%", usage)}' | sed 's/,/./'
                elif is_osx; then
                        iostat -c 2 disk0 | sed '/^\s*$/d' | tail -n 1 | awk '{usage=100-$6} END {printf("%3.1f%%", usage)}' | sed 's/,/./'
                elif is_freebsd || is_openbsd; then
                        iostat -c 2 | sed '/^\s*$/d' | tail -n 1 | awk '{usage=100-$NF} END {printf("%3.1f%%", usage)}' | sed 's/,/./'
                else
                        echo "Unknown iostat version please create an issue"
                fi
        elif command_exists "sar"; then
                sar -u 1 1 | sed '/^\s*$/d' | tail -n 1 | awk '{usage=100-$NF} END {printf("%3.1f%%", usage)}' | sed 's/,/./'
        else
                if is_cygwin; then
                        usage="$(WMIC cpu get LoadPercentage | grep -Eo '^[0-9]+')"
                        printf "%3.1f%%" $usage
                else
                        load=`ps -aux | awk '{print $3}' | tail -n+2 | awk '{s+=$1} END {print s}'`
                        cpus=$(cpus_number)
                        echo "$load $cpus" | awk '{printf "%3.1f%%", $1/$2}'
                fi
        fi
}

main() {
        print_cpu_percentage
}
main

jgeralnik added a commit to jgeralnik/tmux-net-speed that referenced this issue Feb 6, 2021
The code assumes that the status bar will only be updated every
status-interval seconds

In practice status-interval is a maximum value, not a minimum value. So
if the status bar is actually updated every second even though the
configuration is for 5 seconds all of the calculations are off and the
bitrate will be calculated as a fifth of the real rate.

See tmux-plugins/tmux-cpu#15 for a similar
issue with a different plugin, except that here it is much worse because
it actually leads to a WRONG RESULT and not just a faster update. This
commit implements @BrainMaestro 's suggestion from that thread.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants