Created
September 17, 2014 20:02
-
-
Save angrycub/79ee6be7ee8264a2ff3c to your computer and use it in GitHub Desktop.
This grabs the same OS commands as we use in riak-debug without any Riak specific commands.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
## ------------------------------------------------------------------- | |
## | |
## riak-debug-lite: Gather info from a node for troubleshooting. | |
## | |
## Copyright (c) 2013 Basho Technologies, Inc. All Rights Reserved. | |
## | |
## This file is provided to you under the Apache License, | |
## Version 2.0 (the "License"); you may not use this file | |
## except in compliance with the License. You may obtain | |
## a copy of the License at | |
## | |
## http://www.apache.org/licenses/LICENSE-2.0 | |
## | |
## Unless required by applicable law or agreed to in writing, | |
## software distributed under the License is distributed on an | |
## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
## KIND, either express or implied. See the License for the | |
## specific language governing permissions and limitations | |
## under the License. | |
## | |
## ------------------------------------------------------------------- | |
# If you start to think "We should execute some Erlang in here", then go work | |
# on Riaknostic, which is called with `riak-admin diag` below. | |
# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is. | |
if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then | |
POSIX_SHELL="true" | |
export POSIX_SHELL | |
# To support 'whoami' add /usr/ucb to path | |
PATH=/usr/ucb:$PATH | |
export PATH | |
exec /usr/bin/ksh $0 "$@" | |
fi | |
unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well | |
### | |
### Function declarations | |
### | |
echoerr () { echo "$@" 1>&2; } | |
mkdir_or_die () { | |
# If the dir already exists, just return | |
[ -d "$1" ] && return | |
mkdir -p "$1" | |
if [ 0 -ne $? ]; then | |
echoerr "Error creating riak-debug directories. Aborting." | |
echoerr "$1" | |
exit 1 | |
fi | |
} | |
dump () { | |
# first argument is the filename to hold the command output | |
out=$1 | |
shift | |
# next argument is the base command to execute. skip dump if not available. | |
[ -z "`command -v $1`" ] && return | |
# execute the rest of the arguments as the command | |
$* >> "$out" 2>&1 | |
# grab the return value | |
retval=$? | |
# put the command and the retval in the .info/$out file to aid automation. | |
# note: this will miss some escaping for, e.g., find, but it's not critical. | |
# get command that was run with `head -1 .info/$out` | |
# get return value from command with `tail -1 .info/$out` | |
echo "$*" > .info/"$out" | |
echo $retval >> .info/"$out" | |
if [ 0 -eq $retval ]; then | |
printf '.' 1>&2 | |
else | |
printf 'E' 1>&2 | |
fi | |
return $retval | |
} | |
usage () { | |
cat << 'EOF' | |
riak-debug: Gather info from a node for troubleshooting. See 'man riak-debug'. | |
Usage: riak-debug-lite [-s] [-e] [FILENAME | -] | |
-h, --help Help - you are here. | |
-s, --syscmds Gather general system commands. | |
FILENAME Output filename for the tar.gz archive. Use - to specify stdout. | |
Defaults: Get system commands. | |
Output in current directory to NODE_NAME-riak-debug.tar.gz or | |
HOSTNAME-riak-debug.tar.gz if NODE_NAME cannot be found. | |
EOF | |
exit | |
} | |
### | |
### Set up variables | |
### | |
get_syscmds=0 | |
### | |
### Parse options | |
### | |
while [ -n "$1" ]; do | |
case "$1" in | |
-h|--help) | |
usage | |
;; | |
-s|--syscmds) | |
get_syscmds=1 | |
;; | |
-) | |
# If truly specifying stdout as the output file, it should be last | |
if [ $# -gt 1 ]; then | |
echoerr "Trailing options following filename $1. Aborting." | |
echoerr "See 'riak-debug -h' and manpage for help." | |
exit 1 | |
fi | |
outfile="-" | |
;; | |
*) | |
# Shouldn't get here until the last option, the output filename. | |
if [ '-' = "$outfile" ]; then | |
echoerr "Filename $1 given but stdout, -, already specified." | |
echoerr "Aborting. See 'riak-debug -h' and manpage for help." | |
exit 1 | |
fi | |
# The filename shouldn't start with a '-'. The single character '-' | |
# is handled as a special case above. | |
if [ '-' = `echo "$1" | awk 'BEGIN {FS=""} {print $1}'` ]; then | |
echoerr "Unrecognized option $1. Aborting" | |
echoerr "See 'riak-debug -h' and manpage for help." | |
exit 1 | |
fi | |
if [ $# -gt 1 ]; then | |
echoerr "Trailing options following filename $1. Aborting." | |
echoerr "See 'riak-debug -h' and manpage for help." | |
exit 1 | |
fi | |
outfile="$1" | |
;; | |
esac | |
shift | |
done | |
### | |
### Finish setting up variables and overrides | |
### | |
if [ 0 -eq $(($get_syscmds)) ]; then | |
# Nothing specific was requested, so get everything except extracmds | |
get_syscmds=1 | |
fi | |
start_dir="$TMPDIR" | |
if [ -z "$start_dir" ]; then | |
start_dir=/tmp | |
fi | |
# Strip any trailing slash from TMPDIR | |
start_dir="`echo $start_dir | sed 's#/$##'`" | |
debug_dir="`hostname`-riak-debug" | |
if [ -d "${start_dir}"/"${debug_dir}" ]; then | |
echoerr "Temporary directory already exists. Aborting." | |
echoerr "${start_dir}"/"${debug_dir}" | |
exit 1 | |
fi | |
if [ -z "$outfile" ]; then | |
# If output file not specified, output to the default | |
outfile="`pwd`"/"${debug_dir}".tar.gz | |
fi | |
if [ '-' != "$outfile" ] && [ -f "$outfile" ]; then | |
echoerr "Output file already exists. Aborting." | |
echoerr "$outfile" | |
exit 1 | |
fi | |
### | |
### Gather system commands | |
### | |
if [ 1 -eq $get_syscmds ]; then | |
mkdir_or_die "${start_dir}"/"${debug_dir}"/commands/.info | |
cd "${start_dir}"/"${debug_dir}"/commands | |
# System info | |
dump date date | |
dump w w | |
dump last last | |
dump hostname hostname | |
dump uname uname -a | |
dump lsb_release lsb_release | |
dump ps ps aux | |
dump vmstat vmstat 1 5 | |
dump free free -m | |
dump df df | |
dump df_i df -i | |
dump dmesg dmesg | |
dump mount mount | |
dump sysctl sysctl -a | |
dump rpm rpm -qa | |
dump dpkg dpkg -l | |
dump pkg_info pkg_info | |
dump sestatus sestatus -v | |
dump ifconfig ifconfig -a | |
dump netstat_i netstat -i | |
dump netstat_an netstat -an | |
dump netstat_rn netstat -rn | |
dump pfctl_rules pfctl -s rules | |
dump pfctl_nat pfctl -s nat | |
# If swapctl exists, prefer it over swapon | |
if [ -n "`command -v swapctl`" ]; then | |
dump swapctl swapctl -s | |
else | |
dump swapon swapon -s | |
fi | |
BLOCKDEV=/sbin/blockdev | |
if [ -e $BLOCKDEV ]; then | |
for mount_point in `mount | egrep '^/' | awk '{print $1}'`; do | |
flat_point=`echo $mount_point | sed 's:/:_:g'` | |
dump blockdev.$flat_point $BLOCKDEV --getra $mount_point | |
done | |
else | |
dump blockdev._ echo $BLOCKDEV is not available | |
fi | |
# Running iptables commands if the module is not loaded can automatically | |
# load them. This is rarely desired and can even cause connectivity | |
# problems if, e.g., nf_conntrack gets autoloaded and autoenabled. | |
if [ -n "`command -v lsmod`" ]; then | |
if [ -n "`lsmod 2>/dev/null | awk '{print $1}' | grep iptable_filter`" ]; then | |
dump iptables_rules iptables -n -L | |
else | |
dump iptables_rules echo "iptables module not loaded" | |
fi | |
if [ -n "`lsmod 2>/dev/null | awk '{print $1}' | grep nf_conntrack`" ]; then | |
dump iptables_nat iptables -t nat -n -L | |
else | |
dump iptables_nat echo "nf_conntrack module not loaded" | |
fi | |
fi | |
if [ -f /proc/diskstats ]; then | |
# Linux iostat | |
dump iostat_linux iostat -mx 1 5 | |
elif [ -d /proc ]; then | |
# No diskstats, but proc, probably Solaris or SmartOS | |
dump iostat_smartos iostat -xnz 1 5 | |
else | |
# BSD style iostat | |
dump iostat_bsd iostat -dIw 1 -c 5 | |
fi | |
# Dump files | |
[ -f /etc/release ] && dump release cat /etc/release | |
[ -f /etc/redhat-release ] && dump redhat_release cat /etc/redhat-release | |
[ -f /etc/debian_version ] && dump debian_version cat /etc/debian_version | |
[ -f /etc/security/limits.conf ] && dump limits.conf cat /etc/security/limits.conf | |
[ -f /var/log/messages ] && dump messages cat /var/log/messages | |
[ -f /var/log/syslog ] && dump messages cat /var/log/syslog | |
[ -f /proc/diskstats ] && dump diskstats cat /proc/diskstats | |
[ -f /proc/cpuinfo ] && dump cpuinfo cat /proc/cpuinfo | |
[ -f /proc/meminfo ] && dump meminfo cat /proc/meminfo | |
# Dump directories and finds | |
[ -d /dev/disk/by-id ] && dump disk_by_id ls -l /dev/disk/by-id | |
[ -d /sys/block ] && dump schedulers find /sys/block/ -type l -print -exec cat {}/queue/scheduler \; | |
[ -d /proc/net/bonding ] && dump bonding find /proc/net/bonding/ -type f -print -exec cat {} \; | |
[ -d /sys/class/net ] && dump rx_crc_errors find /sys/class/net/ -type l -print -exec cat {}/statistics/rx_crc_errors \; | |
# A bit more complicated, but let's get all of limits.d if it's there | |
if [ -d /etc/security/limits.d ]; then | |
# check to ensure there is at least something to get | |
if [ -n "`find /etc/security/limits.d -maxdepth 1 -name '*.conf' -print -quit`" ]; then | |
mkdir_or_die "${start_dir}"/"${debug_dir}"/commands/limits.d | |
# Mirror the directory, only copying files that match the pattern | |
cd /etc/security/limits.d | |
find . -type f -name '*.conf' -exec sh -c ' | |
mkdir -p "$0/${1%/*}"; | |
cp "$1" "$0/$1" | |
' "${start_dir}"/"${debug_dir}"/commands/limits.d {} \; | |
fi | |
fi | |
fi | |
### | |
### Produce the output file | |
### | |
# One last sanity check before transferring or removing anything | |
cd "${start_dir}" | |
if [ -z "$debug_dir" ] || [ ! -d "$debug_dir" ]; then | |
echoerr "Couldn't find ${start_dir}/${debug_dir}. Aborting" | |
exit 1 | |
fi | |
if [ '-' = "$outfile" ]; then | |
# So we don't get a file literally named - | |
tar zcf - "${debug_dir}" | |
else | |
tar zcf "$outfile" "${debug_dir}" | |
# provide some indication of the output filename | |
printf " $outfile" 1>&2 | |
fi | |
rm -rf "${debug_dir}" | |
# keep things looking pretty | |
echoerr "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment