Добавлены конфиги tmux и zsh
This commit is contained in:
21
tmux/plugins/tmux-plugin-sysstat/LICENSE
Normal file
21
tmux/plugins/tmux-plugin-sysstat/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2017 Alexey Samoshkin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
372
tmux/plugins/tmux-plugin-sysstat/readme.md
Normal file
372
tmux/plugins/tmux-plugin-sysstat/readme.md
Normal file
@@ -0,0 +1,372 @@
|
||||
|
||||
Tmux sysstat plugin
|
||||
===================
|
||||
Allow to print CPU usage, memory & swap, load average, net I/O metrics in Tmux status bar
|
||||
|
||||

|
||||
|
||||
You might checkout [tmux-config](https://github.com/samoshkin/tmux-config) repo to see this plugin in action.
|
||||
|
||||
Features
|
||||
--------
|
||||
- CPU usage
|
||||
- Memory available/free, used, total (KiB,MiB,GiB), free/used %
|
||||
- Swap used, free, total, free/used %
|
||||
- load average for last 1,5,15 minutes
|
||||
- configurable thresholds (low, medium, stress) with custom colors
|
||||
- tweak each metric output using templates (e.g, 'used 10% out of 16G')
|
||||
- configurable size scale (K,M,G)
|
||||
- OSX, Linux support
|
||||
- [ ] **TODO:** network I/O metric support
|
||||
|
||||
Tested on: OS X El Capitan 10.11.5, Ubuntu 14 LTS, CentOS 7, FreeBSD 11.1.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
Best installed through [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (TMP). Add following line to your `.tmux.conf` file:
|
||||
|
||||
```
|
||||
set -g @plugin 'samoshkin/tmux-plugin-sysstat'
|
||||
```
|
||||
|
||||
Use `prefix + I` from inside tmux to install all plugins and source them. If you prefer, same effect can be achieved from [command line](https://github.com/tmux-plugins/tpm/blob/master/docs/managing_plugins_via_cmd_line.md):
|
||||
|
||||
```
|
||||
$ ~.tmux/plugins/tpm/bin/install_plugins
|
||||
```
|
||||
|
||||
Basic usage
|
||||
-----------
|
||||
|
||||
Once plugged in, tmux `status-left` or `status-right` options can be configured with following placeholders. Each placeholder will be expanded to metric's default output.
|
||||
|
||||
- `#{sysstat_cpu}`, CPU usage - `CPU:40.2%`
|
||||
- `#{sysstat_mem}`, memory usage - `MEM:73%`
|
||||
- `#{sysstat_swap}`, swap usage - `SW:66%`
|
||||
- `#{sysstat_loadavg}`, system load average - `0.25 0.04 0.34`
|
||||
|
||||
For example:
|
||||
```
|
||||
set -g status-right "#{sysstat_cpu} | #{sysstat_mem} | #{sysstat_swap} | #{sysstat_loadavg} | #[fg=cyan]#(echo $USER)#[default]@#H"
|
||||
```
|
||||
|
||||
Changing default output
|
||||
------------------------
|
||||
|
||||
You can change default output for CPU and memory metrics, if you need more fields to show, or you want to provide custom template. In your `.tmux.conf`:
|
||||
|
||||
For example, to get `Used 4.5G out of 16G` output for memory metric:
|
||||
|
||||
```
|
||||
set -g @sysstat_mem_view_tmpl '#Used [fg=#{mem.color}]#{mem.used}#[default] out of #{mem.total}'
|
||||
```
|
||||
|
||||
If you don't want `CPU:` prefix and don't like colored output for CPU metric:
|
||||
|
||||
```
|
||||
set -g @sysstat_cpu_view_tmpl '#{cpu.pused}'
|
||||
```
|
||||
|
||||
### Supported fields
|
||||
|
||||
As you can see, each metric can be configured with template, containing fixed text (`CPU:`), color placeholder (`#[fg=#{mem.color}]`) and field placeholder (`#{mem.used}`). This approach gives you the ultimate control over the output for each metric. Following field placeholders are supported:
|
||||
|
||||
<table>
|
||||
<th>CPU</th>
|
||||
<tr>
|
||||
<td><code>#{cpu.color}</code></td>
|
||||
<td>main metric color</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{cpu.pused}</code></td>
|
||||
<td>CPU usage percentage</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<th>Memory</th>
|
||||
<tr>
|
||||
<td><code>#{mem.color}</code></td>
|
||||
<td>main metric color</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{mem.free}</code></td>
|
||||
<td>free/available memory</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{mem.pfree}</code></td>
|
||||
<td>free memory percentage against total</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{mem.used}</code></td>
|
||||
<td>used memory</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{mem.pused}</code></td>
|
||||
<td>used memory percentage against total</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{mem.total}</code></td>
|
||||
<td>total installed memory</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<th>Swap</th>
|
||||
<tr>
|
||||
<td><code>#{swap.color}</code></td>
|
||||
<td>main swap metric color</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{swap.free}</code></td>
|
||||
<td>free swap memory</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{swap.pfree}</code></td>
|
||||
<td>free swap memory percentage against total swap space</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{swap.used}</code></td>
|
||||
<td>used swap memory</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{swap.pused}</code></td>
|
||||
<td>used swap memory percentage against total swap space</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>#{swap.total}</code></td>
|
||||
<td>total swap space</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Change size scale
|
||||
|
||||
free/used/total memory can be shown both in absolute and relative units. When it comes to absolute units, you can choose *size scale factor* to choose between GiB, MiB, KiB. Default is GiB. If you have less than 3-4G memory installed, it makes sense to use MiB. KiB option is less practical, because it yields pretty lengthy output, which does not fit status bar limited estate.
|
||||
|
||||
```
|
||||
set -g @sysstat_mem_size_unit "G"
|
||||
```
|
||||
|
||||
If you choose `G` for size scale, output will have `%.1f` (1 digit after floating point), otherwise size is integer (4.5G, 1024M, 1232345K).
|
||||
|
||||
Thresholds and colored output
|
||||
---------------
|
||||
Each metric output is colored by default. Colors vary depending on metric value.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><b>Threshold</b></td>
|
||||
<td><b>CPU</b></td>
|
||||
<td><b>Memory</b></td>
|
||||
<td><b>Swap</b></td>
|
||||
<td><b>Default color</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>low</td>
|
||||
<td>x < 30%</td>
|
||||
<td>x < 75%</td>
|
||||
<td>x < 25%</td>
|
||||
<td>green</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>medium</td>
|
||||
<td>30% < x < 80%</td>
|
||||
<td>75% < x < 90%</td>
|
||||
<td>25% < x < 75%</td>
|
||||
<td>yellow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>high</td>
|
||||
<td>x > 80%</td>
|
||||
<td>x > 90%</td>
|
||||
<td>x > 75%</td>
|
||||
<td>red</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
You can change thresholds in your `.tmux.conf`:
|
||||
|
||||
```
|
||||
set -g @sysstat_cpu_medium_threshold "75"
|
||||
set -g @sysstat_cpu_stress_threshold "95"
|
||||
|
||||
set -g @sysstat_mem_medium_threshold "85"
|
||||
set -g @sysstat_mem_stress_threshold "95"
|
||||
|
||||
set -g @sysstat_swap_medium_threshold "80"
|
||||
set -g @sysstat_swap_stress_threshold "90"
|
||||
```
|
||||
|
||||
You can change colors for each threshold individually. You can use ANSI basic colors (red, cyan, green) or if your terminal supports 256 colors (and most do nowadays), use `colourXXX` format.
|
||||
|
||||
```
|
||||
set -g @sysstat_cpu_color_low "colour076"
|
||||
set -g @sysstat_cpu_color_medium "colour220"
|
||||
set -g @sysstat_cpu_color_stress "colour160"
|
||||
set -g @sysstat_mem_color_low "green"
|
||||
set -g @sysstat_mem_color_medium "blue"
|
||||
set -g @sysstat_mem_color_stress "cyan"
|
||||
```
|
||||
|
||||
`#{(mem|cpu|swap).color}` placeholder in your `@sysstat_(mem|cpu|swap)_view_tmpl` would be replaced by corresponding color, depending on whether metric value falls in particular threshold.
|
||||
|
||||
### 256 color palette support
|
||||
|
||||
For 256 color palette support, make sure that `tmux` and parent terminal are configured with correct terminal type. See [here](https://unix.stackexchange.com/questions/1045/getting-256-colors-to-work-in-tmux) and [there](https://github.com/tmux/tmux/wiki/FAQ)
|
||||
|
||||
```
|
||||
# ~/.tmux.conf
|
||||
set -g default-terminal "screen-256color"
|
||||
```
|
||||
|
||||
```
|
||||
# parent terminal
|
||||
$ echo $TERM
|
||||
xterm-256color
|
||||
|
||||
# jump into a tmux session
|
||||
$ tmux new
|
||||
$ echo $TERM
|
||||
screen-256color
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Multiple colors for each threshold
|
||||
|
||||
You can have up to *3* colors configured for each threshold. To understand why you might need this, let tackle this task. Note, this is rather advanced use case.
|
||||
|
||||
> I want `CPU: #{cpu.pused}` metric output, have green and yellow text colors at "low" and "medium" threshold, and finally, for "high" threshold, I want to use red color, but reverse foreground and background, that is use red for background, and white for text. More over I want "CPU:" text colored apart in red
|
||||
|
||||
Like this:
|
||||
|
||||

|
||||
|
||||
You can achieve the result using following configuration:
|
||||
|
||||
```
|
||||
set -g @sysstat_cpu_view_tmpl '#[fg=#{cpu.color3}]CPU:#[default] #[fg=#{cpu.color},bg=#{cpu.color2}]#{cpu.pused}#[default]'
|
||||
|
||||
set -g @sysstat_cpu_color_low "$color_level_ok default default"
|
||||
set -g @sysstat_cpu_color_medium "$color_level_warn default default"
|
||||
set -g @sysstat_cpu_color_stress "white,bold $color_level_stress $color_level_stress"
|
||||
```
|
||||
|
||||
Tmux status-interval setting
|
||||
-----------------------------
|
||||
You can configure status refresh interval, increasing or reducing frequency of `tmux-plugin-sysstat` command invocations.
|
||||
|
||||
```
|
||||
set -g status-interval 5
|
||||
```
|
||||
|
||||
It's adviced to set `status-interval` to some reasonable value, like 5-10 seconds. More frequent updates (1 second) are useless, because they distract, and results in extra resource stress spent on metrics calculation itself.
|
||||
|
||||
|
||||
|
||||
Internals: CPU calculation
|
||||
--------------------------------------------------
|
||||
<span style="color: blue">**NOTE:** Stop here if you want to just use this plugin without making your feet wet. If you're hardcore tmux user and are curious about internals, keep reading</span>
|
||||
|
||||
Internally, we use `iostat` and `top` on OSX, and `vmstat` and `top` on Linux to collect metric value. Neither requires you to install extra packages. These commands are run in sampling mode to report stats every N seconds M times. First sample include average values since the system start. Second one is the average CPU per second for last N seconds (exactly what we need)
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ iostat -c 2 -w 5
|
||||
disk0 cpu load average
|
||||
KB/t tps MB/s us sy id 1m 5m 15m
|
||||
44.22 6 0.26 3 2 95 1.74 1.90 2.15
|
||||
5.47 8 0.04 4 5 91 1.84 1.92 2.16 << use this row, 2nd sample
|
||||
```
|
||||
|
||||
We align CPU calculation intervals (`-w`) with tmux status bar refresh interval (`status-interval` setting).
|
||||
|
||||
Internals: memory calculation
|
||||
----------------------------
|
||||
You might ask what we treat as `free` memory and how it's calculated.
|
||||
|
||||
### OSX
|
||||
Let's start with OSX. We use `vm_stat` command (not same as `vmstat` on Linux), which reports following data (number of memory pages, not KB):
|
||||
|
||||
```
|
||||
$ vm_stat
|
||||
Pages free: 37279
|
||||
Pages active: 1514200
|
||||
Pages inactive: 1152997
|
||||
Pages speculative: 6214
|
||||
Pages throttled: 0
|
||||
Pages wired down: 1174408
|
||||
Pages purgeable: 15405
|
||||
Pages stored in compressor: 1615663
|
||||
Pages occupied by compressor: 306717
|
||||
```
|
||||
|
||||
Total installed memory formula is:
|
||||
```
|
||||
Total = free + active + inactive + speculative + occupied by compressor + wired
|
||||
```
|
||||
|
||||
where
|
||||
- `free`, completely unused memory by the system
|
||||
- `wired`, critical information stored in RAM by system, kernel and key applications. Never swapped to the hard drive, never replaced with user-level data.
|
||||
- `active`, information currently in use or very recently used by applications. When this kind of memory is not used for long (or application is closed), it's move to inactive memory.
|
||||
- `inactive`, like buffers/cached memory in Linux. Memory for applications, which recently exited, retained for faster start-up of same application in future.
|
||||
|
||||
So the question what constitutes `free` and `used` memory. It turns out, that various monitoring and system statistics tools on OSX each calculate it differently.
|
||||
|
||||
- htop: `used = active + wired`, `free` = `total - used`
|
||||
- top. Used = `used = active + inactive + occupied by compressor + wired`; Free = `free + speculative` Resident set size (RSS) = `active`
|
||||
- OSX activity Monitor. Used = `app memory + wired + compressor`. Note, it's not clear what is app memory.
|
||||
|
||||
In general, they either treat currently used memory, which can be reclaimed in case of need (cached, inactive, occupied by compressor), as `used` or `free`.
|
||||
|
||||
It makes sense to talk about `available` memory rather than `free` one. Available memory is unused memory + any used memory which can be reclaimed for application needs.
|
||||
|
||||
So, `tmux-plugin-sysstat`, uses following formula:
|
||||
|
||||
```
|
||||
used = active + wired
|
||||
available/free = free/unused + inactive + speculative + occupied by compressor
|
||||
```
|
||||
|
||||
### Linux
|
||||
|
||||
Same thinking can be applied to Linux systems.
|
||||
|
||||
Usually commands like `free` report free/unused, used, buffers, cache memory kinds.
|
||||
|
||||
```
|
||||
$ free
|
||||
total used free shared buffers cached
|
||||
Mem: 1016464 900236 116228 21048 93448 241544
|
||||
-/+ buffers/cache: 565244 451220
|
||||
Swap: 1046524 141712 904812
|
||||
```
|
||||
|
||||
Second line indicates available memory (free + buffers + cache), with an assumption that buffers and cache can be 100% reclaimed in case of need.
|
||||
|
||||
However, we're not using free, because its output varies per system. For example on RHEL7, there is no `-/+ buffers/cache`, and `available` memory is reported in different way. We read directly from `/proc/meminfo`
|
||||
|
||||
```
|
||||
$ cat /proc/meminfo
|
||||
|
||||
MemTotal: 1016232 kB
|
||||
MemFree: 152672 kB
|
||||
MemAvailable: 637832 kB
|
||||
Buffers: 0 kB
|
||||
Cached: 529040 kB
|
||||
```
|
||||
|
||||
`tmux-plugin-sysstat` uses following formula:
|
||||
|
||||
```
|
||||
free/available = MemAvailable; // if MemAvailable present
|
||||
free/available = MemFree + Buffers + Cached;
|
||||
used = MemTotal - free/avaialble
|
||||
```
|
||||
|
||||
Using `MemAvailable` is more accurate way of getting available memory, rather than manual calculation `free + buffers + cache`, because the assumption that `buffers + cache` can be 100% reclaimed for new application needs might be wrong. When using `MemAvailable`, OS calculates available memory for you, which is apparently better and accurate approach.
|
||||
|
||||
See [this topic](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773) on more reasoning about `MemAvailable` field.
|
||||
78
tmux/plugins/tmux-plugin-sysstat/scripts/cpu.sh
Executable file
78
tmux/plugins/tmux-plugin-sysstat/scripts/cpu.sh
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -u
|
||||
set -e
|
||||
|
||||
LC_NUMERIC=C
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
source "$CURRENT_DIR/helpers.sh"
|
||||
|
||||
cpu_tmp_dir=$(tmux show-option -gqv "@sysstat_cpu_tmp_dir")
|
||||
|
||||
cpu_view_tmpl=$(get_tmux_option "@sysstat_cpu_view_tmpl" 'CPU:#[fg=#{cpu.color}]#{cpu.pused}#[default]')
|
||||
|
||||
cpu_medium_threshold=$(get_tmux_option "@sysstat_cpu_medium_threshold" "30")
|
||||
cpu_stress_threshold=$(get_tmux_option "@sysstat_cpu_stress_threshold" "80")
|
||||
|
||||
cpu_color_low=$(get_tmux_option "@sysstat_cpu_color_low" "green")
|
||||
cpu_color_medium=$(get_tmux_option "@sysstat_cpu_color_medium" "yellow")
|
||||
cpu_color_stress=$(get_tmux_option "@sysstat_cpu_color_stress" "red")
|
||||
|
||||
get_cpu_color(){
|
||||
local cpu_used=$1
|
||||
|
||||
if fcomp "$cpu_stress_threshold" "$cpu_used"; then
|
||||
echo "$cpu_color_stress";
|
||||
elif fcomp "$cpu_medium_threshold" "$cpu_used"; then
|
||||
echo "$cpu_color_medium";
|
||||
else
|
||||
echo "$cpu_color_low";
|
||||
fi
|
||||
}
|
||||
|
||||
print_cpu_usage() {
|
||||
local cpu_pused=$(get_cpu_usage_or_collect)
|
||||
local cpu_color=$(get_cpu_color "$cpu_pused")
|
||||
|
||||
local cpu_view="$cpu_view_tmpl"
|
||||
cpu_view="${cpu_view//'#{cpu.pused}'/$(printf "%.1f%%" "$cpu_pused")}"
|
||||
cpu_view="${cpu_view//'#{cpu.color}'/$(echo "$cpu_color" | awk '{ print $1 }')}"
|
||||
cpu_view="${cpu_view//'#{cpu.color2}'/$(echo "$cpu_color" | awk '{ print $2 }')}"
|
||||
cpu_view="${cpu_view//'#{cpu.color3}'/$(echo "$cpu_color" | awk '{ print $3 }')}"
|
||||
|
||||
echo "$cpu_view"
|
||||
}
|
||||
|
||||
get_cpu_usage_or_collect() {
|
||||
local collect_cpu_metric="$cpu_tmp_dir/cpu_collect.metric"
|
||||
|
||||
# read cpu metric from file, otherwise 0 as a temporary null value, until first cpu metric is collected
|
||||
[ -f "$collect_cpu_metric" ] && cat "$collect_cpu_metric" || echo "0.0"
|
||||
|
||||
start_cpu_collect_if_required >/dev/null 2>&1
|
||||
}
|
||||
|
||||
start_cpu_collect_if_required() {
|
||||
local collect_cpu_pidfile="$cpu_tmp_dir/cpu_collect.pid"
|
||||
|
||||
# check if cpu collect process is running, otherwise start it in background
|
||||
if [ -f "$collect_cpu_pidfile" ] && ps -p "$(cat "$collect_cpu_pidfile")" > /dev/null 2>&1; then
|
||||
return;
|
||||
fi
|
||||
|
||||
jobs >/dev/null 2>&1
|
||||
"$CURRENT_DIR/cpu_collect.sh" &>/dev/null &
|
||||
if [ -n "$(jobs -n)" ]; then
|
||||
echo "$!" > "${collect_cpu_pidfile}"
|
||||
else
|
||||
echo "Failed to start CPU collect job" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main(){
|
||||
print_cpu_usage
|
||||
}
|
||||
|
||||
main
|
||||
53
tmux/plugins/tmux-plugin-sysstat/scripts/cpu_collect.sh
Executable file
53
tmux/plugins/tmux-plugin-sysstat/scripts/cpu_collect.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
LC_NUMERIC=C
|
||||
|
||||
set -u
|
||||
set -e
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
source "$CURRENT_DIR/helpers.sh"
|
||||
|
||||
refresh_interval=$(get_tmux_option "status-interval" "5")
|
||||
samples_count="60"
|
||||
cpu_metric_file="$(get_tmux_option "@sysstat_cpu_tmp_dir" "/dev/null")/cpu_collect.metric"
|
||||
|
||||
get_cpu_usage() {
|
||||
if is_osx; then
|
||||
if command_exists "iostat"; then
|
||||
iostat -w "$refresh_interval" -c "$samples_count" \
|
||||
| stdbuf -o0 awk 'NR > 2 { print 100-$(NF-3); }'
|
||||
else
|
||||
top -l "$samples_count" -s "$refresh_interval" -n 0 \
|
||||
| sed -u -nr '/CPU usage/s/.*,[[:space:]]*([0-9]+[.,][0-9]*)%[[:space:]]*idle.*/\1/p' \
|
||||
| stdbuf -o0 awk '{ print 100-$0 }'
|
||||
fi
|
||||
elif ! command_exists "vmstat"; then
|
||||
if is_freebsd; then
|
||||
vmstat -n "$refresh_interval" -c "$samples_count" \
|
||||
| stdbuf -o0 awk 'NR>2 {print 100-$(NF-0)}'
|
||||
else
|
||||
vmstat -n "$refresh_interval" "$samples_count" \
|
||||
| stdbuf -o0 awk 'NR>2 {print 100-$(NF-2)}'
|
||||
fi
|
||||
else
|
||||
if is_freebsd; then
|
||||
top -d"$samples_count" \
|
||||
| sed -u -nr '/CPU:/s/.*,[[:space:]]*([0-9]+[.,][0-9]*)%[[:space:]]*id.*/\1/p' \
|
||||
| stdbuf -o0 awk '{ print 100-$0 }'
|
||||
else
|
||||
top -b -n "$samples_count" -d "$refresh_interval" \
|
||||
| sed -u -nr '/%Cpu/s/.*,[[:space:]]*([0-9]+[.,][0-9]*)[[:space:]]*id.*/\1/p' \
|
||||
| stdbuf -o0 awk '{ print 100-$0 }'
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
get_cpu_usage | while read -r value; do
|
||||
echo "$value" | tee "$cpu_metric_file"
|
||||
done
|
||||
}
|
||||
|
||||
main
|
||||
|
||||
76
tmux/plugins/tmux-plugin-sysstat/scripts/helpers.sh
Executable file
76
tmux/plugins/tmux-plugin-sysstat/scripts/helpers.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
|
||||
get_tmux_option() {
|
||||
local option="$1"
|
||||
local default_value="$2"
|
||||
local option_value="$(tmux show-option -gqv "$option")"
|
||||
if [ -z "$option_value" ]; then
|
||||
echo "$default_value"
|
||||
else
|
||||
echo "$option_value"
|
||||
fi
|
||||
}
|
||||
|
||||
set_tmux_option() {
|
||||
local option="$1"
|
||||
local value="$2"
|
||||
tmux set-option -gq "$option" "$value"
|
||||
}
|
||||
|
||||
is_osx() {
|
||||
[ $(uname) == "Darwin" ]
|
||||
}
|
||||
|
||||
is_linux(){
|
||||
[ $(uname -s) == "Linux" ]
|
||||
}
|
||||
|
||||
is_freebsd() {
|
||||
[ $(uname) == FreeBSD ]
|
||||
}
|
||||
|
||||
command_exists() {
|
||||
local command="$1"
|
||||
type "$command" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# because bash does not support floating-point math
|
||||
# but awk does
|
||||
calc() {
|
||||
local stdin;
|
||||
read -d '' -u 0 stdin;
|
||||
awk "BEGIN { print $stdin }";
|
||||
}
|
||||
|
||||
# "<" math operator which works with floats, once again based on awk
|
||||
fcomp() {
|
||||
awk -v n1="$1" -v n2="$2" 'BEGIN {if (n1<n2) exit 0; exit 1}'
|
||||
}
|
||||
|
||||
# get_mem_usage* function returns values in KiB
|
||||
# 1 - scale to KiB
|
||||
# 1024 - scale to MiB
|
||||
# 1048576 - scale to GiB
|
||||
function get_size_scale_factor(){
|
||||
local size_unit="$1"
|
||||
case "$size_unit" in
|
||||
G) echo 1048576;;
|
||||
M) echo 1024;;
|
||||
K) echo 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Depending on scale factor, change precision
|
||||
# 12612325K - no digits after floating point
|
||||
# 1261M - no digits after floating point
|
||||
# 1.1G - 1 digit after floating point
|
||||
function get_size_format(){
|
||||
local size_unit="$1"
|
||||
case "$size_unit" in
|
||||
G) echo '%.1f%s';;
|
||||
M) echo '%.0f%s';;
|
||||
K) echo '%.0f%s';;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
|
||||
28
tmux/plugins/tmux-plugin-sysstat/scripts/loadavg.sh
Executable file
28
tmux/plugins/tmux-plugin-sysstat/scripts/loadavg.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -u
|
||||
set -e
|
||||
|
||||
LC_NUMERIC=C
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
source "$CURRENT_DIR/helpers.sh"
|
||||
|
||||
loadavg_per_cpu_core=$(get_tmux_option "@sysstat_loadavg_per_cpu_core" "true")
|
||||
|
||||
get_num_of_cores(){
|
||||
is_osx && sysctl -n hw.ncpu || nproc
|
||||
}
|
||||
|
||||
main(){
|
||||
local num_cores=$([ "$loadavg_per_cpu_core" == "true" ] && get_num_of_cores || echo 1)
|
||||
|
||||
uptime | awk -v num_cores="$num_cores" '{
|
||||
sub(/,$/, "", $(NF-2));
|
||||
sub(/,$/, "", $(NF-1));
|
||||
sub(/,$/, "", $NF);
|
||||
printf "%.2f %.2f %.2f", $(NF-2)/num_cores, $(NF-1)/num_cores, $NF/num_cores
|
||||
}'
|
||||
}
|
||||
|
||||
main
|
||||
130
tmux/plugins/tmux-plugin-sysstat/scripts/mem.sh
Executable file
130
tmux/plugins/tmux-plugin-sysstat/scripts/mem.sh
Executable file
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -u
|
||||
set -e
|
||||
|
||||
LC_NUMERIC=C
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
source "$CURRENT_DIR/helpers.sh"
|
||||
|
||||
mem_view_tmpl=$(get_tmux_option "@sysstat_mem_view_tmpl" 'MEM:#[fg=#{mem.color}]#{mem.pused}#[default]')
|
||||
|
||||
mem_medium_threshold=$(get_tmux_option "@sysstat_mem_medium_threshold" "75")
|
||||
mem_stress_threshold=$(get_tmux_option "@sysstat_mem_stress_threshold" "90")
|
||||
|
||||
mem_color_low=$(get_tmux_option "@sysstat_mem_color_low" "green")
|
||||
mem_color_medium=$(get_tmux_option "@sysstat_mem_color_medium" "yellow")
|
||||
mem_color_stress=$(get_tmux_option "@sysstat_mem_color_stress" "red")
|
||||
|
||||
size_unit=$(get_tmux_option "@sysstat_mem_size_unit" "G")
|
||||
|
||||
get_mem_color() {
|
||||
local mem_pused=$1
|
||||
|
||||
if fcomp "$mem_stress_threshold" "$mem_pused"; then
|
||||
echo "$mem_color_stress";
|
||||
elif fcomp "$mem_medium_threshold" "$mem_pused"; then
|
||||
echo "$mem_color_medium";
|
||||
else
|
||||
echo "$mem_color_low";
|
||||
fi
|
||||
}
|
||||
|
||||
print_mem() {
|
||||
local mem_usage
|
||||
local scale
|
||||
local size_format
|
||||
|
||||
if is_osx; then
|
||||
mem_usage=$(get_mem_usage_osx)
|
||||
elif is_linux; then
|
||||
mem_usage=$(get_mem_usage_linux)
|
||||
elif is_freebsd; then
|
||||
mem_usage=$(get_mem_usage_freebsd)
|
||||
fi
|
||||
|
||||
local size_scale="$(get_size_scale_factor "$size_unit")"
|
||||
local size_format="$(get_size_format "$size_unit")"
|
||||
|
||||
# Extract free and used memory in MiB, calculate total and percentage
|
||||
local mem_free=$(echo $mem_usage | awk -v scale="$size_scale" '{ print $1/scale }')
|
||||
local mem_used=$(echo $mem_usage | awk -v scale="$size_scale" '{ print $2/scale }')
|
||||
local mem_total=$(echo "$mem_free + $mem_used" | calc)
|
||||
local mem_pused=$(echo "($mem_used / $mem_total) * 100" | calc)
|
||||
local mem_pfree=$(echo "($mem_free / $mem_total) * 100" | calc)
|
||||
|
||||
# Calculate colors for mem and swap
|
||||
local mem_color=$(get_mem_color "$mem_pused")
|
||||
|
||||
local mem_view="$mem_view_tmpl"
|
||||
mem_view="${mem_view//'#{mem.used}'/$(printf "$size_format" "$mem_used" "$size_unit")}"
|
||||
mem_view="${mem_view//'#{mem.pused}'/$(printf "%.0f%%" "$mem_pused")}"
|
||||
mem_view="${mem_view//'#{mem.free}'/$(printf "$size_format" "$mem_free" "$size_unit")}"
|
||||
mem_view="${mem_view//'#{mem.pfree}'/$(printf "%.0f%%" "$mem_pfree")}"
|
||||
mem_view="${mem_view//'#{mem.total}'/$(printf "$size_format" "$mem_total" "$size_unit")}"
|
||||
mem_view="${mem_view//'#{mem.color}'/$(echo "$mem_color" | awk '{ print $1 }')}"
|
||||
mem_view="${mem_view//'#{mem.color2}'/$(echo "$mem_color" | awk '{ print $2 }')}"
|
||||
mem_view="${mem_view//'#{mem.color3}'/$(echo "$mem_color" | awk '{ print $3 }')}"
|
||||
|
||||
echo "$mem_view"
|
||||
}
|
||||
|
||||
|
||||
# Report like it does htop on OSX:
|
||||
# used = active + wired
|
||||
# free = free + inactive + speculative + occupied by compressor
|
||||
# see `vm_stat` command
|
||||
get_mem_usage_osx(){
|
||||
|
||||
local page_size=$(sysctl -nq "vm.pagesize")
|
||||
vm_stat | awk -v page_size=$page_size -F ':' '
|
||||
BEGIN { free=0; used=0 }
|
||||
|
||||
/Pages active/ ||
|
||||
/Pages wired/ {
|
||||
gsub(/^[ \t]+|[ \t]+$/, "", $2); used+=$2;
|
||||
}
|
||||
/Pages free/ ||
|
||||
/Pages inactive/ ||
|
||||
/Pages speculative/ ||
|
||||
/Pages occupied by compressor/ {
|
||||
gsub(/^[ \t]+|[ \t]+$/, "", $2); free+=$2;
|
||||
}
|
||||
|
||||
END { print (free * page_size)/1024, (used * page_size)/1024 }
|
||||
'
|
||||
}
|
||||
|
||||
# Relies on vmstat, but could also be done with top on FreeBSD
|
||||
get_mem_usage_freebsd(){
|
||||
vmstat -H | tail -n 1 | awk '{ print $5, $4 }'
|
||||
}
|
||||
|
||||
# Method #1. Sum up free+buffers+cached, treat it as "available" memory, assuming buff+cache can be reclaimed. Note, that this assumption is not 100% correct, buff+cache most likely cannot be 100% reclaimed, but this is how memory calculation is used to be done on Linux
|
||||
|
||||
# Method #2. If "MemAvailable" is provided by system, use it. This is more correct method, because we're not relying on fragile "free+buffer+cache" equation.
|
||||
|
||||
# See: Interpreting /proc/meminfo and free output for Red Hat Enterprise Linux 5, 6 and 7 - Red Hat Customer Portal - https://access.redhat.com/solutions/406773
|
||||
|
||||
# See: kernel/git/torvalds/linux.git - /proc/meminfo: provide estimated available memory - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
|
||||
get_mem_usage_linux(){
|
||||
</proc/meminfo awk '
|
||||
BEGIN { total=0; free=0; }
|
||||
/MemTotal:/ { total=$2; }
|
||||
|
||||
/MemFree:/ { free+=$2; }
|
||||
/Buffers:/ { free+=$2; }
|
||||
/Cached:/ { free+=$2; }
|
||||
|
||||
/MemAvailable:/ { free=$2; exit;}
|
||||
END { print free, total-free }
|
||||
'
|
||||
}
|
||||
|
||||
main() {
|
||||
print_mem
|
||||
}
|
||||
|
||||
main
|
||||
|
||||
95
tmux/plugins/tmux-plugin-sysstat/scripts/swap.sh
Executable file
95
tmux/plugins/tmux-plugin-sysstat/scripts/swap.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -u
|
||||
set -e
|
||||
|
||||
LC_NUMERIC=C
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
source "$CURRENT_DIR/helpers.sh"
|
||||
|
||||
swap_view_tmpl=$(get_tmux_option "@sysstat_swap_view_tmpl" 'SW:#[fg=#{swap.color}]#{swap.pused}#[default]')
|
||||
|
||||
swap_medium_threshold=$(get_tmux_option "@sysstat_swap_medium_threshold" "25")
|
||||
swap_stress_threshold=$(get_tmux_option "@sysstat_swap_stress_threshold" "75")
|
||||
|
||||
swap_color_low=$(get_tmux_option "@sysstat_swap_color_low" "green")
|
||||
swap_color_medium=$(get_tmux_option "@sysstat_swap_color_medium" "yellow")
|
||||
swap_color_stress=$(get_tmux_option "@sysstat_swap_color_stress" "red")
|
||||
|
||||
size_unit=$(get_tmux_option "@sysstat_swap_size_unit" "G")
|
||||
|
||||
get_swap_color() {
|
||||
local swap_pused=$1
|
||||
|
||||
if fcomp "$swap_stress_threshold" "$swap_pused"; then
|
||||
echo "$swap_color_stress";
|
||||
elif fcomp "$swap_medium_threshold" "$swap_pused"; then
|
||||
echo "$swap_color_medium";
|
||||
else
|
||||
echo "$swap_color_low";
|
||||
fi
|
||||
}
|
||||
|
||||
print_swap() {
|
||||
local swap_usage
|
||||
|
||||
|
||||
if is_osx; then
|
||||
swap_usage=$(get_swap_usage_osx)
|
||||
elif is_linux; then
|
||||
swap_usage=$(get_swap_usage_linux)
|
||||
fi
|
||||
|
||||
local size_scale="$(get_size_scale_factor "$size_unit")"
|
||||
local size_format="$(get_size_format "$size_unit")"
|
||||
|
||||
# Extract swap free and used in MiB, calculate total and percentage
|
||||
local swap_free=$(echo $swap_usage | awk -v scale="$size_scale" '{ print $1/scale }')
|
||||
local swap_used=$(echo $swap_usage | awk -v scale="$size_scale" '{ print $2/scale }')
|
||||
local swap_total=$(echo "$swap_free + $swap_used" | calc)
|
||||
local swap_pused=$(echo "($swap_used / $swap_total) * 100" | calc)
|
||||
local swap_pfree=$(echo "($swap_free / $swap_total) * 100" | calc)
|
||||
|
||||
# Calculate colors for mem and swap
|
||||
local swap_color=$(get_swap_color "$swap_pused")
|
||||
|
||||
local swap_view="$swap_view_tmpl"
|
||||
swap_view="${swap_view//'#{swap.used}'/$(printf "$size_format" "$swap_used" "$size_unit")}"
|
||||
swap_view="${swap_view//'#{swap.pused}'/$(printf "%.0f%%" "$swap_pused")}"
|
||||
swap_view="${swap_view//'#{swap.free}'/$(printf "$size_format" "$swap_free" "$size_unit")}"
|
||||
swap_view="${swap_view//'#{swap.pfree}'/$(printf "%.0f%%" "$swap_pfree")}"
|
||||
swap_view="${swap_view//'#{swap.total}'/$(printf "$size_format" "$swap_total" "$size_unit")}"
|
||||
swap_view="${swap_view//'#{swap.color}'/$(echo "$swap_color" | awk '{ print $1 }')}"
|
||||
swap_view="${swap_view//'#{swap.color2}'/$(echo "$swap_color" | awk '{ print $2 }')}"
|
||||
swap_view="${swap_view//'#{swap.color3}'/$(echo "$swap_color" | awk '{ print $3 }')}"
|
||||
|
||||
echo "$swap_view"
|
||||
}
|
||||
|
||||
get_swap_usage_osx(){
|
||||
|
||||
# assume swap size in MB
|
||||
local swap_used=$(sysctl -nq vm.swapusage | awk -F ' ' '{ print $2 }' | awk -F '=' '{gsub(/^[ ]|[M]$/, "", $2); printf "%d", $2 * 1024 }')
|
||||
local swap_free=$(sysctl -nq vm.swapusage | awk -F ' ' '{ print $3 }' | awk -F '=' '{gsub(/^[ ]|[M]$/, "", $2); printf "%d", $2 * 1024 }')
|
||||
|
||||
printf "%s %s" "$swap_free" "$swap_used"
|
||||
}
|
||||
|
||||
get_swap_usage_linux(){
|
||||
</proc/meminfo awk '
|
||||
BEGIN { total=0; free=0; }
|
||||
/SwapTotal:/ { total=$2; }
|
||||
/SwapFree:/ { free=$2; }
|
||||
END { print free, total-free }
|
||||
'
|
||||
}
|
||||
|
||||
main() {
|
||||
print_swap
|
||||
}
|
||||
|
||||
main
|
||||
|
||||
|
||||
|
||||
43
tmux/plugins/tmux-plugin-sysstat/sysstat.tmux
Executable file
43
tmux/plugins/tmux-plugin-sysstat/sysstat.tmux
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
source "$CURRENT_DIR/scripts/helpers.sh"
|
||||
|
||||
placeholders=(
|
||||
"\#{sysstat_cpu}"
|
||||
"\#{sysstat_mem}"
|
||||
"\#{sysstat_swap}"
|
||||
"\#{sysstat_loadavg}"
|
||||
)
|
||||
|
||||
commands=(
|
||||
"#($CURRENT_DIR/scripts/cpu.sh)"
|
||||
"#($CURRENT_DIR/scripts/mem.sh)"
|
||||
"#($CURRENT_DIR/scripts/swap.sh)"
|
||||
"#($CURRENT_DIR/scripts/loadavg.sh)"
|
||||
)
|
||||
|
||||
do_interpolation() {
|
||||
local all_interpolated="$1"
|
||||
for ((i=0; i<${#commands[@]}; i++)); do
|
||||
all_interpolated=${all_interpolated//${placeholders[$i]}/${commands[$i]}}
|
||||
done
|
||||
echo "$all_interpolated"
|
||||
}
|
||||
|
||||
update_tmux_option() {
|
||||
local option="$1"
|
||||
local option_value="$(get_tmux_option "$option")"
|
||||
local new_option_value="$(do_interpolation "$option_value")"
|
||||
set_tmux_option "$option" "$new_option_value"
|
||||
}
|
||||
|
||||
main() {
|
||||
cpu_tmp_dir=$(mktemp -d)
|
||||
tmux set-option -gq "@sysstat_cpu_tmp_dir" "$cpu_tmp_dir"
|
||||
|
||||
update_tmux_option "status-right"
|
||||
update_tmux_option "status-left"
|
||||
}
|
||||
|
||||
main
|
||||
Reference in New Issue
Block a user