Skip to content

services

azure_bootstrap.services

Service implementations for Azure bootstrap library.

This module contains bootstrap services for application initialization.

Modules:

Name Description
application_bootstrap

Application bootstrap orchestrator that handles the complete startup flow.

bootstrap_logging

Bootstrap logging configuration for handling initialization before full telemetry setup.

interfaces

Service interfaces for Azure bootstrap library.

telemetry

Classes:

Name Description
ApplicationBootstrap

Orchestrates the complete application startup sequence with proper logging flow.

BootstrapLogger

Bootstrap logging manager that provides safe logging before full configuration.

TelemetryManager

Manages Application Insights telemetry and structured logging

Functions:

Name Description
create_enhanced_config_repository

Factory function to create an enhanced configuration repository.

initialize_application

Convenience function to perform complete application bootstrap.

get_bootstrap_logger

Get a logger that works during bootstrap phase.

ApplicationBootstrap

ApplicationBootstrap(secrets_repository: SecretsRepositoryInterface | None = None)

Bases: ApplicationBootstrapInterface

Orchestrates the complete application startup sequence with proper logging flow.

This class handles the complex bootstrap process that requires careful ordering to avoid circular dependencies between logging, configuration, and secrets.

Bootstrap Flow
  1. Initialize console logging (safe fallback that always works)
  2. Try App Insights from environment variables if available
  3. Create and load enhanced configuration from App Config/Key Vault
  4. Attempt to upgrade logging to App Insights if connection string is now available
  5. Load all configuration to os.environ for transparent application access
  6. Log completion and provide access to configured components
Key Features
  • Eliminates circular dependencies between logging and configuration
  • Provides working logging throughout the entire bootstrap process
  • Graceful fallbacks at every step ensure robustness
  • Comprehensive logging of bootstrap progress and decisions
  • Transparent configuration access via os.environ after completion
Usage Example

Simple bootstrap

bootstrap = ApplicationBootstrap() config_repo = bootstrap.initialize()

Bootstrap with secrets repository

bootstrap = ApplicationBootstrap(secrets_repository=my_secrets_repo) config_repo = bootstrap.initialize()

After bootstrap, all configs are in os.environ

app_insights_key = os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING") database_host = os.getenv("DATABASE_HOST")

Initialize the application bootstrap orchestrator.

Parameters:

Name Type Description Default
secrets_repository SecretsRepositoryInterface | None

Optional secrets repository for Key Vault integration

None

Methods:

Name Description
initialize

Execute the complete bootstrap sequence with proper logging flow.

get_config_repository

Get the configured repository after bootstrap.

is_bootstrap_completed

Check if bootstrap process has completed successfully.

Source code in azure_bootstrap/services/application_bootstrap.py
def __init__(self, secrets_repository: SecretsRepositoryInterface | None = None) -> None:
    """
    Initialize the application bootstrap orchestrator.

    Args:
        secrets_repository: Optional secrets repository for Key Vault integration
    """
    # Start with bootstrap logging immediately
    BootstrapLogger.configure_bootstrap_logging()
    self.logger = get_bootstrap_logger(__name__)

    self.secrets_repository = secrets_repository
    self.config_repository: EnhancedConfigRepositoryInterface | None = None
    self._bootstrap_completed = False

    self.logger.info(
        "ApplicationBootstrap initialized",
        extra={
            "has_secrets_repository": bool(secrets_repository),
            "operation": "bootstrap_init",
            "component": "ApplicationBootstrap",
        },
    )

initialize

Execute the complete bootstrap sequence with proper logging flow.

This method orchestrates the entire application startup process following the correct sequence to avoid circular dependencies while ensuring working logging throughout.

Returns:

Type Description
EnhancedConfigRepositoryInterface

Configured enhanced configuration repository with all configs loaded

Raises:

Type Description
RuntimeError

If bootstrap fails in an unrecoverable way

