Developer-friendly logging helpers for Azure Functions Python
Project description
azure-functions-logging
Read this in: 한국어 | 日本語 | 简体中文
Invocation-aware observability for Azure Functions Python v2.
Surfaces invocation_id, detects cold starts, warns on host.json misconfig, and outputs Application Insights-ready structured logs — without replacing Python's standard logging.
Why This Exists
Azure Functions Python logging has specific failure modes that generic logging libraries don't address:
| Problem | What happens | This library |
|---|---|---|
host.json log level conflict |
Your INFO logs silently disappear in Azure |
Detects and warns at startup |
No invocation_id in logs |
Impossible to correlate logs to a specific execution | Auto-injects from context object |
| Cold start invisible | No signal when a new worker instance starts | Detects automatically on first inject_context() |
| Noisy third-party loggers | azure-core, urllib3 flood your Application Insights |
SamplingFilter / RedactionFilter |
| Local vs cloud output mismatch | Colorized output breaks in production pipelines | Environment-aware formatter switching |
| PII leaking into logs | Sensitive fields logged in exception tracebacks | RedactionFilter with pattern matching |
Before / After
Without azure-functions-logging — plain print() output, no context, no structure:
With azure-functions-logging — colorized local dev output and production-ready JSON:
Installation
pip install azure-functions-logging
Quick Start
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")
# {"level": "INFO", "invocation_id": "abc-123", "cold_start": true, ...}
return func.HttpResponse("OK")
Invocation Context
inject_context(context) should be the first line of every handler. It binds:
invocation_id— unique per execution, correlates all logs for one requestfunction_name— the Azure Functions function nametrace_id— trace context from the platformcold_start—Trueon first invocation of this worker process
def my_function(req, context):
inject_context(context)
logger.info("handler started")
# every log from here carries invocation_id and cold_start
Without inject_context(), these fields are None in every log line.
Structured JSON Output (Production)
Use JSON format when logs feed Application Insights or any aggregation system:
setup_logging(format="json")
Output per log line (NDJSON — one JSON object per line):
{"timestamp": "2024-01-15T10:30:00Z", "level": "INFO", "logger": "my_module",
"message": "order accepted", "invocation_id": "abc-123", "function_name": "OrderHandler",
"cold_start": false, "trace_id": "00-abc...", "extra": {"order_id": "o-999"}}
Extra fields appear in extra and are indexable in Application Insights:
logger.info("order accepted", order_id="o-999", tenant_id="t-1")
host.json Conflict Detection
If your host.json suppresses log levels that your app emits, you get this warning at startup:
WARNING: host.json logLevel.default is 'Warning'. Logs below WARNING will be suppressed in Azure.
Recommended host.json baseline:
{
"version": "2.0",
"logging": {
"logLevel": {
"default": "Information",
"Function": "Information"
}
}
}
Noise Control
Suppress chatty third-party loggers without removing them:
from azure_functions_logging import SamplingFilter, setup_logging
import logging
setup_logging()
# Only log 1 in 10 azure-core messages
logging.getLogger("azure").addFilter(SamplingFilter(rate=0.1))
# Silence urllib3 completely in production
logging.getLogger("urllib3").setLevel(logging.WARNING)
PII Redaction
Strip sensitive fields before they reach Application Insights:
from azure_functions_logging import RedactionFilter, setup_logging
import logging
setup_logging()
root = logging.getLogger()
root.addFilter(RedactionFilter(patterns=["password", "token", "secret"]))
Any log record where the message or extra fields match a pattern will have those values replaced with [REDACTED].
Local vs Cloud
| Environment | Format | Behavior |
|---|---|---|
| Local terminal | color (default) |
Colorized [TIME] [LEVEL] [LOGGER] message |
| Azure / Core Tools | json |
NDJSON, no ANSI codes, host-managed handlers |
| CI / pipeline | json |
NDJSON, machine-parseable |
setup_logging() detects FUNCTIONS_WORKER_RUNTIME and WEBSITE_INSTANCE_ID to choose the right path automatically. In Azure, it installs context filters without adding handlers (avoids duplicate output from the host pipeline).
Context Binding
Attach request-scoped metadata to every log without passing it through every call:
def process_order(order_id: str) -> None:
order_logger = logger.bind(order_id=order_id, region="eastus")
order_logger.info("processing started") # includes order_id + region
order_logger.info("processing complete") # same metadata, new message
Create bound loggers per-invocation. Do not cache them at module level.
Documentation
- Full docs: yeongseon.github.io/azure-functions-logging
- Configuration reference
- Troubleshooting guide
- API reference
Ecosystem
- azure-functions-doctor — Pre-deploy health gate CLI
- azure-functions-validation — Request and response validation
- azure-functions-openapi — OpenAPI and Swagger UI
- azure-functions-scaffold — Project scaffolding
- azure-functions-python-cookbook — Recipes and examples
Disclaimer
This project is an independent community project and is not affiliated with, endorsed by, or maintained by Microsoft.
Azure and Azure Functions are trademarks of Microsoft Corporation.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file azure_functions_logging-0.4.0.tar.gz.
File metadata
- Download URL: azure_functions_logging-0.4.0.tar.gz
- Upload date:
- Size: 197.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1148356b791c0fe2ee34d97d6cd974d8deae640314a961c9ab9dd8da8282b2ca
|
|
| MD5 |
1e721a5c15eb917a28f30ab7bc75999d
|
|
| BLAKE2b-256 |
4c756c6b25e2b4b8970dd3f034964459b1d7ce33509288762294178eb7590152
|
Provenance
The following attestation bundles were made for azure_functions_logging-0.4.0.tar.gz:
Publisher:
release.yml on yeongseon/azure-functions-logging
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
azure_functions_logging-0.4.0.tar.gz -
Subject digest:
1148356b791c0fe2ee34d97d6cd974d8deae640314a961c9ab9dd8da8282b2ca - Sigstore transparency entry: 1154433979
- Sigstore integration time:
-
Permalink:
yeongseon/azure-functions-logging@4581131d53a5725add9ddb9a102bbc8cc2d38ed0 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/yeongseon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4581131d53a5725add9ddb9a102bbc8cc2d38ed0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file azure_functions_logging-0.4.0-py3-none-any.whl.
File metadata
- Download URL: azure_functions_logging-0.4.0-py3-none-any.whl
- Upload date:
- Size: 16.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f9083b5e9448910aa8b717bfb70af45039ddebf9726f63c9b4dfb6b11b2e3e6
|
|
| MD5 |
f38474ff512e9299506b20ee56264461
|
|
| BLAKE2b-256 |
da9eb1517174f28cea7a5bb2fc280fe86e7f315b56347cde3f863cea67602e5a
|
Provenance
The following attestation bundles were made for azure_functions_logging-0.4.0-py3-none-any.whl:
Publisher:
release.yml on yeongseon/azure-functions-logging
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
azure_functions_logging-0.4.0-py3-none-any.whl -
Subject digest:
1f9083b5e9448910aa8b717bfb70af45039ddebf9726f63c9b4dfb6b11b2e3e6 - Sigstore transparency entry: 1154433980
- Sigstore integration time:
-
Permalink:
yeongseon/azure-functions-logging@4581131d53a5725add9ddb9a102bbc8cc2d38ed0 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/yeongseon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4581131d53a5725add9ddb9a102bbc8cc2d38ed0 -
Trigger Event:
push
-
Statement type: