Skip to content

Latest commit

 

History

History
782 lines (552 loc) · 16.1 KB

File metadata and controls

782 lines (552 loc) · 16.1 KB

Runtime Configuration

The Bash Logging Module allows you to change configuration settings during script execution, providing flexibility for different phases of operation.

Table of Contents

Overview

Runtime configuration functions let you modify logging behavior without reinitializing the logger. This is useful for:

  • Enabling debug mode for specific operations
  • Changing log format for different sections
  • Temporarily disabling journal logging
  • Adjusting settings based on conditions

Available Functions

set_log_level

Change the minimum log level for displayed messages.

Syntax:

set_log_level LEVEL

Parameters:

  • LEVEL - DEBUG, INFO, NOTICE, WARN, ERROR, CRITICAL, ALERT, EMERGENCY, or 0-7

Examples:

# Enable debug logging
set_log_level DEBUG

# Show only warnings and errors
set_log_level WARN

# Show only errors and above
set_log_level ERROR

# Using numeric values
set_log_level 7  # DEBUG
set_log_level 4  # WARN

set_timezone_utc

Switch between UTC and local time for timestamps.

Syntax:

set_timezone_utc BOOLEAN

Parameters:

  • BOOLEAN - true to use UTC, false to use local time

Examples:

# Switch to UTC time
set_timezone_utc true

# Switch to local time
set_timezone_utc false

set_log_format

Change the log message format.

Syntax:

set_log_format FORMAT

Parameters:

  • FORMAT - Format string with placeholders

Examples:

# Change to minimal format
set_log_format "[%l] %m"

# Change to detailed format
set_log_format "%d %z [%l] [%s] %m"

# Change to custom format
set_log_format "%d [%s] %l: %m"

See Formatting for format options.

set_script_name

Change the script name that appears in log messages.

Syntax:

set_script_name NAME

Parameters:

  • NAME - String identifier for the script in log messages

Examples:

# Change script name for a specific phase
set_script_name "init-phase"

# Use component name
set_script_name "database-module"

# Restore original name
set_script_name "main-script"

This is particularly useful when:

  • The logger was sourced from a shell RC file (where auto-detection returns "unknown")
  • Different phases of a script should be logged with different identifiers
  • Multiple components in a script need distinct log identifiers

set_journal_logging

Enable or disable systemd journal logging.

Syntax:

set_journal_logging BOOLEAN

Parameters:

  • BOOLEAN - true to enable, false to disable

Examples:

# Enable journal logging
set_journal_logging true

# Disable journal logging
set_journal_logging false

set_journal_tag

Change the tag used for journal/syslog entries.

Syntax:

set_journal_tag TAG

Parameters:

  • TAG - String identifier for journal entries

Examples:

# Change journal tag
set_journal_tag "new-tag"

# Use component name
set_journal_tag "database-backup"

# Use operation name
set_journal_tag "cleanup-job"

set_syslog_facility

Change the syslog facility used for journal/syslog entries.

Syntax:

set_syslog_facility FACILITY

Parameters:

  • FACILITY - One of: kern, user, mail, daemon, auth, syslog, lpr, news, uucp, cron, authpriv, ftp, local0, local1, local2, local3, local4, local5, local6, local7

Examples:

# Route logs to a custom application facility
set_syslog_facility local0

# Restore default behavior
set_syslog_facility daemon

set_unsafe_allow_newlines

Enable or disable unsafe mode for newlines in log messages.

Warning: When enabled, newline sanitization is disabled and log injection becomes possible. Only use this when you control all log inputs and your log processing can handle embedded newlines safely.

Syntax:

set_unsafe_allow_newlines BOOLEAN

Parameters:

  • BOOLEAN - true to allow newlines, false to sanitize them (default)

Examples:

# Enable unsafe mode (not recommended)
set_unsafe_allow_newlines true

# Restore secure default
set_unsafe_allow_newlines false

set_unsafe_allow_ansi_codes

Enable or disable unsafe mode for ANSI escape codes in log messages.

Warning: When enabled, ANSI code stripping is disabled and terminal manipulation attacks become possible. Only use this when you control all log inputs and trust their source completely.

Syntax:

set_unsafe_allow_ansi_codes BOOLEAN

Parameters:

  • BOOLEAN - true to allow ANSI codes, false to strip them (default)

Examples:

# Enable unsafe mode (not recommended)
set_unsafe_allow_ansi_codes true

# Restore secure default
set_unsafe_allow_ansi_codes false