Source code in azure_bootstrap/services/application_bootstrap.py
def initialize(self) -> EnhancedConfigRepositoryInterface:
    """
    Execute the complete bootstrap sequence with proper logging flow.

    This method orchestrates the entire application startup process following
    the correct sequence to avoid circular dependencies while ensuring working
    logging throughout.

    Returns:
        Configured enhanced configuration repository with all configs loaded

    Raises:
        RuntimeError: If bootstrap fails in an unrecoverable way
    """
    if self._bootstrap_completed and self.config_repository is not None:
        self.logger.info("Bootstrap already completed, returning existing config repository")
        return self.config_repository

    self.logger.info(
        "Starting application bootstrap sequence",
        extra={
            "operation": "bootstrap_start",
            "component": "ApplicationBootstrap",
            "bootstrap_phase": "initialization",
        },
    )

    try:
        # Phase 1: Initial telemetry setup with environment variables only
        self._initialize_telemetry_from_environment()

        # Phase 2: Load enhanced configuration from App Config/Key Vault
        self._load_enhanced_configuration()

        # Phase 3: Upgrade telemetry if App Insights connection string is now available
        self._upgrade_telemetry_from_config()

        # Phase 4: Final configuration loading to os.environ
        self._finalize_configuration_loading()

        # Mark bootstrap as completed
        self._bootstrap_completed = True

        self.logger.info(
            "Application bootstrap completed successfully",
            extra={
                "operation": "bootstrap_complete",
                "component": "ApplicationBootstrap",
                "bootstrap_phase": "completed",
                "telemetry_enabled": bool(telemetry_manager.tracer),
                "config_repository_type": type(self.config_repository).__name__,
            },
        )

        if self.config_repository is not None:
            return self.config_repository
        raise RuntimeError("Bootstrap completed but config repository is None")

    except Exception as e:
        self.logger.error(
            "Application bootstrap failed",
            extra={
                "error_type": type(e).__name__,
                "error_message": str(e),
                "operation": "bootstrap_error",
                "component": "ApplicationBootstrap",
                "bootstrap_phase": "failed",
            },
            exc_info=True,
        )
        raise RuntimeError(f"Application bootstrap failed: {str(e)}") from e

get_config_repository

get_config_repository() -> EnhancedConfigRepositoryInterface | None

Get the configured repository after bootstrap.

Returns:

Type Description
EnhancedConfigRepositoryInterface | None

The enhanced configuration repository if bootstrap is complete, None otherwise

Source code in azure_bootstrap/services/application_bootstrap.py
def get_config_repository(self) -> EnhancedConfigRepositoryInterface | None:
    """
    Get the configured repository after bootstrap.

    Returns:
        The enhanced configuration repository if bootstrap is complete, None otherwise
    """
    return self.config_repository if self._bootstrap_completed else None

is_bootstrap_completed

is_bootstrap_completed() -> bool

Check if bootstrap process has completed successfully.

Returns:

Type Description
bool

True if bootstrap completed successfully, False otherwise

Source code in azure_bootstrap/services/application_bootstrap.py
def is_bootstrap_completed(self) -> bool:
    """
    Check if bootstrap process has completed successfully.

    Returns:
        True if bootstrap completed successfully, False otherwise
    """
    return self._bootstrap_completed

BootstrapLogger

Bases: BootstrapLoggerInterface

Bootstrap logging manager that provides safe logging before full configuration.

This class handles the chicken-and-egg problem where: 1. Configuration loading needs logging 2. Logging (App Insights) needs configuration

Solution: Start with basic logging, then upgrade to full telemetry later.

Methods:

Name Description
configure_bootstrap_logging

Configure basic logging that works before full configuration is loaded.

is_bootstrap_configured

Check if bootstrap logging is configured.

create_logger

Create a logger with bootstrap configuration if not already done.

configure_bootstrap_logging classmethod

configure_bootstrap_logging(level: str | None = None) -> None

Configure basic logging that works before full configuration is loaded.

This provides immediate, safe logging during application bootstrap. Later, telemetry_manager.configure() will enhance it with App Insights.

Parameters:

Name Type Description Default
level str | None

Logging level (DEBUG, INFO, WARNING, ERROR). If not provided, reads from LOG_LEVEL environment variable, defaulting to INFO.

