Sentry is a great error aggregation service. We use it for every service we deploy at work. It lets us monitor and troubleshoot incidents of errors. It also integrates nicely with Slack, a messaging tool we use for everything.
It integrates nicely with Javascript, Ruby, and Python stacks among others — but as a RESTful service you can also access it directly from the command line.
Sometimes, you start writing a Bash shell script that grows so much that you need to start logging errors in a central error aggregation service. Frankly, that’s a sign that you should have picked a different language for the initial implementation, whether Python or Ruby or something else more robust. However, once you have such a Bash script, porting it arguably becomes as problematic as instrumenting it.
Bash client for Sentry
A quick Google search turns up more feature-complete attempts at a command line client. You may want to follow the link and use that instead.
Still, for posterity, here’s something I used to instrument such a Bash script last year:
# Install dependencies on Alpine Linux apk --no-cache add --virtual build-dependencies gcc python-dev musl-dev pip2 install httpie # Transform a Sentry DSN into useful components trim() { local var="$*" # remove leading whitespace characters var="${var#"${var%%[![:space:]]*}"}" # remove trailing whitespace characters var="${var%"${var##*[![:space:]]}"}" echo -n "$var" } SENTRY_DSN=$(trim "${SENTRY_DSN:-}") SENTRY_KEY="$(echo $SENTRY_DSN | sed -E "s@^.*//(.*):.*@1@g")" SENTRY_SECRET="$(echo $SENTRY_DSN | sed -E "s@^.*:(.*)@.*@1@g")" SENTRY_PROJECT_ID="$(echo $SENTRY_DSN | sed -E "s@^.*/([0-9]*)@1@g")" SENTRY_URL_WITH_PROJECT="${SENTRY_DSN/${SENTRY_KEY}:${SENTRY_SECRET}@/}" SENTRY_URL="${SENTRY_URL_WITH_PROJECT//[0-9]*/}" # Bash function to report errors to Sentry # Usage: # report_error "${FUNCNAME[0]}:$LINENO" "Uh oh, spaghettios!" report_error() { [[ -z "${SENTRY_DSN:-}" ]] && return declare culprit declare timestamp declare message declare x_sentry_auth declare referer declare body declare url declare content_type culprit=${1:?} timestamp=$(date +%Y-%m-%dT%H:%M:%S) message=${2:?} x_sentry_auth="X-Sentry-Auth:Sentry sentry_version=5" x_sentry_auth="${x_sentry_auth:?},sentry_client=0.1.0" x_sentry_auth="${x_sentry_auth:?},sentry_timestamp=${timestamp:?}" x_sentry_auth="${x_sentry_auth:?},sentry_key=${SENTRY_KEY:?}" x_sentry_auth="${x_sentry_auth:?},sentry_secret=${SENTRY_SECRET:?}" referer="Referer:http://example.com/" content_type="Content-Type: application/json" url="${SENTRY_URL:?}/api/${SENTRY_PROJECT_ID:?}/store/" body=$(cat <<BODY { "culprit": "${culprit:?}", "timestamp": "${timestamp:?}", "message": "${message:?}", "tags": { "BACKUP_INTERVAL": "${BACKUP_INTERVAL:?}" }, "exception": [{ "type": "BackupError", "value": "${message:?}", "module": "${BASH_SOURCE[0]}" }] } BODY ) echo "$body" | http POST "${url:?}" "${x_sentry_auth:?}" "${referer:?}" "${content_type:?}" }