Security Note:

By default, bash-logger strips ANSI escape sequences from all user input to prevent:

  • Terminal display manipulation (clear screen, cursor repositioning)
  • Window title changes for social engineering or information disclosure
  • Fake log messages through visual spoofing
  • Terminal emulator exploits via malicious sequences

Library-generated ANSI codes (for log level colors) are preserved and applied at output time, so colored logging still works when enabled.

Use Cases

Conditional Debug Mode

Enable debug logging based on command-line arguments:

#!/bin/bash
source /path/to/logging.sh

# Initialize with default level
init_logger --level INFO

# Parse command line arguments
for arg in "$@"; do
    if [[ "$arg" == "--debug" ]]; then
        set_log_level DEBUG
        log_debug "Debug mode enabled"
    fi
done

log_info "Application starting"
log_debug "This only shows if --debug was passed"

Phase-Based Logging

Use different log levels for different phases:

#!/bin/bash
source /path/to/logging.sh

init_logger --log "/var/log/app.log"

# Initialization phase - verbose
set_log_level DEBUG
log_debug "Loading configuration"
log_debug "Connecting to database"

# Normal operation - standard
set_log_level INFO
log_info "Processing data"

# Critical phase - errors only
set_log_level ERROR
log_info "This won't show"
log_error "This will show"

Dynamic Format Changes

Change format for different sections:

#!/bin/bash
source /path/to/logging.sh

init_logger --format "%d [%l] [%s] %m"

log_info "Starting processing"

# Switch to minimal format for detailed debug output
set_log_format "[%l] %m"
set_log_level DEBUG

for i in {1..100}; do
    log_debug "Processing item $i"
done

# Return to detailed format
set_log_format "%d [%l] [%s] %m"
set_log_level INFO

log_info "Processing complete"

Conditional Journal Logging

Enable journal logging only for specific conditions:

#!/bin/bash
source /path/to/logging.sh

init_logger --level INFO

# Enable journal logging for production environment
if [[ "${ENV}" == "production" ]]; then
    set_journal_logging true
    set_journal_tag "myapp-prod"
    log_info "Journal logging enabled for production"
fi

log_info "Application running"

Timezone Switching

Switch timezone based on operation:

#!/bin/bash
source /path/to/logging.sh

init_logger --format "%d %z [%l] %m"

# Local time for user-facing messages
set_timezone_utc false
log_info "Script started at local time"

# UTC for API calls or distributed operations
set_timezone_utc true
log_info "Making API call"
# ... API operations ...

# Back to local time
set_timezone_utc false
log_info "Script completed at local time"

Environment-Based Settings

Adjust settings based on environment:

#!/bin/bash
source /path/to/logging.sh

init_logger --log "/var/log/app.log"

case "${ENVIRONMENT}" in
    development)
        set_log_level DEBUG
        set_log_format "[%l] %m"
        ;;
    testing)
        set_log_level INFO
        set_log_format "%d [%l] %m"
        ;;
    production)
        set_log_level WARN
        set_log_format "%d %z [%l] [%s] %m"
        set_timezone_utc true
        set_journal_logging true
        set_journal_tag "myapp"
        ;;
esac

log_info "Environment: ${ENVIRONMENT}"

Error Recovery

Increase logging detail when errors occur:

#!/bin/bash
source /path/to/logging.sh

init_logger --level INFO

function process_item() {
    local item=$1

    if ! some_operation "$item"; then
        # Error occurred - enable debug mode for troubleshooting
        log_error "Error processing $item, enabling debug mode"
        set_log_level DEBUG

        # Retry with debug output
        log_debug "Retrying $item with debug output"
        if ! some_operation "$item"; then
            log_error "Retry failed for $item"
            return 1
        fi

        # Restore normal log level
        set_log_level INFO
    fi

    return 0
}

for item in "${items[@]}"; do
    process_item "$item"
done

Temporary Format Change

Change format temporarily for specific output:

#!/bin/bash
source /path/to/logging.sh

init_logger

# Save current format (if needed for restoration)
ORIGINAL_FORMAT="%d [%l] [%s] %m"

log_info "Starting data export"

# Use minimal format for data listing
set_log_format "%m"
log_info "Record 1"
log_info "Record 2"
log_info "Record 3"

# Restore original format
set_log_format "$ORIGINAL_FORMAT"

log_info "Export complete"

Script Name for Different Phases

Change script name to identify different execution phases:

#!/bin/bash
source /path/to/logging.sh