None
Source code in azure_bootstrap/services/bootstrap_logging.py
@classmethod
def configure_bootstrap_logging(cls, level: str | None = None) -> None:
    """
    Configure basic logging that works before full configuration is loaded.

    This provides immediate, safe logging during application bootstrap.
    Later, telemetry_manager.configure() will enhance it with App Insights.

    Args:
        level: Logging level (DEBUG, INFO, WARNING, ERROR). If not provided,
               reads from LOG_LEVEL environment variable, defaulting to INFO.
    """
    if cls._configured:
        return

    # Determine logging level: parameter > env var > default (INFO)
    if level is None:
        level = os.environ.get("LOG_LEVEL", "INFO")

    # Validate the level - default to INFO if invalid
    numeric_level = getattr(logging, level.upper(), None)
    if not isinstance(numeric_level, int):
        numeric_level = logging.INFO
        level = "INFO"

    # Set up basic formatter for bootstrap phase with extra fields support
    cls._basic_formatter = ExtraFieldsFormatter(
        "%(asctime)s - [BOOTSTRAP] - %(name)s - %(levelname)s - %(message)s"
    )

    # Configure root logger with basic settings
    root_logger = logging.getLogger()
    root_logger.setLevel(numeric_level)

    # Ensure we have at least one handler
    if not root_logger.handlers:
        handler = logging.StreamHandler()
        if cls._basic_formatter is not None:
            handler.setFormatter(cls._basic_formatter)
        root_logger.addHandler(handler)
    else:
        # Update existing handlers with bootstrap formatter
        if cls._basic_formatter is not None:
            for handler in root_logger.handlers:  # type: ignore
                if hasattr(handler, "setFormatter"):
                    handler.setFormatter(cls._basic_formatter)

    cls._configured = True

    # Log bootstrap completion
    bootstrap_logger = logging.getLogger(__name__)
    bootstrap_logger.info(
        "Bootstrap logging configured successfully",
        extra={"phase": "bootstrap", "level": level, "handlers": len(root_logger.handlers)},
    )

is_bootstrap_configured classmethod

is_bootstrap_configured() -> bool

Check if bootstrap logging is configured.

Source code in azure_bootstrap/services/bootstrap_logging.py
@classmethod
def is_bootstrap_configured(cls) -> bool:
    """Check if bootstrap logging is configured."""
    return cls._configured

create_logger classmethod

create_logger(name: str) -> Logger

Create a logger with bootstrap configuration if not already done.

Parameters:

Name Type Description Default
name str

Logger name (typically name)

required

Returns:

Type Description
Logger

Configured logger ready for use

Source code in azure_bootstrap/services/bootstrap_logging.py
@classmethod
def create_logger(cls, name: str) -> logging.Logger:
    """
    Create a logger with bootstrap configuration if not already done.

    Args:
        name: Logger name (typically __name__)

    Returns:
        Configured logger ready for use
    """
    if not cls._configured:
        cls.configure_bootstrap_logging()

    return logging.getLogger(name)

TelemetryManager

TelemetryManager()

Bases: TelemetryManagerInterface

Manages Application Insights telemetry and structured logging

Methods:

Name Description
configure

Configure Application Insights telemetry with support for bootstrap flow reconfiguration

try_upgrade_from_config

Attempt to upgrade from basic logging to App Insights after config is loaded

get_tracer

Get the configured tracer

create_span

Create a new trace span

log_email_processing_start

Log email processing start with structured data

log_email_processing_success

Log successful email processing

log_email_processing_error

Log email processing error

log_queue_message_received

Log queue message processing

log_storage_operation

Log storage operations

Source code in azure_bootstrap/services/telemetry.py
def __init__(self) -> None:
    self.tracer: Any = None
    self._configured = False

configure

configure(connection_string: str | None = None, allow_reconfigure: bool = False) -> bool

Configure Application Insights telemetry with support for bootstrap flow reconfiguration

Parameters:

Name Type Description Default
connection_string str | None

App Insights connection string

None
allow_reconfigure bool

If True, allows reconfiguration even if already configured

