04 - Logging and Monitoring (Dedicated)¶
Capture structured logs, query telemetry, and validate operational visibility.
Prerequisites¶
- You completed 03 - Configuration.
- Your function app
$APP_NAMEis deployed and running with Application Insights connected.
What You'll Build¶
- Emit structured application logs from Node.js HTTP functions.
- Query Application Insights traces to verify telemetry ingestion.
- Use
az webapp log tailfor real-time log streaming on Dedicated plans.
Infrastructure Context
Plan: Dedicated (B1) | Monitoring: Application Insights (auto-created) | Log streaming: az webapp log tail
Application Insights is auto-created with the same name as the function app. On Dedicated plans, real-time log streaming uses az webapp log tail (not az functionapp log tail, which does not exist).
flowchart LR
FA[Function App\nDedicated B1] -->|Telemetry SDK| AI[Application Insights\nfunc-ndded-04100022]
FA -->|stdout/stderr| LOGS[Log Stream\naz webapp log tail]
subgraph MONITORING["Observability"]
AI
LOGS
KQL[KQL Queries\ntraces / requests]
end
AI --> KQL
style FA fill:#ff8c00,color:#fff
style MONITORING fill:#E3F2FD,stroke:#1976D2
style AI fill:#FFF3E0 Steps¶
-
Review the logging function.
The reference app includes
src/functions/logLevels.jswhich emits structured logs at different severity levels:const { app } = require('@azure/functions'); app.http('logLevels', { methods: ['GET'], route: 'loglevels', handler: async (_request, context) => { context.log('Info-level message from logLevels'); context.warn('Warning-level message from logLevels'); context.error('Error-level message from logLevels'); return { status: 200, jsonBody: { logged: true } }; } }); -
Generate telemetry by invoking endpoints.
curl --request GET "https://$APP_NAME.azurewebsites.net/api/health" curl --request GET "https://$APP_NAME.azurewebsites.net/api/hello/Monitor" curl --request GET "https://$APP_NAME.azurewebsites.net/api/info"Telemetry ingestion delay
Application Insights has a 2–5 minute ingestion delay for new data. Wait at least 3 minutes after invoking endpoints before querying traces.
-
Query Application Insights traces.
App Insights name
The Application Insights resource is auto-created with the same name as the function app (
func-ndded-04100022), not$APP_NAME-ai. Use--app "$APP_NAME"for queries.az monitor app-insights query \ --app "$APP_NAME" \ --resource-group "$RG" \ --analytics-query "traces | where timestamp > ago(30m) | project timestamp, message, severityLevel | take 20" \ --output jsonExpected output (abridged):
{ "tables": [ { "name": "PrimaryResult", "columns": [ { "name": "timestamp", "type": "datetime" }, { "name": "message", "type": "string" }, { "name": "severityLevel", "type": "int" } ], "rows": [ ["2026-04-09T16:03:51.569Z", "Node.js v20 reached EOL on 2026-04...", 3], ["2026-04-09T16:03:51.731Z", "Using the AzureStorage storage provider.", 1], ["2026-04-09T16:03:54.950Z", "Initializing Warmup Extension.", 1], ["2026-04-09T16:04:20.575Z", "Handled hello for Monitor", 1] ] } ] }How to read this
severityLevel: 1= Information,2= Warning,3= Error- Runtime startup messages appear first, followed by your function logs
- The Node.js EOL warning (severity 3) is expected for Node.js 20 deployments
-
Stream real-time logs (Dedicated plan).
az functionapp log taildoes not existAs of Azure CLI 2.83.0,
az functionapp log tailis not a valid command. On Dedicated plans, useaz webapp log tailinstead, which works because Dedicated Function Apps run on App Service infrastructure.Then in another terminal, trigger a request:
Expected log stream output:
-
Query request performance metrics.
Verification¶
The query result proves telemetry ingestion is active for your Function App. Verify:
tracestable contains your function log messagesrequeststable shows HTTP invocations with status codes and durationsaz webapp log tailstreams real-time logs (notaz functionapp log tail)
See Also¶
- Tutorial Overview & Plan Chooser
- Node.js Language Guide
- Platform: Hosting Plans
- Operations: Deployment
- Recipes Index