Reliable automation

Write structured log lines

Add timestamps, levels, and one event per line so human and automated readers can follow a run.

10 minute lesson

~~~

Automation often runs without a terminal. When a backup job fires at 03:00, nobody is watching — the log is the only witness. Logs must show when, what, and whether an operation succeeded, in a shape both a human and grep can process.

A small logger function

Create a small logger:

log() {
  local level=$1
  shift
  printf '%s level=%s message=%q\n' "$(date -u +%FT%TZ)" "$level" "$*"
}

log info 'backup started'
# 2026-08-03T15:12:09Z level=info message=backup\ started

Piece by piece: shift drops the level from the arguments so $* holds only the message words. date -u +%FT%TZ prints a UTC timestamp like 2026-08-03T15:12:09Z — always log in UTC, or the first daylight-saving change makes your timeline lie. The %q format quotes the message so spaces and special characters survive as one parseable field.

One event per line, key=value fields. That’s the entire format. grep 'level=error' finds failures, and a log shipper parses it without custom rules.

Use it through a run

log info 'backup started'
if tar -czf "$archive" -C /var/www .; then
  log info 'archive created'
else
  log error 'tar failed'
  exit 1
fi

Redirect output to a lab file and generate success and error events:

./backup.sh >> /tmp/backup.log 2>&1
grep 'level=error' /tmp/backup.log

Verify each event carries a timestamp and a level, and that the error path logged before exiting. A failure the log never mentions is the failure you’ll debug blind.

Keep a run identifier when several jobs may overlap. Add run=$$ — the shell’s process ID — as a field on every line, and interleaved runs untangle instantly instead of reading as one confused story.

What must never be logged

Redact tokens, passwords, cookies, and private content before logging. The classic leak is logging a full curl command line, Authorization header included: the secret then lives in a world-readable file long after it was rotated. Log which endpoint you called and the status you got back, never the credential that authenticated you.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →