Logging in Scripts (Timestamped log Function)
In this page:
A Basic Timestamped Logger
A log function that prefixes every message with the current timestamp keeps output consistent and makes it possible to reconstruct the sequence and timing of events after the fact.
Example: A Basic Timestamped Logger
#!/bin/bash
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}
log "script starting"
log "doing some work"
log "script finished"
Login to try C/C++/Java/PHP code in the editor
Logging to stderr
Sending log output to stderr instead of stdout keeps it separate from the script's actual results, so stdout can still be piped or captured cleanly by another program.
Example: Logging to stderr
#!/bin/bash
log() {
echo "[$(date +'%H:%M:%S')] $1" >&2
}
log "this is a diagnostic message"
echo "this is the actual result"
Login to try C/C++/Java/PHP code in the editor
Adding Log Levels
Extending the logging function to accept a severity level (INFO, WARN, ERROR) makes it easy to filter or visually distinguish message importance later, without changing every call site's structure.
Example: Adding Log Levels
#!/bin/bash
log() {
local level=$1
shift
echo "[$(date +'%H:%M:%S')] [$level] $*"
}
log INFO "starting process"
log WARN "low disk space detected"
log ERROR "failed to connect, but continuing demo"
Login to try C/C++/Java/PHP code in the editor
Sending Logs to a File and the Screen
Piping the logger's output through tee -a writes each message to a persistent log file while still showing it immediately, combining two previously covered techniques.
Example: Sending Logs to a File and the Screen
#!/bin/bash
log() {
echo "[$(date +'%H:%M:%S')] $1" | tee -a run.log
}
log "first event"
log "second event"
echo "--- saved log file ---"
cat run.log
rm -f run.log
Login to try C/C++/Java/PHP code in the editor
- Using plain
echofor status messages throughout a script, making it impossible to tell later when each event occurred. - Writing log messages to stdout when they should go to stderr (or a dedicated log file), mixing diagnostics with actual program output.
- Forgetting to flush or account for buffering when logging from background jobs, which can cause log lines to interleave unpredictably.
- A small
logfunction wrappingdateplus the message keeps timestamp formatting consistent across an entire script. - Logging to stderr keeps diagnostic output separate from a script's actual stdout results.
date +"%Y-%m-%d %H:%M:%S"is a common, sortable timestamp format for log lines.- Centralizing logging in one function makes it easy to later redirect all log output to a file, syslog, or both.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first:
- Quoting Pitfalls and Why to Always Quote Variables
- set -euo pipefail as a Script Header
- Structuring a Script (Functions, main() Pattern, Exit at the End)
- Idempotent Scripts (Safe to Re-Run)
- Logging in Scripts (Timestamped log Function)
- Writing Portable Scripts (Bash-isms vs POSIX sh)
- Capstone: A Real-World Backup/Cleanup Script