Skip to content

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 webapp log tail \
  --name "$APP_NAME" \
  --resource-group "$RG"

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:

{"logged":true}

Next Steps

Next: 05 - Infrastructure as Code

See Also

Sources