04 - Logging and Monitoring (Flex Consumption)¶
Enable production-grade observability with Application Insights, structured logs, and baseline alerting for Java handlers.
Prerequisites¶
| Tool | Version | Purpose |
|---|---|---|
| JDK | 17+ | Compile and run Java functions locally |
| Maven | 3.6+ | Build and package Java artifacts |
| Azure Functions Core Tools | v4 | Start local host and publish artifacts |
| Azure CLI | 2.61+ | Provision Azure resources and inspect app state |
Flex Consumption plan basics
Flex Consumption (FC1) keeps serverless economics while adding VNet integration, configurable instance memory (512 MB to 4096 MB), and per-function scaling. Microsoft recommends it for many new apps.
What You'll Build¶
You will instrument Java handlers with structured logs, route telemetry to Application Insights, and validate query-based monitoring signals for a Flex Consumption-hosted app.
flowchart LR
A[ExecutionContext logger] --> B[FunctionAppLogs]
B --> C[Application Insights]
C --> D[Dashboards and alerts] Steps¶
Step 1 - Emit structured logs in handler methods¶
The Java reference app uses ExecutionContext.getLogger() for structured logging. Here is the LogLevelsFunction that emits at multiple severity levels:
@FunctionName("logLevels")
public HttpResponseMessage run(
@HttpTrigger(
name = "req",
methods = {HttpMethod.GET},
authLevel = AuthorizationLevel.ANONYMOUS,
route = "loglevels")
HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
context.getLogger().info("Info-level message from logLevels");
context.getLogger().warning("Warning-level message from logLevels");
context.getLogger().severe("Error-level message from logLevels");
return request.createResponseBuilder(HttpStatus.OK)
.header("Content-Type", "application/json")
.body("{\"logged\":true}")
.build();
}
Step 2 - Generate telemetry by calling endpoints¶
# Trigger structured logging
curl --request GET "https://$APP_NAME.azurewebsites.net/api/loglevels"
# Trigger health check
curl --request GET "https://$APP_NAME.azurewebsites.net/api/health"
# Trigger intentional errors for error telemetry
curl --request GET "https://$APP_NAME.azurewebsites.net/api/testerror"
Telemetry ingestion delay
Application Insights telemetry takes 2-5 minutes to become available for queries after the first request. Wait before running queries.
Step 3 - Confirm Application Insights connection¶
Application Insights is auto-created with the function app. Verify the connection:
az functionapp config appsettings list \
--name "$APP_NAME" \
--resource-group "$RG" \
--query "[?name=='APPLICATIONINSIGHTS_CONNECTION_STRING'].value" \
--output tsv
Step 4 - Query recent traces¶
az monitor app-insights query \
--app "$APP_NAME" \
--resource-group "$RG" \
--analytics-query "traces | where timestamp > ago(30m) | project timestamp, message, severityLevel | order by timestamp desc | take 20"
Use --resource-group with --app
On Flex Consumption, --app "$APP_NAME" alone may fail with PathNotFoundError. Always include --resource-group "$RG" to resolve the App Insights component correctly.
Step 5 - Query request metrics¶
az monitor app-insights query \
--app "$APP_NAME" \
--resource-group "$RG" \
--analytics-query "requests | where timestamp > ago(30m) | project timestamp, name, resultCode, duration | order by timestamp desc | take 20"
Step 6 - View live log stream¶
az functionapp log tail does not exist
As of Azure CLI 2.83.0, use az webapp log tail (not az functionapp log tail) to stream live logs from a function app.
Step 7 - Add an alert for HTTP 5xx spikes¶
FUNCTION_APP_ID=$(az functionapp show \
--name "$APP_NAME" \
--resource-group "$RG" \
--query "id" \
--output tsv)
az monitor metrics alert create \
--name "func-java-http5xx" \
--resource-group "$RG" \
--scopes "$FUNCTION_APP_ID" \
--condition "total Http5xx > 5" \
--window-size 5m \
--evaluation-frequency 1m
Verification¶
Traces query output (showing user-emitted log messages):
timestamp message severityLevel
--------------------------- ----------------------------------------- -------------
2026-04-09T16:57:01.000Z Info-level message from logLevels 1
2026-04-09T16:57:01.000Z Warning-level message from logLevels 2
2026-04-09T16:57:01.000Z Error-level message from logLevels 3
Requests query output:
timestamp name resultCode duration
--------------------------- -------------- ---------- --------
2026-04-09T16:57:03.000Z testError 500 14.59
2026-04-09T16:57:02.000Z health 200 4.00
2026-04-09T16:57:01.000Z logLevels 200 5.00
LogLevels endpoint response:
Next Steps¶
See Also¶
- Tutorial Overview & Plan Chooser
- Java Language Guide
- Platform: Hosting Plans
- Operations: Deployment
- Recipes Index