Skip to content

Configuration

This guide documents every setup_logging() option and how configuration behaves across local development, Azure Functions Core Tools, and Azure-hosted runtimes.

Function Signature

def setup_logging(
    *,
    level: int = logging.INFO,
    format: str = "color",
    logger_name: str | None = None,
) -> None

setup_logging() is designed to be called once during startup.

Configuration Principles

  • Idempotent initialization: repeated calls are no-ops.
  • Environment-aware behavior: local and Azure runtime paths differ.
  • Standard logging compatibility: no custom logging framework required.

Note

In Azure or Core Tools environments, the library intentionally avoids adding handlers to prevent duplicate output.

Parameter: level

level controls message filtering in local standalone execution.

Accepted values are standard logging levels:

  • logging.DEBUG
  • logging.INFO (default)
  • logging.WARNING
  • logging.ERROR
  • logging.CRITICAL

Example:

import logging
from azure_functions_logging import setup_logging

setup_logging(level=logging.DEBUG)

Behavior details:

  • Local standalone: applied to target logger.
  • Azure/Core Tools: host pipeline governs output; app-level level may be effectively constrained by host config.

Parameter: format

format selects output formatter in local standalone mode.

Supported values:

  • "color" (default)
  • "json"

Example:

from azure_functions_logging import setup_logging

setup_logging(format="json")

If an unsupported value is provided, setup_logging() raises ValueError.

Warning

Use format="json" for machine parsing and centralized ingestion. Color output is optimized for human readability in terminals.

Parameter: logger_name

logger_name lets you target a specific logger in local standalone mode.

from azure_functions_logging import setup_logging

setup_logging(logger_name="my_service")

When logger_name is None:

  • Local standalone: root logger is configured.
  • Azure/Core Tools: root handlers receive ContextFilter.

When logger_name is set:

  • Local standalone: named logger is configured.
  • Azure/Core Tools: filter installation still follows runtime-safe behavior.

Practical recommendation:

  • Prefer root configuration unless you have a clear logger isolation strategy.

Idempotency and Reconfiguration

setup_logging() uses internal setup state to guarantee idempotency.

Implications:

  • First call wins.
  • Later calls do not replace handler/formatter choices.
  • Conflicting setup calls in different modules can lead to surprising expectations.

Best practice:

from azure_functions_logging import setup_logging

# Run once at module import or startup hook
setup_logging(format="json")

Environment Detection

The setup path depends on environment signals:

  • Functions environment check: FUNCTIONS_WORKER_RUNTIME
  • Azure-hosted check: WEBSITE_INSTANCE_ID

Execution behavior by environment:

Local standalone Python process

  • Sets logger level.
  • Adds StreamHandler if no handlers exist.
  • Installs ContextFilter on handlers.
  • Uses selected formatter (ColorFormatter or JsonFormatter).

Azure Functions / Core Tools

  • Does not add new handlers.
  • Does not override host-managed handler strategy.
  • Installs ContextFilter to enrich records with invocation fields.
  • Emits host-level conflict warning checks.

Tip

This split behavior prevents duplicate logs in Azure while still giving rich local developer output.

host.json Level Conflict Warning

In Azure/Core Tools paths, the library checks host.json and warns if host defaults are stricter than your configured level.

Example warning intent:

host.json logLevel.default is set to 'Warning' ... Logs below 'Warning' will be suppressed.

Why this matters:

  • You may set level=logging.INFO in code.
  • Host config can still suppress INFO lines.
  • Without a warning, this looks like missing logs.

Recommended host.json baseline:

{
  "logging": {
    "logLevel": {
      "default": "Information"
    }
  }
}

Color vs JSON Format Selection

Use format="color" when:

  • You are iterating locally.
  • Humans are primary log consumers.
  • You want fast visual scanning of level severity.

Use format="json" when:

  • Logs feed aggregation systems.
  • You need structured indexing and queries.
  • You rely on downstream analytics and alerting.

Using get_logger() with Configuration

Typical startup and logger creation:

from azure_functions_logging import get_logger, setup_logging

setup_logging(format="json")
logger = get_logger(__name__)
logger.info("application initialized")

get_logger(name) returns a FunctionLogger wrapper that preserves standard logging ergonomics and supports context binding.

Advanced Pattern: Custom Formatter Pipeline

For advanced local scenarios you can still combine standard logging with this package:

import logging
from azure_functions_logging import setup_logging

setup_logging(format="json")

custom_handler = logging.StreamHandler()
custom_handler.setFormatter(logging.Formatter("%(levelname)s %(name)s %(message)s"))

target = logging.getLogger("custom")
target.addHandler(custom_handler)
target.setLevel(logging.INFO)

Guidelines for advanced customization:

  • Avoid duplicating handlers on root unless intentional.
  • Keep inject_context(context) in handlers so context fields remain available.
  • Prefer one canonical output format per deployment tier.

Validation Checklist

Before finalizing configuration:

  • Verify setup is called exactly once.
  • Verify chosen format matches consumer expectations.
  • Verify host.json does not suppress required levels.
  • Verify named logger usage is consistent across modules.
  • Verify JSON output can be parsed by your log ingestion tool.

See Also