The original post (Japanese) was written on 23 July 2025.
MicronautからAzure Monitorにtraceを送信したい – Logico Inside
This entry is related to the following one. Please take a look for background information.
Send signals from Micronaut native image applications to Azure Monitor | Microsoft Community Hub
Prerequisites
- Maven: 3.9.10
- JDK version 21
- Micronaut: 4.9.0 or later
The following tutorial was used as a reference.
OpenTelemetry Tracing with Oracle Cloud and the Micronaut Framework
As of 13 August 2025, GDK (Graal Dev Kit) guides are also available.
Create and Trace a Micronaut Application Using Azure Monitor
Create an archetype
We can create an archetype using Micronaut’s CLI (mn
) or Micronaut Launch. In this entry, use application.yml
instead of application.properties
for application configuration. So, we need to specify the feature “yaml” so that we can include dependencies for using yaml.
mn create-app \
--build=maven \
--jdk=21 \
--lang=java \
--test=junit \
--features=tracing-opentelemetry-http,validation,graalvm,azure-tracing,http-client,yaml \
dev.logicojp.micronaut.azuremonitor-metric
When using Micronaut Launch, click [FEATURES] and select the following features.
- tracing-opentelemetry-http
- validation
- graalvm
- azure-tracing
- http-client
- yaml
After all features are selected, click [GENERATE PROJECT] and choose [Download Zip] to download an archetype in Zip file.
Implementation
<dependency>
<groupid>io.micronaut.tracing</groupid>
<artifactid>micronaut-tracing-opentelemetry-http</artifactid>
<scope>compile</scope>
</dependency>
In this section, we’re going to use the tutorial in Micronaut Guides. We can use these codes as they are, but several points are modified.
a) For sending traces to Application Insights
Please note that we didn’t include metrics in this article because we discussed them in the last one.
Starting with Micronaut 4.9.0, a feature package called micronaut-azure-tracing
has been added. This feature enables sending traces to Application Insights.
<dependency>
<groupid>io.micronaut.azure</groupid>
<artifactid>micronaut-azure-tracing</artifactid>
</dependency>
Indeed, this dependency is necessary for sending data to Application Insights. However, adding this dependency and specifying the Application Insights connection string is not enough to send traces from applications. micronaut-azure-tracing
depends upon the three dependencies listed below. This shows that adding dependencies for trace collection and creation are required.
com.azure:azure-monitor-opentelemetry-autoconfigure
io.micronaut:micronaut-inject
io.micronaut.tracing:micronaut-tracing-opentelemetry
In this case, we want to obtain HTTP traces, so we will add dependencies for generating HTTP traces.
<dependency>
<groupid>io.micronaut.tracing</groupid>
<artifactid>micronaut-tracing-opentelemetry-http</artifactid>
<scope>compile</scope>
</dependency>
Where setting the connection string for micronaut-azure-tracing
is different from where for micrometer-azure-monitor
( azure.tracing.connection-string
). If we want to retrieve not only metrics but traces, the setting location is different, which can be confusing. We can also use environment variables to specify the connection string.
azure.tracing.connection-string="InstrumentationKey=...."
azure:
tracing:
connection-string: InstrumentationKey=....
b) pom.xml
To use the GraalVM Reachability Metadata Repository, we need to add this dependency. The latest version is 0.11.0 as of 23 July, 2025.
<dependency>
<groupid>org.graalvm.buildtools</groupid>
<artifactid>graalvm-reachability-metadata</artifactid>
<version>0.11.0</version>
</dependency>
Add the GraalVM Maven plugin and enable the use of GraalVM Reachability Metadata obtained from the above dependency. This plugin lets us set optimization levels using buildArg
(in this example, the optimisation level is specified). We can also add it to native-image.properties
, the native-image
tool (and the Maven/Gradle plugin) will read it.
<plugin>
<groupid>org.graalvm.buildtools</groupid>
<artifactid>native-maven-plugin</artifactid>
<configuration>
<metadatarepository>
<enabled>true</enabled>
</metadatarepository>
<buildargs combine.children="append">
<buildarg>-Ob</buildarg>
</buildargs>
<quickbuild>true</quickbuild>
</configuration>
</plugin>
c) To avoid version conflicts with dependencies used in the Azure SDK
This often happens when using Netty and/or Jackson. To avoid version conflicts during Native Image generation, Micronaut offers alternative components that we can choose. For example, if we want to avoid Netty version conflicts, we can use undertow.
Dependencies | Alternatives |
Netty | undertow, jetty, Tomcat |
Jackson | JSON-P / JSON-B, BSON |
HTTP Client | JDK HTTP Client |
For now, let’s build it as a Java application.
mvn clean package
Test as a Java application
At first, verify that the application is running without any problems and that traces are being sent to Application Insights. Then, run the application using the Tracing Agent to generate the necessary configuration files.
# (1) Collect configuration files such as reflect-config.json
$JAVA_HOME/bin/java \
-agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/{groupId}/{artifactId}/ \
-jar ./target/{artifactId}-{version}.jar
# (2)-a Generate a trace file
$JAVA_HOME/bin/java \
-agentlib:native-image-agent=trace-output=/path/to/trace-file.json \
-jar ./target/{artifactId}-{version}.jar
# (2)-b Generate a reachability metadata file from the collected trace file
native-image-configure generate \
--trace-input=/path/to/trace-file.json \
--output-dir=/path/to/config-dir/
Configure Native Image with the Tracing Agent
Collect Metadata with the Tracing Agent
Make the following files in the specified folder.
jni-config.json
reflect-config.json
proxy-config.json
resource-config.json
reachability-metadata.json
These files can be located at src/main/resources/META-INF/native-image
. The native-image
tool picks up configuration files located in the directory src/main/resources/META-INF/native-image
. However, it is recommended that we place the files in subdirectories divided by groupId
and artifactId
, as shown below.
src/main/resources/META-INF/native-image/{groupId}/{artifactId}
native-image.properties
When creating a native image, we call the following command.
mvn package -Dpackaging=native-image
We should specify the timing of class initialization (build time or runtime), the command line options for the native-image
tool (the same command line options work in Maven/Gradle plugin), and the JVM arguments in the native-image.properties
file. Indeed, these settings can be specified in pom.xml
, but it is recommended that they be externalized.
This is also explained in the metric entry, so some details will be left out. If needed, please check the metric entry.
Send metrics from Micronaut native image applications to Azure Monitor | Microsoft Community Hub
Build a Native Image application
Building a native image application takes a long time (though it has got quicker over time). If building it for testing purpose, we strongly recommend enabling Quick Build and setting the optimization level to -Ob
option (although this will still take time). See below for more information.
Maven plugin for GraalVM Native Image
Gradle plugin for GraalVM Native Image
Optimizations and Performance
Test as a native image application
Let’s check if the application works. To check the inventory of desktop, execute the following call.
curl https://<container apps="" url="" and="" port="">/store/inventory/desktop</container>
We should receive a response like this.
{"warehouse":7,"item":"desktop","store":2}
In Azure Monitor (Application Insights) Application Map, we can observe this interaction visually.
Switching to the trace page shows us traces and custom properties on the right of the screen.
Press enter or click to view image in full size
Then, we add an order. For example, if we place an order for five desktops and then receive 202 Accepted
, we need to call inventory check API again. This will show that the number has increased by five and the desktop order has changed to seven (original was 2).
$ curl -X "POST" "https://<container apps="" url="" and="" port="">/store/order" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{"item":"desktop", "count":5}'
$ curl https://<container apps="" url="" and="" port="">/store/inventory/desktop</container></container>
Within azuremonitor-trace
, an HTTP Client is used internally to execute POST /warehouse/order
. Looking at the Application Map in Azure Monitor (Application Insights), we can confirm that a call to azuremonitor-trace
itself is occurring.
The trace at the time of order placement is as follows.
Clicking ‘View all’ in the red frame, we can check the details of each trace.