Skip to content

Distributed Tracing for Java Azure Functions

kaibocai edited this page Sep 20, 2022 · 35 revisions

What is distributed tracing?

Distributed tracing is the equivalent of call stacks for modern cloud and microservices architectures, with the addition of a simplistic performance profiler thrown in. In Azure Monitor, we provide two experiences for consuming distributed trace data. The first is our transaction diagnostics view, which is like a call stack with a time dimension added in. The transaction diagnostics view provides visibility into one single transaction/request, and is helpful for finding the root cause of reliability issues and performance bottlenecks on a per request basis.

Azure Monitor also offers an application map view which aggregates many transactions to show a topological view of how the systems interact, and what the average performance and error rates are.

What is being supported by Java Azure Functions ?

You can now view richer data from your function applications pertaining to the following requests, dependencies, logs and metrics.

How to enable it for Java Function Apps?

Navigate to the functions app Overview blade, go to configurations. Under Application Settings click "+ New application setting". Add the following two application settings with below values, then click Save on the upper left. DONE!

Windows:

  • XDT_MicrosoftApplicationInsights_Java -> 1
  • ApplicationInsightsAgent_EXTENSION_VERSION -> ~2

Linux Dedicated/Premium

  • ApplicationInsightsAgent_EXTENSION_VERSION -> ~3

Linux Consumption

  • APPLICATIONINSIGHTS_ENABLE_AGENT: true

What would you expect to see in Application Insights?

  • Application Map - Application Map helps you spot performance bottlenecks or failure hotspots across all components and dependencies of your distributed application.

  • End-to-end transaction monitoring - Use end-to-end transaction monitoring to view one single distributed trace . This enables easy diagnostics for the application component, dependency, or exception that caused a transaction slowdown or failure.

  • Dashboards - Application Insights provides you an overview dashboard to allow quick, at-a-glance assessment of your application's health and performance. The dashboard allows you to drill-down into failures, performance etc.

  • Live Stream Metrics - Live Metrics Stream provides near-real-time performance indicators to make sure everything works as expected. Live stream can be used for various scenarios such as to validate a fix while it is released, by watching performance and failure counts, or observing the effect of test loads, and diagnosing issues live.

  • Smart Detection - Smart detections needs no configuration and provides automatic alerts that adapt to your app's normal patterns of telemetry and trigger when there's something outside the usual pattern.

  • Metrics Explorer - Explore, filter, and segment aggregated data such as rates of requests, failures, and exceptions, response times, and page load times.

  • Analytics - Answer tough questions about your app's performance and usage with KQL – a powerful query language.

Customize Distribute Agent

Note: this approach doesn't apply to consumption plan.
If you don't want to use the default version of distribute agent, you can follow below steps to point to a specific version of distribute agent.

  1. Get the target agent jar and put it into your project directory.
  2. Use maven plugin maven-resources-plugin to copy the agent jar into the build directory. Example:
<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>copy-resources</id>
            <phase>package</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <overwrite>true</overwrite>
                <outputDirectory>${stagingDirectory}</outputDirectory>
                <resources>
                    <resource>
                        <directory>${project.basedir}</directory>
                        <includes>
                            <include>applicationinsights-agent-3.3.2-SNAPSHOT.jar</include>
                        </includes>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

The ${stagingDirectory} has value

<stagingDirectory>${project.build.directory}/azure-functions/${functionAppName}</stagingDirectory>
  1. Add appsetting to point to the target agent in plugin azure-functions-maven-plugin.
  • For dedicate and premium plan: use appsetting JAVA_OPTS
  • For Linux consumption plan: for now Linux consumption don't support customize distribute agent version.
  • For Windows consumption plan: use appsetting: languageWorkers:java:arguments
    For consumption plan this will cause cold start as it require tor restart java process. Reference
    Example:
<plugin>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-functions-maven-plugin</artifactId>
    <version>${azure.functions.maven.plugin.version}</version>
    <configuration>
        <!-- function app name -->
        <appName>${functionAppName}</appName>
        <!-- function app resource group -->
        <resourceGroup>java-functions-group</resourceGroup>
        <!-- function app service plan name -->
        <appServicePlanName>java-functions-app-service-plan</appServicePlanName>
        <!-- function app region-->
        <!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-regions for all valid values -->
        <region>westus</region>
        <!-- function pricingTier, default to be consumption if not specified -->
        <!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-pricing-tiers for all valid values -->
        <pricingTier>EP1</pricingTier>
        <!-- Whether to disable application insights, default is false -->
        <!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details for all valid configurations for application insights-->
        <!-- <disableAppInsights></disableAppInsights> -->
        <runtime>
            <!-- runtime os, could be windows, linux or docker-->
            <os>linux</os>
            <javaVersion>8</javaVersion>
        </runtime>
        <appSettings>
            <property>
                <name>FUNCTIONS_EXTENSION_VERSION</name>
                <value>~4</value>
            </property>
            <property>
                <!-- point to the agent jar inside of the deployment directory -->
                <name>JAVA_OPTS</name>
                <value>-javaagent:applicationinsights-agent-3.3.2-SNAPSHOT.jar</value>
            </property>
        </appSettings>
    </configuration>
    <executions>
        <execution>
            <id>package-functions</id>
            <goals>
                <goal>package</goal>
            </goals>
        </execution>
    </executions>
</plugin>
  1. Redeploy the function app. The target agent should be the distributed agent that used by your function app.

Few things to keep in mind:

  • This feature is currently in public preview for Java Azure Functions, and has a cold start implication of 8-9 seconds in the Windows Consumption plan. For Linux Consumption plan there will be no cold start implication.
  • We would love to hear if you find this feature useful for your scenario and any other feedback that you may have so as to improve on its various aspects. We will consider making this functionality available out of the box by default with an optimized cold start based on demand.

Feedback

You can reach out to us with any feedback on javaazurefunctions@microsoft.com