# azure-functions-logging

> Structured logging for Azure Functions Python — invocation-aware, Application Insights-ready, zero breaking changes.

## Package Info

- PyPI: `pip install azure-functions-logging`
- Version: 0.7.1
- Python: >=3.10, <3.15
- License: MIT
- Docs: https://yeongseon.github.io/azure-functions-logging-python/
- Repository: https://github.com/yeongseon/azure-functions-logging-python

## What It Does

Surfaces `invocation_id`, detects cold starts, warns on `host.json` misconfig, and outputs Application Insights-ready structured logs — without replacing Python's standard `logging`.

Key features:
- **Invocation context** — auto-injects `invocation_id`, `function_name`, `cold_start` into every log
- **Structured JSON output** — Application Insights-ready NDJSON format for production
- **Noise control** — `SamplingFilter` rate-limits chatty third-party loggers
- **PII protection** — `RedactionFilter` masks sensitive fields before they reach log aggregation
- **Root logger contract** — in Azure/Core Tools mode, no handlers are added; `ContextFilter` is installed on existing root handlers and on the root logger itself (so direct calls on the root logger carry context). To guarantee coverage for records that propagate from named child loggers to handlers attached later, call `install_context_factory()`. In standalone mode (`logger_name=None`), the root logger's level is set and a `StreamHandler` is added if none exist.
- **Zero runtime dependency** — on azure-functions (works with any context-like object)

## Core API

- `setup_logging(*, level=logging.INFO, format="color", logger_name=None, functions_formatter=None, host_json_path=None)` — Keyword-only. One-call logging setup for local or Azure (pass `logger_name=None` for root logger configuration in standalone mode).
- `get_logger(name)` → `FunctionLogger` — Create a logger with context binding support
- `FunctionLogger` — Enhanced logger wrapper with `bind()`, `log()`, `hasHandlers()`, `setLevel()`, `isEnabledFor()`, `getEffectiveLevel()` for stdlib parity
- `JsonFormatter` — JSON log formatter (NDJSON), use with `functions_formatter=` in Azure
- `RedactionFilter` — Filter to redact sensitive fields (password, token, api_key, etc.)
- `SamplingFilter` — Filter for log sampling/rate-limiting noisy loggers
- `logging_context(context)` — **Recommended** context manager: injects on enter, always restores on exit
- `inject_context(context)` → `ContextTokens` — Set contextvars; returns tokens for paired restore
- `restore_context(tokens)` — Restore previous contextvars from tokens (paired with `inject_context`)
- `reset_context()` — Clear all context vars unconditionally (for test teardown)
- `with_context` — Decorator to inject context per-request (sync/async)
- `install_context_factory()` — Opt-in global LogRecordFactory so context flows to every record
- `get_logging_metadata(func)` — Inspect `@with_context` metadata on a function; returns `dict[str, Any] | None`
- `ContextTokens` — Type alias for the token bundle returned by `inject_context()`

## Quick Start

```python
import azure.functions as func
from azure_functions_logging import get_logger, logging_context, setup_logging

setup_logging()
logger = get_logger(__name__)

app = func.FunctionApp()

@app.route(route="hello")
def hello(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    with logging_context(context):  # binds invocation_id, function_name, cold_start; always restores on exit
        logger.info("Request received")
        return func.HttpResponse("OK")
```

Or use the decorator:

```python
import azure.functions as func
from azure_functions_logging import with_context, get_logger, setup_logging

setup_logging()
logger = get_logger(__name__)

@with_context
def handler(req, context):
    logger.info("This automatically has context")
    return func.HttpResponse("OK")
```

## Documentation

- [Getting Started](https://yeongseon.github.io/azure-functions-logging-python/getting-started/)
- [API Reference](https://yeongseon.github.io/azure-functions-logging-python/api/)
- [Configuration](https://yeongseon.github.io/azure-functions-logging-python/configuration/)
- [Examples](https://yeongseon.github.io/azure-functions-logging-python/examples/)
- [Troubleshooting](https://yeongseon.github.io/azure-functions-logging-python/troubleshooting/)

## Ecosystem

Part of the Azure Functions Python DX Toolkit:
- azure-functions-validation — Request/response validation
- azure-functions-openapi — OpenAPI spec and Swagger UI
- azure-functions-langgraph — Deploy LangGraph agents as Azure Functions
- azure-functions-doctor — Pre-deploy diagnostics CLI
- azure-functions-scaffold — Project scaffolding CLI