False
Source code in azure_bootstrap/services/telemetry.py
def configure(
    self, connection_string: str | None = None, allow_reconfigure: bool = False
) -> bool:
    """
    Configure Application Insights telemetry with support for bootstrap flow reconfiguration

    Args:
        connection_string: App Insights connection string
        allow_reconfigure: If True, allows reconfiguration even if already configured
    """
    if self._configured and not allow_reconfigure:
        return True

    try:
        # Get connection string from environment or parameter
        app_insights_connection_string = connection_string or os.environ.get(
            "APPLICATIONINSIGHTS_CONNECTION_STRING"
        )

        if not app_insights_connection_string:
            logging.warning(
                "Application Insights connection string not found. Using basic logging."
            )
            self._configure_logging()
            self._configured = True
            return True

        if not TELEMETRY_AVAILABLE:
            logging.warning("Azure Monitor OpenTelemetry not available. Using basic logging.")
            self._configure_logging()
            self._configured = True
            return True

        # Configure Azure Monitor
        configure_azure_monitor(
            connection_string=app_insights_connection_string,
            enable_live_metrics=True,
        )

        # Instrument Azure Functions (if available)
        if AZURE_FUNCTIONS_INSTRUMENTOR_AVAILABLE and AzureFunctionsInstrumentor:
            AzureFunctionsInstrumentor().instrument()

        # Get tracer
        self.tracer = trace.get_tracer(__name__)

        # Configure structured logging
        self._configure_logging()

        self._configured = True
        logging.info("Application Insights telemetry configured successfully")
        return True

    except Exception as e:
        logging.error(f"Failed to configure Application Insights: {str(e)}")
        # Fallback to basic logging
        self._configure_logging()
        self._configured = True
        return True

try_upgrade_from_config

try_upgrade_from_config(config_repository: EnhancedConfigRepositoryInterface) -> bool

Attempt to upgrade from basic logging to App Insights after config is loaded

This method is called after configuration loading to check if an App Insights connection string is now available from App Config/Key Vault that wasn't available during initial bootstrap.

Parameters:

Name Type Description Default
config_repository EnhancedConfigRepositoryInterface

Enhanced config repository to check for connection string

required

Returns:

Type Description
bool

True if upgrade was attempted (success or failure), False if no upgrade needed

Source code in azure_bootstrap/services/telemetry.py
def try_upgrade_from_config(self, config_repository: EnhancedConfigRepositoryInterface) -> bool:
    """
    Attempt to upgrade from basic logging to App Insights after config is loaded

    This method is called after configuration loading to check if an App Insights
    connection string is now available from App Config/Key Vault that wasn't
    available during initial bootstrap.

    Args:
        config_repository: Enhanced config repository to check for connection string

    Returns:
        True if upgrade was attempted (success or failure), False if no upgrade needed
    """
    # Don't upgrade if already using App Insights
    if self.tracer is not None:
        logging.debug("Already using Application Insights, no upgrade needed")
        return False

    # Check if connection string is now available from config
    # First try get_value() which checks env vars, cache, App Config, then Key Vault fallback
    # If not found, try get_secret_value() for direct Key Vault access
    try:
        app_insights_connection_string = config_repository.get_value(
            "APPLICATIONINSIGHTS_CONNECTION_STRING"
        )

        # If not found via get_value, try direct Key Vault access as last resort
        if not app_insights_connection_string:
            app_insights_connection_string = config_repository.get_secret_value(
                "APPLICATIONINSIGHTS_CONNECTION_STRING"
            )

        if app_insights_connection_string:
            logging.info(
                "Found Application Insights connection string in config, upgrading from basic logging"
            )

            # Reconfigure with the new connection string
            success = self.configure(
                connection_string=app_insights_connection_string, allow_reconfigure=True
            )

            if success and self.tracer:
                logging.info("Successfully upgraded to Application Insights telemetry")
                return True
            else:
                logging.warning(
                    "Failed to upgrade to Application Insights, continuing with basic logging"
                )
                return True
        else:
            logging.debug("No Application Insights connection string found in config")
            return False

    except Exception as e:
        logging.warning(f"Error checking for Application Insights upgrade: {str(e)}")
        return False

get_tracer

get_tracer() -> Any

Get the configured tracer

Source code in azure_bootstrap/services/telemetry.py
def get_tracer(self) -> Any:
    """Get the configured tracer"""
    return self.tracer

create_span

create_span(name: str, attributes: dict[str, Any] | None = None) -> Any

Create a new trace span

Source code in azure_bootstrap/services/telemetry.py
def create_span(self, name: str, attributes: dict[str, Any] | None = None) -> Any:
    """Create a new trace span"""
    # Check if telemetry is available and tracer is configured
    has_tracer = bool(getattr(self, "tracer", None))
    if TELEMETRY_AVAILABLE and has_tracer and self.tracer is not None:
        return self.tracer.start_span(name, attributes=attributes)
    return None

