API Reference¶
This reference documents the public API exported by azure_functions_logging.
Use this page together with:
- Configuration for setup behavior by environment.
- Usage Guide for complete implementation patterns.
- Examples for runnable snippets.
setup_logging¶
Configure logging for the current environment. Behavior depends on the detected environment:
- Azure / Core Tools: Installs
ContextFilteron the root logger's handlers only. Does NOT add handlers or modify the root logger level (respectshost.jsonconfiguration). Iffunctions_formatteris provided, it is applied to every root handler before the filter is added. - Standalone local development: Adds a
StreamHandlerwithColorFormatterorJsonFormatterto the specified logger (or root logger iflogger_nameis None). Sets the level.
This function is idempotent per logger_name — calling it multiple times
for the same logger has no additional effect.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
int
|
Logging level for local development. Ignored in Azure/Core Tools. |
INFO
|
format
|
str
|
Log output format for local development. Supported values are
|
'color'
|
logger_name
|
str | None
|
Optional logger name to configure. When None, configures the root logger (local dev) or installs filter on root handlers (Azure). |
None
|
functions_formatter
|
Formatter | None
|
Optional custom formatter applied to all root handlers when running inside Azure/Core Tools. Useful for injecting a custom JSON formatter or third-party formatter without losing ContextFilter integration. |
None
|
host_json_path
|
Path | str | None
|
Optional explicit path to a |
None
|
use_record_factory
|
bool
|
When True, install :func: |
False
|
.. warning::
``use_record_factory=True`` modifies the **global**
``logging.LogRecordFactory``, which affects all loggers in the process
(including third-party libraries). The four context field names
(``invocation_id``, ``function_name``, ``trace_id``, ``cold_start``)
become reserved LogRecord attributes — passing them via ``extra=`` to
stdlib loggers will raise ``KeyError``. Prefer :class:`FunctionLogger`
(which sanitizes ``extra`` keys automatically) when this option is on.
Source code in src/azure_functions_logging/_setup.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | |
Usage Notes¶
- Call once during startup.
- Default format is
"color". - In Azure/Core Tools runtime, filter-only behavior avoids duplicate handlers.
Example¶
import logging
from azure_functions_logging import setup_logging
setup_logging(level=logging.INFO, format="json")
Example: Named Target Logger¶
Example: Invalid Format Handling¶
from azure_functions_logging import setup_logging
try:
setup_logging(format="pretty")
except ValueError:
pass
get_logger¶
Create a FunctionLogger wrapping a standard logging.Logger.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
Logger name. Typically |
None
|
Returns:
| Type | Description |
|---|---|
FunctionLogger
|
A |
Source code in src/azure_functions_logging/__init__.py
Usage Notes¶
- Returns a
FunctionLoggerwrapper over a standard logger. - Pass
__name__for module-level identity. - Use the wrapper methods like standard logging methods.
Example¶
from azure_functions_logging import get_logger, setup_logging
setup_logging()
logger = get_logger(__name__)
logger.info("module logger ready")
Example: Root Logger Wrapper¶
from azure_functions_logging import get_logger, setup_logging
setup_logging()
root_logger = get_logger()
root_logger.warning("root logger event")
FunctionLogger¶
Wrapper around a standard logging.Logger with context binding.
FunctionLogger delegates all standard logging methods to the underlying
logger. The bind() method returns a new wrapper with additional context
fields that are merged into extra on each log call.
Context from bind() is supplementary to the ContextFilter-based
context (invocation_id, function_name, etc.) which is set globally via
inject_context().
Source code in src/azure_functions_logging/_logger.py
name
property
¶
Return the name of the underlying logger.
bind(**kwargs)
¶
Return a new FunctionLogger with additional bound context.
The returned logger shares the same underlying logging.Logger
but carries merged context fields. This is an immutable operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Any
|
Context key-value pairs to bind. |
{}
|
Returns:
| Type | Description |
|---|---|
FunctionLogger
|
A new |
Source code in src/azure_functions_logging/_logger.py
clear_context()
¶
critical(msg, *args, **kwargs)
¶
debug(msg, *args, **kwargs)
¶
error(msg, *args, **kwargs)
¶
exception(msg, *args, **kwargs)
¶
Log an ERROR message with exception info.
getEffectiveLevel()
¶
hasHandlers()
¶
info(msg, *args, **kwargs)
¶
isEnabledFor(level)
¶
log(level, msg, *args, **kwargs)
¶
Log msg at the given level, mirroring logging.Logger.log.
Honors the same bind < extra < kwargs merge precedence
as :meth:info / :meth:warning / etc. and applies the same
reserved-key sanitization.
Source code in src/azure_functions_logging/_logger.py
setLevel(level)
¶
Usage Notes¶
bind()returns a new immutable logger wrapper with merged context.clear_context()clears bound context on that wrapper instance.- Logging methods mirror standard logger API.
Example: Binding Context¶
from azure_functions_logging import get_logger, setup_logging
setup_logging(format="json")
logger = get_logger("checkout")
request_logger = logger.bind(request_id="r-100", user_id="u-55")
request_logger.info("checkout started")
Example: Chained Binding¶
base = get_logger("service")
l1 = base.bind(tenant_id="tenant-a")
l2 = l1.bind(operation="import")
l2.info("import queued")
Example: Clearing Bound Context¶
log = get_logger("demo").bind(session="s-1")
log.info("before clear")
log.clear_context()
log.info("after clear")
Example: Exception Logging¶
log = get_logger("errors")
try:
raise RuntimeError("boom")
except RuntimeError:
log.exception("operation failed", phase="load")
JsonFormatter¶
Bases: Formatter
Structured JSON log formatter.
Output is newline-delimited JSON (NDJSON), with one JSON object per log line. Context fields (invocation_id, function_name, etc.) are included when present on the LogRecord (set by ContextFilter).
Unserializable values in extra are coerced to strings via
:func:_json_default rather than dropping the log record.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_string_length
|
int
|
Maximum character length for each native string value
in |
2048
|
truncate_native_strings
|
bool
|
When |
False
|
Source code in src/azure_functions_logging/_json_formatter.py
format(record)
¶
Format a log record as one NDJSON object.
Fully fail-safe: every step (message rendering, exception formatting,
timestamp, JSON serialization) is wrapped so that a hostile
__str__ / __repr__, a malformed exc_info triple, or a
cyclic extra payload never raises out of format(). Worst-case
we still emit a single valid JSON object with sentinel values.
Source code in src/azure_functions_logging/_json_formatter.py
Usage Notes¶
- Use indirectly via
setup_logging(format="json")for most cases. - Produces one JSON object per line (NDJSON style).
- Includes context fields when available on log records.
Example: Automatic Selection¶
from azure_functions_logging import get_logger, setup_logging
setup_logging(format="json")
logger = get_logger("api")
logger.info("json formatter active", version="v1")
Example: Manual Formatter Wiring¶
import logging
from azure_functions_logging import JsonFormatter, get_logger
handler = logging.StreamHandler()
handler.setFormatter(JsonFormatter())
target = logging.getLogger("manual")
target.handlers = [handler]
target.setLevel(logging.INFO)
logger = get_logger("manual")
logger.info("manual formatter configured")
SamplingFilter¶
Bases: Filter
Rate-limit a logger to emit at most rate records per window seconds.
Useful for high-frequency loggers (e.g. per-request HTTP logs, polling loops) that can saturate the Azure Functions gRPC channel.
All records that exceed the rate cap are silently dropped. Records at WARNING and above are always passed through, regardless of the cap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rate
|
int
|
Maximum number of records to pass per window. Must be >= 1. |
100
|
window
|
float
|
Rolling time window in seconds. Default: 1.0. |
1.0
|
name
|
str
|
Optional logger-name scope. When set, only matching loggers are subject to sampling; non-matching records pass through unchanged. Empty string matches all loggers (default). |
''
|
per_logger
|
bool
|
When False (default), all matching records share one rate
bucket per filter instance. When True, each |
False
|
Example::
filter = SamplingFilter(rate=10, window=1.0)
handler.addFilter(filter)
Source code in src/azure_functions_logging/_filters.py
filter(record)
¶
Return True to emit the record, False to drop it.
Source code in src/azure_functions_logging/_filters.py
Usage Notes¶
WARNINGand above always pass.name=scopes sampling to matching logger names; non-matching records bypass sampling.per_logger=Falseshares one bucket across all matching records on the filter instance.per_logger=Truegives eachrecord.namean independent bucket/window.
Example: Per-Logger Buckets for Azure SDK Logs¶
import logging
from azure_functions_logging import SamplingFilter
for handler in logging.getLogger().handlers:
handler.addFilter(SamplingFilter(rate=10, window=1.0, name="azure", per_logger=True))
RedactionFilter¶
Bases: Filter
Mask PII / sensitive values on LogRecord extra attributes in-place.
Iterates over all non-standard attributes on the LogRecord and
replaces the value of any key whose lowercased name is in
sensitive_keys with "***".
This filter mutates the record in-place so both ColorFormatter and
JsonFormatter see redacted values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensitive_keys
|
Iterable[str] | None
|
Iterable of key names to redact (case-insensitive). When None,
uses the built-in default set (23 keys):
|
None
|
name
|
str
|
Optional logger-name scope. When set, only matching loggers are subject to redaction; non-matching records pass through unchanged. |
''
|
Example::
filter = RedactionFilter()
handler.addFilter(filter)
Source code in src/azure_functions_logging/_filters.py
filter(record)
¶
Redact sensitive fields on the record. Always returns True.
Source code in src/azure_functions_logging/_filters.py
inject_context¶
Set invocation context from an Azure Functions context object.
Extracts invocation_id, function_name, trace_id, and cold_start from the provided context and stores them in contextvars.
This function is safe to call with any object. Missing or inaccessible attributes are silently ignored (Principle 3: context injection failures never cause application failures).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
Any
|
An Azure Functions context object (func.Context). |
required |
Returns:
| Type | Description |
|---|---|
ContextTokens
|
A mapping of ContextVar to Token that can be passed to |
ContextTokens
|
|
Source code in src/azure_functions_logging/_context.py
Usage Notes¶
- Call at the start of every function invocation.
- Sets invocation metadata in context variables.
- Enables automatic cold start field in output.
Example: Azure Function Entrypoint¶
import azure.functions as func
from azure_functions_logging import get_logger, inject_context, setup_logging
setup_logging(format="json")
logger = get_logger(__name__)
app = func.FunctionApp()
@app.route(route="status")
def status(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
inject_context(context)
logger.info("status request")
return func.HttpResponse("ok")
Example: Safe with Partial Context Object¶
from azure_functions_logging import get_logger, inject_context, setup_logging
class PartialContext:
invocation_id = "local-123"
setup_logging(format="json")
logger = get_logger("partial")
inject_context(PartialContext())
logger.info("partial context accepted")
End-to-End API Example¶
import logging
import azure.functions as func
from azure_functions_logging import get_logger, inject_context, setup_logging
setup_logging(level=logging.INFO, format="json")
logger = get_logger(__name__)
app = func.FunctionApp()
@app.route(route="orders")
def orders(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
inject_context(context)
req_logger = logger.bind(route="/orders", method=req.method)
req_logger.info("orders request started")
req_logger.info("orders request completed")
return func.HttpResponse("ok")