Skip to content

04 - Logging and Monitoring (Dedicated)

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

Dedicated plan basics

Dedicated (App Service Plan) runs functions on standard App Service infrastructure with predictable pricing. B1 provides 1 vCPU, 1.75 GB memory. It supports Always On, manual/auto-scale, deployment slots, and VNet integration.

What You'll Build

You will verify Application Insights connectivity, query structured logs from the deployed function app, configure streaming logs, and set up a baseline alert rule for failure detection.

flowchart TD
    A[ExecutionContext logger] --> B[FunctionAppLogs]
    B --> C[Application Insights]
    C --> D[Dashboards and alerts]

Steps

Step 1 - Emit structured logs in handler methods

The reference app's Health.java uses ExecutionContext.getLogger():

@FunctionName("health")
public HttpResponseMessage health(
    @HttpTrigger(name = "req", methods = {HttpMethod.GET},
        authLevel = AuthorizationLevel.ANONYMOUS, route = "health")
    HttpRequestMessage<Optional<String>> request,
    final ExecutionContext context) {

    context.getLogger().info("event=health-check status=started invocationId="
        + context.getInvocationId());

    return request.createResponseBuilder(HttpStatus.OK)
        .header("Content-Type", "application/json")
        .body("{\"status\":\"healthy\"}")
        .build();
}

Step 2 - Confirm Application Insights connection

Application Insights is auto-created with the function app. Verify the connection string is set:

az functionapp config appsettings list \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --query "[?name=='APPLICATIONINSIGHTS_CONNECTION_STRING'].value" \
  --output tsv
CLI element Explanation
Command(s) az functionapp config appsettings list
Key flags --name, --resource-group, --query, --output
Variables $APP_NAME, $RG
Expected result Azure CLI applies the configuration change; confirm the returned JSON or follow-up query shows the expected value.

Step 3 - Trigger requests and wait for telemetry ingestion

# Generate traffic
curl --request GET "https://$APP_NAME.azurewebsites.net/api/health"
curl --request GET "https://$APP_NAME.azurewebsites.net/api/hello/Monitoring"
curl --request GET "https://$APP_NAME.azurewebsites.net/api/loglevels"

# Wait for telemetry ingestion (2-5 minutes for new App Insights)
sleep 180

Telemetry ingestion delay

Application Insights typically takes 2-5 minutes to ingest and index new telemetry, especially for newly created instances. If queries return empty results, wait and retry.

Step 4 - Query recent traces

az monitor app-insights query \
  --apps "$APP_NAME" \
  --resource-group "$RG" \
  --analytics-query "traces | where timestamp > ago(30m) | project timestamp, message, severityLevel | order by timestamp desc | take 10"
CLI element Explanation
Command(s) az monitor app-insights query
Key flags --apps, --resource-group, --analytics-query
Variables $APP_NAME, $RG
Expected result Azure CLI returns the requested resource data; verify names, IDs, status fields, or metric values match the scenario.

Step 5 - Query request performance

az monitor app-insights query \
  --apps "$APP_NAME" \
  --resource-group "$RG" \
  --analytics-query "requests | where timestamp > ago(30m) | project timestamp, name, resultCode, duration | order by timestamp desc | take 10"
CLI element Explanation
Command(s) az monitor app-insights query
Key flags --apps, --resource-group, --analytics-query
Variables $APP_NAME, $RG
Expected result Azure CLI returns the requested resource data; verify names, IDs, status fields, or metric values match the scenario.

Step 6 - View streaming logs

az webapp log tail \
  --name "$APP_NAME" \
  --resource-group "$RG"
CLI element Explanation
Command(s) az webapp log tail
Key flags --name, --resource-group
Variables $APP_NAME, $RG
Expected result Azure CLI completes successfully and returns JSON, table, or no output depending on the command; verify the next documented check before continuing.

Expected output:

Welcome, you are now connected to log-streaming service.
Starting Log Tail -n 10 of existing logs ----
/appsvctmp/volatile/logs/runtime/container.log
2026-04-09T17:26:00.465Z Hosting environment: Production
2026-04-09T17:26:00.465Z Content root path: /azure-functions-host
2026-04-09T17:26:00.465Z Now listening on: http://[::]:80
2026-04-09T17:26:00.465Z Application started. Press Ctrl+C to shut down.

az functionapp log tail does not exist

As of Azure CLI 2.83.0, az functionapp log tail is not a valid command. Use az webapp log tail instead — it works for function apps on all plans.

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
CLI element Explanation
Command(s) az functionapp show, az monitor metrics alert create
Key flags --name, --resource-group, --query, --output, --scopes, --condition, --window-size, --evaluation-frequency
Variables $APP_NAME, $RG, $FUNCTION_APP_ID
Expected result Azure CLI returns provisioning details; confirm the resource name and successful provisioning state before continuing.

Verification

Streaming logs output:

Hosting environment: Production
Content root path: /azure-functions-host
Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.

Dedicated Always On keeps logs flowing

Like Premium, Dedicated enables Always On by default. The function app remains warm, and streaming logs will always have an active connection.

Next Steps

Next: 05 - Infrastructure as Code

See Also

Sources