@azure/mcp-linux-arm64 2.0.0-beta.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.txt +5683 -4849
- package/README.md +148 -27
- package/dist/Azure.Mcp.Tools.AzureMigrate.xml +1060 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/ActivityProcessors.md +119 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/AddApplicationInsightsTelemetry.md +129 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/AddApplicationInsightsTelemetryWorkerService.md +115 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/AddOpenTelemetry.md +153 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/ApplicationInsightsWeb.md +103 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/AzureMonitorExporter.md +137 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/ConfigureOpenTelemetryProvider.md +218 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/ConfigureResource.md +119 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/ConsoleExporter.md +47 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/EntityFrameworkInstrumentation.md +56 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/HttpInstrumentation.md +109 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/LogProcessors.md +101 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/OpenTelemetrySdkCreate.md +146 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/OtlpExporter.md +88 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/RedisInstrumentation.md +63 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/Sampling.md +86 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/SdkCreateTracerProviderBuilder.md +127 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/SqlClientInstrumentation.md +53 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/TelemetryClient.md +122 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/TelemetryConfigurationBuilder.md +173 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/UseAzureMonitor.md +96 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/UseAzureMonitorExporter.md +146 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/WithLogging.md +109 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/WithMetrics.md +105 -0
- package/dist/Instrumentation/Resources/api-reference/dotnet/WithTracing.md +91 -0
- package/dist/Instrumentation/Resources/concepts/dotnet/appinsights-aspnetcore.md +113 -0
- package/dist/Instrumentation/Resources/concepts/dotnet/aspnet-classic-appinsights.md +95 -0
- package/dist/Instrumentation/Resources/concepts/dotnet/azure-monitor-distro.md +102 -0
- package/dist/Instrumentation/Resources/concepts/dotnet/opentelemetry-pipeline.md +57 -0
- package/dist/Instrumentation/Resources/concepts/nodejs/azure-monitor-overview.md +106 -0
- package/dist/Instrumentation/Resources/concepts/nodejs/opentelemetry-pipeline.md +201 -0
- package/dist/Instrumentation/Resources/concepts/python/azure-monitor-overview.md +122 -0
- package/dist/Instrumentation/Resources/concepts/python/opentelemetry-pipeline.md +154 -0
- package/dist/Instrumentation/Resources/examples/dotnet/aspnet-classic-setup.md +80 -0
- package/dist/Instrumentation/Resources/examples/dotnet/aspnetcore-distro-setup.md +156 -0
- package/dist/Instrumentation/Resources/examples/dotnet/aspnetcore-setup.md +160 -0
- package/dist/Instrumentation/Resources/examples/dotnet/workerservice-setup.md +154 -0
- package/dist/Instrumentation/Resources/examples/nodejs/bunyan-setup.md +301 -0
- package/dist/Instrumentation/Resources/examples/nodejs/console-setup.md +284 -0
- package/dist/Instrumentation/Resources/examples/nodejs/express-setup.md +169 -0
- package/dist/Instrumentation/Resources/examples/nodejs/fastify-setup.md +237 -0
- package/dist/Instrumentation/Resources/examples/nodejs/langchain-js-setup.md +310 -0
- package/dist/Instrumentation/Resources/examples/nodejs/mongodb-setup.md +185 -0
- package/dist/Instrumentation/Resources/examples/nodejs/mysql-setup.md +231 -0
- package/dist/Instrumentation/Resources/examples/nodejs/nestjs-setup.md +184 -0
- package/dist/Instrumentation/Resources/examples/nodejs/nextjs-setup.md +320 -0
- package/dist/Instrumentation/Resources/examples/nodejs/postgres-setup.md +147 -0
- package/dist/Instrumentation/Resources/examples/nodejs/redis-setup.md +198 -0
- package/dist/Instrumentation/Resources/examples/nodejs/winston-setup.md +260 -0
- package/dist/Instrumentation/Resources/examples/python/console-setup.md +392 -0
- package/dist/Instrumentation/Resources/examples/python/django-setup.md +269 -0
- package/dist/Instrumentation/Resources/examples/python/fastapi-setup.md +256 -0
- package/dist/Instrumentation/Resources/examples/python/flask-setup.md +218 -0
- package/dist/Instrumentation/Resources/examples/python/genai-setup.md +214 -0
- package/dist/Instrumentation/Resources/examples/python/generic-setup.md +164 -0
- package/dist/Instrumentation/Resources/migration/dotnet/aad-authentication-migration.md +150 -0
- package/dist/Instrumentation/Resources/migration/dotnet/appinsights-2x-to-3x-code-migration.md +164 -0
- package/dist/Instrumentation/Resources/migration/dotnet/appinsights-2x-to-3x-no-code-change.md +92 -0
- package/dist/Instrumentation/Resources/migration/dotnet/aspnet-classic-2x-to-3x-code-migration.md +190 -0
- package/dist/Instrumentation/Resources/migration/dotnet/console-2x-to-3x-code-migration.md +106 -0
- package/dist/Instrumentation/Resources/migration/dotnet/ilogger-migration.md +54 -0
- package/dist/Instrumentation/Resources/migration/dotnet/workerservice-2x-to-3x-code-migration.md +126 -0
- package/dist/Instrumentation/Resources/migration/dotnet/workerservice-2x-to-3x-no-code-change.md +102 -0
- package/dist/azmcp +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Basic Azure Monitor Setup for Next.js
|
|
2
|
+
|
|
3
|
+
This guide shows how to add Azure Monitor OpenTelemetry to a Next.js application using the instrumentation hook.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 18.x or higher
|
|
8
|
+
- npm or yarn
|
|
9
|
+
- Next.js 13.4+ application (App Router recommended)
|
|
10
|
+
- Azure Application Insights resource
|
|
11
|
+
|
|
12
|
+
## Step 1: Install Package
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @azure/monitor-opentelemetry
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Step 2: Create Instrumentation File
|
|
19
|
+
|
|
20
|
+
Create a new file `instrumentation.js` (or `instrumentation.ts`) in your project root:
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
const { useAzureMonitor } = require('@azure/monitor-opentelemetry');
|
|
24
|
+
|
|
25
|
+
export function register() {
|
|
26
|
+
// Only initialize on server-side
|
|
27
|
+
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
28
|
+
useAzureMonitor({
|
|
29
|
+
azureMonitorExporterOptions: {
|
|
30
|
+
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
> **Note**: The `register()` function is called once when the Next.js server starts. The `NEXT_RUNTIME` check ensures telemetry only initializes on the server, not in Edge runtime.
|
|
38
|
+
|
|
39
|
+
## Step 3: Enable Instrumentation Hook and Externalize Packages
|
|
40
|
+
|
|
41
|
+
Update your `next.config.js` to enable the instrumentation hook **and** externalize server-only packages. Without this, Next.js's webpack bundler will try to resolve Node.js built-in modules (`fs`, `stream`, etc.) used by `@grpc/grpc-js` and other OpenTelemetry dependencies, causing `Module not found` errors.
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
/** @type {import('next').NextConfig} */
|
|
45
|
+
const nextConfig = {
|
|
46
|
+
experimental: {
|
|
47
|
+
instrumentationHook: true,
|
|
48
|
+
serverComponentsExternalPackages: [
|
|
49
|
+
'@azure/monitor-opentelemetry',
|
|
50
|
+
'@opentelemetry/sdk-node',
|
|
51
|
+
'@opentelemetry/api',
|
|
52
|
+
'@opentelemetry/exporter-logs-otlp-grpc',
|
|
53
|
+
'@opentelemetry/otlp-grpc-exporter-base',
|
|
54
|
+
'@grpc/grpc-js',
|
|
55
|
+
'@grpc/proto-loader',
|
|
56
|
+
'@opentelemetry/instrumentation',
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
webpack: (config, { isServer }) => {
|
|
60
|
+
if (isServer) {
|
|
61
|
+
config.externals = config.externals || [];
|
|
62
|
+
config.externals.push({
|
|
63
|
+
'@azure/monitor-opentelemetry': 'commonjs @azure/monitor-opentelemetry',
|
|
64
|
+
'@opentelemetry/sdk-node': 'commonjs @opentelemetry/sdk-node',
|
|
65
|
+
'@opentelemetry/instrumentation': 'commonjs @opentelemetry/instrumentation',
|
|
66
|
+
'@opentelemetry/api': 'commonjs @opentelemetry/api',
|
|
67
|
+
'@grpc/grpc-js': 'commonjs @grpc/grpc-js',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return config;
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
module.exports = nextConfig;
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
> **Important**: Both `serverComponentsExternalPackages` and `webpack.externals` are required. The `serverComponentsExternalPackages` tells Next.js to skip bundling these packages for Server Components, while the `webpack.externals` configuration ensures the instrumentation hook itself (which runs outside the Server Components context) also resolves these packages from `node_modules` at runtime instead of bundling them.
|
|
78
|
+
|
|
79
|
+
> **Note (Next.js-specific)**: If you use logging libraries like **Bunyan** or **Winston** in a Next.js app, you must also add them to both `serverComponentsExternalPackages` and `webpack.externals`. Bunyan in particular has optional native dependencies (`dtrace-provider`, `source-map-support`) that webpack cannot resolve. This is not an issue in standard Node.js apps (Express, Fastify, etc.) where these libraries work without special configuration. See the [Using Logging Libraries](#using-logging-libraries-bunyan-winston) section below.
|
|
80
|
+
|
|
81
|
+
## Step 4: Configure Connection String
|
|
82
|
+
|
|
83
|
+
Create a `.env.local` file in your project root:
|
|
84
|
+
|
|
85
|
+
```env
|
|
86
|
+
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://...
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
> **Important**: Use `.env.local` for local development. For production, set this in your hosting platform's environment variables.
|
|
90
|
+
|
|
91
|
+
## Step 5: Add Custom Telemetry (Optional)
|
|
92
|
+
|
|
93
|
+
In your API routes or Server Components:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// app/api/users/route.ts
|
|
97
|
+
import { trace } from '@opentelemetry/api';
|
|
98
|
+
import { NextResponse } from 'next/server';
|
|
99
|
+
|
|
100
|
+
export async function GET(request: Request) {
|
|
101
|
+
const span = trace.getActiveSpan();
|
|
102
|
+
|
|
103
|
+
// Add custom attributes
|
|
104
|
+
span?.setAttribute('api.endpoint', '/api/users');
|
|
105
|
+
span?.setAttribute('operation.type', 'list-users');
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
const users = await fetchUsers();
|
|
109
|
+
return NextResponse.json(users);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
span?.recordException(error as Error);
|
|
112
|
+
return NextResponse.json({ error: 'Failed to fetch users' }, { status: 500 });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
In Server Components:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// app/users/page.tsx
|
|
121
|
+
import { trace } from '@opentelemetry/api';
|
|
122
|
+
|
|
123
|
+
export default async function UsersPage() {
|
|
124
|
+
const span = trace.getActiveSpan();
|
|
125
|
+
span?.setAttribute('page.name', 'users');
|
|
126
|
+
|
|
127
|
+
const users = await fetchUsers();
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<div>
|
|
131
|
+
{users.map(user => <UserCard key={user.id} user={user} />)}
|
|
132
|
+
</div>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Using Logging Libraries (Bunyan, Winston)
|
|
138
|
+
|
|
139
|
+
> **Next.js-specific**: The configuration in this section is only required because Next.js bundles server code with webpack. In standard Node.js applications (Express, Fastify, NestJS, etc.), Bunyan and Winston work out of the box — just install them, enable the instrumentation option, and use them. No externalization or runtime exports are needed. See the Bunyan Setup Guide(see in basic-setup-bunyan-nodejs.md) for the standard approach.
|
|
140
|
+
|
|
141
|
+
In Next.js, you need extra configuration because webpack tries to bundle these libraries and their native/optional dependencies, which causes `Module not found` errors.
|
|
142
|
+
|
|
143
|
+
### Step 1: Install the logging library
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
npm install bunyan
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Step 2: Add to externals in next.config.js
|
|
150
|
+
|
|
151
|
+
Add the logging library to **both** `serverComponentsExternalPackages` and `webpack.externals`:
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
experimental: {
|
|
155
|
+
serverComponentsExternalPackages: [
|
|
156
|
+
// ... existing packages ...
|
|
157
|
+
'bunyan', // Add this
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
webpack: (config, { isServer }) => {
|
|
161
|
+
if (isServer) {
|
|
162
|
+
config.externals = config.externals || [];
|
|
163
|
+
config.externals.push({
|
|
164
|
+
// ... existing externals ...
|
|
165
|
+
bunyan: 'commonjs bunyan', // Add this
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return config;
|
|
169
|
+
},
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
> **Why is this needed in Next.js?** Bunyan has optional native dependencies (`dtrace-provider`, `source-map-support`) that webpack cannot resolve. Next.js bundles server code with webpack, so these modules must be externalized. In standard Node.js apps (Express, Fastify, etc.), this is not an issue because there is no webpack bundling step.
|
|
173
|
+
|
|
174
|
+
### Step 3: Enable bunyan instrumentation
|
|
175
|
+
|
|
176
|
+
Update your `instrumentation.js` to enable bunyan log collection:
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
const { useAzureMonitor } = require('@azure/monitor-opentelemetry');
|
|
180
|
+
|
|
181
|
+
export function register() {
|
|
182
|
+
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
183
|
+
useAzureMonitor({
|
|
184
|
+
azureMonitorExporterOptions: {
|
|
185
|
+
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
|
|
186
|
+
},
|
|
187
|
+
instrumentationOptions: {
|
|
188
|
+
bunyan: { enabled: true }
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Step 4: Use in API routes (Next.js-specific)
|
|
196
|
+
|
|
197
|
+
In Next.js, mark API routes that use bunyan with `export const runtime = 'nodejs'` to ensure they run on the Node.js runtime (as opposed to Next.js's Edge runtime). This is a Next.js concept and does not apply to standard Node.js apps:
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
import { NextResponse } from 'next/server';
|
|
201
|
+
import bunyan from 'bunyan';
|
|
202
|
+
|
|
203
|
+
export const runtime = 'nodejs';
|
|
204
|
+
|
|
205
|
+
const logger = bunyan.createLogger({ name: 'my-nextjs-app' });
|
|
206
|
+
|
|
207
|
+
export async function GET(request) {
|
|
208
|
+
logger.info({ action: 'fetch-data' }, 'Handling request');
|
|
209
|
+
logger.warn({ reason: 'slow-query' }, 'Query took longer than expected');
|
|
210
|
+
logger.error({ err: new Error('Something failed') }, 'Operation failed');
|
|
211
|
+
|
|
212
|
+
return NextResponse.json({ success: true });
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Bunyan logs will be collected by the OpenTelemetry bunyan instrumentation and exported to Application Insights as traces with proper severity mapping.
|
|
217
|
+
|
|
218
|
+
> **Winston**: The same Next.js-specific pattern applies — add `winston` to webpack externals and enable `winston: { enabled: true }` in `instrumentationOptions`. In standard Node.js apps, just enable the instrumentation option — no externalization needed.
|
|
219
|
+
|
|
220
|
+
## What Gets Tracked Automatically
|
|
221
|
+
|
|
222
|
+
✅ **Server-Side Requests**: All API routes and Server Component renders
|
|
223
|
+
✅ **Dependencies**: Outgoing HTTP calls via `fetch()`
|
|
224
|
+
✅ **Exceptions**: Unhandled errors in API routes and Server Components
|
|
225
|
+
✅ **Performance**: Response times and request counts
|
|
226
|
+
✅ **Database Calls**: Queries through supported ORMs (Prisma, etc.)
|
|
227
|
+
|
|
228
|
+
> **Note**: Client-side rendering and navigation are NOT tracked by server-side telemetry. Use Application Insights JavaScript SDK for client-side monitoring.
|
|
229
|
+
|
|
230
|
+
## Verify It Works
|
|
231
|
+
|
|
232
|
+
1. Start your development server:
|
|
233
|
+
```bash
|
|
234
|
+
npm run dev
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
2. Make some requests:
|
|
238
|
+
```bash
|
|
239
|
+
curl http://localhost:3000/api/users
|
|
240
|
+
```
|
|
241
|
+
Or navigate to pages in your browser.
|
|
242
|
+
|
|
243
|
+
3. Check Azure Portal:
|
|
244
|
+
- Navigate to your Application Insights resource
|
|
245
|
+
- Go to "Transaction search" or "Live Metrics"
|
|
246
|
+
- You should see requests appearing within 1-2 minutes
|
|
247
|
+
|
|
248
|
+
## Complete package.json Example
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"name": "nextjs-azure-monitor-demo",
|
|
253
|
+
"version": "1.0.0",
|
|
254
|
+
"scripts": {
|
|
255
|
+
"dev": "next dev",
|
|
256
|
+
"build": "next build",
|
|
257
|
+
"start": "next start"
|
|
258
|
+
},
|
|
259
|
+
"dependencies": {
|
|
260
|
+
"@azure/monitor-opentelemetry": "^1.0.0",
|
|
261
|
+
"next": "^14.0.0",
|
|
262
|
+
"react": "^18.2.0",
|
|
263
|
+
"react-dom": "^18.2.0"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Project Structure
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
my-nextjs-app/
|
|
272
|
+
├── app/
|
|
273
|
+
│ ├── api/
|
|
274
|
+
│ │ └── users/
|
|
275
|
+
│ │ └── route.ts
|
|
276
|
+
│ ├── layout.tsx
|
|
277
|
+
│ └── page.tsx
|
|
278
|
+
├── instrumentation.js ← Azure Monitor setup
|
|
279
|
+
├── next.config.js ← Enable instrumentationHook
|
|
280
|
+
├── .env.local ← Connection string
|
|
281
|
+
└── package.json
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Troubleshooting
|
|
285
|
+
|
|
286
|
+
**Module not found: Can't resolve 'fs' / 'stream' / 'net' / 'tls'?**
|
|
287
|
+
- This is the most common issue. Next.js tries to bundle server-only Node.js modules used by `@grpc/grpc-js` and OpenTelemetry packages.
|
|
288
|
+
- **Fix**: Add `serverComponentsExternalPackages` AND `webpack.externals` to `next.config.js` as shown in Step 3.
|
|
289
|
+
- Both configurations are required — `serverComponentsExternalPackages` alone is not sufficient for the instrumentation hook.
|
|
290
|
+
- Ensure `@opentelemetry/instrumentation`, `@opentelemetry/sdk-node`, and `@grpc/grpc-js` are all included in `webpack.externals`.
|
|
291
|
+
|
|
292
|
+
**Module not found: Can't resolve 'source-map-support' or './src/build' (dtrace-provider)?**
|
|
293
|
+
- This occurs when using Bunyan in Next.js. Bunyan has optional native dependencies that webpack cannot resolve.
|
|
294
|
+
- **Fix**: Add `bunyan` to both `serverComponentsExternalPackages` and `webpack.externals` as shown in the [Using Logging Libraries](#using-logging-libraries-bunyan-winston) section.
|
|
295
|
+
|
|
296
|
+
**Module not found: Can't resolve '@azure/functions-core'?**
|
|
297
|
+
- This is a harmless warning. `@azure/functions-core` is an optional dependency used only in Azure Functions environments.
|
|
298
|
+
- It can be safely ignored for standalone Next.js deployments.
|
|
299
|
+
|
|
300
|
+
**No telemetry appearing?**
|
|
301
|
+
- Verify `instrumentationHook: true` is in `next.config.js`
|
|
302
|
+
- Check that `instrumentation.js` is in the project root (not in `/app` or `/src`)
|
|
303
|
+
- Ensure connection string is correct
|
|
304
|
+
- Wait 2-3 minutes for initial data to appear
|
|
305
|
+
|
|
306
|
+
**Edge Runtime not supported?**
|
|
307
|
+
- Azure Monitor OpenTelemetry only works with Node.js runtime
|
|
308
|
+
- Ensure your API routes are not using Edge runtime
|
|
309
|
+
- The `NEXT_RUNTIME` check prevents errors in Edge environments
|
|
310
|
+
|
|
311
|
+
**Development vs Production?**
|
|
312
|
+
- Telemetry works in both `npm run dev` and `npm run start`
|
|
313
|
+
- In development, you may see more verbose logging
|
|
314
|
+
|
|
315
|
+
## Next Steps
|
|
316
|
+
|
|
317
|
+
- Add client-side monitoring with Application Insights JavaScript SDK
|
|
318
|
+
- Configure custom dimensions and metrics
|
|
319
|
+
- Set up alerts and dashboards in Azure Portal
|
|
320
|
+
- Enable distributed tracing across microservices
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Basic Azure Monitor Setup for Node.js with PostgreSQL
|
|
2
|
+
|
|
3
|
+
This guide shows how to add Azure Monitor OpenTelemetry to a Node.js application using PostgreSQL.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 14.x or higher
|
|
8
|
+
- npm or yarn
|
|
9
|
+
- Node.js application with PostgreSQL (`pg` package)
|
|
10
|
+
- Azure Application Insights resource
|
|
11
|
+
|
|
12
|
+
## Step 1: Install Package
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @azure/monitor-opentelemetry
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Step 2: Initialize at Startup
|
|
19
|
+
|
|
20
|
+
Create or update your main entry point (typically `index.js` or `server.js`):
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
// IMPORTANT: This must be the first line, before any other imports
|
|
24
|
+
const { useAzureMonitor } = require('@azure/monitor-opentelemetry');
|
|
25
|
+
|
|
26
|
+
// Initialize Azure Monitor - PostgreSQL queries will be automatically instrumented
|
|
27
|
+
useAzureMonitor({
|
|
28
|
+
azureMonitorExporterOptions: {
|
|
29
|
+
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Now load your application code
|
|
34
|
+
const express = require('express');
|
|
35
|
+
const { Pool } = require('pg');
|
|
36
|
+
|
|
37
|
+
const app = express();
|
|
38
|
+
const port = process.env.PORT || 3000;
|
|
39
|
+
|
|
40
|
+
// PostgreSQL connection pool
|
|
41
|
+
const pool = new Pool({
|
|
42
|
+
connectionString: process.env.DATABASE_URL
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
app.use(express.json());
|
|
46
|
+
|
|
47
|
+
app.get('/api/users', async (req, res) => {
|
|
48
|
+
// This query will be automatically tracked as a dependency
|
|
49
|
+
const result = await pool.query('SELECT * FROM users LIMIT 10');
|
|
50
|
+
res.json(result.rows);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
app.listen(port, () => {
|
|
54
|
+
console.log(`Server listening on port ${port}`);
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Step 3: Configure Connection String
|
|
59
|
+
|
|
60
|
+
Create a `.env` file in your project root:
|
|
61
|
+
|
|
62
|
+
```env
|
|
63
|
+
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://...
|
|
64
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
|
|
65
|
+
PORT=3000
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Install `dotenv` to load environment variables:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm install dotenv
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Load it at the very top of your entry file:
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
require('dotenv').config();
|
|
78
|
+
const { useAzureMonitor } = require('@azure/monitor-opentelemetry');
|
|
79
|
+
// ... rest of code
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## What Gets Instrumented Automatically
|
|
83
|
+
|
|
84
|
+
With Azure Monitor OpenTelemetry, the following PostgreSQL operations are automatically tracked:
|
|
85
|
+
|
|
86
|
+
- **Queries**: All SQL queries executed via `pg` client
|
|
87
|
+
- **Query duration**: Time taken for each database operation
|
|
88
|
+
- **Query results**: Success/failure status
|
|
89
|
+
- **Connection info**: Database name and server details
|
|
90
|
+
|
|
91
|
+
## Step 4: Add Custom Telemetry (Optional)
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
const { trace } = require('@opentelemetry/api');
|
|
95
|
+
|
|
96
|
+
app.post('/api/users', async (req, res) => {
|
|
97
|
+
const tracer = trace.getTracer('my-app');
|
|
98
|
+
|
|
99
|
+
await tracer.startActiveSpan('create-user', async (span) => {
|
|
100
|
+
try {
|
|
101
|
+
span.setAttribute('user.email', req.body.email);
|
|
102
|
+
|
|
103
|
+
const result = await pool.query(
|
|
104
|
+
'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
|
|
105
|
+
[req.body.name, req.body.email]
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
span.setAttribute('user.id', result.rows[0].id);
|
|
109
|
+
res.status(201).json(result.rows[0]);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
span.recordException(error);
|
|
112
|
+
span.setStatus({ code: 2, message: error.message });
|
|
113
|
+
res.status(500).json({ error: 'Database error' });
|
|
114
|
+
} finally {
|
|
115
|
+
span.end();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Viewing Telemetry in Azure Portal
|
|
122
|
+
|
|
123
|
+
1. Open your Application Insights resource in Azure Portal
|
|
124
|
+
2. Navigate to "Application Map" to see PostgreSQL as a dependency
|
|
125
|
+
3. Use "Transaction search" to find specific database operations
|
|
126
|
+
4. Check "Dependencies" under "Investigate" to see query performance
|
|
127
|
+
|
|
128
|
+
## Troubleshooting
|
|
129
|
+
|
|
130
|
+
### PostgreSQL queries not appearing
|
|
131
|
+
|
|
132
|
+
1. Ensure `useAzureMonitor()` is called **before** importing `pg`
|
|
133
|
+
2. Verify the connection string is set correctly
|
|
134
|
+
3. Check that queries are being executed (not just connections)
|
|
135
|
+
|
|
136
|
+
### High latency in telemetry
|
|
137
|
+
|
|
138
|
+
PostgreSQL instrumentation captures all queries. For high-throughput applications, consider:
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
useAzureMonitor({
|
|
142
|
+
azureMonitorExporterOptions: {
|
|
143
|
+
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
|
|
144
|
+
},
|
|
145
|
+
samplingRatio: 0.5 // Sample 50% of requests
|
|
146
|
+
});
|
|
147
|
+
```
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Basic Azure Monitor Setup for Node.js with Redis
|
|
2
|
+
|
|
3
|
+
This guide shows how to add Azure Monitor OpenTelemetry to a Node.js application using Redis.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 14.x or higher
|
|
8
|
+
- npm or yarn
|
|
9
|
+
- Node.js application with Redis (`redis` or `ioredis` package)
|
|
10
|
+
- Azure Application Insights resource
|
|
11
|
+
|
|
12
|
+
## Step 1: Install Package
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @azure/monitor-opentelemetry
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Step 2: Initialize at Startup
|
|
19
|
+
|
|
20
|
+
Create or update your main entry point (typically `index.js` or `server.js`):
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
// IMPORTANT: This must be the first line, before any other imports
|
|
24
|
+
const { useAzureMonitor } = require('@azure/monitor-opentelemetry');
|
|
25
|
+
|
|
26
|
+
// Initialize Azure Monitor - Redis operations will be automatically instrumented
|
|
27
|
+
useAzureMonitor({
|
|
28
|
+
azureMonitorExporterOptions: {
|
|
29
|
+
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Now load your application code
|
|
34
|
+
const express = require('express');
|
|
35
|
+
const { createClient } = require('redis');
|
|
36
|
+
|
|
37
|
+
const app = express();
|
|
38
|
+
const port = process.env.PORT || 3000;
|
|
39
|
+
|
|
40
|
+
// Redis client
|
|
41
|
+
const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379';
|
|
42
|
+
const redisClient = createClient({ url: redisUrl });
|
|
43
|
+
|
|
44
|
+
async function connectToRedis() {
|
|
45
|
+
redisClient.on('error', err => console.error('Redis Client Error:', err));
|
|
46
|
+
await redisClient.connect();
|
|
47
|
+
console.log('Connected to Redis');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
app.use(express.json());
|
|
51
|
+
|
|
52
|
+
app.get('/api/cache/:key', async (req, res) => {
|
|
53
|
+
// This operation will be automatically tracked as a dependency
|
|
54
|
+
const value = await redisClient.get(req.params.key);
|
|
55
|
+
if (value === null) {
|
|
56
|
+
return res.status(404).json({ error: 'Key not found' });
|
|
57
|
+
}
|
|
58
|
+
res.json({ key: req.params.key, value: JSON.parse(value) });
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
app.post('/api/cache', async (req, res) => {
|
|
62
|
+
const { key, value, ttl } = req.body;
|
|
63
|
+
const options = ttl ? { EX: ttl } : {};
|
|
64
|
+
await redisClient.set(key, JSON.stringify(value), options);
|
|
65
|
+
res.status(201).json({ key, value });
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
connectToRedis().then(() => {
|
|
69
|
+
app.listen(port, () => {
|
|
70
|
+
console.log(`Server listening on port ${port}`);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Step 3: Configure Connection String
|
|
76
|
+
|
|
77
|
+
Create a `.env` file in your project root:
|
|
78
|
+
|
|
79
|
+
```env
|
|
80
|
+
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://...
|
|
81
|
+
REDIS_URL=redis://localhost:6379
|
|
82
|
+
PORT=3000
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Install `dotenv` to load environment variables:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm install dotenv
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Load it at the very top of your entry file:
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
require('dotenv').config();
|
|
95
|
+
const { useAzureMonitor } = require('@azure/monitor-opentelemetry');
|
|
96
|
+
// ... rest of code
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## What Gets Instrumented Automatically
|
|
100
|
+
|
|
101
|
+
With Azure Monitor OpenTelemetry, the following Redis operations are automatically tracked:
|
|
102
|
+
|
|
103
|
+
- **Commands**: GET, SET, DEL, HGET, HSET, LPUSH, etc.
|
|
104
|
+
- **Command duration**: Time taken for each operation
|
|
105
|
+
- **Database index**: Which Redis database was used
|
|
106
|
+
- **Success/failure**: Operation status
|
|
107
|
+
|
|
108
|
+
## Using with ioredis
|
|
109
|
+
|
|
110
|
+
If you're using `ioredis`, the setup is the same:
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
require('dotenv').config();
|
|
114
|
+
const { useAzureMonitor } = require('@azure/monitor-opentelemetry');
|
|
115
|
+
|
|
116
|
+
useAzureMonitor({
|
|
117
|
+
azureMonitorExporterOptions: {
|
|
118
|
+
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const Redis = require('ioredis');
|
|
123
|
+
const express = require('express');
|
|
124
|
+
|
|
125
|
+
const redis = new Redis(process.env.REDIS_URL);
|
|
126
|
+
|
|
127
|
+
const app = express();
|
|
128
|
+
|
|
129
|
+
app.get('/api/cache/:key', async (req, res) => {
|
|
130
|
+
const value = await redis.get(req.params.key);
|
|
131
|
+
res.json({ key: req.params.key, value });
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Step 4: Add Custom Telemetry (Optional)
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
const { trace } = require('@opentelemetry/api');
|
|
139
|
+
|
|
140
|
+
app.post('/api/session', async (req, res) => {
|
|
141
|
+
const tracer = trace.getTracer('my-app');
|
|
142
|
+
|
|
143
|
+
await tracer.startActiveSpan('create-session', async (span) => {
|
|
144
|
+
try {
|
|
145
|
+
const sessionId = `session:${Date.now()}`;
|
|
146
|
+
span.setAttribute('session.id', sessionId);
|
|
147
|
+
|
|
148
|
+
await redisClient.set(sessionId, JSON.stringify(req.body), { EX: 3600 });
|
|
149
|
+
|
|
150
|
+
res.status(201).json({ sessionId });
|
|
151
|
+
} catch (error) {
|
|
152
|
+
span.recordException(error);
|
|
153
|
+
span.setStatus({ code: 2, message: error.message });
|
|
154
|
+
res.status(500).json({ error: 'Cache error' });
|
|
155
|
+
} finally {
|
|
156
|
+
span.end();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Using with Azure Cache for Redis
|
|
163
|
+
|
|
164
|
+
For Azure Cache for Redis, update your connection string:
|
|
165
|
+
|
|
166
|
+
```env
|
|
167
|
+
REDIS_URL=rediss://:YOUR_ACCESS_KEY@YOUR_REDIS_NAME.redis.cache.windows.net:6380
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Note the `rediss://` protocol for SSL connections (required by Azure Cache for Redis).
|
|
171
|
+
|
|
172
|
+
## Viewing Telemetry in Azure Portal
|
|
173
|
+
|
|
174
|
+
1. Open your Application Insights resource in Azure Portal
|
|
175
|
+
2. Navigate to "Application Map" to see Redis as a dependency
|
|
176
|
+
3. Use "Transaction search" to find specific cache operations
|
|
177
|
+
4. Check "Dependencies" under "Investigate" to see operation performance
|
|
178
|
+
|
|
179
|
+
## Troubleshooting
|
|
180
|
+
|
|
181
|
+
### Redis operations not appearing
|
|
182
|
+
|
|
183
|
+
1. Ensure `useAzureMonitor()` is called **before** importing `redis` or `ioredis`
|
|
184
|
+
2. Verify the connection string is set correctly
|
|
185
|
+
3. Check that operations are being executed (not just connections)
|
|
186
|
+
|
|
187
|
+
### High volume of telemetry
|
|
188
|
+
|
|
189
|
+
Redis is often used for high-frequency operations. Consider sampling:
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
useAzureMonitor({
|
|
193
|
+
azureMonitorExporterOptions: {
|
|
194
|
+
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
|
|
195
|
+
},
|
|
196
|
+
samplingRatio: 0.1 // Sample 10% of requests
|
|
197
|
+
});
|
|
198
|
+
```
|