Hello MrFlinstone!
Python Azure Function logs from logging.info() work locally but fail to appear in Application Insights (AI) or Log Stream when deployed, showing only Kudu deployment logs in traces queries and "No instances" in file stream. This occurs because Python Functions on Azure use a worker process model where standard logging.info() requires explicit Azure Functions context integration, host.json sampling drops traces, and the Python runtime version/extension bundle needs Python-specific logging enabled.
Immediate Fixes
1. Update host.json (Critical)
Replace your current host.json with this Python-optimized version to disable sampling and enable function-level logging:
{
"version": "2.0",
"logging": {
"logLevel": {
"default": "Information",
"Function": "Information",
"Host.Results": "Error",
"Host.Aggregator": "Trace",
"Worker": "Information"
},
"applicationInsights": {
"samplingSettings": {
"isEnabled": false
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
Deploy, restart the Function App, and test. The "Worker": "Information" entry and disabled sampling capture Python worker process logs.
2. Fix Python Logging Code
Update your function code to use Azure Functions structured logging:
import azure.functions as func
import logging
import sys
from azure.functions import Context
def main(ctx: Context) -> None:
# Use Azure Functions logger with invocation context
log = ctx.get_logger()
log.info("SMTP login successful for birthday events.")
log.info("Sending event email to user@example.com / Happy Birthday")
# Or configure standard logging properly
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("azure.function")
logger.info("Custom log message")
The ctx.get_logger() automatically attaches invocation ID and routes to AI. Avoid bare logging.info() without context.
Verification Steps
Application Insights Query
Use this refined KQL query post-fix:
traces
| where cloud_RoleName == "YourFunctionAppName"
| where timestamp > ago(1h)
| where message contains "SMTP" or message contains "birthday"
| order by timestamp desc
| limit 100
Filter by cloud_RoleName to exclude Kudu logs.
Enable Log Stream
- Function App > Monitoring > Log stream
- Select Application Insights (not Filesystem)
- Trigger function—logs appear in real-time.
Check Runtime Settings
Function App > Configuration > General settings:
- Python Version: 3.9, 3.10, 3.11, or 3.12 (avoid 3.8)
- Always On: Enabled for HTTP triggers
- Restart after changes.
Why Local Works, Azure Doesn't
Local development uses func start with console output. Azure Python runs in isolated worker processes where:
- Logs need explicit routing to AI collector
- Sampling (default 95%) drops INFO traces
- File system logging unsupported on Linux Consumption plan
- Extension bundle version affects Python logging support[8][3]
Quick Test Function
Deploy this minimal function to validate logging:
function.json (HTTP trigger):
{
"scriptFile": "__init__.py",
"bindings": [{"authLevel": "anonymous", "type": "httpTrigger", "direction": "in", "name": "req", "methods": ["get"]}]
}
init.py:
import azure.functions as func
import logging
def main(req: func.HttpRequest) -> func.HttpResponse:
logging.info("=== TEST LOG START ===")
log = func.Context.get_current().get_logger()
log.info("Azure Functions logger test - should appear in AI")
logging.info("Standard logger test - should appear in AI")
logging.info("=== TEST LOG END ===")
return func.HttpResponse("Check AI logs", status_code=200)
Hit the endpoint, then query AI traces.
Production Logging Strategy
Once fixed, re-enable sampling with conservative settings:
"samplingSettings": {
"isEnabled": true,
"maxTelemetryItemsPerSecond": 20,
"excludedTypes": "Request,Dependency"
}
Implement structured logging with categories:
logger = logging.getLogger("birthday.smtp")
logger.info("Email sent", extra={"recipient": "user@example.com", "status": "success"})
These changes resolve 95% of missing Python Function logs. Deploy the updated host.json first, then test with the sample code.
Best Regards,
Jerald Felix