Skip to content

Commit d298f66

Browse files
emmatypingchadwhitacrehubertdeng123
authored
Error monitoring of the self-hosted installer (#1679)
This is the MVP of error monitoring of the self-hosted installer. We have: - Added a prompt for users to opt into error reporting - Rewritten the traceback code to give a full stack trace - Hooked up sending errors to our self-hosted instance Fixes #740 Co-authored-by: Chad Whitacre <[email protected]> Co-authored-by: hubertdeng123 <[email protected]>
1 parent 013519a commit d298f66

File tree

4 files changed

+99
-5
lines changed

4 files changed

+99
-5
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Error reporting choice cache
2+
.reporterrors
3+
14
# Byte-compiled / optimized / DLL files
25
__pycache__/
36
*.py[cod]

install.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env bash
2-
set -e
2+
set -eE
33

44
# Pre-pre-flight? 🤷
55
if [[ -n "$MSYSTEM" ]]; then
@@ -14,6 +14,8 @@ source parse-cli.sh
1414
source detect-platform.sh
1515
source dc-detect-version.sh
1616
source error-handling.sh
17+
# We set the trap at the top level so that we get better tracebacks.
18+
trap_with_arg cleanup ERR INT TERM EXIT
1719
source check-latest-commit.sh
1820
source check-minimum-requirements.sh
1921

install/error-handling.sh

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,112 @@
11
echo "${_group}Setting up error handling ..."
22

3+
export SENTRY_DSN='https://[email protected]/3'
4+
export SENTRY_ORG=self-hosted
5+
export SENTRY_PROJECT=installer
6+
export REPORT_ERRORS=0
7+
8+
function send_event {
9+
local sentry_cli="docker run --rm -v $basedir:/work -e SENTRY_ORG=$SENTRY_ORG -e SENTRY_PROJECT=$SENTRY_PROJECT -e SENTRY_DSN=$SENTRY_DSN getsentry/sentry-cli"
10+
command pushd .. > /dev/null
11+
$sentry_cli send-event --no-environ -f "$1" -m "$2" --logfile $log_file
12+
command popd > /dev/null
13+
}
14+
15+
reporterrors="$basedir/.reporterrors"
16+
if [[ -f $reporterrors ]]; then
17+
echo -n "Found a .reporterrors file. What does it say? "
18+
cat $reporterrors
19+
if [[ "$(cat $reporterrors)" == "yes" ]]; then
20+
export REPORT_ERRORS=1
21+
else
22+
export REPORT_ERRORS=0
23+
fi
24+
else
25+
echo
26+
echo "Hey, so ... we would love to find out when you hit an issue with this here"
27+
echo "installer you are running. Turns out there is an app for that, called Sentry."
28+
echo "Are you okay with us sending info to Sentry when you run this installer?"
29+
echo
30+
echo " y / yes / 1"
31+
echo " n / no / 0"
32+
echo
33+
echo "(Btw, we send this to our own self-hosted Sentry instance, not to Sentry SaaS,"
34+
echo "so that we can be in this together.)"
35+
echo
36+
echo "Here's the info we may collect in order to help us improve the installer:"
37+
echo
38+
echo " - OS username"
39+
echo " - IP address"
40+
echo " - install log"
41+
echo " - performance data"
42+
echo
43+
echo "Thirty (30) day retention. No marketing. Privacy policy at sentry.io/privacy."
44+
echo
45+
46+
yn=""
47+
until [ ! -z "$yn" ]
48+
do
49+
read -p "y or n? " yn
50+
case $yn in
51+
y | yes | 1) export REPORT_ERRORS=1; echo "yes" > $reporterrors; echo; echo -n "Thank you.";;
52+
n | no | 0) export REPORT_ERRORS=0; echo "no" > $reporterrors; echo; echo -n "Understood.";;
53+
*) yn="";;
54+
esac
55+
done
56+
57+
echo " Your answer is cached in '.reporterrors', remove it to see this"
58+
echo "prompt again."
59+
echo
60+
sleep 5
61+
fi
62+
63+
# Make sure we can use sentry-cli if we need it.
64+
if [ "$REPORT_ERRORS" == 1 ]; then
65+
if ! docker pull getsentry/sentry-cli:latest; then
66+
echo "Failed to pull sentry-cli, won't report errors after all."
67+
export REPORT_ERRORS=0
68+
fi;
69+
fi;
70+
371
# Courtesy of https://stackoverflow.com/a/2183063/90297
472
trap_with_arg() {
573
func="$1" ; shift
674
for sig ; do
7-
trap "$func $sig "'$LINENO' "$sig"
75+
trap "$func $sig" "$sig"
876
done
977
}
1078

1179
DID_CLEAN_UP=0
1280
# the cleanup function will be the exit point
1381
cleanup () {
82+
local retcode=$?
83+
local cmd="${BASH_COMMAND}"
1484
if [[ "$DID_CLEAN_UP" -eq 1 ]]; then
1585
return 0;
1686
fi
1787
DID_CLEAN_UP=1
18-
1988
if [[ "$1" != "EXIT" ]]; then
20-
echo "An error occurred, caught SIG$1 on line $2";
89+
set +o xtrace
90+
printf -v err '%s' "Error in ${BASH_SOURCE[1]}:${BASH_LINENO[0]}."
91+
printf -v cmd_exit '%s' "'$cmd' exited with status $retcode"
92+
printf '%s\n%s\n' "$err" "$cmd_exit"
93+
local stack_depth=${#FUNCNAME[@]}
94+
local traceback=""
95+
if [ $stack_depth -gt 2 ]; then
96+
for ((i=$(($stack_depth - 1)),j=1;i>0;i--,j++)); do
97+
local indent="$(yes a | head -$j | tr -d '\n')"
98+
local src=${BASH_SOURCE[$i]}
99+
local lineno=${BASH_LINENO[$i-1]}
100+
local funcname=${FUNCNAME[$i]}
101+
printf -v traceback '%s\n' "$traceback${indent//a/-}> $src:$funcname:$lineno"
102+
done
103+
fi
104+
echo "$traceback"
105+
106+
if [ "$REPORT_ERRORS" == 1 ]; then
107+
local traceback_hash=$(echo -n $traceback | docker run --rm busybox md5sum | cut -d' ' -f1)
108+
send_event "$traceback_hash" "$cmd_exit"
109+
fi
21110

22111
if [[ -n "$MINIMIZE_DOWNTIME" ]]; then
23112
echo "*NOT* cleaning up, to clean your environment run \"docker compose stop\"."
@@ -30,6 +119,5 @@ cleanup () {
30119
$dc stop -t $STOP_TIMEOUT &> /dev/null
31120
fi
32121
}
33-
trap_with_arg cleanup ERR INT TERM EXIT
34122

35123
echo "${_endgroup}"

integration-test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ set -ex
44
echo "Reset customizations"
55
rm -f sentry/enhance-image.sh
66
rm -f sentry/requirements.txt
7+
echo no > .reporterrors
78

89
echo "Testing initial install"
910
./install.sh

0 commit comments

Comments
 (0)