| #!/bin/sh |
| |
| . /etc/utils.sh |
| |
| DELAY="$1" # if empty, run only once |
| |
| printstat() |
| { |
| local result="$1" |
| shift |
| |
| "$@" | sort -rn | head -n 5 | ( |
| while read val comm arg0 arg1 junk; do |
| [ "$comm" = "python" ] && comm=${arg1##/*/} # use the .py script name |
| result="$result $comm($val)" |
| done; |
| echo "$result" |
| ) |
| } |
| |
| |
| freemem() |
| { |
| free | ( |
| read header |
| read h1 total junk |
| read h2a h2b real_used real_free junk |
| echo "$1 total=$total used=$real_used free=$real_free" |
| ) |
| } |
| |
| |
| dfspace() |
| { |
| df -k | { |
| out= |
| read header |
| while read dev blocks used avail percent fs junk; do |
| if [ "$used" != 0 ]; then |
| out="$out$fs:$used " |
| fi |
| done |
| echo "$1 $out" |
| } |
| } |
| |
| |
| carriers() |
| { |
| ip link show | { |
| out= |
| while IFS=': ' read n ifc flags smtu mtu sdisc disc sstate state junk; do |
| if [ "$smtu $sdisc $sstate" = "mtu qdisc state" ]; then |
| out="$out$ifc($state) " |
| fi |
| done |
| echo "$1 $out" |
| } |
| } |
| |
| |
| contains() |
| { |
| [ "$1" != "${1#.*$2}" ] |
| } |
| |
| |
| ip_only() |
| { |
| while read ip junk; do |
| contains "$ip" ":" || echo "$ip" "$junk" |
| done |
| } |
| |
| |
| ip6_only() |
| { |
| while read ip junk; do |
| contains "$ip" ":" && echo "$ip" "$junk" |
| done |
| } |
| |
| |
| nameservers() |
| { |
| grep '^nameserver' /etc/resolv.conf | while read ns ip junk; do |
| echo "$ip" |
| done |
| } |
| |
| |
| defaultroutes() |
| { |
| ip "$@" route list | while read a b IP c IF d; do |
| if [ "$a $b" = "default via" ]; then |
| if startswith "$IP" "fe80:"; then |
| # IPV6 link-local address, return IP and interface |
| echo "$IP,$IF" |
| else |
| echo "$IP" |
| fi |
| fi |
| done |
| } |
| |
| |
| do_ping() |
| { |
| VER=$1 |
| IP=$2 |
| shift 2 |
| ping$VER -n -c1 -w5 "$@" $IP 2>&1 | { |
| while read nbytes bytes from ip serial ttl time ms; do |
| if [ "$bytes $from $ms" = "bytes from ms" ]; then |
| echo "${time#time=}ms/${ttl#ttl=}ttl" |
| exit |
| fi |
| done |
| echo "ERR" |
| } |
| } |
| |
| |
| pings() |
| { |
| out= |
| for ip in \ |
| 127.0.0.1 \ |
| $(defaultroutes) \ |
| $(nameservers | ip_only) \ |
| gstatic.com |
| do |
| out="$out$ip($(do_ping "" $ip)) " |
| done |
| echo "$1 $out" |
| } |
| |
| |
| pings6() |
| { |
| out= |
| for ip_if in \ |
| ::1 \ |
| $(defaultroutes -6) \ |
| $(nameservers | ip6_only) \ |
| gstatic.com |
| do |
| out=$out$(echo "$ip_if" | while IFS=, read ip if; do |
| if [ -n "$if" ]; then |
| echo "$ip($(do_ping "6" $ip -I $if)) " |
| else |
| echo "$ip($(do_ping "6" $ip)) " |
| fi |
| done) |
| done |
| echo "$1 $out" |
| } |
| |
| |
| gstatics() |
| { |
| gs=$(gstatic) |
| rv=$? |
| echo "$gs" | while read ip stat; do |
| echo -n "$ip($stat) " |
| done |
| echo |
| return $rv |
| } |
| |
| while :; do |
| # time used by each process, followed by cumulative time (which includes |
| # children, including already terminated ones). Note that the 'cputime' |
| # format doesn't work with --cumulative, so we need to use bsdtime instead. |
| printstat "cputop:" ps --no-headers -e -o bsdtime,comm,cmd |
| printstat "ccputop:" ps --no-headers --cumulative -e -o bsdtime,comm,cmd |
| |
| printstat "memtop:" ps --no-headers -e -o rss,comm,cmd |
| echo "loadavg: $(cat /proc/loadavg)" |
| freemem "mem:" |
| dfspace "df:" |
| carriers "carriers:" |
| |
| # these can cause network activity, so /tmp/disable_pings is a way to |
| # stop it if it's getting annoying or causing trouble. |
| if [ ! -e /tmp/disable_pings ]; then |
| echo "gstatic: $(gstatics)" |
| pings "ping:" "$gs_retval" |
| pings6 "ping6:" "$gs_retval" |
| runnable find-servers && echo "find-servers: $(find-servers)" |
| echo "dns: $(dnsck 8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844)" |
| fi |
| |
| if [ -n "$DELAY" ]; then |
| sleep "$DELAY" || exit 1 |
| else |
| break |
| fi |
| done |