# Initialize with a default name (useful for RC files or complex scripts)
init_logger --name "my-app"

log_info "Application starting"

# Change name for initialization phase
set_script_name "my-app:init"
log_info "Loading configuration"
log_info "Connecting to database"

# Change name for main processing
set_script_name "my-app:main"
log_info "Processing data"

# Change name for cleanup
set_script_name "my-app:cleanup"
log_info "Cleaning up resources"

# Restore original name
set_script_name "my-app"
log_info "Application complete"

Tag-Based Component Logging

Change journal tag based on component:

#!/bin/bash
source /path/to/logging.sh

init_logger --journal --tag "main"

function database_operations() {
    set_journal_tag "myapp-database"
    log_info "Starting database operations"
    # ... database work ...
    log_info "Database operations complete"
}

function api_operations() {
    set_journal_tag "myapp-api"
    log_info "Starting API operations"
    # ... API work ...
    log_info "API operations complete"
}

log_info "Application starting"
database_operations
api_operations
set_journal_tag "main"
log_info "Application complete"

Runtime vs. Initialization

When to Use Initialization Options

Use initialization options (init_logger) for:

  • Default configuration
  • Settings that apply to entire script
  • Static configuration from files
  • Initial setup
# Set baseline configuration
init_logger --log "/var/log/app.log" --level INFO --journal

When to Use Runtime Functions

Use runtime functions for:

  • Dynamic changes during execution
  • Conditional settings
  • Temporary changes
  • Phase-based configuration
# Change during execution
if [[ "$error_count" -gt 10 ]]; then
    set_log_level DEBUG  # Investigate issues
fi

Best Practices

1. Document Runtime Changes

Make it clear when and why settings change:

# Enabling debug mode for complex operation
log_info "Starting complex calculation"
set_log_level DEBUG
# ... complex operation ...
set_log_level INFO
log_info "Complex calculation complete"

2. Restore Original Settings

If you change settings temporarily, restore them:

ORIGINAL_LEVEL="INFO"
set_log_level DEBUG
# ... temporary debug section ...
set_log_level "$ORIGINAL_LEVEL"

3. Use Functions for Common Patterns

Encapsulate common runtime configuration patterns:

enable_debug_mode() {
    set_log_level DEBUG
    set_log_format "[%l] %m"
    log_debug "Debug mode enabled"
}

disable_debug_mode() {
    set_log_level INFO
    set_log_format "%d [%l] [%s] %m"
    log_info "Debug mode disabled"
}

4. Be Cautious with Production Changes

Avoid frequently changing settings in production:

# Good: Set once based on environment
if [[ "$ENV" == "production" ]]; then
    set_log_level WARN
fi

# Bad: Constantly changing levels
set_log_level DEBUG
set_log_level INFO
set_log_level DEBUG  # Confusing

5. Log Configuration Changes

Log when you change important settings:

log_info "Changing log level to DEBUG for diagnostics"
set_log_level DEBUG

log_info "Restoring log level to INFO"
set_log_level INFO

Limitations

Cannot Change After Initialization

Some settings can only be set at initialization:

  • Log file path (--log)
  • Console output (--quiet)
  • Stderr level (--stderr-level)
  • Color mode (--color / --no-color)

To change these, you must reinitialize the logger.

No Persistence

Runtime changes don't persist across script executions. If you need persistent changes, modify your initialization or configuration file.

Examples

Debug Mode Toggle

#!/bin/bash
source /path/to/logging.sh

init_logger

DEBUG_MODE=false

# Function to toggle debug mode
toggle_debug() {
    if [[ "$DEBUG_MODE" == "true" ]]; then
        DEBUG_MODE=false
        set_log_level INFO
        log_info "Debug mode disabled"
    else
        DEBUG_MODE=true
        set_log_level DEBUG
        log_info "Debug mode enabled"
    fi
}

# Use in script
log_info "Starting work"
toggle_debug  # Enable
log_debug "Debug info"
toggle_debug  # Disable
log_debug "This won't show"

Adaptive Logging

#!/bin/bash
source /path/to/logging.sh

init_logger --level INFO

ERROR_COUNT=0

function process_item() {
    if ! operation; then
        ((ERROR_COUNT++))

        # After 5 errors, enable debug mode
        if [[ $ERROR_COUNT -eq 5 ]]; then
            log_warn "High error rate, enabling debug mode"
            set_log_level DEBUG
        fi

        return 1
    fi
    return 0
}

Related Documentation