Skip to main content

Developer-friendly logging helpers for Azure Functions Python

Project description

azure-functions-logging

PyPI Python Version CI Release Security Scans codecov pre-commit Docs License: MIT

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:

Before: plain print output with no context

With azure-functions-logging — colorized local dev output and production-ready JSON:

After: structured color output and 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 request
  • function_name — the Azure Functions function name
  • trace_id — trace context from the platform
  • cold_startTrue on 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

Ecosystem

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

azure_functions_logging-0.4.0.tar.gz (197.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

azure_functions_logging-0.4.0-py3-none-any.whl (16.1 kB view details)

Uploaded Python 3

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

Hashes for azure_functions_logging-0.4.0.tar.gz
Algorithm Hash digest
SHA256 1148356b791c0fe2ee34d97d6cd974d8deae640314a961c9ab9dd8da8282b2ca
MD5 1e721a5c15eb917a28f30ab7bc75999d
BLAKE2b-256 4c756c6b25e2b4b8970dd3f034964459b1d7ce33509288762294178eb7590152

See more details on using hashes here.

Provenance

The following attestation bundles were made for azure_functions_logging-0.4.0.tar.gz:

Publisher: release.yml on yeongseon/azure-functions-logging

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file azure_functions_logging-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for azure_functions_logging-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1f9083b5e9448910aa8b717bfb70af45039ddebf9726f63c9b4dfb6b11b2e3e6
MD5 f38474ff512e9299506b20ee56264461
BLAKE2b-256 da9eb1517174f28cea7a5bb2fc280fe86e7f315b56347cde3f863cea67602e5a

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page