OpenTelemetry setup in NextJS with AppRouter and Azure Monitor Application Insights
Updated on 15 June 2024 here
OpenTelemetry is an open-source observability framework for generating, collecting, and exporting telemetry data (metrics, logs, and traces) for analysis to understand your software's performance and behavior. You can analyze them using Prometheus, Jaeger, and other observability tools. It's a CNCF-incubated project and is the second most contributed project in the CNCF landscape, second only to Kubernetes.
The main advantage of using OpenTelemetry is that it provides a vendor-neutral way to collect telemetry data. This means you can switch your observability platform without having to change your application code.
In this post, I will guide you through the process of setting up OpenTelemetry in a NextJS application with AppRouter and exporting the telemetry data to Azure Monitor Application Insights.
Setting up OpenTelemetry in NextJS with AppRouter
It is easiest to set up using the @vercel/otel
library because it supports exporting to 3rd parties and results in the least amount of code. This will also work with self-hosted setups in Docker (e.g. Azure Container Apps), Azure App Service, PM2, etc.
Read the official docs at https://vercel.com/docs/observability/otel-overview.
Installing packages
As per the official docs, you need to install @vercel/otel
and @opentelemetry/api
. To support Azure Monitor Application Insights, you also need to install @azure/monitor-opentelemetry-exporter
.
Notes:
- The
@azure/monitor-opentelemetry-exporter
is in beta - The
@vercel/otel
package relies on older versions of@opentelemetry/api
, so you may need to control the versions by overriding or installing the relied-upon version.
In my case, I run the following command (versions may change later):
Instrumentation file
To set up OpenTelemetry in NextJS, you need to create an instrumentation.ts
file at the root of your project. Here's how your instrumentation.ts
file should look like:
In this file, we're calling registerOTel
which handles the setup of OpenTelemetry for NodeJS and specific elements for NextJS. Setting the traceExporter
becomes the next important thing.
Remember to set the correct value for connectionString
as copied from the Azure Portal.
Enabling instrumentation
As of the time of this writing, instrumentation using the instrumentation.ts
file is experimental (see docs). You can enable it in your next.config.ts
by setting experimental.instrumentationHook = true
Nuances of the setup
At this point, you will start to get errors on the build. The first one will read Module not found: Can't resolve 'os'
then subsequently be followed by fs
, child_process
, and path
modules. These are Webpack warnings and my suspicion is they will disappear when @azure/monitor-opentelemetry-exporter
is out of beta or when we start using turbopack
in place of Webpack.
Sentry guides us on how to solve this at https://sentry.io/answers/module-not-found-nextjs/#how-to-resolve, but we need to fix this on the server side because that is where the telemetry is collected. I changed my next.config.js
file to have the following Webpack config.
Update 15 June 2024
Making webpack changes is not necessary, instead selectively exporter.
Your next.config.js
file:
Your instrumentation.ts
file:
Update 23 Aug 2024
While this works, there may be issues when you set it up on your end. When debugging locally it takes about 1-3 minutes to show up on Azure portal.
To you .env
or .env.*
files add OTEL_LOG_LEVEL=debug
, restart the app, open a page a couple of times (generates traces), then you will see logs like:
Otherwise, there should be a meaningful error message
Conclusion
With this setup, your NextJS application with AppRouter is now ready to export telemetry data to Azure Monitor Application Insights. Run your app and navigate across several pages for telemetry to be sent to Azure. Remember that it can take a few minutes for the data to show up on Azure Portal, usually two minutes.
If you like this work, feel free to sponsor my work here.