# 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.4.1
- Python: >=3.10, <3.15
- License: MIT
- Docs: https://yeongseon.github.io/azure-functions-logging/
- Repository: https://github.com/yeongseon/azure-functions-logging

## 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
- **No root logger mutation** — respects `host.json` configuration, installs filters only
- **Zero runtime dependency** — on azure-functions (works with any context-like object)

## Core API

- `setup_logging(level, format, ...)` — One-call logging setup for local or Azure
- `get_logger(name)` → `FunctionLogger` — Create a logger with context binding support
- `FunctionLogger` — Enhanced logger wrapper with `bind()` for context
- `JsonFormatter` — JSON log formatter (NDJSON)
- `RedactionFilter` — Filter to redact sensitive fields (password, token, api_key, etc.)
- `SamplingFilter` — Filter for log sampling/rate-limiting noisy loggers
- `inject_context(context)` — Set contextvars-based fields from Azure Functions context
- `with_context` — Decorator to inject context per-request (sync/async)

## Quick Start

```python
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="hello")
def hello(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    inject_context(context)  # binds invocation_id, function_name, cold_start
    logger.info("Request received")
    return func.HttpResponse("OK")
```

Or use the decorator:

```python
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/getting-started/)
- [API Reference](https://yeongseon.github.io/azure-functions-logging/api/)
- [Configuration](https://yeongseon.github.io/azure-functions-logging/configuration/)
- [Examples](https://yeongseon.github.io/azure-functions-logging/examples/)
- [Troubleshooting](https://yeongseon.github.io/azure-functions-logging/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