log_email_processing_start

log_email_processing_start(message_id: str | None = None, user_email: str | None = None) -> None

Log email processing start with structured data

Source code in azure_bootstrap/services/telemetry.py
def log_email_processing_start(
    self, message_id: str | None = None, user_email: str | None = None
) -> None:
    """Log email processing start with structured data"""
    log_data = {
        "event": "email_processing_start",
        "message_id": message_id,
        "user_email": user_email,
        "operation": "read_email",
    }
    logging.info("Email processing started", extra=log_data)

log_email_processing_success

log_email_processing_success(message_id: str, user_email: str, processing_time_ms: int) -> None

Log successful email processing

Source code in azure_bootstrap/services/telemetry.py
def log_email_processing_success(
    self, message_id: str, user_email: str, processing_time_ms: int
) -> None:
    """Log successful email processing"""
    log_data = {
        "event": "email_processing_success",
        "message_id": message_id,
        "user_email": user_email,
        "processing_time_ms": processing_time_ms,
        "operation": "read_email",
    }
    logging.info("Email processing completed successfully", extra=log_data)

log_email_processing_error

log_email_processing_error(error: str, message_id: str | None = None, user_email: str | None = None) -> None

Log email processing error

Source code in azure_bootstrap/services/telemetry.py
def log_email_processing_error(
    self, error: str, message_id: str | None = None, user_email: str | None = None
) -> None:
    """Log email processing error"""
    log_data = {
        "event": "email_processing_error",
        "error": error,
        "message_id": message_id,
        "user_email": user_email,
        "operation": "read_email",
    }
    logging.error("Email processing failed", extra=log_data)

log_queue_message_received

log_queue_message_received(queue_name: str, message_id: str) -> None

Log queue message processing

Source code in azure_bootstrap/services/telemetry.py
def log_queue_message_received(self, queue_name: str, message_id: str) -> None:
    """Log queue message processing"""
    log_data = {
        "event": "queue_message_received",
        "queue_name": queue_name,
        "message_id": message_id,
        "operation": "queue_processing",
    }
    logging.info("Queue message received", extra=log_data)

log_storage_operation

log_storage_operation(operation: str, container: str, blob_name: str, success: bool) -> None

Log storage operations

Source code in azure_bootstrap/services/telemetry.py
def log_storage_operation(
    self, operation: str, container: str, blob_name: str, success: bool
) -> None:
    """Log storage operations"""
    log_data = {
        "event": "storage_operation",
        "operation": operation,
        "container": container,
        "blob_name": blob_name,
        "success": success,
    }
    level = logging.INFO if success else logging.ERROR
    logging.log(level, f"Storage operation: {operation}", extra=log_data)

create_enhanced_config_repository

create_enhanced_config_repository(app_config_connection_string: str | None = None, secrets_repository: SecretsRepositoryInterface | None = None, auto_load_to_environ: bool = False) -> EnhancedConfigRepositoryInterface

Factory function to create an enhanced configuration repository.

This factory function provides a convenient way to create a properly configured EnhancedConfigRepository instance.

Parameters:

Name Type Description Default
app_config_connection_string str | None

Azure App Configuration connection string

None
secrets_repository SecretsRepositoryInterface | None

Optional secrets repository for Key Vault integration

None
auto_load_to_environ bool

If True, automatically load configs to os.environ on init

False

Returns:

Name Type Description
EnhancedConfigRepositoryInterface EnhancedConfigRepositoryInterface

Configured repository instance

Usage

Simple usage with environment variables only

config_repo = create_enhanced_config_repository()

With App Config

config_repo = create_enhanced_config_repository( app_config_connection_string="Endpoint=...", auto_load_to_environ=True )

With App Config and Key Vault

secrets_repo = SecretsRepository(vault_url="...") config_repo = create_enhanced_config_repository( app_config_connection_string="Endpoint=...", secrets_repository=secrets_repo, auto_load_to_environ=True )

