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¶
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")
Recommended File Layout¶
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.jsonlevel configuration if running in Functions runtime.