@azure/mcp-linux-arm64 2.0.0-beta.8 → 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 +149 -26
- 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/appsettings.json +5 -0
- package/dist/azmcp +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# Basic Azure Monitor Setup for Node.js with Bunyan Logging
|
|
2
|
+
|
|
3
|
+
This guide shows how to add Azure Monitor OpenTelemetry to a Node.js application using Bunyan for logging.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 14.x or higher
|
|
8
|
+
- npm or yarn
|
|
9
|
+
- Node.js application with Bunyan (`bunyan` 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 with Bunyan log collection enabled
|
|
27
|
+
useAzureMonitor({
|
|
28
|
+
azureMonitorExporterOptions: {
|
|
29
|
+
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
|
|
30
|
+
},
|
|
31
|
+
instrumentationOptions: {
|
|
32
|
+
bunyan: { enabled: true }
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Now load your application code
|
|
37
|
+
const express = require('express');
|
|
38
|
+
const bunyan = require('bunyan');
|
|
39
|
+
|
|
40
|
+
// Create Bunyan logger
|
|
41
|
+
const logger = bunyan.createLogger({
|
|
42
|
+
name: 'my-app',
|
|
43
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
44
|
+
serializers: bunyan.stdSerializers
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const app = express();
|
|
48
|
+
const port = process.env.PORT || 3000;
|
|
49
|
+
|
|
50
|
+
app.use(express.json());
|
|
51
|
+
|
|
52
|
+
// Request logging middleware
|
|
53
|
+
app.use((req, res, next) => {
|
|
54
|
+
logger.info({ req }, 'Incoming request');
|
|
55
|
+
next();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
app.get('/api/users', (req, res) => {
|
|
59
|
+
logger.info('Fetching users');
|
|
60
|
+
res.json([{ id: 1, name: 'Alice' }]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
app.listen(port, () => {
|
|
64
|
+
logger.info({ port }, 'Server listening');
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Step 3: Configure Connection String
|
|
69
|
+
|
|
70
|
+
Create a `.env` file in your project root:
|
|
71
|
+
|
|
72
|
+
```env
|
|
73
|
+
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://...
|
|
74
|
+
LOG_LEVEL=info
|
|
75
|
+
PORT=3000
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Install `dotenv` to load environment variables:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm install dotenv
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Load it at the very top of your entry file:
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
require('dotenv').config();
|
|
88
|
+
const { useAzureMonitor } = require('@azure/monitor-opentelemetry');
|
|
89
|
+
// ... rest of code
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## What Gets Collected
|
|
93
|
+
|
|
94
|
+
With Bunyan instrumentation enabled, the following log data is sent to Azure Monitor:
|
|
95
|
+
|
|
96
|
+
- **Log level**: fatal, error, warn, info, debug, trace
|
|
97
|
+
- **Log message**: The log content
|
|
98
|
+
- **Log fields**: All additional fields passed to the logger
|
|
99
|
+
- **Timestamp**: When the log was created
|
|
100
|
+
- **Trace context**: Correlation with distributed traces
|
|
101
|
+
|
|
102
|
+
## Log Level Mapping
|
|
103
|
+
|
|
104
|
+
Bunyan log levels are mapped to Application Insights severity levels:
|
|
105
|
+
|
|
106
|
+
| Bunyan Level | Numeric | Application Insights Severity |
|
|
107
|
+
|-------------|---------|------------------------------|
|
|
108
|
+
| fatal | 60 | Critical |
|
|
109
|
+
| error | 50 | Error |
|
|
110
|
+
| warn | 40 | Warning |
|
|
111
|
+
| info | 30 | Information |
|
|
112
|
+
| debug | 20 | Verbose |
|
|
113
|
+
| trace | 10 | Verbose |
|
|
114
|
+
|
|
115
|
+
## Step 4: Structured Logging Best Practices
|
|
116
|
+
|
|
117
|
+
Bunyan excels at structured logging. Use its features effectively:
|
|
118
|
+
|
|
119
|
+
### Add Context to Logs
|
|
120
|
+
|
|
121
|
+
```javascript
|
|
122
|
+
// Good: Structured logging with context
|
|
123
|
+
logger.info({ userId: user.id, email: user.email }, 'User created');
|
|
124
|
+
|
|
125
|
+
// Good: Error logging with error serializer
|
|
126
|
+
logger.error({ err: error, email: req.body.email }, 'Failed to create user');
|
|
127
|
+
|
|
128
|
+
// Good: Request/response logging
|
|
129
|
+
logger.info({ req, res }, 'Request completed');
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Child Loggers for Request Context
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
app.use((req, res, next) => {
|
|
136
|
+
// Create a child logger with request context
|
|
137
|
+
req.log = logger.child({
|
|
138
|
+
requestId: req.headers['x-request-id'] || Math.random().toString(36).substr(2, 9),
|
|
139
|
+
path: req.path,
|
|
140
|
+
method: req.method
|
|
141
|
+
});
|
|
142
|
+
next();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
app.get('/api/users/:id', (req, res) => {
|
|
146
|
+
// Use the request-scoped logger
|
|
147
|
+
req.log.info({ userId: req.params.id }, 'Fetching user');
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const user = getUserById(req.params.id);
|
|
151
|
+
req.log.debug({ user }, 'User found');
|
|
152
|
+
res.json(user);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
req.log.error({ err: error, userId: req.params.id }, 'User not found');
|
|
155
|
+
res.status(404).json({ error: 'User not found' });
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Custom Serializers
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
const logger = bunyan.createLogger({
|
|
164
|
+
name: 'my-app',
|
|
165
|
+
serializers: {
|
|
166
|
+
...bunyan.stdSerializers,
|
|
167
|
+
user: (user) => ({
|
|
168
|
+
id: user.id,
|
|
169
|
+
email: user.email,
|
|
170
|
+
role: user.role
|
|
171
|
+
}),
|
|
172
|
+
order: (order) => ({
|
|
173
|
+
id: order.id,
|
|
174
|
+
total: order.total,
|
|
175
|
+
itemCount: order.items.length
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Use custom serializers
|
|
181
|
+
logger.info({ user }, 'User logged in');
|
|
182
|
+
logger.info({ order }, 'Order created');
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Step 5: Custom Telemetry (Optional)
|
|
186
|
+
|
|
187
|
+
Combine logging with custom spans:
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
const { trace } = require('@opentelemetry/api');
|
|
191
|
+
|
|
192
|
+
app.post('/api/orders', async (req, res) => {
|
|
193
|
+
const tracer = trace.getTracer('my-app');
|
|
194
|
+
|
|
195
|
+
await tracer.startActiveSpan('create-order', async (span) => {
|
|
196
|
+
req.log.info({ itemCount: req.body.items.length }, 'Creating order');
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
const order = await createOrder(req.body);
|
|
200
|
+
|
|
201
|
+
req.log.info({ order }, 'Order created successfully');
|
|
202
|
+
|
|
203
|
+
span.setAttribute('order.id', order.id);
|
|
204
|
+
res.status(201).json(order);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
req.log.error({ err: error }, 'Failed to create order');
|
|
207
|
+
|
|
208
|
+
span.recordException(error);
|
|
209
|
+
span.setStatus({ code: 2, message: error.message });
|
|
210
|
+
res.status(500).json({ error: 'Failed to create order' });
|
|
211
|
+
} finally {
|
|
212
|
+
span.end();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Viewing Logs in Azure Portal
|
|
219
|
+
|
|
220
|
+
1. Open your Application Insights resource in Azure Portal
|
|
221
|
+
2. Navigate to "Logs" under Monitoring
|
|
222
|
+
3. Query traces table:
|
|
223
|
+
|
|
224
|
+
```kusto
|
|
225
|
+
traces
|
|
226
|
+
| where timestamp > ago(1h)
|
|
227
|
+
| where customDimensions.name == "my-app"
|
|
228
|
+
| project timestamp, message, severityLevel, customDimensions
|
|
229
|
+
| order by timestamp desc
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
4. Use "Transaction search" to see logs correlated with requests
|
|
233
|
+
|
|
234
|
+
## Troubleshooting
|
|
235
|
+
|
|
236
|
+
### Bunyan logs not appearing
|
|
237
|
+
|
|
238
|
+
1. Ensure `bunyan` instrumentation is enabled in options
|
|
239
|
+
2. Verify `useAzureMonitor()` is called **before** importing `bunyan`
|
|
240
|
+
3. Check that the connection string is valid
|
|
241
|
+
|
|
242
|
+
### Using Bunyan with Next.js
|
|
243
|
+
|
|
244
|
+
> **Note**: The standard setup in this guide (Steps 1-5) works for Express, Fastify, NestJS, and other standard Node.js frameworks with no special configuration. The issues below are **specific to Next.js** because it bundles server-side code with webpack.
|
|
245
|
+
|
|
246
|
+
Bunyan has optional native dependencies (`dtrace-provider`, `source-map-support`) that Next.js's webpack bundler cannot resolve. You'll see errors like:
|
|
247
|
+
|
|
248
|
+
- `Module not found: Can't resolve 'source-map-support'`
|
|
249
|
+
- `Module not found: Can't resolve './src/build'` (from `dtrace-provider`)
|
|
250
|
+
|
|
251
|
+
**Fix**: Add `bunyan` to both `serverComponentsExternalPackages` and `webpack.externals` in your `next.config.js`:
|
|
252
|
+
|
|
253
|
+
```javascript
|
|
254
|
+
const nextConfig = {
|
|
255
|
+
experimental: {
|
|
256
|
+
instrumentationHook: true,
|
|
257
|
+
serverComponentsExternalPackages: [
|
|
258
|
+
'@azure/monitor-opentelemetry',
|
|
259
|
+
// ... other OpenTelemetry packages ...
|
|
260
|
+
'bunyan',
|
|
261
|
+
],
|
|
262
|
+
},
|
|
263
|
+
webpack: (config, { isServer }) => {
|
|
264
|
+
if (isServer) {
|
|
265
|
+
config.externals = config.externals || [];
|
|
266
|
+
config.externals.push({
|
|
267
|
+
// ... other OpenTelemetry externals ...
|
|
268
|
+
bunyan: 'commonjs bunyan',
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
return config;
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
In Next.js, also mark API routes using bunyan with `export const runtime = 'nodejs'` to ensure they run on the Node.js runtime (not Edge). This is a Next.js-specific concept and does not apply to standard Node.js apps.
|
|
277
|
+
|
|
278
|
+
See the Next.js Setup Guide(see in basic-setup-nextjs.md) for the full Next.js + bunyan configuration.
|
|
279
|
+
|
|
280
|
+
### Log fields not appearing correctly
|
|
281
|
+
|
|
282
|
+
Ensure you're using the correct Bunyan logging format:
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
// Correct: fields object first, then message
|
|
286
|
+
logger.info({ userId: 123 }, 'User action');
|
|
287
|
+
|
|
288
|
+
// Incorrect: message first (fields won't be captured properly)
|
|
289
|
+
logger.info('User action', { userId: 123 });
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Too many logs being sent
|
|
293
|
+
|
|
294
|
+
Control log volume by adjusting the log level:
|
|
295
|
+
|
|
296
|
+
```javascript
|
|
297
|
+
const logger = bunyan.createLogger({
|
|
298
|
+
name: 'my-app',
|
|
299
|
+
level: process.env.NODE_ENV === 'production' ? 'warn' : 'debug'
|
|
300
|
+
});
|
|
301
|
+
```
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# Basic Azure Monitor Setup for Node.js with Console Logging
|
|
2
|
+
|
|
3
|
+
This guide shows how to add Azure Monitor to a Node.js application that uses built-in console logging.
|
|
4
|
+
|
|
5
|
+
> **Important**: To capture `console.log`, `console.warn`, `console.error`, etc. as telemetry in Application Insights, you must use the `applicationinsights` npm package (the Application Insights SDK). The `@azure/monitor-opentelemetry` package does **not** support automatic console log collection — it only supports structured logging libraries like Bunyan and Winston.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- Node.js 14.x or higher
|
|
10
|
+
- npm or yarn
|
|
11
|
+
- Node.js application using console logging
|
|
12
|
+
- Azure Application Insights resource
|
|
13
|
+
|
|
14
|
+
## Step 1: Install Package
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install applicationinsights
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Step 2: Initialize at Startup
|
|
21
|
+
|
|
22
|
+
Create or update your main entry point (typically `index.js` or `server.js`):
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
// IMPORTANT: This must be the first line, before any other imports
|
|
26
|
+
const appInsights = require('applicationinsights');
|
|
27
|
+
|
|
28
|
+
// Initialize Application Insights with console log collection
|
|
29
|
+
appInsights.setup(process.env.APPLICATIONINSIGHTS_CONNECTION_STRING)
|
|
30
|
+
.setAutoCollectConsole(true, true) // Enable console.log and console.error collection
|
|
31
|
+
.start();
|
|
32
|
+
|
|
33
|
+
// Now load your application code
|
|
34
|
+
const express = require('express');
|
|
35
|
+
|
|
36
|
+
const app = express();
|
|
37
|
+
const port = process.env.PORT || 3000;
|
|
38
|
+
|
|
39
|
+
app.use(express.json());
|
|
40
|
+
|
|
41
|
+
// Request logging middleware
|
|
42
|
+
app.use((req, res, next) => {
|
|
43
|
+
console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`);
|
|
44
|
+
next();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
app.get('/api/users', (req, res) => {
|
|
48
|
+
console.log('Fetching users');
|
|
49
|
+
res.json([{ id: 1, name: 'Alice' }]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
app.listen(port, () => {
|
|
53
|
+
console.log(`Server listening on port ${port}`);
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Step 3: Configure Connection String
|
|
58
|
+
|
|
59
|
+
Create a `.env` file in your project root:
|
|
60
|
+
|
|
61
|
+
```env
|
|
62
|
+
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://...
|
|
63
|
+
PORT=3000
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Install `dotenv` to load environment variables:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install dotenv
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Load it at the very top of your entry file:
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
require('dotenv').config();
|
|
76
|
+
const { useAzureMonitor } = require('@azure/monitor-opentelemetry');
|
|
77
|
+
// ... rest of code
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Why `applicationinsights` Instead of `@azure/monitor-opentelemetry`?
|
|
81
|
+
|
|
82
|
+
The `@azure/monitor-opentelemetry` package is the recommended OpenTelemetry-based SDK for Node.js, but it only supports automatic log collection from **Bunyan** and **Winston** logging libraries. It does **not** have a `console` instrumentation option.
|
|
83
|
+
|
|
84
|
+
The `applicationinsights` package (Application Insights Node.js SDK) provides built-in support for capturing `console.log` output via `setAutoCollectConsole(true)`. If you want to use the OpenTelemetry-based SDK instead, consider migrating to Winston or Bunyan for structured logging.
|
|
85
|
+
|
|
86
|
+
## What Gets Collected
|
|
87
|
+
|
|
88
|
+
With `setAutoCollectConsole(true, true)` enabled, the following is captured:
|
|
89
|
+
|
|
90
|
+
| Console Method | Application Insights Severity |
|
|
91
|
+
|---------------|------------------------------|
|
|
92
|
+
| console.error() | Error |
|
|
93
|
+
| console.warn() | Warning |
|
|
94
|
+
| console.info() | Information |
|
|
95
|
+
| console.log() | Information |
|
|
96
|
+
| console.debug() | Verbose |
|
|
97
|
+
| console.trace() | Verbose |
|
|
98
|
+
|
|
99
|
+
## Step 4: Best Practices for Console Logging
|
|
100
|
+
|
|
101
|
+
### Use Appropriate Log Levels
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
// Error conditions
|
|
105
|
+
console.error('Failed to connect to database:', error.message);
|
|
106
|
+
|
|
107
|
+
// Warning conditions
|
|
108
|
+
console.warn('API rate limit approaching:', currentRate);
|
|
109
|
+
|
|
110
|
+
// Informational messages
|
|
111
|
+
console.info('User logged in:', userId);
|
|
112
|
+
console.log('Processing request for:', endpoint);
|
|
113
|
+
|
|
114
|
+
// Debug information
|
|
115
|
+
console.debug('Request body:', JSON.stringify(body));
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Structured-ish Logging with Console
|
|
119
|
+
|
|
120
|
+
While console doesn't support true structured logging, you can format messages consistently:
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
function log(level, message, data = {}) {
|
|
124
|
+
const timestamp = new Date().toISOString();
|
|
125
|
+
const dataStr = Object.keys(data).length ? ` ${JSON.stringify(data)}` : '';
|
|
126
|
+
console[level](`[${timestamp}] ${message}${dataStr}`);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Usage
|
|
130
|
+
log('info', 'User created', { userId: 123, email: 'user@example.com' });
|
|
131
|
+
log('error', 'Database connection failed', { host: 'localhost', error: err.message });
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Request Context Helper
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
function createRequestLogger(req) {
|
|
138
|
+
const requestId = req.headers['x-request-id'] || Math.random().toString(36).substr(2, 9);
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
info: (message, data = {}) => {
|
|
142
|
+
console.log(`[${requestId}] ${message}`, data);
|
|
143
|
+
},
|
|
144
|
+
error: (message, data = {}) => {
|
|
145
|
+
console.error(`[${requestId}] ${message}`, data);
|
|
146
|
+
},
|
|
147
|
+
warn: (message, data = {}) => {
|
|
148
|
+
console.warn(`[${requestId}] ${message}`, data);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
app.use((req, res, next) => {
|
|
154
|
+
req.log = createRequestLogger(req);
|
|
155
|
+
next();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
app.get('/api/users/:id', (req, res) => {
|
|
159
|
+
req.log.info(`Fetching user ${req.params.id}`);
|
|
160
|
+
// ...
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Step 5: Custom Telemetry (Optional)
|
|
165
|
+
|
|
166
|
+
Combine logging with custom spans:
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
const { trace } = require('@opentelemetry/api');
|
|
170
|
+
|
|
171
|
+
app.post('/api/orders', async (req, res) => {
|
|
172
|
+
const tracer = trace.getTracer('my-app');
|
|
173
|
+
|
|
174
|
+
await tracer.startActiveSpan('create-order', async (span) => {
|
|
175
|
+
console.log('Creating order with', req.body.items.length, 'items');
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
const order = await createOrder(req.body);
|
|
179
|
+
|
|
180
|
+
console.log('Order created successfully:', order.id);
|
|
181
|
+
|
|
182
|
+
span.setAttribute('order.id', order.id);
|
|
183
|
+
res.status(201).json(order);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error('Failed to create order:', error.message);
|
|
186
|
+
|
|
187
|
+
span.recordException(error);
|
|
188
|
+
span.setStatus({ code: 2, message: error.message });
|
|
189
|
+
res.status(500).json({ error: 'Failed to create order' });
|
|
190
|
+
} finally {
|
|
191
|
+
span.end();
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## When to Consider Upgrading to a Logging Library
|
|
198
|
+
|
|
199
|
+
Console logging is fine for simple applications, but consider Winston or Bunyan when you need:
|
|
200
|
+
|
|
201
|
+
- **Structured logging**: Proper JSON logging with metadata
|
|
202
|
+
- **Log levels**: Configurable filtering by environment
|
|
203
|
+
- **Multiple transports**: File, HTTP, or other destinations
|
|
204
|
+
- **Better performance**: Async logging for high-throughput apps
|
|
205
|
+
- **Request correlation**: Automatic trace context propagation
|
|
206
|
+
|
|
207
|
+
## Viewing Logs in Azure Portal
|
|
208
|
+
|
|
209
|
+
1. Open your Application Insights resource in Azure Portal
|
|
210
|
+
2. Navigate to "Logs" under Monitoring
|
|
211
|
+
3. Query traces table:
|
|
212
|
+
|
|
213
|
+
```kusto
|
|
214
|
+
traces
|
|
215
|
+
| where timestamp > ago(1h)
|
|
216
|
+
| project timestamp, message, severityLevel
|
|
217
|
+
| order by timestamp desc
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
4. Filter by severity:
|
|
221
|
+
|
|
222
|
+
```kusto
|
|
223
|
+
traces
|
|
224
|
+
| where timestamp > ago(1h)
|
|
225
|
+
| where severityLevel >= 3 // Warning and above
|
|
226
|
+
| project timestamp, message, severityLevel
|
|
227
|
+
| order by timestamp desc
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Troubleshooting
|
|
231
|
+
|
|
232
|
+
### Console logs not appearing
|
|
233
|
+
|
|
234
|
+
1. Ensure `setAutoCollectConsole(true, true)` is called during setup
|
|
235
|
+
2. Verify `appInsights.setup().start()` is called **before** any console.log calls
|
|
236
|
+
3. Check that the connection string is valid
|
|
237
|
+
4. For short-lived apps (scripts that exit immediately), call `appInsights.defaultClient.flush()` before the process exits to ensure telemetry is sent
|
|
238
|
+
|
|
239
|
+
### Too many logs being sent
|
|
240
|
+
|
|
241
|
+
Console instrumentation captures all console output. To reduce volume:
|
|
242
|
+
|
|
243
|
+
1. Use sampling:
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
const appInsights = require('applicationinsights');
|
|
247
|
+
appInsights.setup(process.env.APPLICATIONINSIGHTS_CONNECTION_STRING)
|
|
248
|
+
.setAutoCollectConsole(true, true)
|
|
249
|
+
.start();
|
|
250
|
+
|
|
251
|
+
// Set sampling percentage (e.g., 50%)
|
|
252
|
+
appInsights.defaultClient.config.samplingPercentage = 50;
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
2. Or only collect console.error (not console.log):
|
|
256
|
+
|
|
257
|
+
```javascript
|
|
258
|
+
// First parameter: collect console.log (false = disabled)
|
|
259
|
+
// Second parameter: collect console.error (true = enabled)
|
|
260
|
+
appInsights.setup(process.env.APPLICATIONINSIGHTS_CONNECTION_STRING)
|
|
261
|
+
.setAutoCollectConsole(false, true)
|
|
262
|
+
.start();
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Migration Path to Structured Logging
|
|
266
|
+
|
|
267
|
+
When you're ready to upgrade, here's a simple migration to Winston:
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
// Before: console
|
|
271
|
+
console.log('User created:', userId);
|
|
272
|
+
console.error('Database error:', error.message);
|
|
273
|
+
|
|
274
|
+
// After: Winston
|
|
275
|
+
const winston = require('winston');
|
|
276
|
+
const logger = winston.createLogger({
|
|
277
|
+
level: 'info',
|
|
278
|
+
format: winston.format.json(),
|
|
279
|
+
transports: [new winston.transports.Console()]
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
logger.info('User created', { userId });
|
|
283
|
+
logger.error('Database error', { error: error.message });
|
|
284
|
+
```
|