Send Useful, Safe Syslog Messages with logger

logger lets a script drop a message into syslog with a proper tag and priority, so a 3am failure leaves a trail instead of silence. This guide gets you sending a tagged message with a chosen facility and severity, feeding multi-line input from a file or another command, and dry-running a script so testing does not write anything real.

Allow about ten minutes. You need a shell and the logger command. The local manual page is for util-linux 2.39.3, while this machine's PATH currently resolves util-linux 2.41.3 from Homebrew. The options used here are present in both, but check logger --version on a different host before copying a deployment script. Ordinary local logging normally needs no elevated privileges.

1. Confirm the command and make a no-write test

Start by confirming which executable your shell will run:

$ command -v logger
/home/linuxbrew/.linuxbrew/bin/logger
$ logger --version
logger from util-linux 2.41.3

For a safe syntax check, combine --no-act with --stderr. The first option does everything except write the message; the second prints the message to standard error so you can see it:

$ logger --no-act --stderr --tag backup-check --priority user.notice "backup preflight passed"
backup-check: backup preflight passed

The exact prefix can vary by util-linux release. What matters is exit status 0 and a visible message, with no new log entry. Check the status straight away if a script's next step depends on it:

$ printf 'exit status: %s\n' "$?"
exit status: 0

Checkpoint: Do not remove --no-act until the tag, priority and message are the values you intended.

2. Write one local message with a clear tag

A message argument gets sent to the system log. Use --tag so an administrator can find messages from your script without relying on the account name:

$ logger --tag backup-check --priority user.notice "backup preflight passed"
$ printf 'logger exit status: %s\n' "$?"
logger exit status: 0

On a system using journald, look for the tag with:

$ journalctl --no-pager -t backup-check -n 10

You may need membership of the adm or systemd-journal group to see messages from other users. If the command returns success but you cannot see the entry, ask the logging administrator which journal or traditional syslog destination receives that facility. A missing display is not proof the message was rejected.

3. Give a script a stable identity

Use a fixed tag and put useful context in the message. Quote the whole message so spaces and shell characters stay inside one argument:

logger --tag nightly-backup --priority local0.info \
  "host=$HOSTNAME result=success archive=$ARCHIVE_NAME"

The tag marks each line. If you need the logger process ID, add --id or the short -i. For a script sending several related messages, the manual recommends --id=$$ so the parent script's PID is reused throughout:

logger --id=$$ --tag nightly-backup --priority local0.info \
  "archive upload started"

An exit status of 0 is not proof that an operator can later read the entry: it only means the invocation succeeded according to the local logging path. Keep enough context in the tag and message to trace the event afterwards.

4. Send a file one line at a time

Use --file when the source is already a text file. It cannot be combined with a command-line message:

$ logger --tag import-report --priority local0.info --file /path/to/report.txt
$ printf 'logger exit status: %s\n' "$?"
logger exit status: 0

Each input line becomes a log message, and empty lines are normally processed too. Add --skip-empty when blank lines are just formatting:

$ logger --skip-empty --tag import-report --priority local0.info --file /path/to/report.txt

Tip: whitespace-only lines are not empty for this option, so a line containing spaces can still be logged. That small distinction is a common source of unexpected blank-looking entries.

5. Pipe command output and preserve priorities

With no message and no --file, logger reads standard input, which suits a short report:

$ printf 'phase=check\nphase=complete\n' | \
  logger --tag deployment --priority local0.info
$ printf 'logger exit status: %s\n' "$?"
logger exit status: 0

If the input already carries syslog priority prefixes such as <134>, add --prio-prefix. The number encodes facility times eight plus level. A line without a prefix falls back to the priority from --priority:

$ printf '<134>cache warmed\nordinary progress\n' | \
  logger --prio-prefix --tag cache-job --priority local0.notice

--prio-prefix affects input lines, not a message supplied directly on the command line. Do not enable it merely because a message contains angle brackets.

6. Send to a remote syslog server only deliberately

Warning: Remote logging sends data to another host and may expose message contents, host details or credentials accidentally included in a command's output. Review the data, transport and firewall rules before using this in production.

For a remote destination, use --server. Without a transport flag, logger tries UDP first and then TCP if that fails. Select UDP with --udp or TCP with --tcp, and set a port explicitly when the receiver does not use the service names from /etc/services:

$ logger --server LOG_HOST.example --tcp --port 601 \
  --tag app-check --priority local0.info "health check passed"

Use a placeholder hostname until the receiver has been approved. This command can create network traffic and a real operational record, so do not test it against a production host with sample secrets. RFC 5424 has been the default protocol for remote logging in util-linux since version 2.26; --rfc3164 requests the older BSD syslog format when the receiver requires it.

7. Handle common mistakes without changing the host

A message beginning with a hyphen can be mistaken for an option. End options with --:

$ logger --tag parser -- --input rejected

If a file cannot be read, check its permissions and path before adding sudo. Elevated privileges are not normally needed for local logger use, and they do not repair a missing syslog socket or a remote network rule. If a service account must write a protected file's contents to the log, review that data flow first: logging secrets is a disclosure incident, not a permissions problem.

Recovery: there is no portable delete operation in logger, so an accidental test entry cannot be undone from here. Keep the tag distinctive, tell the log administrator which entry was generated, and apply the site's normal retention or redaction process. Do not delete an entire journal or log file to remove one message.

Done means