Logr is a Bash logging utility simplifying debugging and error messages in your Bash scripts. There’s probably a great utility already out there for this, but I didn’t find any that fit my needs.
Logr is basically shorthand for the logger command in Bash. You can use simpler logging commands such as:
logr debug "A quick debug message"
logr notice "One that goes to your log and /var/logs/system.log"
You can source Logr at the beginning of any bash script and enable logging with a simple logr start command. Logr uses logger command to write custom messages to your own log, optionally to STDERR, and notice, warning, and error messages to both of those as well as the system log (/var/logs/system.log), which can be viewed in Console (on Mac).
Logr has no built-in log rotation capabilities, so that needs to be handled via the Apache rotatelogs (/usr/sbin/rotatelogs), newsyslog, or any of the available log management tools.
Because console output from logr goes to STDERR, it can be used in scripts where STDOUT is piped without affecting results.
Configuration
You can change the location of the custom log files with $__logr_LOG_DIR. The default is ~/logs/, but it can be set to anything you want. E.g. in ~/.bash_profile use export __logr_LOG_DIR=${HOME}/custom_path to change it, or define the variables before calling logr start directly in the script.
You can define the name of a custom log when starting logging, or just let it default to ~/logs/scripts.log. You can change the name of the log with $__logr_DEFAULT_LOG. E.g. export __logr_DEFAULT_LOG=my_scripts.
By default, logr uses the “user” logging facility. If you need to change this, you can set $__logr_FACILITY, either in the script itself or in a global init file (i.e. ~/.bashrc or ~/.bash_profile).
Usage
Source the script
source ~/scripts/logr.bash
You can source the script in a login file (e.g. ~/.bash_profile) and use it in functions added to the main scope by your shell login. Otherwise, source it in a single script and it will stay out of the main scope. Note that sourcing it in a login file does not make it available to scripts run from the shell.
Start the logger
A call to logr start begins logging to ~/logs/scripts.log
You can override the default log name with logr start LOG_NAME
Call logr in your script where you want log messages
logr [log|notice|info|debug|warn|error] MESSAGE
If no level is given, it defaults to the “user.info” facility for easy logging
logr MESSAGE
If you set the logging mode to “quiet” (which is default), you can use tail -f to see the results of your script as it runs. Debug and info messages can go to your custom log file without polluting system.log.
Commands
logr start
Must be called first, initializes logging, sets global log file
If the first paramater is “verbose” or “quiet”, it toggles STDERR output (defaults to quiet).
If the first parameter (or second, if called in combination with verbose/quiet) is “clean” it will clear the log before writing. This is ignored if a custom log name is not specified, won’t overwrite the default “scripts.log” file.
The last parameter is a custom name of log source. If not specified, it defaults to “scripts” (.log will be appended).
The custom name affects both the tag in the system log (for high-level log messages) and the name of the custom log file.
Example:logr start verbose logger_test
logr verbose and logr quiet
Enables/disables STDERR output, can be called at any point in a script
logr clear
Clears a custom log (ignored if using the default “scripts” log)
logr [level] MESSAGE
level can be one of debug, info, log, notice, warn, error, or emerg
debug and info levels go to custom log with <DEBUG> or <INFO> indicator, but not to /var/logs/system.log.
debug level shows full function stack separated by /, so if it’s inside of a function called from another function, you can see the backtrace, e.g. logger_test:nested_func\script_func\main
# Oct 26 08:47:17 logger_test:nested_func\script_func\main[28953] <Debug>: debug message from inside nested function calls
error, warn, and notice go to custom log and system.log with appropriate indicator. log is an alias for notice.
emerg goes to /var/log/system.log, custom log, and broadcasts a message to all logged in users.
If no level is given before MESSAGE, logr assumes info.
The script
Demo
Demo output
On the command line:
Oct 26 11:42:21 logger_test[61091] <Info>: ====> BEGIN LOGGING
Oct 26 11:42:21 logger_test:main[61093] <Info>: Just some info (does not go to system.log)
Oct 26 11:42:21 logger_test:main[61095] <Info>: No level assumes info
Oct 26 11:42:21 logger_test:main[61097] <Info>: It also works without quoting, if special characters are quoted
Oct 26 11:42:21 logger_test:main[61099] <Info>: Special characters include ", `, ', $, ?, &, !, $, [\], etc.
Broadcast Message from root@pibble.local
(no tty) at 11:42 CDT...
Emergency logs to all logs, and broadcasts to all users
In ~/logs/logger_test.log:
Oct 26 11:42:21 logger_test[61091] <Info>: ====> BEGIN LOGGING
Oct 26 11:42:21 logger_test:main[61093] <Info>: Just some info (does not go to system.log)
Oct 26 11:42:21 logger_test:main[61095] <Info>: No level assumes info
Oct 26 11:42:21 logger_test:main[61097] <Info>: It also works without quoting, if special characters are quoted
Oct 26 11:42:21 logger_test:main[61099] <Info>: Special characters include ", `, ', $, ?, &, !, $, [\], etc.
Oct 26 11:42:21 logger_test:main[61102] <Debug>: A debug message does not go to system.log
Oct 26 11:42:21 logger_test:main[61103] <Notice>: notice goes to both system log and script log
Oct 26 11:42:21 logger_test:main[61104] <Warning>: A WARNING: Everything higher than notice goes to syslog
Oct 26 11:42:21 logger_test:main[61105] <Error>: Uh oh, an error... that definitely goes to syslog
Oct 26 11:42:21 logger_test:main[61106] <Emergency>: Emergency logs to all logs, and broadcasts to all users
Oct 26 11:42:21 logger_test:script_func[61108] <Warning>: This message comes from inside a function, note the :script_func tag instead of :main
Oct 26 11:42:21 logger_test:nested_func\script_func\main[61110] <Debug>: debug shows function stack separated by /
Hopefully this is useful. Let me know if you have ideas, improvements, or issues.