Skip to content

Example: Basic Setup

This example shows a complete local-first setup using setup_logging() and get_logger() with standard log levels.

Goal

You will configure logging once, emit all severity levels, and verify expected output shape.

Example Code

import logging
from azure_functions_logging import get_logger, setup_logging

# Configure once at startup
setup_logging(level=logging.DEBUG, format="color")

logger = get_logger(__name__)

logger.debug("debug message", component="init")
logger.info("info message", component="init")
logger.warning("warning message", component="init")
logger.error("error message", component="init")

try:
    raise RuntimeError("sample failure")
except RuntimeError:
    logger.exception("exception message", component="init")

What to Expect

Local output should include:

  • Timestamp.
  • Colorized level text.
  • Logger name.
  • Message.
  • Exception stack trace for exception().

Illustrative output:

14:41:00 DEBUG    __main__  debug message
14:41:00 INFO     __main__  info message
14:41:00 WARNING  __main__  warning message
14:41:00 ERROR    __main__  error message
14:41:00 ERROR    __main__  exception message
Traceback (most recent call last):
  ...
RuntimeError: sample failure

Why This Pattern Works

  • setup_logging() centralizes configuration.
  • get_logger(__name__) gives module-specific identity.
  • No custom logging framework knowledge required.
  • Existing Python logging habits still apply.

Common Variants

Variant A: INFO and Above

import logging
from azure_functions_logging import setup_logging

setup_logging(level=logging.INFO)

Variant B: JSON Output

import logging
from azure_functions_logging import setup_logging

setup_logging(level=logging.INFO, format="json")

Variant C: Named Logger Targeting

from azure_functions_logging import get_logger, setup_logging

setup_logging(logger_name="payments")
logger = get_logger("payments.api")
logger.info("named logger active")
my_function_app/
  function_app.py
  requirements.txt

Inside function_app.py:

  • Run setup at import time.
  • Keep one logger per module.
  • Use bound loggers for request-local metadata.

Azure Functions Handler Example

import azure.functions as func
from azure_functions_logging import get_logger, inject_context, setup_logging

setup_logging()
logger = get_logger(__name__)

app = func.FunctionApp()


@app.route(route="ping")
def ping(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    inject_context(context)
    logger.info("ping received")
    return func.HttpResponse("pong")

This adds invocation context fields automatically when available.

Troubleshooting Quick Checks

  • No logs: confirm setup_logging() executed before first log call.
  • Missing DEBUG: ensure level=logging.DEBUG.
  • Duplicate logs: ensure no extra root handlers were added elsewhere.
  • Missing context fields: ensure inject_context(context) runs per invocation.

Production Notes

  • Use format="json" for ingestion.
  • Keep color output for local developer workflows.
  • Validate host.json level configuration if running in Functions runtime.