Source code in azure_bootstrap/repositories/enhanced_config_repository.py
def create_enhanced_config_repository(
    app_config_connection_string: str | None = None,
    secrets_repository: SecretsRepositoryInterface | None = None,
    auto_load_to_environ: bool = False,
) -> EnhancedConfigRepositoryInterface:
    """
    Factory function to create an enhanced configuration repository.

    This factory function provides a convenient way to create a properly
    configured EnhancedConfigRepository instance.

    Args:
        app_config_connection_string: Azure App Configuration connection string
        secrets_repository: Optional secrets repository for Key Vault integration
        auto_load_to_environ: If True, automatically load configs to os.environ on init

    Returns:
        EnhancedConfigRepositoryInterface: Configured repository instance

    Usage:
        # Simple usage with environment variables only
        config_repo = create_enhanced_config_repository()

        # With App Config
        config_repo = create_enhanced_config_repository(
            app_config_connection_string="Endpoint=...",
            auto_load_to_environ=True
        )

        # With App Config and Key Vault
        secrets_repo = SecretsRepository(vault_url="...")
        config_repo = create_enhanced_config_repository(
            app_config_connection_string="Endpoint=...",
            secrets_repository=secrets_repo,
            auto_load_to_environ=True
        )
    """
    logger.info(
        "Creating enhanced configuration repository",
        extra={
            "has_app_config": bool(app_config_connection_string),
            "has_secrets_repo": bool(secrets_repository),
            "auto_load": auto_load_to_environ,
            "operation": "create_repository",
        },
    )

    return EnhancedConfigRepository(
        app_config_connection_string=app_config_connection_string,
        secrets_repository=secrets_repository,
        auto_load_to_environ=auto_load_to_environ,
    )

initialize_application

initialize_application(secrets_repository: SecretsRepositoryInterface | None = None) -> EnhancedConfigRepositoryInterface

Convenience function to perform complete application bootstrap.

This is the main entry point for application initialization. It handles the complete bootstrap sequence and returns the configured repository.

Parameters:

Name Type Description Default
secrets_repository SecretsRepositoryInterface | None

Optional secrets repository for Key Vault integration

None

Returns:

Type Description
EnhancedConfigRepositoryInterface

Configured enhanced configuration repository with all configs loaded

Example

Simple initialization

config_repo = initialize_application()

With secrets repository

from src.repositories.secrets_repository import create_secrets_repository secrets_repo = create_secrets_repository() config_repo = initialize_application(secrets_repository=secrets_repo)

After initialization, use standard os.environ access

app_insights_key = os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING")

Source code in azure_bootstrap/services/application_bootstrap.py
def initialize_application(
    secrets_repository: SecretsRepositoryInterface | None = None,
) -> EnhancedConfigRepositoryInterface:
    """
    Convenience function to perform complete application bootstrap.

    This is the main entry point for application initialization. It handles
    the complete bootstrap sequence and returns the configured repository.

    Args:
        secrets_repository: Optional secrets repository for Key Vault integration

    Returns:
        Configured enhanced configuration repository with all configs loaded

    Example:
        # Simple initialization
        config_repo = initialize_application()

        # With secrets repository
        from src.repositories.secrets_repository import create_secrets_repository
        secrets_repo = create_secrets_repository()
        config_repo = initialize_application(secrets_repository=secrets_repo)

        # After initialization, use standard os.environ access
        app_insights_key = os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING")
    """
    bootstrap = ApplicationBootstrap(secrets_repository=secrets_repository)
    repo = bootstrap.initialize()
    global _last_initialized_repo
    _last_initialized_repo = repo
    return repo

get_bootstrap_logger

get_bootstrap_logger(name: str) -> Logger

Get a logger that works during bootstrap phase.

Parameters:

Name Type Description Default
name str

Logger name (typically name)

required

Returns:

Type Description
Logger

Logger configured for bootstrap use

Example

from src.infrastructure.bootstrap_logging import get_bootstrap_logger

logger = get_bootstrap_logger(name) logger.info("This works before full telemetry setup!")

Source code in azure_bootstrap/services/bootstrap_logging.py
def get_bootstrap_logger(name: str) -> logging.Logger:
    """
    Get a logger that works during bootstrap phase.

    Args:
        name: Logger name (typically __name__)

    Returns:
        Logger configured for bootstrap use

    Example:
        from src.infrastructure.bootstrap_logging import get_bootstrap_logger

        logger = get_bootstrap_logger(__name__)
        logger.info("This works before full telemetry setup!")
    """
    return BootstrapLogger.create_logger(name)