aboutsummaryrefslogtreecommitdiff
path: root/scripts/rc-sstat.in
blob: a204dbdafbc729203d2461a4d5580780e2d6e9f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!@SHELL@
# Copyright (c) 2015 The OpenRC Authors.
# See the Authors file at the top-level directory of this distribution and
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
#
# This file is part of OpenRC. It is subject to the license terms in
# the LICENSE file found in the top-level directory of this
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
# This file may not be copied, modified, propagated, or distributed
#    except according to the terms contained in the LICENSE file.

# Define variables
scandir="/run/openrc/s6-scan"
statfile=/dev/shm/s6-svstat.${USER}

color_red='\E[01;31m'
color_green='\E[32m'
color_yellow='\E[01;33m'

# Time Modules
uptimeModules() {
	# Given a single integer argument representing seconds of uptime...
	# convert uptime to a friendly human readable string: '2d 16h 58m 46s'
	# define a variable to keep track of the longest length uptime string
	uSec=${1:-0}

	uDay=$(( $uSec / 86400 ))
	uSec=$(( $uSec % 86400 ))
	uHour=$(( $uSec / 3600 ))
	uSec=$(( $uSec % 3600 ))
	uMin=$(( $uSec / 60 ))
	uSec=$(( $uSec % 60 ))

	[ $uDay -ne 0 ] && pDay="${uDay}d " || pDay=""
	[ $uHour -ne 0 ] && pHour="${uHour}h " || pHour=""
	[ $uMin -ne 0 ] && pMin="${uMin}m " || pMin=""
	[ $uSec -ne 0 ] && pSec="${uSec}s " || pSec=""

	parsedUptime="$( echo ${pDay}${pHour}${pMin}${pSec} | sed 's#[ \t]*$##' )"
	uCharCount=${#parsedUptime}
}

# Make sure we are running as root
if [ $(id -u) != 0 ]; then
	printf "This command must be run as root\n"
	exit 1
fi

# Make sure scandir exists
if [ ! -d $scandir ]; then
	printf "%s\n" "$scandir does not exist"
	exit 1
fi

# Make sure s6-svscan is running
if ! pgrep s6-svscan >/dev/null ; then
	printf "s6-svscan is not running\n"
	exit 1
fi

# If TERM is undefined (launching sstat through an ssh command) then make it vt100
if [ -z $TERM -o $TERM = "dumb" ]; then
	export TERM=vt100
fi

# Gather list of candidate services s6-supervise may be supervising
# filter for folders and symlinks at /run/openrc/s6-scan/* ommiting output starting with '.'
services="$(find $scandir -maxdepth 1 -mindepth 1 \( -type d -or -type l \) | awk -F'/' '{ if ( $NF !~ "^\\." ) print $NF}')"
if [ -z "$services" ]; then
	printf "s6 found no services configured for supervision\n"
	exit 1
fi

# Gather status for each service from s6-svstat
# write to tmp file in memory for non I/O bound repeatative access
rm -f $statfile 2>/dev/null
for service in $services ; do
	echo "$service $(s6-svstat ${scandir}/${service})" >> $statfile
done

# Define longest string from parsed uptime (default to 7 to match string length of 'Up Time')
timeStringLength=7
for uptime in $(awk '$2 == "up" {print $5}' $statfile | sort -run)
do
	uptimeModules $uptime
	[ ${uCharCount} -gt $timeStringLength ] && timeStringLength=$uCharCount
done


#   Print the status header like so...
#                Service Name  State    PID         Up Time           Start Time
#----------------------------  -----  -----  --------------  -------------------
printf "\n"
printf "%28s  %5s  %5s  %${timeStringLength}s  %19s\n" "Service Name" "State" "PID" "Up Time" "Start Time"
for dashes in 28 5 5 $timeStringLength 19 ; do
	printf "%0.s-" $(seq 1 $dashes) ; echo -n '  '
done && printf "\n"


#   sshd up (pid 26300) 80373 seconds
cat $statfile | \
while read line
do
	set $line

	service=$1
	state=$2
	pid=${4/)/}
	time=$5

	# call function to convert time in seconds and define additional variables
	uptimeModules $time

	if [ "$state" = up ]; then
		if [ $time -lt 30 ]; then
			# uptime < 30 seconds, color the whole line yellow
			echo -en "$color_yellow"
			# 1st 4 columns are printed with printf for space padding
			printf "%28s  %5s  %5s  %${timeStringLength}s" $service $state $pid "$parsedUptime"
			# 4th column is output from date -d
			echo -e "  $(date -d "${time} seconds ago" "+%F %T")"
			# reset terminal colors
			tput sgr0
		else
			printf "%28s" $service
			# uptime > 30 seconds, color just the "state" value green
			echo -en "$color_green"
			printf "  %5s" $state
			# reset terminal colors
			tput sgr0
			printf "  %5s" $pid
			printf "  %${timeStringLength}s"  "$parsedUptime"
			echo -e "  $(date -d "${time} seconds ago" "+%F %T")"
		fi
	else
		printf "%28s" $service
		echo -en "$color_red"
		printf "  %5s" $state
		tput sgr0
		echo ""
	fi
done

# Cleanup
rm -f $statfile 2>/dev/null

printf "\n\n"

rc-status