This document provides comprehensive examples demonstrating various use cases for the Bash Logging Module.
- Basic Examples
- Configuration File Examples
- CLI Tool Examples
- Dynamic Configuration Examples
- Function-Based Examples
- System Service Examples
- Cron Job Examples
- Data Processing Examples
- Security Examples
- Testing Examples
- Multi-Environment Examples
- Complex Integration Example
- Related Documentation
#!/bin/bash
# Source the logging module
source /path/to/logging.sh
# Initialize with default settings
init_logger
log_info "Script starting"
log_debug "Debug information"
# ... script operations ...
log_warn "Warning: resource usage high"
log_info "Script completed"#!/bin/bash
# Source the logging module
source /path/to/logging.sh
# Initialize with file output and verbose mode
init_logger --log "/tmp/myapp.log" --verbose
log_info "Application starting"
log_debug "Configuration loaded" # This will be logged due to verbose mode
# ... application operations ...
log_info "Application completed"#!/bin/bash
# Source the logging module
source /path/to/logging.sh
# Initialize with multiple outputs and custom format
init_logger \
--log "/var/log/myapp.log" \
--journal \
--tag "myapp" \
--format "%d %z [%l] [%s] %m" \
--utc \
--level INFO
log_info "Application initialized with comprehensive logging"#!/bin/bash
# Source the logging module
source /path/to/logging.sh
# Initialize from configuration file
# All settings are defined in the INI file
init_logger --config /etc/myapp/logging.conf
log_info "Application started with config file settings"
# You can still override specific settings via CLI
# init_logger --config /etc/myapp/logging.conf --level DEBUGExample configuration file (/etc/myapp/logging.conf):
[logging]
level = INFO
format = %d %z [%l] [%s] %m
log_file = /var/log/myapp/app.log
journal = true
tag = myapp
utc = true
color = auto
stderr_level = ERROR#!/bin/bash
source /path/to/logging.sh
# Determine environment
ENV="${APP_ENV:-production}"
# Select appropriate config file
case "$ENV" in
development)
init_logger --config /etc/myapp/logging-dev.conf
;;
testing)
init_logger --config /etc/myapp/logging-test.conf
;;
production)
init_logger --config /etc/myapp/logging-prod.conf
;;
esac
log_info "Running in $ENV environment"When building a CLI tool that produces both program output and diagnostic logs, send all logs to stderr to keep stdout clean:
#!/bin/bash
source /path/to/logging.sh
# Send all log messages to stderr, keeping stdout for program output
init_logger --stderr-level DEBUG --level INFO
log_info "Processing input..."
# Program output goes to stdout (can be piped)
echo "result1"
echo "result2"
log_info "Processing complete"
# Usage: ./mytool.sh > results.txt
# Log messages appear on screen, results go to file#!/bin/bash
source /path/to/logging.sh
# Default: only errors to stderr
STDERR_LEVEL="ERROR"
# Parse arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--warnings-to-stderr)
STDERR_LEVEL="WARN"
shift
;;
--all-to-stderr)
STDERR_LEVEL="DEBUG"
shift
;;
*)
shift
;;
esac
done
init_logger --stderr-level "$STDERR_LEVEL" --level DEBUG
log_debug "Debug info"
log_info "Starting operation"
log_warn "Warning: disk space low"
log_error "Error: file not found"#!/bin/bash
# Source the logging module
source /path/to/logging.sh
# Basic initialization
init_logger
# Parse command line arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--debug)
set_log_level DEBUG
shift
;;
--quiet)
set_log_level ERROR
shift
;;
*)
shift
;;
esac
done
log_debug "Debug mode enabled" # Only shows if --debug was passed
log_info "Normal operation"Note: The logger provides --verbose option when called using init_logger --verbose, but the provided
set_log_level function accepts log levels based on their common names (DEBUG, INFO, WARN, ERROR) or their numeric
values (0-7). The example above uses a command line parser in the calling script to optionally enable DEBUG logging by
accepting a local argument --debug and then using the set_log_level function.
#!/bin/bash
# Source the logging module
source /path/to/logging.sh
# Initialize with custom format and UTC time
init_logger --format "%d %z [%l] [%s] %m" --utc
log_info "Starting processing job"
# Later, change format for a specific part of the script
set_log_format "[%l] %m"
log_info "Using simplified format"
# Return to original format
set_log_format "%d %z [%l] [%s] %m"
log_info "Back to detailed format"#!/bin/bash
source /path/to/logging.sh
init_logger --log "/var/log/myapp.log"
function process_item() {
local item=$1
log_debug "Processing item: $item"
# Processing logic...
if [[ "$item" == "important" ]]; then
log_info "Found important item"
fi
# Error handling
if [[ "$?" -ne 0 ]]; then
log_error "Failed to process item: $item"
return 1
fi
log_debug "Completed processing item: $item"
return 0
}
log_info "Starting batch processing"
process_item "test"
process_item "important"
log_info "Batch processing complete"#!/bin/bash
source /path/to/logging.sh
init_logger --level INFO
function process_with_retry() {
local item=$1
log_info "Processing $item"
if ! perform_operation "$item"; then
log_error "Operation failed, enabling debug and retrying"
set_log_level DEBUG
if ! perform_operation "$item"; then
log_error "Retry also failed"
set_log_level INFO
return 1
fi
log_info "Retry succeeded"
set_log_level INFO
fi
return 0
}
for item in "${items[@]}"; do
process_with_retry "$item"
done#!/bin/bash
# Source the logging module
source /path/to/logging.sh
# Initialize with journal logging
init_logger --journal --tag "myservice"
log_info "Service starting"
# ... service operations ...
log_error "Error encountered: $error_message"
log_info "Service completed"View with:
journalctl -t myservice -f#!/bin/bash
# /usr/local/bin/myservice.sh
source /usr/local/lib/logging.sh
# Log to both journal and file
init_logger \
--journal --tag "myservice" \
--log "/var/log/myservice/service.log" \
--level INFO \
--utc
log_info "Service started"
# Main service loop
while true; do
log_debug "Checking status"
if ! check_health; then
log_error "Health check failed"
fi
sleep 60
doneSystemd unit file (/etc/systemd/system/myservice.service):
[Unit]
Description=My Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myservice.sh
Restart=always
User=myservice
Group=myservice
[Install]
WantedBy=multi-user.target#!/bin/bash
source /path/to/logging.sh
# Log everything to file, but only errors to stderr (cron emails stderr)
init_logger \
--log "/var/log/backup/backup.log" \
--level INFO \
--stderr-level ERROR
log_info "Backup job started"
if backup_database; then
log_info "Database backup successful"
else
log_error "Database backup failed" # This will trigger cron email
fi
log_info "Backup job completed"Crontab entry:
0 2 * * * /usr/local/bin/backup-script.sh#!/bin/bash
source /path/to/logging.sh
# Send all logs to stderr so data can be piped
init_logger --stderr-level DEBUG --level INFO
log_info "Starting data processing"
# Read input, process, output to stdout
while IFS= read -r line; do
log_debug "Processing line: $line"
# Process data
result=$(process_data "$line")
# Output result to stdout (pipeable)
echo "$result"
done
log_info "Processing complete"Usage:
# Pipe data through processor
cat input.txt | ./process.sh | ./next-stage.sh#!/bin/bash
source /path/to/logging.sh
init_logger --log "/var/log/batch.log" --level INFO
FILES=(/data/*.csv)
TOTAL=${#FILES[@]}
CURRENT=0
log_info "Starting batch processing of $TOTAL files"
for file in "${FILES[@]}"; do
((CURRENT++))
PERCENT=$((CURRENT * 100 / TOTAL))
log_info "Processing [$CURRENT/$TOTAL - ${PERCENT}%]: $file"
if process_file "$file"; then
log_debug "Successfully processed $file"
else
log_error "Failed to process $file"
fi
done
log_info "Batch processing complete: $CURRENT files processed"#!/bin/bash
source /path/to/logging.sh
init_logger --log "/var/log/myapp.log" --journal --tag "myapp"
# Regular logs go to file and journal
log_info "User authentication started"
# Sensitive data only appears on console (not in file or journal)
log_sensitive "Authenticating with token: $AUTH_TOKEN"
# Continue with regular logging
log_info "Authentication successful"#!/bin/bash
source /path/to/logging.sh
init_logger --log "/var/log/app.log"
log_info "Loading configuration"
# Load config file
if [[ -f "/etc/myapp/config" ]]; then
source "/etc/myapp/config"
log_info "Configuration loaded from /etc/myapp/config"
# Don't log actual values
log_sensitive "Database password: $DB_PASSWORD"
log_sensitive "API key: $API_KEY"
else
log_error "Configuration file not found"
exit 1
fi
log_info "Application configured successfully"#!/bin/bash
source /path/to/logging.sh
# Verbose, no colors (for CI/CD)
init_logger --verbose --no-color
log_info "Starting test suite"
run_test() {
local test_name=$1
log_debug "Running test: $test_name"
if $test_name; then
log_info "✓ $test_name passed"
return 0
else
log_error "✗ $test_name failed"
return 1
fi
}
FAILURES=0
run_test "test_database_connection" || ((FAILURES++))
run_test "test_api_endpoint" || ((FAILURES++))
run_test "test_data_validation" || ((FAILURES++))
if [[ $FAILURES -eq 0 ]]; then
log_info "All tests passed"
exit 0
else
log_error "$FAILURES tests failed"
exit 1
fi#!/bin/bash
source /path/to/logging.sh
ENV="${ENVIRONMENT:-development}"
case "$ENV" in
development)
init_logger --verbose --color --format "[%l] %m"
;;
testing)
init_logger --level INFO --no-color --log "/tmp/test.log"
;;
staging)
init_logger \
--level INFO \
--log "/var/log/app/staging.log" \
--journal --tag "app-staging" \
--utc
;;
production)
init_logger \
--level WARN \
--log "/var/log/app/production.log" \
--journal --tag "app-prod" \
--utc \
--format "%d %z [%l] [%s] %m"
;;
esac
log_info "Application started in $ENV environment"#!/bin/bash
# Application: data-processor
# Purpose: Process data files with comprehensive logging
source /usr/local/lib/logging.sh
# Configuration
APP_NAME="data-processor"
ENV="${APP_ENV:-production}"
CONFIG_DIR="/etc/${APP_NAME}"
# Initialize logging based on environment
setup_logging() {
case "$ENV" in
development)
init_logger \
--level DEBUG \
--color \
--format "[%l] %m"
;;
production)
init_logger \
--config "${CONFIG_DIR}/logging.conf" \
--tag "$APP_NAME"
;;
esac
if [[ $? -ne 0 ]]; then
echo "ERROR: Failed to initialize logging" >&2
exit 1
fi
}
# Parse command-line arguments
parse_args() {
while [[ "$#" -gt 0 ]]; do
case $1 in
--debug)
set_log_level DEBUG
log_info "Debug mode enabled via command line"
shift
;;
--input)
INPUT_FILE="$2"
shift 2
;;
--output)
OUTPUT_FILE="$2"
shift 2
;;
*)
log_error "Unknown argument: $1"
exit 1
;;
esac
done
}
# Main processing function
process_data() {
local input=$1
local output=$2
log_info "Processing data: $input -> $output"
log_debug "Input file size: $(stat -f%z "$input" 2>/dev/null || stat -c%s "$input") bytes"
local line_count=0
while IFS= read -r line; do
((line_count++))
if [[ $((line_count % 1000)) -eq 0 ]]; then
log_info "Processed $line_count lines"
fi
# Process line
log_debug "Processing line $line_count: $line"
# Error handling
if [[ -z "$line" ]]; then
log_warn "Empty line at line $line_count"
continue
fi
# Output processing result
echo "$processed_line" >> "$output"
done < "$input"
log_info "Processing complete: $line_count lines processed"
}
# Main execution
main() {
setup_logging
log_info "$APP_NAME starting (environment: $ENV)"
parse_args "$@"
if [[ -z "$INPUT_FILE" ]] || [[ -z "$OUTPUT_FILE" ]]; then
log_error "Both --input and --output are required"
exit 1
fi
if [[ ! -f "$INPUT_FILE" ]]; then
log_error "Input file not found: $INPUT_FILE"
exit 1
fi
process_data "$INPUT_FILE" "$OUTPUT_FILE"
log_info "$APP_NAME completed successfully"
}
# Run main function
main "$@"- Getting Started - Basic usage
- Initialization - Configuration options
- Configuration - Config file usage
- Log Levels - Understanding severity levels
- Output Streams - Stream redirection
- Formatting - Custom formats
- Journal Logging - Systemd integration
- Runtime Configuration - Dynamic changes
- Sensitive Data - Security considerations