← Back to Blog
Code Snippets July 3, 2026

Production-Ready Logging Function — Bash

🐚 Code Snippet — July 3, 2026

Production-Ready Logging Function — Bash

Color-coded levels, file output, JSON mode for CI/CD, and a minimum level filter — all in ~60 lines, zero dependencies.

When to use it:
Any deployment script, CI/CD helper, or system automation that needs structured, readable output beyond bare echo.

bash
source logging.sh
log_debug "Variable X = $X"
log_info "Starting deployment..."
log_warn "Disk usage above 80%"
log_error "Failed to connect to database"
log_fatal "Out of memory — aborting"

Optional: redirect to file


export LOG_FILE="/var/log/myapp.log"

Optional: silence DEBUG/INFO in production


export MIN_LOG_LEVEL="warn"

Optional: JSON for CI/CD pipelines


export LOG_JSON="true"


The function (drop-in):

bash`
LOG_FILE="${LOG_FILE:-}"
MIN_LOG_LEVEL="${MIN_LOG_LEVEL:-debug}"
LOG_JSON="${LOG_JSON:-false}"
declare -A LOG_LEVELS=([debug]=0 [info]=1 [warn]=2 [error]=3 [fatal]=4)

ANSI colors (only when TTY and not JSON mode)


if [[ -t 1 && "$LOG_JSON" != "true" ]]; then
readonly RED='\033[0;31m' YELLOW='\033[0;33m' GREEN='\033[0;32m'
readonly CYAN='\033[0;36m' MAGENTA='\033[0;35m' NC='\033[0m'
else
readonly RED='' YELLOW='' GREEN='' CYAN='' MAGENTA='' NC=''
fi

log() {
local level="$1"; shift; local message="$*"
[[ -z "${LOG_LEVELS[$level]+_}" ]] && return 1
(( LOG_LEVELS[$level] < LOG_LEVELS[$MIN_LOG_LEVEL] )) && return 0
local ts=$(date '+%Y-%m-%dT%H:%M:%S%z')
local caller="${BASH_SOURCE[2]:-unknown}:${BASH_LINENO[1]:-0}"

if [[ "$LOG_JSON" == "true" ]]; then
printf '{"level":"%s","ts":"%s","caller":"%s","msg":"%s"}\n' "$level" "$ts" "$caller" "$message"
else
local color; case "$level" in
debug) color="$CYAN";; info) color="$GREEN";; warn) color="$YELLOW";;
error) color="$RED";; fatal) color="$MAGENTA";;
esac
echo "${color}[${level^^}] ${NC}${ts} ${message}"...