@azure/monitor-opentelemetry-exporter 1.0.0-beta.4 → 1.0.0-beta.7
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/CHANGELOG.md +23 -0
- package/README.md +11 -13
- package/dist/index.js +701 -355
- package/dist-esm/src/Declarations/Constants.js +1 -26
- package/dist-esm/src/Declarations/Constants.js.map +1 -1
- package/dist-esm/src/config.js +2 -4
- package/dist-esm/src/config.js.map +1 -1
- package/dist-esm/src/export/trace.js +5 -4
- package/dist-esm/src/export/trace.js.map +1 -1
- package/dist-esm/src/generated/applicationInsightsClient.js +13 -9
- package/dist-esm/src/generated/applicationInsightsClient.js.map +1 -1
- package/dist-esm/src/generated/applicationInsightsClientContext.js +13 -11
- package/dist-esm/src/generated/applicationInsightsClientContext.js.map +1 -1
- package/dist-esm/src/generated/models/index.js +47 -1
- package/dist-esm/src/generated/models/index.js.map +1 -1
- package/dist-esm/src/generated/models/mappers.js +25 -4
- package/dist-esm/src/generated/models/mappers.js.map +1 -1
- package/dist-esm/src/generated/models/parameters.js +6 -1
- package/dist-esm/src/generated/models/parameters.js.map +1 -1
- package/dist-esm/src/platform/nodejs/constants.js +1 -1
- package/dist-esm/src/platform/nodejs/constants.js.map +1 -1
- package/dist-esm/src/platform/nodejs/context/context.js +12 -82
- package/dist-esm/src/platform/nodejs/context/context.js.map +1 -1
- package/dist-esm/src/platform/nodejs/httpSender.js +23 -4
- package/dist-esm/src/platform/nodejs/httpSender.js.map +1 -1
- package/dist-esm/src/platform/nodejs/persist/fileAccessControl.js +171 -0
- package/dist-esm/src/platform/nodejs/persist/fileAccessControl.js.map +1 -0
- package/dist-esm/src/platform/nodejs/persist/fileSystemPersist.js +40 -19
- package/dist-esm/src/platform/nodejs/persist/fileSystemPersist.js.map +1 -1
- package/dist-esm/src/types.js.map +1 -1
- package/dist-esm/src/utils/breezeUtils.js +5 -4
- package/dist-esm/src/utils/breezeUtils.js.map +1 -1
- package/dist-esm/src/utils/constants/applicationinsights.js +9 -31
- package/dist-esm/src/utils/constants/applicationinsights.js.map +1 -1
- package/dist-esm/src/utils/eventhub.js +1 -1
- package/dist-esm/src/utils/eventhub.js.map +1 -1
- package/dist-esm/src/utils/spanUtils.js +253 -100
- package/dist-esm/src/utils/spanUtils.js.map +1 -1
- package/package.json +37 -24
- package/types/monitor-opentelemetry-exporter.d.ts +7 -2
- package/dist-esm/src/utils/constants/span/dbAttributes.js +0 -14
- package/dist-esm/src/utils/constants/span/dbAttributes.js.map +0 -1
- package/dist-esm/src/utils/constants/span/grpcAttributes.js +0 -14
- package/dist-esm/src/utils/constants/span/grpcAttributes.js.map +0 -1
- package/dist-esm/src/utils/constants/span/httpAttributes.js +0 -24
- package/dist-esm/src/utils/constants/span/httpAttributes.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2,20 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
6
|
-
|
|
7
5
|
var api = require('@opentelemetry/api');
|
|
8
6
|
var core = require('@opentelemetry/core');
|
|
9
|
-
var fs = require('fs');
|
|
10
7
|
var os = require('os');
|
|
8
|
+
var url = require('url');
|
|
9
|
+
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
10
|
+
var coreRestPipeline = require('@azure/core-rest-pipeline');
|
|
11
|
+
var coreClient = require('@azure/core-client');
|
|
12
|
+
var fs = require('fs');
|
|
11
13
|
var path = require('path');
|
|
14
|
+
var child_process = require('child_process');
|
|
12
15
|
var util = require('util');
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
18
|
+
|
|
19
|
+
function _interopNamespace(e) {
|
|
20
|
+
if (e && e.__esModule) return e;
|
|
21
|
+
var n = Object.create(null);
|
|
22
|
+
if (e) {
|
|
23
|
+
Object.keys(e).forEach(function (k) {
|
|
24
|
+
if (k !== 'default') {
|
|
25
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
26
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function () { return e[k]; }
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
n["default"] = e;
|
|
34
|
+
return Object.freeze(n);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
38
|
+
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
39
|
+
var url__default = /*#__PURE__*/_interopDefaultLegacy(url);
|
|
40
|
+
var coreClient__namespace = /*#__PURE__*/_interopNamespace(coreClient);
|
|
41
|
+
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
42
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
43
|
+
var child_process__namespace = /*#__PURE__*/_interopNamespace(child_process);
|
|
17
44
|
|
|
18
45
|
// Copyright (c) Microsoft Corporation.
|
|
46
|
+
// Licensed under the MIT license.
|
|
47
|
+
/**
|
|
48
|
+
* Azure service API version.
|
|
49
|
+
*/
|
|
50
|
+
exports.ServiceApiVersion = void 0;
|
|
19
51
|
(function (ServiceApiVersion) {
|
|
20
52
|
/**
|
|
21
53
|
* V2 Version
|
|
@@ -83,7 +115,7 @@ var PerformanceCounter;
|
|
|
83
115
|
* Map a PerformanceCounter/QuickPulseCounter to a QuickPulseCounter. If no mapping exists, mapping is *undefined*
|
|
84
116
|
* @internal
|
|
85
117
|
*/
|
|
86
|
-
|
|
118
|
+
({
|
|
87
119
|
[PerformanceCounter.PROCESSOR_TIME]: QuickPulseCounter.PROCESSOR_TIME,
|
|
88
120
|
[PerformanceCounter.REQUEST_RATE]: QuickPulseCounter.REQUEST_RATE,
|
|
89
121
|
[PerformanceCounter.REQUEST_DURATION]: QuickPulseCounter.REQUEST_DURATION,
|
|
@@ -93,8 +125,8 @@ const PerformanceToQuickPulseCounter = {
|
|
|
93
125
|
[QuickPulseCounter.DEPENDENCY_RATE]: QuickPulseCounter.DEPENDENCY_RATE,
|
|
94
126
|
[QuickPulseCounter.DEPENDENCY_FAILURE_RATE]: QuickPulseCounter.DEPENDENCY_FAILURE_RATE,
|
|
95
127
|
[QuickPulseCounter.DEPENDENCY_DURATION]: QuickPulseCounter.DEPENDENCY_DURATION,
|
|
96
|
-
[QuickPulseCounter.EXCEPTION_RATE]: QuickPulseCounter.EXCEPTION_RATE
|
|
97
|
-
};
|
|
128
|
+
[QuickPulseCounter.EXCEPTION_RATE]: QuickPulseCounter.EXCEPTION_RATE,
|
|
129
|
+
});
|
|
98
130
|
|
|
99
131
|
// Copyright (c) Microsoft Corporation.
|
|
100
132
|
/**
|
|
@@ -161,7 +193,6 @@ class ConnectionStringParser {
|
|
|
161
193
|
ConnectionStringParser.FIELDS_SEPARATOR = ";";
|
|
162
194
|
ConnectionStringParser.FIELD_KEY_VALUE_SEPARATOR = "=";
|
|
163
195
|
|
|
164
|
-
// Copyright (c) Microsoft Corporation.
|
|
165
196
|
const DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS = 60000;
|
|
166
197
|
const DEFAULT_MAX_CONSECUTIVE_FAILURES_BEFORE_WARNING = 10;
|
|
167
198
|
/**
|
|
@@ -173,25 +204,191 @@ const DEFAULT_EXPORTER_CONFIG = {
|
|
|
173
204
|
endpointUrl: DEFAULT_BREEZE_ENDPOINT,
|
|
174
205
|
batchSendRetryIntervalMs: DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS,
|
|
175
206
|
maxConsecutiveFailuresBeforeWarning: DEFAULT_MAX_CONSECUTIVE_FAILURES_BEFORE_WARNING,
|
|
176
|
-
apiVersion: DEFAULT_BREEZE_API_VERSION
|
|
207
|
+
apiVersion: DEFAULT_BREEZE_API_VERSION,
|
|
177
208
|
};
|
|
178
209
|
|
|
179
210
|
// Copyright (c) Microsoft Corporation.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
211
|
+
class FileAccessControl {
|
|
212
|
+
// Check if file access control could be enabled
|
|
213
|
+
static checkFileProtection() {
|
|
214
|
+
if (!FileAccessControl.OS_PROVIDES_FILE_PROTECTION &&
|
|
215
|
+
!FileAccessControl.OS_FILE_PROTECTION_CHECKED) {
|
|
216
|
+
FileAccessControl.OS_FILE_PROTECTION_CHECKED = true;
|
|
217
|
+
// Node's chmod levels do not appropriately restrict file access on Windows
|
|
218
|
+
// Use the built-in command line tool ICACLS on Windows to properly restrict
|
|
219
|
+
// access to the temporary directory used for disk retry mode.
|
|
220
|
+
if (FileAccessControl.USE_ICACLS) {
|
|
221
|
+
// This should be async - but it's currently safer to have this synchronous
|
|
222
|
+
// This guarantees we can immediately fail setDiskRetryMode if we need to
|
|
223
|
+
try {
|
|
224
|
+
FileAccessControl.OS_PROVIDES_FILE_PROTECTION = fs__namespace.existsSync(FileAccessControl.ICACLS_PATH);
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
// Ignore error
|
|
228
|
+
}
|
|
229
|
+
if (!FileAccessControl.OS_PROVIDES_FILE_PROTECTION) {
|
|
230
|
+
api.diag.warn("Could not find ICACLS in expected location! This is necessary to use disk retry mode on Windows.");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
// chmod works everywhere else
|
|
235
|
+
FileAccessControl.OS_PROVIDES_FILE_PROTECTION = true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
static async applyACLRules(directory) {
|
|
240
|
+
if (FileAccessControl.USE_ICACLS) {
|
|
241
|
+
if (FileAccessControl.ACLED_DIRECTORIES[directory] === undefined) {
|
|
242
|
+
// Avoid multiple calls race condition by setting ACLED_DIRECTORIES to false for this directory immediately
|
|
243
|
+
// If batches are being failed faster than the processes spawned below return, some data won't be stored to disk
|
|
244
|
+
// This is better than the alternative of potentially infinitely spawned processes
|
|
245
|
+
FileAccessControl.ACLED_DIRECTORIES[directory] = false;
|
|
246
|
+
try {
|
|
247
|
+
// Restrict this directory to only current user and administrator access
|
|
248
|
+
let identity = await this._getACLIdentity();
|
|
249
|
+
await this._runICACLS(this._getACLArguments(directory, identity));
|
|
250
|
+
FileAccessControl.ACLED_DIRECTORIES[directory] = true;
|
|
251
|
+
}
|
|
252
|
+
catch (ex) {
|
|
253
|
+
FileAccessControl.ACLED_DIRECTORIES[directory] = false; // false is used to cache failed (vs undefined which is "not yet tried")
|
|
254
|
+
throw ex;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
if (!FileAccessControl.ACLED_DIRECTORIES[directory]) {
|
|
259
|
+
throw new Error("Setting ACL restrictions did not succeed (cached result)");
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
static applyACLRulesSync(directory) {
|
|
265
|
+
if (FileAccessControl.USE_ICACLS) {
|
|
266
|
+
// For performance, only run ACL rules if we haven't already during this session
|
|
267
|
+
if (FileAccessControl.ACLED_DIRECTORIES[directory] === undefined) {
|
|
268
|
+
this._runICACLSSync(this._getACLArguments(directory, this._getACLIdentitySync()));
|
|
269
|
+
FileAccessControl.ACLED_DIRECTORIES[directory] = true; // If we get here, it succeeded. _runIACLSSync will throw on failures
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
else if (!FileAccessControl.ACLED_DIRECTORIES[directory]) {
|
|
273
|
+
// falsy but not undefined
|
|
274
|
+
throw new Error("Setting ACL restrictions did not succeed (cached result)");
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
static _runICACLS(args) {
|
|
279
|
+
return new Promise((resolve, reject) => {
|
|
280
|
+
var aclProc = child_process__namespace.spawn(FileAccessControl.ICACLS_PATH, args, {
|
|
281
|
+
windowsHide: true,
|
|
282
|
+
});
|
|
283
|
+
aclProc.on("error", (e) => reject(e));
|
|
284
|
+
aclProc.on("close", (code) => {
|
|
285
|
+
if (code === 0) {
|
|
286
|
+
resolve();
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
reject(new Error(`Setting ACL restrictions did not succeed (ICACLS returned code ${code})`));
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
static _runICACLSSync(args) {
|
|
295
|
+
// Some very old versions of Node (< 0.11) don't have this
|
|
296
|
+
if (child_process__namespace.spawnSync) {
|
|
297
|
+
var aclProc = child_process__namespace.spawnSync(FileAccessControl.ICACLS_PATH, args, {
|
|
298
|
+
windowsHide: true,
|
|
299
|
+
});
|
|
300
|
+
if (aclProc.error) {
|
|
301
|
+
throw aclProc.error;
|
|
302
|
+
}
|
|
303
|
+
else if (aclProc.status !== 0) {
|
|
304
|
+
throw new Error(`Setting ACL restrictions did not succeed (ICACLS returned code ${aclProc.status})`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
throw new Error("Could not synchronously call ICACLS under current version of Node.js");
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
static _getACLIdentity() {
|
|
312
|
+
return new Promise((resolve, reject) => {
|
|
313
|
+
if (FileAccessControl.ACL_IDENTITY) {
|
|
314
|
+
resolve(FileAccessControl.ACL_IDENTITY);
|
|
315
|
+
}
|
|
316
|
+
var psProc = child_process__namespace.spawn(FileAccessControl.POWERSHELL_PATH, ["-Command", "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name"], {
|
|
317
|
+
windowsHide: true,
|
|
318
|
+
stdio: ["ignore", "pipe", "pipe"], // Needed to prevent hanging on Win 7
|
|
319
|
+
});
|
|
320
|
+
let data = "";
|
|
321
|
+
psProc.stdout.on("data", (d) => (data += d));
|
|
322
|
+
psProc.on("error", (e) => reject(e));
|
|
323
|
+
psProc.on("close", (code) => {
|
|
324
|
+
FileAccessControl.ACL_IDENTITY = data && data.trim();
|
|
325
|
+
if (code === 0) {
|
|
326
|
+
resolve(FileAccessControl.ACL_IDENTITY);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
reject(new Error(`Getting ACL identity did not succeed (PS returned code ${code})`));
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
static _getACLIdentitySync() {
|
|
335
|
+
if (FileAccessControl.ACL_IDENTITY) {
|
|
336
|
+
return FileAccessControl.ACL_IDENTITY;
|
|
337
|
+
}
|
|
338
|
+
// Some very old versions of Node (< 0.11) don't have this
|
|
339
|
+
if (child_process__namespace.spawnSync) {
|
|
340
|
+
var psProc = child_process__namespace.spawnSync(FileAccessControl.POWERSHELL_PATH, ["-Command", "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name"], {
|
|
341
|
+
windowsHide: true,
|
|
342
|
+
stdio: ["ignore", "pipe", "pipe"], // Needed to prevent hanging on Win 7
|
|
343
|
+
});
|
|
344
|
+
if (psProc.error) {
|
|
345
|
+
throw psProc.error;
|
|
346
|
+
}
|
|
347
|
+
else if (psProc.status !== 0) {
|
|
348
|
+
throw new Error(`Getting ACL identity did not succeed (PS returned code ${psProc.status})`);
|
|
349
|
+
}
|
|
350
|
+
FileAccessControl.ACL_IDENTITY = psProc.stdout && psProc.stdout.toString().trim();
|
|
351
|
+
return FileAccessControl.ACL_IDENTITY;
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
throw new Error("Could not synchronously get ACL identity under current version of Node.js");
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
static _getACLArguments(directory, identity) {
|
|
358
|
+
return [
|
|
359
|
+
directory,
|
|
360
|
+
"/grant",
|
|
361
|
+
"*S-1-5-32-544:(OI)(CI)F",
|
|
362
|
+
"/grant",
|
|
363
|
+
`${identity}:(OI)(CI)F`,
|
|
364
|
+
"/inheritance:r",
|
|
365
|
+
]; // Remove all inherited permissions
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
FileAccessControl.ICACLS_PATH = `${process.env.systemdrive}/windows/system32/icacls.exe`;
|
|
369
|
+
FileAccessControl.POWERSHELL_PATH = `${process.env.systemdrive}/windows/system32/windowspowershell/v1.0/powershell.exe`;
|
|
370
|
+
FileAccessControl.ACLED_DIRECTORIES = {};
|
|
371
|
+
FileAccessControl.ACL_IDENTITY = null;
|
|
372
|
+
FileAccessControl.OS_FILE_PROTECTION_CHECKED = false;
|
|
373
|
+
FileAccessControl.OS_PROVIDES_FILE_PROTECTION = false;
|
|
374
|
+
FileAccessControl.USE_ICACLS = os__namespace.type() === "Windows_NT";
|
|
375
|
+
|
|
376
|
+
// Copyright (c) Microsoft Corporation.
|
|
377
|
+
const readdirAsync$1 = util.promisify(fs__namespace.readdir);
|
|
378
|
+
const statAsync$1 = util.promisify(fs__namespace.stat);
|
|
379
|
+
const lstatAsync = util.promisify(fs__namespace.lstat);
|
|
380
|
+
const mkdirAsync = util.promisify(fs__namespace.mkdir);
|
|
184
381
|
/**
|
|
185
382
|
* Computes the size (in bytes) of all files in a directory at the root level. Asynchronously.
|
|
186
383
|
* @internal
|
|
187
384
|
*/
|
|
188
385
|
const getShallowDirectorySize = async (directory) => {
|
|
189
386
|
// Get the directory listing
|
|
190
|
-
const files = await readdirAsync(directory);
|
|
387
|
+
const files = await readdirAsync$1(directory);
|
|
191
388
|
let totalSize = 0;
|
|
192
389
|
// Query all file sizes
|
|
193
390
|
for (const file of files) {
|
|
194
|
-
const fileStats = await statAsync(
|
|
391
|
+
const fileStats = await statAsync$1(path__namespace.join(directory, file));
|
|
195
392
|
if (fileStats.isFile()) {
|
|
196
393
|
totalSize += fileStats.size;
|
|
197
394
|
}
|
|
@@ -225,11 +422,11 @@ const confirmDirExists = async (directory) => {
|
|
|
225
422
|
};
|
|
226
423
|
|
|
227
424
|
// Copyright (c) Microsoft Corporation.
|
|
228
|
-
const statAsync
|
|
229
|
-
const readdirAsync
|
|
230
|
-
const readFileAsync = util.promisify(
|
|
231
|
-
const unlinkAsync = util.promisify(
|
|
232
|
-
const writeFileAsync = util.promisify(
|
|
425
|
+
const statAsync = util.promisify(fs__namespace.stat);
|
|
426
|
+
const readdirAsync = util.promisify(fs__namespace.readdir);
|
|
427
|
+
const readFileAsync = util.promisify(fs__namespace.readFile);
|
|
428
|
+
const unlinkAsync = util.promisify(fs__namespace.unlink);
|
|
429
|
+
const writeFileAsync = util.promisify(fs__namespace.writeFile);
|
|
233
430
|
/**
|
|
234
431
|
* File system persist class.
|
|
235
432
|
* @internal
|
|
@@ -239,36 +436,56 @@ class FileSystemPersist {
|
|
|
239
436
|
this.fileRetemptionPeriod = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
240
437
|
this.cleanupTimeOut = 60 * 60 * 1000; // 1 hour
|
|
241
438
|
this.maxBytesOnDisk = 50000000; // ~50MB
|
|
439
|
+
this._tempDirectory = "";
|
|
242
440
|
this._fileCleanupTimer = null;
|
|
243
441
|
this._options = Object.assign(Object.assign({}, DEFAULT_EXPORTER_CONFIG), options);
|
|
442
|
+
this._enabled = true;
|
|
443
|
+
FileAccessControl.checkFileProtection();
|
|
444
|
+
if (!FileAccessControl.OS_PROVIDES_FILE_PROTECTION) {
|
|
445
|
+
this._enabled = false;
|
|
446
|
+
api.diag.error("Sufficient file protection capabilities were not detected. Files will not be persisted");
|
|
447
|
+
}
|
|
244
448
|
if (!this._options.instrumentationKey) {
|
|
245
|
-
|
|
449
|
+
this._enabled = false;
|
|
450
|
+
api.diag.error(`No instrumentation key was provided to FileSystemPersister. Files will not be persisted`);
|
|
246
451
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
this._fileCleanupTimer
|
|
251
|
-
this.
|
|
252
|
-
|
|
253
|
-
|
|
452
|
+
if (this._enabled) {
|
|
453
|
+
this._tempDirectory = path__namespace.join(os__namespace.tmpdir(), FileSystemPersist.TEMPDIR_PREFIX + this._options.instrumentationKey);
|
|
454
|
+
// Starts file cleanup task
|
|
455
|
+
if (!this._fileCleanupTimer) {
|
|
456
|
+
this._fileCleanupTimer = setTimeout(() => {
|
|
457
|
+
this._fileCleanupTask();
|
|
458
|
+
}, this.cleanupTimeOut);
|
|
459
|
+
this._fileCleanupTimer.unref();
|
|
460
|
+
}
|
|
254
461
|
}
|
|
255
462
|
}
|
|
256
463
|
push(value) {
|
|
257
|
-
|
|
258
|
-
|
|
464
|
+
if (this._enabled) {
|
|
465
|
+
api.diag.debug("Pushing value to persistent storage", value.toString());
|
|
466
|
+
return this._storeToDisk(JSON.stringify(value));
|
|
467
|
+
}
|
|
468
|
+
return new Promise((resolve) => {
|
|
469
|
+
resolve(false);
|
|
470
|
+
});
|
|
259
471
|
}
|
|
260
472
|
async shift() {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
473
|
+
if (this._enabled) {
|
|
474
|
+
api.diag.debug("Searching for filesystem persisted files");
|
|
475
|
+
try {
|
|
476
|
+
const buffer = await this._getFirstFileOnDisk();
|
|
477
|
+
if (buffer) {
|
|
478
|
+
return JSON.parse(buffer.toString("utf8"));
|
|
479
|
+
}
|
|
266
480
|
}
|
|
481
|
+
catch (e) {
|
|
482
|
+
api.diag.debug("Failed to read persisted file", e);
|
|
483
|
+
}
|
|
484
|
+
return null;
|
|
267
485
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
return null;
|
|
486
|
+
return new Promise((resolve) => {
|
|
487
|
+
resolve(null);
|
|
488
|
+
});
|
|
272
489
|
}
|
|
273
490
|
/**
|
|
274
491
|
* Check for temp telemetry files
|
|
@@ -276,16 +493,16 @@ class FileSystemPersist {
|
|
|
276
493
|
*/
|
|
277
494
|
async _getFirstFileOnDisk() {
|
|
278
495
|
try {
|
|
279
|
-
const stats = await statAsync
|
|
496
|
+
const stats = await statAsync(this._tempDirectory);
|
|
280
497
|
if (stats.isDirectory()) {
|
|
281
|
-
const origFiles = await readdirAsync
|
|
282
|
-
const files = origFiles.filter((f) =>
|
|
498
|
+
const origFiles = await readdirAsync(this._tempDirectory);
|
|
499
|
+
const files = origFiles.filter((f) => path__namespace.basename(f).includes(FileSystemPersist.FILENAME_SUFFIX));
|
|
283
500
|
if (files.length === 0) {
|
|
284
501
|
return null;
|
|
285
502
|
}
|
|
286
503
|
else {
|
|
287
504
|
const firstFile = files[0];
|
|
288
|
-
const filePath =
|
|
505
|
+
const filePath = path__namespace.join(this._tempDirectory, firstFile);
|
|
289
506
|
const payload = await readFileAsync(filePath);
|
|
290
507
|
// delete the file first to prevent double sending
|
|
291
508
|
await unlinkAsync(filePath);
|
|
@@ -324,7 +541,7 @@ class FileSystemPersist {
|
|
|
324
541
|
return false;
|
|
325
542
|
}
|
|
326
543
|
const fileName = `${new Date().getTime()}${FileSystemPersist.FILENAME_SUFFIX}`;
|
|
327
|
-
const fileFullPath =
|
|
544
|
+
const fileFullPath = path__namespace.join(this._tempDirectory, fileName);
|
|
328
545
|
// Mode 600 is w/r for creator and no read access for others
|
|
329
546
|
api.diag.info(`saving data to disk at: ${fileFullPath}`);
|
|
330
547
|
try {
|
|
@@ -338,10 +555,10 @@ class FileSystemPersist {
|
|
|
338
555
|
}
|
|
339
556
|
async _fileCleanupTask() {
|
|
340
557
|
try {
|
|
341
|
-
const stats = await statAsync
|
|
558
|
+
const stats = await statAsync(this._tempDirectory);
|
|
342
559
|
if (stats.isDirectory()) {
|
|
343
|
-
const origFiles = await readdirAsync
|
|
344
|
-
const files = origFiles.filter((f) =>
|
|
560
|
+
const origFiles = await readdirAsync(this._tempDirectory);
|
|
561
|
+
const files = origFiles.filter((f) => path__namespace.basename(f).includes(FileSystemPersist.FILENAME_SUFFIX));
|
|
345
562
|
if (files.length === 0) {
|
|
346
563
|
return false;
|
|
347
564
|
}
|
|
@@ -351,7 +568,7 @@ class FileSystemPersist {
|
|
|
351
568
|
const fileCreationDate = new Date(parseInt(file.split(FileSystemPersist.FILENAME_SUFFIX)[0]));
|
|
352
569
|
const expired = new Date(+new Date() - this.fileRetemptionPeriod) > fileCreationDate;
|
|
353
570
|
if (expired) {
|
|
354
|
-
const filePath =
|
|
571
|
+
const filePath = path__namespace.join(this._tempDirectory, file);
|
|
355
572
|
await unlinkAsync(filePath);
|
|
356
573
|
}
|
|
357
574
|
});
|
|
@@ -369,6 +586,61 @@ class FileSystemPersist {
|
|
|
369
586
|
FileSystemPersist.TEMPDIR_PREFIX = "ot-azure-exporter-";
|
|
370
587
|
FileSystemPersist.FILENAME_SUFFIX = ".ai.json";
|
|
371
588
|
|
|
589
|
+
/*
|
|
590
|
+
* Copyright (c) Microsoft Corporation.
|
|
591
|
+
* Licensed under the MIT License.
|
|
592
|
+
*
|
|
593
|
+
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
594
|
+
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
595
|
+
*/
|
|
596
|
+
/** Known values of {@link DataPointType} that the service accepts. */
|
|
597
|
+
var KnownDataPointType;
|
|
598
|
+
(function (KnownDataPointType) {
|
|
599
|
+
KnownDataPointType["Measurement"] = "Measurement";
|
|
600
|
+
KnownDataPointType["Aggregation"] = "Aggregation";
|
|
601
|
+
})(KnownDataPointType || (KnownDataPointType = {}));
|
|
602
|
+
/** Known values of {@link SeverityLevel} that the service accepts. */
|
|
603
|
+
var KnownSeverityLevel;
|
|
604
|
+
(function (KnownSeverityLevel) {
|
|
605
|
+
KnownSeverityLevel["Verbose"] = "Verbose";
|
|
606
|
+
KnownSeverityLevel["Information"] = "Information";
|
|
607
|
+
KnownSeverityLevel["Warning"] = "Warning";
|
|
608
|
+
KnownSeverityLevel["Error"] = "Error";
|
|
609
|
+
KnownSeverityLevel["Critical"] = "Critical";
|
|
610
|
+
})(KnownSeverityLevel || (KnownSeverityLevel = {}));
|
|
611
|
+
/** Known values of {@link ContextTagKeys} that the service accepts. */
|
|
612
|
+
var KnownContextTagKeys;
|
|
613
|
+
(function (KnownContextTagKeys) {
|
|
614
|
+
KnownContextTagKeys["AiApplicationVer"] = "ai.application.ver";
|
|
615
|
+
KnownContextTagKeys["AiDeviceId"] = "ai.device.id";
|
|
616
|
+
KnownContextTagKeys["AiDeviceLocale"] = "ai.device.locale";
|
|
617
|
+
KnownContextTagKeys["AiDeviceModel"] = "ai.device.model";
|
|
618
|
+
KnownContextTagKeys["AiDeviceOemName"] = "ai.device.oemName";
|
|
619
|
+
KnownContextTagKeys["AiDeviceOsVersion"] = "ai.device.osVersion";
|
|
620
|
+
KnownContextTagKeys["AiDeviceType"] = "ai.device.type";
|
|
621
|
+
KnownContextTagKeys["AiLocationIp"] = "ai.location.ip";
|
|
622
|
+
KnownContextTagKeys["AiLocationCountry"] = "ai.location.country";
|
|
623
|
+
KnownContextTagKeys["AiLocationProvince"] = "ai.location.province";
|
|
624
|
+
KnownContextTagKeys["AiLocationCity"] = "ai.location.city";
|
|
625
|
+
KnownContextTagKeys["AiOperationId"] = "ai.operation.id";
|
|
626
|
+
KnownContextTagKeys["AiOperationName"] = "ai.operation.name";
|
|
627
|
+
KnownContextTagKeys["AiOperationParentId"] = "ai.operation.parentId";
|
|
628
|
+
KnownContextTagKeys["AiOperationSyntheticSource"] = "ai.operation.syntheticSource";
|
|
629
|
+
KnownContextTagKeys["AiOperationCorrelationVector"] = "ai.operation.correlationVector";
|
|
630
|
+
KnownContextTagKeys["AiSessionId"] = "ai.session.id";
|
|
631
|
+
KnownContextTagKeys["AiSessionIsFirst"] = "ai.session.isFirst";
|
|
632
|
+
KnownContextTagKeys["AiUserAccountId"] = "ai.user.accountId";
|
|
633
|
+
KnownContextTagKeys["AiUserId"] = "ai.user.id";
|
|
634
|
+
KnownContextTagKeys["AiUserAuthUserId"] = "ai.user.authUserId";
|
|
635
|
+
KnownContextTagKeys["AiCloudRole"] = "ai.cloud.role";
|
|
636
|
+
KnownContextTagKeys["AiCloudRoleVer"] = "ai.cloud.roleVer";
|
|
637
|
+
KnownContextTagKeys["AiCloudRoleInstance"] = "ai.cloud.roleInstance";
|
|
638
|
+
KnownContextTagKeys["AiCloudLocation"] = "ai.cloud.location";
|
|
639
|
+
KnownContextTagKeys["AiInternalSdkVersion"] = "ai.internal.sdkVersion";
|
|
640
|
+
KnownContextTagKeys["AiInternalAgentVersion"] = "ai.internal.agentVersion";
|
|
641
|
+
KnownContextTagKeys["AiInternalNodeName"] = "ai.internal.nodeName";
|
|
642
|
+
})(KnownContextTagKeys || (KnownContextTagKeys = {}));
|
|
643
|
+
|
|
372
644
|
/*
|
|
373
645
|
* Copyright (c) Microsoft Corporation.
|
|
374
646
|
* Licensed under the MIT License.
|
|
@@ -394,7 +666,12 @@ const body = {
|
|
|
394
666
|
required: true,
|
|
395
667
|
type: {
|
|
396
668
|
name: "Sequence",
|
|
397
|
-
element: {
|
|
669
|
+
element: {
|
|
670
|
+
type: {
|
|
671
|
+
name: "Composite",
|
|
672
|
+
className: "TelemetryItem"
|
|
673
|
+
}
|
|
674
|
+
}
|
|
398
675
|
}
|
|
399
676
|
}
|
|
400
677
|
};
|
|
@@ -553,7 +830,10 @@ const TrackResponse = {
|
|
|
553
830
|
type: {
|
|
554
831
|
name: "Sequence",
|
|
555
832
|
element: {
|
|
556
|
-
type: {
|
|
833
|
+
type: {
|
|
834
|
+
name: "Composite",
|
|
835
|
+
className: "TelemetryErrorDetails"
|
|
836
|
+
}
|
|
557
837
|
}
|
|
558
838
|
}
|
|
559
839
|
}
|
|
@@ -625,24 +905,28 @@ const MetricDataPoint = {
|
|
|
625
905
|
},
|
|
626
906
|
count: {
|
|
627
907
|
serializedName: "count",
|
|
908
|
+
nullable: true,
|
|
628
909
|
type: {
|
|
629
910
|
name: "Number"
|
|
630
911
|
}
|
|
631
912
|
},
|
|
632
913
|
min: {
|
|
633
914
|
serializedName: "min",
|
|
915
|
+
nullable: true,
|
|
634
916
|
type: {
|
|
635
917
|
name: "Number"
|
|
636
918
|
}
|
|
637
919
|
},
|
|
638
920
|
max: {
|
|
639
921
|
serializedName: "max",
|
|
922
|
+
nullable: true,
|
|
640
923
|
type: {
|
|
641
924
|
name: "Number"
|
|
642
925
|
}
|
|
643
926
|
},
|
|
644
927
|
stdDev: {
|
|
645
928
|
serializedName: "stdDev",
|
|
929
|
+
nullable: true,
|
|
646
930
|
type: {
|
|
647
931
|
name: "Number"
|
|
648
932
|
}
|
|
@@ -706,7 +990,12 @@ const TelemetryExceptionDetails = {
|
|
|
706
990
|
serializedName: "parsedStack",
|
|
707
991
|
type: {
|
|
708
992
|
name: "Sequence",
|
|
709
|
-
element: {
|
|
993
|
+
element: {
|
|
994
|
+
type: {
|
|
995
|
+
name: "Composite",
|
|
996
|
+
className: "StackFrame"
|
|
997
|
+
}
|
|
998
|
+
}
|
|
710
999
|
}
|
|
711
1000
|
}
|
|
712
1001
|
}
|
|
@@ -867,11 +1156,15 @@ const TelemetryExceptionData = {
|
|
|
867
1156
|
type: {
|
|
868
1157
|
name: "Sequence",
|
|
869
1158
|
element: {
|
|
870
|
-
type: {
|
|
1159
|
+
type: {
|
|
1160
|
+
name: "Composite",
|
|
1161
|
+
className: "TelemetryExceptionDetails"
|
|
1162
|
+
}
|
|
871
1163
|
}
|
|
872
1164
|
}
|
|
873
1165
|
}, severityLevel: {
|
|
874
1166
|
serializedName: "severityLevel",
|
|
1167
|
+
nullable: true,
|
|
875
1168
|
type: {
|
|
876
1169
|
name: "String"
|
|
877
1170
|
}
|
|
@@ -942,7 +1235,12 @@ const MetricsData = {
|
|
|
942
1235
|
required: true,
|
|
943
1236
|
type: {
|
|
944
1237
|
name: "Sequence",
|
|
945
|
-
element: {
|
|
1238
|
+
element: {
|
|
1239
|
+
type: {
|
|
1240
|
+
name: "Composite",
|
|
1241
|
+
className: "MetricDataPoint"
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
946
1244
|
}
|
|
947
1245
|
}, properties: {
|
|
948
1246
|
serializedName: "properties",
|
|
@@ -1273,9 +1571,7 @@ var Mappers = /*#__PURE__*/Object.freeze({
|
|
|
1273
1571
|
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
1274
1572
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
1275
1573
|
*/
|
|
1276
|
-
|
|
1277
|
-
const packageVersion = "1.0.0-beta.2";
|
|
1278
|
-
class ApplicationInsightsClientContext extends coreHttp.ServiceClient {
|
|
1574
|
+
class ApplicationInsightsClientContext extends coreClient__namespace.ServiceClient {
|
|
1279
1575
|
/**
|
|
1280
1576
|
* Initializes a new instance of the ApplicationInsightsClientContext class.
|
|
1281
1577
|
* @param options The parameter options
|
|
@@ -1285,13 +1581,17 @@ class ApplicationInsightsClientContext extends coreHttp.ServiceClient {
|
|
|
1285
1581
|
if (!options) {
|
|
1286
1582
|
options = {};
|
|
1287
1583
|
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1584
|
+
const defaults = {
|
|
1585
|
+
requestContentType: "application/json; charset=utf-8"
|
|
1586
|
+
};
|
|
1587
|
+
const packageDetails = `azsdk-js-monitor-opentelemetry-exporter/1.0.0-beta.7`;
|
|
1588
|
+
const userAgentPrefix = options.userAgentOptions && options.userAgentOptions.userAgentPrefix
|
|
1589
|
+
? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
|
|
1590
|
+
: `${packageDetails}`;
|
|
1591
|
+
const optionsWithDefaults = Object.assign(Object.assign(Object.assign({}, defaults), options), { userAgentOptions: {
|
|
1592
|
+
userAgentPrefix
|
|
1593
|
+
}, baseUri: options.endpoint || "{Host}/v2.1" });
|
|
1594
|
+
super(optionsWithDefaults);
|
|
1295
1595
|
// Assigning values to Constant parameters
|
|
1296
1596
|
this.host = options.host || "https://dc.services.visualstudio.com";
|
|
1297
1597
|
}
|
|
@@ -1318,12 +1618,11 @@ class ApplicationInsightsClient extends ApplicationInsightsClientContext {
|
|
|
1318
1618
|
* @param options The options parameters.
|
|
1319
1619
|
*/
|
|
1320
1620
|
track(body, options) {
|
|
1321
|
-
|
|
1322
|
-
return this.sendOperationRequest({ body, options: operationOptions }, trackOperationSpec);
|
|
1621
|
+
return this.sendOperationRequest({ body, options }, trackOperationSpec);
|
|
1323
1622
|
}
|
|
1324
1623
|
}
|
|
1325
1624
|
// Operation Specifications
|
|
1326
|
-
const serializer =
|
|
1625
|
+
const serializer = coreClient__namespace.createSerializer(Mappers, /* isXml */ false);
|
|
1327
1626
|
const trackOperationSpec = {
|
|
1328
1627
|
path: "/track",
|
|
1329
1628
|
httpMethod: "POST",
|
|
@@ -1335,19 +1634,24 @@ const trackOperationSpec = {
|
|
|
1335
1634
|
bodyMapper: TrackResponse
|
|
1336
1635
|
},
|
|
1337
1636
|
400: {
|
|
1338
|
-
bodyMapper: TrackResponse
|
|
1637
|
+
bodyMapper: TrackResponse,
|
|
1638
|
+
isError: true
|
|
1339
1639
|
},
|
|
1340
1640
|
402: {
|
|
1341
|
-
bodyMapper: TrackResponse
|
|
1641
|
+
bodyMapper: TrackResponse,
|
|
1642
|
+
isError: true
|
|
1342
1643
|
},
|
|
1343
1644
|
429: {
|
|
1344
|
-
bodyMapper: TrackResponse
|
|
1645
|
+
bodyMapper: TrackResponse,
|
|
1646
|
+
isError: true
|
|
1345
1647
|
},
|
|
1346
1648
|
500: {
|
|
1347
|
-
bodyMapper: TrackResponse
|
|
1649
|
+
bodyMapper: TrackResponse,
|
|
1650
|
+
isError: true
|
|
1348
1651
|
},
|
|
1349
1652
|
503: {
|
|
1350
|
-
bodyMapper: TrackResponse
|
|
1653
|
+
bodyMapper: TrackResponse,
|
|
1654
|
+
isError: true
|
|
1351
1655
|
}
|
|
1352
1656
|
},
|
|
1353
1657
|
requestBody: body,
|
|
@@ -1358,6 +1662,7 @@ const trackOperationSpec = {
|
|
|
1358
1662
|
};
|
|
1359
1663
|
|
|
1360
1664
|
// Copyright (c) Microsoft Corporation.
|
|
1665
|
+
const applicationInsightsResource = "https://monitor.azure.com//.default";
|
|
1361
1666
|
/**
|
|
1362
1667
|
* Exporter HTTP sender class
|
|
1363
1668
|
* @internal
|
|
@@ -1367,9 +1672,18 @@ class HttpSender {
|
|
|
1367
1672
|
this._exporterOptions = _exporterOptions;
|
|
1368
1673
|
// Build endpoint using provided configuration or default values
|
|
1369
1674
|
this._appInsightsClientOptions = {
|
|
1370
|
-
host: this._exporterOptions.endpointUrl
|
|
1675
|
+
host: this._exporterOptions.endpointUrl,
|
|
1371
1676
|
};
|
|
1372
1677
|
this._appInsightsClient = new ApplicationInsightsClient(Object.assign({}, this._appInsightsClientOptions));
|
|
1678
|
+
// Handle redirects in HTTP Sender
|
|
1679
|
+
this._appInsightsClient.pipeline.removePolicy({ name: coreRestPipeline.redirectPolicyName });
|
|
1680
|
+
if (this._exporterOptions.aadTokenCredential) {
|
|
1681
|
+
let scopes = [applicationInsightsResource];
|
|
1682
|
+
this._appInsightsClient.pipeline.addPolicy(coreRestPipeline.bearerTokenAuthenticationPolicy({
|
|
1683
|
+
credential: this._exporterOptions.aadTokenCredential,
|
|
1684
|
+
scopes: scopes,
|
|
1685
|
+
}));
|
|
1686
|
+
}
|
|
1373
1687
|
}
|
|
1374
1688
|
/**
|
|
1375
1689
|
* Send Azure envelopes
|
|
@@ -1377,9 +1691,17 @@ class HttpSender {
|
|
|
1377
1691
|
*/
|
|
1378
1692
|
async send(envelopes) {
|
|
1379
1693
|
var _a;
|
|
1694
|
+
let options = {};
|
|
1380
1695
|
try {
|
|
1381
|
-
|
|
1382
|
-
|
|
1696
|
+
let response;
|
|
1697
|
+
function onResponse(rawResponse, flatResponse) {
|
|
1698
|
+
response = rawResponse;
|
|
1699
|
+
if (options.onResponse) {
|
|
1700
|
+
options.onResponse(rawResponse, flatResponse);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
await this._appInsightsClient.track(envelopes, Object.assign(Object.assign({}, options), { onResponse }));
|
|
1704
|
+
return { statusCode: response === null || response === void 0 ? void 0 : response.status, result: (_a = response === null || response === void 0 ? void 0 : response.bodyAsText) !== null && _a !== void 0 ? _a : "" };
|
|
1383
1705
|
}
|
|
1384
1706
|
catch (e) {
|
|
1385
1707
|
throw e;
|
|
@@ -1394,7 +1716,7 @@ class HttpSender {
|
|
|
1394
1716
|
}
|
|
1395
1717
|
handlePermanentRedirect(location) {
|
|
1396
1718
|
if (location) {
|
|
1397
|
-
const locUrl = new url__default.URL(location);
|
|
1719
|
+
const locUrl = new url__default["default"].URL(location);
|
|
1398
1720
|
if (locUrl && locUrl.host) {
|
|
1399
1721
|
this._appInsightsClient.host = "https://" + locUrl.host;
|
|
1400
1722
|
}
|
|
@@ -1402,6 +1724,37 @@ class HttpSender {
|
|
|
1402
1724
|
}
|
|
1403
1725
|
}
|
|
1404
1726
|
|
|
1727
|
+
// Copyright (c) Microsoft Corporation.
|
|
1728
|
+
// Licensed under the MIT license.
|
|
1729
|
+
/**
|
|
1730
|
+
* AI MS Links.
|
|
1731
|
+
* @internal
|
|
1732
|
+
*/
|
|
1733
|
+
const MS_LINKS = "_MS.links";
|
|
1734
|
+
/**
|
|
1735
|
+
* AI enqueued time attribute.
|
|
1736
|
+
* @internal
|
|
1737
|
+
*/
|
|
1738
|
+
const ENQUEUED_TIME = "enqueuedTime";
|
|
1739
|
+
/**
|
|
1740
|
+
* AI time since enqueued attribute.
|
|
1741
|
+
* @internal
|
|
1742
|
+
*/
|
|
1743
|
+
const TIME_SINCE_ENQUEUED = "timeSinceEnqueued";
|
|
1744
|
+
/**
|
|
1745
|
+
* AzureMonitorTraceExporter version.
|
|
1746
|
+
* @internal
|
|
1747
|
+
*/
|
|
1748
|
+
const packageVersion = "1.0.0-beta.7";
|
|
1749
|
+
var DependencyTypes;
|
|
1750
|
+
(function (DependencyTypes) {
|
|
1751
|
+
DependencyTypes["InProc"] = "InProc";
|
|
1752
|
+
DependencyTypes["QueueMessage"] = "Queue Message";
|
|
1753
|
+
DependencyTypes["Sql"] = "SQL";
|
|
1754
|
+
DependencyTypes["Http"] = "Http";
|
|
1755
|
+
DependencyTypes["Grpc"] = "GRPC";
|
|
1756
|
+
})(DependencyTypes || (DependencyTypes = {}));
|
|
1757
|
+
|
|
1405
1758
|
// Copyright (c) Microsoft Corporation.
|
|
1406
1759
|
let instance = null;
|
|
1407
1760
|
/**
|
|
@@ -1409,102 +1762,32 @@ let instance = null;
|
|
|
1409
1762
|
* @internal
|
|
1410
1763
|
*/
|
|
1411
1764
|
class Context {
|
|
1412
|
-
constructor(
|
|
1413
|
-
/**
|
|
1414
|
-
* Path to this module's `package.json` relative to
|
|
1415
|
-
* `Context.ROOT_PATH`
|
|
1416
|
-
*/
|
|
1417
|
-
_exporterPrefix = "./",
|
|
1418
|
-
/**
|
|
1419
|
-
* Path to end user application folder which contains `package.json`
|
|
1420
|
-
* relative to `Context.ROOT_PATH`
|
|
1421
|
-
*/
|
|
1422
|
-
_appPrefix = "../../../") {
|
|
1423
|
-
this._exporterPrefix = _exporterPrefix;
|
|
1424
|
-
this._appPrefix = _appPrefix;
|
|
1765
|
+
constructor() {
|
|
1425
1766
|
this.tags = {};
|
|
1426
|
-
this._loadApplicationContext();
|
|
1427
1767
|
this._loadDeviceContext();
|
|
1428
1768
|
this._loadInternalContext();
|
|
1429
1769
|
}
|
|
1430
|
-
_loadApplicationContext() {
|
|
1431
|
-
if (Object.keys(Context.appVersion).length === 0) {
|
|
1432
|
-
// note: this should return the host package.json
|
|
1433
|
-
let packageJson = null;
|
|
1434
|
-
const packageJsonPath = path.resolve(__dirname, Context.JS_NODE_PREFIX, this._appPrefix, Context.ROOT_PATH, "./package.json");
|
|
1435
|
-
const packageJsonPathTsNode = path.resolve(__dirname, this._appPrefix, Context.ROOT_PATH, "./package.json");
|
|
1436
|
-
Context.appVersion[packageJsonPath] = "unknown";
|
|
1437
|
-
try {
|
|
1438
|
-
packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
1439
|
-
}
|
|
1440
|
-
catch (_) {
|
|
1441
|
-
try {
|
|
1442
|
-
packageJson = JSON.parse(fs.readFileSync(packageJsonPathTsNode, "utf8"));
|
|
1443
|
-
}
|
|
1444
|
-
catch (exception) {
|
|
1445
|
-
api.diag.warn("Failed to load Application version", exception);
|
|
1446
|
-
}
|
|
1447
|
-
}
|
|
1448
|
-
if (packageJson && typeof packageJson.version === "string") {
|
|
1449
|
-
Context.appVersion[packageJsonPath] = packageJson.version;
|
|
1450
|
-
}
|
|
1451
|
-
this.tags["ai.application.ver"] = Context.appVersion[packageJsonPath];
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
1770
|
_loadDeviceContext() {
|
|
1455
|
-
this.tags[
|
|
1456
|
-
this.tags["ai.device.osVersion"] = os && `${os.type()} ${os.release()}`;
|
|
1457
|
-
// not yet supported tags
|
|
1458
|
-
this.tags["ai.device.osArchitecture"] = os && os.arch();
|
|
1459
|
-
this.tags["ai.device.osPlatform"] = os && os.platform();
|
|
1771
|
+
this.tags[KnownContextTagKeys.AiDeviceOsVersion] = os__namespace && `${os__namespace.type()} ${os__namespace.release()}`;
|
|
1460
1772
|
}
|
|
1461
1773
|
_loadInternalContext() {
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
const packageJsonPath = path.resolve(__dirname, Context.JS_NODE_PREFIX, this._exporterPrefix, Context.ROOT_PATH, "./package.json");
|
|
1468
|
-
const packageJsonPathTsNode = path.resolve(__dirname, this._exporterPrefix, Context.ROOT_PATH, "./package.json");
|
|
1469
|
-
Context.sdkVersion = "unknown";
|
|
1470
|
-
try {
|
|
1471
|
-
packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
1472
|
-
}
|
|
1473
|
-
catch (_) {
|
|
1474
|
-
try {
|
|
1475
|
-
packageJson = JSON.parse(fs.readFileSync(packageJsonPathTsNode, "utf8"));
|
|
1476
|
-
}
|
|
1477
|
-
catch (exception) {
|
|
1478
|
-
api.diag.warn("Failed to load Exporter version", exception);
|
|
1479
|
-
throw exception;
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
if (packageJson && typeof packageJson.version === "string") {
|
|
1483
|
-
Context.sdkVersion = packageJson.version;
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1486
|
-
this.tags["ai.internal.sdkVersion"] = `node${Context.nodeVersion}:ot${core.SDK_INFO.VERSION}:ext${Context.sdkVersion}`;
|
|
1774
|
+
const { node } = process.versions;
|
|
1775
|
+
[Context.nodeVersion] = node.split(".");
|
|
1776
|
+
Context.opentelemetryVersion = core.SDK_INFO[semanticConventions.SemanticResourceAttributes.TELEMETRY_SDK_VERSION];
|
|
1777
|
+
Context.sdkVersion = packageVersion;
|
|
1778
|
+
this.tags[KnownContextTagKeys.AiInternalSdkVersion] = `node${Context.nodeVersion}:otel${Context.opentelemetryVersion}:ext${Context.sdkVersion}`;
|
|
1487
1779
|
}
|
|
1488
1780
|
}
|
|
1489
|
-
Context.appVersion = {};
|
|
1490
1781
|
Context.sdkVersion = null;
|
|
1491
1782
|
Context.opentelemetryVersion = null;
|
|
1492
1783
|
Context.nodeVersion = "";
|
|
1493
|
-
/**
|
|
1494
|
-
* Add extra ../ to access on environments not using ts-node
|
|
1495
|
-
*/
|
|
1496
|
-
Context.JS_NODE_PREFIX = "../";
|
|
1497
|
-
/**
|
|
1498
|
-
* Path to azure-opentelemetry-exporter
|
|
1499
|
-
*/
|
|
1500
|
-
Context.ROOT_PATH = "../../../../";
|
|
1501
1784
|
/**
|
|
1502
1785
|
* Singleton Context instance.
|
|
1503
1786
|
* @internal
|
|
1504
1787
|
*/
|
|
1505
|
-
function getInstance(
|
|
1788
|
+
function getInstance() {
|
|
1506
1789
|
if (!instance) {
|
|
1507
|
-
instance = new Context(
|
|
1790
|
+
instance = new Context();
|
|
1508
1791
|
}
|
|
1509
1792
|
return instance;
|
|
1510
1793
|
}
|
|
@@ -1516,12 +1799,13 @@ function getInstance(exporterPrefix, appPrefix) {
|
|
|
1516
1799
|
* @internal
|
|
1517
1800
|
*/
|
|
1518
1801
|
function isRetriable(statusCode) {
|
|
1519
|
-
return (statusCode === 206 || //
|
|
1802
|
+
return (statusCode === 206 || // Partial Accept
|
|
1803
|
+
statusCode === 401 || // Unauthorized
|
|
1804
|
+
statusCode === 403 || // Forbidden
|
|
1520
1805
|
statusCode === 408 || // Timeout
|
|
1521
|
-
statusCode === 429 || //
|
|
1522
|
-
statusCode === 439 || // Quota
|
|
1806
|
+
statusCode === 429 || // Too many requests
|
|
1523
1807
|
statusCode === 500 || // Server Error
|
|
1524
|
-
statusCode === 503 // Server
|
|
1808
|
+
statusCode === 503 // Server Unavailable
|
|
1525
1809
|
);
|
|
1526
1810
|
}
|
|
1527
1811
|
/**
|
|
@@ -1544,100 +1828,6 @@ function msToTimeSpan(ms) {
|
|
|
1544
1828
|
return `${daysText + hour}:${min}:${sec}`;
|
|
1545
1829
|
}
|
|
1546
1830
|
|
|
1547
|
-
// Copyright (c) Microsoft Corporation.
|
|
1548
|
-
/**
|
|
1549
|
-
* OpenTelemetry HTTP method attribute.
|
|
1550
|
-
* @internal
|
|
1551
|
-
*/
|
|
1552
|
-
const HTTP_METHOD = conventions.SemanticAttributes.HTTP_METHOD;
|
|
1553
|
-
/**
|
|
1554
|
-
* OpenTelemetry HTTP URL attribute.
|
|
1555
|
-
* @internal
|
|
1556
|
-
*/
|
|
1557
|
-
const HTTP_URL = conventions.SemanticAttributes.HTTP_URL;
|
|
1558
|
-
/**
|
|
1559
|
-
* OpenTelemetry HTTP route attribute.
|
|
1560
|
-
* @internal
|
|
1561
|
-
*/
|
|
1562
|
-
const HTTP_ROUTE = conventions.SemanticAttributes.HTTP_ROUTE;
|
|
1563
|
-
/**
|
|
1564
|
-
* OpenTelemetry HTTP status code attribute.
|
|
1565
|
-
* @internal
|
|
1566
|
-
*/
|
|
1567
|
-
const HTTP_STATUS_CODE = conventions.SemanticAttributes.HTTP_STATUS_CODE;
|
|
1568
|
-
|
|
1569
|
-
// Copyright (c) Microsoft Corporation.
|
|
1570
|
-
// Licensed under the MIT license.
|
|
1571
|
-
/**
|
|
1572
|
-
* AI cloud role tag name.
|
|
1573
|
-
* @internal
|
|
1574
|
-
*/
|
|
1575
|
-
const AI_CLOUD_ROLE = "ai.cloud.role";
|
|
1576
|
-
/**
|
|
1577
|
-
* AI cloud role isntance tag name.
|
|
1578
|
-
* @internal
|
|
1579
|
-
*/
|
|
1580
|
-
const AI_CLOUD_ROLE_INSTACE = "ai.cloud.roleInstance";
|
|
1581
|
-
/**
|
|
1582
|
-
* AI operation Id tag name.
|
|
1583
|
-
* @internal
|
|
1584
|
-
*/
|
|
1585
|
-
const AI_OPERATION_ID = "ai.operation.id";
|
|
1586
|
-
/**
|
|
1587
|
-
* AI operation parent Id tag name.
|
|
1588
|
-
* @internal
|
|
1589
|
-
*/
|
|
1590
|
-
const AI_OPERATION_PARENT_ID = "ai.operation.parentId";
|
|
1591
|
-
/**
|
|
1592
|
-
* AI operation tag name.
|
|
1593
|
-
* @internal
|
|
1594
|
-
*/
|
|
1595
|
-
const AI_OPERATION_NAME = "ai.operation.name";
|
|
1596
|
-
/**
|
|
1597
|
-
* AI MS Links.
|
|
1598
|
-
* @internal
|
|
1599
|
-
*/
|
|
1600
|
-
const MS_LINKS = "_MS.links";
|
|
1601
|
-
/**
|
|
1602
|
-
* AI InProc attribute.
|
|
1603
|
-
* @internal
|
|
1604
|
-
*/
|
|
1605
|
-
const INPROC = "InProc";
|
|
1606
|
-
/**
|
|
1607
|
-
* AI enqueued time attribute.
|
|
1608
|
-
* @internal
|
|
1609
|
-
*/
|
|
1610
|
-
const ENQUEUED_TIME = "enqueuedTime";
|
|
1611
|
-
/**
|
|
1612
|
-
* AI time since enqueued attribute.
|
|
1613
|
-
* @internal
|
|
1614
|
-
*/
|
|
1615
|
-
const TIME_SINCE_ENQUEUED = "timeSinceEnqueued";
|
|
1616
|
-
|
|
1617
|
-
// Copyright (c) Microsoft Corporation.
|
|
1618
|
-
/**
|
|
1619
|
-
* OpenTelemetry GRPC method attribute.
|
|
1620
|
-
* @internal
|
|
1621
|
-
*/
|
|
1622
|
-
const GRPC_METHOD = conventions.SemanticAttributes.RPC_METHOD;
|
|
1623
|
-
/**
|
|
1624
|
-
* OpenTelemetry GRPC status code attribute.
|
|
1625
|
-
* @internal
|
|
1626
|
-
*/
|
|
1627
|
-
const GRPC_STATUS_CODE = conventions.SemanticAttributes.RPC_GRPC_STATUS_CODE;
|
|
1628
|
-
|
|
1629
|
-
// Copyright (c) Microsoft Corporation.
|
|
1630
|
-
/**
|
|
1631
|
-
* OpenTelemetry DB name attribute.
|
|
1632
|
-
* @internal
|
|
1633
|
-
*/
|
|
1634
|
-
const DB_NAME = conventions.SemanticAttributes.DB_NAME;
|
|
1635
|
-
/**
|
|
1636
|
-
* OpenTelemetry DB statement attribute.
|
|
1637
|
-
* @internal
|
|
1638
|
-
*/
|
|
1639
|
-
const DB_STATEMENT = conventions.SemanticAttributes.DB_STATEMENT;
|
|
1640
|
-
|
|
1641
1831
|
// Copyright (c) Microsoft Corporation.
|
|
1642
1832
|
// Licensed under the MIT license.
|
|
1643
1833
|
/**
|
|
@@ -1681,7 +1871,7 @@ const getTimeSinceEnqueued = (span) => {
|
|
|
1681
1871
|
*/
|
|
1682
1872
|
const parseEventHubSpan = (span, baseData) => {
|
|
1683
1873
|
const namespace = span.attributes[AzNamespace];
|
|
1684
|
-
const peerAddress = (span.attributes[
|
|
1874
|
+
const peerAddress = (span.attributes[semanticConventions.SemanticAttributes.NET_PEER_NAME] ||
|
|
1685
1875
|
span.attributes["peer.address"] ||
|
|
1686
1876
|
"unknown").replace(/\/$/g, ""); // remove trailing "/"
|
|
1687
1877
|
const messageBusDestination = (span.attributes[MessageBusDestination] || "unknown");
|
|
@@ -1706,35 +1896,70 @@ const parseEventHubSpan = (span, baseData) => {
|
|
|
1706
1896
|
function createTagsFromSpan(span) {
|
|
1707
1897
|
const context = getInstance();
|
|
1708
1898
|
const tags = Object.assign({}, context.tags);
|
|
1709
|
-
tags[
|
|
1899
|
+
tags[KnownContextTagKeys.AiOperationId] = span.spanContext().traceId;
|
|
1710
1900
|
if (span.parentSpanId) {
|
|
1711
|
-
tags[
|
|
1901
|
+
tags[KnownContextTagKeys.AiOperationParentId] = span.parentSpanId;
|
|
1712
1902
|
}
|
|
1713
1903
|
if (span.resource && span.resource.attributes) {
|
|
1714
|
-
const serviceName = span.resource.attributes[
|
|
1715
|
-
const serviceNamespace = span.resource.attributes[
|
|
1716
|
-
const serviceInstanceId = span.resource.attributes[conventions.ResourceAttributes.SERVICE_INSTANCE_ID];
|
|
1904
|
+
const serviceName = span.resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_NAME];
|
|
1905
|
+
const serviceNamespace = span.resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_NAMESPACE];
|
|
1717
1906
|
if (serviceName) {
|
|
1718
1907
|
if (serviceNamespace) {
|
|
1719
|
-
tags[
|
|
1908
|
+
tags[KnownContextTagKeys.AiCloudRole] = `${serviceNamespace}.${serviceName}`;
|
|
1720
1909
|
}
|
|
1721
1910
|
else {
|
|
1722
|
-
tags[
|
|
1911
|
+
tags[KnownContextTagKeys.AiCloudRole] = String(serviceName);
|
|
1723
1912
|
}
|
|
1724
1913
|
}
|
|
1914
|
+
const serviceInstanceId = span.resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_INSTANCE_ID];
|
|
1725
1915
|
if (serviceInstanceId) {
|
|
1726
|
-
tags[
|
|
1916
|
+
tags[KnownContextTagKeys.AiCloudRoleInstance] = String(serviceInstanceId);
|
|
1917
|
+
}
|
|
1918
|
+
else {
|
|
1919
|
+
tags[KnownContextTagKeys.AiCloudRoleInstance] = os__default["default"] && os__default["default"].hostname();
|
|
1920
|
+
}
|
|
1921
|
+
const endUserId = span.resource.attributes[semanticConventions.SemanticAttributes.ENDUSER_ID];
|
|
1922
|
+
if (endUserId) {
|
|
1923
|
+
tags[KnownContextTagKeys.AiUserId] = String(endUserId);
|
|
1727
1924
|
}
|
|
1728
1925
|
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
span.attributes[
|
|
1732
|
-
|
|
1926
|
+
if (span.kind === api.SpanKind.SERVER) {
|
|
1927
|
+
const httpMethod = span.attributes[semanticConventions.SemanticAttributes.HTTP_METHOD];
|
|
1928
|
+
const httpClientIp = span.attributes[semanticConventions.SemanticAttributes.HTTP_CLIENT_IP];
|
|
1929
|
+
const netPeerIp = span.attributes[semanticConventions.SemanticAttributes.NET_PEER_IP];
|
|
1930
|
+
if (httpMethod) {
|
|
1931
|
+
const httpRoute = span.attributes[semanticConventions.SemanticAttributes.HTTP_ROUTE];
|
|
1932
|
+
const httpUrl = span.attributes[semanticConventions.SemanticAttributes.HTTP_URL];
|
|
1933
|
+
tags[KnownContextTagKeys.AiOperationName] = span.name; // Default
|
|
1934
|
+
if (httpRoute) {
|
|
1935
|
+
tags[KnownContextTagKeys.AiOperationName] = `${httpMethod} ${httpRoute}`;
|
|
1936
|
+
}
|
|
1937
|
+
else if (httpUrl) {
|
|
1938
|
+
try {
|
|
1939
|
+
let url$1 = new url.URL(String(httpUrl));
|
|
1940
|
+
tags[KnownContextTagKeys.AiOperationName] = `${httpMethod} ${url$1.pathname}`;
|
|
1941
|
+
}
|
|
1942
|
+
catch (ex) { }
|
|
1943
|
+
}
|
|
1944
|
+
if (httpClientIp) {
|
|
1945
|
+
tags[KnownContextTagKeys.AiLocationIp] = String(httpClientIp);
|
|
1946
|
+
}
|
|
1947
|
+
else if (netPeerIp) {
|
|
1948
|
+
tags[KnownContextTagKeys.AiLocationIp] = String(netPeerIp);
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
else {
|
|
1952
|
+
tags[KnownContextTagKeys.AiOperationName] = span.name;
|
|
1953
|
+
if (netPeerIp) {
|
|
1954
|
+
tags[KnownContextTagKeys.AiLocationIp] = String(netPeerIp);
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1733
1957
|
}
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1958
|
+
// TODO: Operation Name and Location IP TBD for non server spans
|
|
1959
|
+
const httpUserAgent = span.attributes[semanticConventions.SemanticAttributes.HTTP_USER_AGENT];
|
|
1960
|
+
if (httpUserAgent) {
|
|
1961
|
+
// TODO: Not exposed in Swagger, need to update def
|
|
1962
|
+
tags["ai.user.userAgent"] = String(httpUserAgent);
|
|
1738
1963
|
}
|
|
1739
1964
|
return tags;
|
|
1740
1965
|
}
|
|
@@ -1742,99 +1967,223 @@ function createPropertiesFromSpan(span) {
|
|
|
1742
1967
|
const properties = {};
|
|
1743
1968
|
const measurements = {};
|
|
1744
1969
|
for (const key of Object.keys(span.attributes)) {
|
|
1745
|
-
if (!(key.startsWith("http.") ||
|
|
1970
|
+
if (!(key.startsWith("http.") ||
|
|
1971
|
+
key.startsWith("rpc.") ||
|
|
1972
|
+
key.startsWith("db.") ||
|
|
1973
|
+
key.startsWith("peer.") ||
|
|
1974
|
+
key.startsWith("net."))) {
|
|
1746
1975
|
properties[key] = span.attributes[key];
|
|
1747
1976
|
}
|
|
1748
1977
|
}
|
|
1749
1978
|
const links = span.links.map((link) => ({
|
|
1750
1979
|
operation_Id: link.context.traceId,
|
|
1751
|
-
id: link.context.spanId
|
|
1980
|
+
id: link.context.spanId,
|
|
1752
1981
|
}));
|
|
1753
1982
|
if (links.length > 0) {
|
|
1754
1983
|
properties[MS_LINKS] = JSON.stringify(links);
|
|
1755
1984
|
}
|
|
1756
1985
|
return [properties, measurements];
|
|
1757
1986
|
}
|
|
1987
|
+
function isSqlDB(dbSystem) {
|
|
1988
|
+
return (dbSystem === semanticConventions.DbSystemValues.DB2 ||
|
|
1989
|
+
dbSystem === semanticConventions.DbSystemValues.DERBY ||
|
|
1990
|
+
dbSystem === semanticConventions.DbSystemValues.MARIADB ||
|
|
1991
|
+
dbSystem === semanticConventions.DbSystemValues.MSSQL ||
|
|
1992
|
+
dbSystem === semanticConventions.DbSystemValues.ORACLE ||
|
|
1993
|
+
dbSystem === semanticConventions.DbSystemValues.SQLITE ||
|
|
1994
|
+
dbSystem === semanticConventions.DbSystemValues.OTHER_SQL ||
|
|
1995
|
+
dbSystem === semanticConventions.DbSystemValues.HSQLDB ||
|
|
1996
|
+
dbSystem === semanticConventions.DbSystemValues.H2);
|
|
1997
|
+
}
|
|
1998
|
+
function getUrl(span) {
|
|
1999
|
+
const httpMethod = span.attributes[semanticConventions.SemanticAttributes.HTTP_METHOD];
|
|
2000
|
+
if (httpMethod) {
|
|
2001
|
+
const httpUrl = span.attributes[semanticConventions.SemanticAttributes.HTTP_URL];
|
|
2002
|
+
if (httpUrl) {
|
|
2003
|
+
return String(httpUrl);
|
|
2004
|
+
}
|
|
2005
|
+
else {
|
|
2006
|
+
const httpScheme = span.attributes[semanticConventions.SemanticAttributes.HTTP_SCHEME];
|
|
2007
|
+
const httpTarget = span.attributes[semanticConventions.SemanticAttributes.HTTP_TARGET];
|
|
2008
|
+
if (httpScheme && httpTarget) {
|
|
2009
|
+
const httpHost = span.attributes[semanticConventions.SemanticAttributes.HTTP_HOST];
|
|
2010
|
+
if (httpHost) {
|
|
2011
|
+
return `${httpScheme}://${httpHost}${httpTarget}`;
|
|
2012
|
+
}
|
|
2013
|
+
else {
|
|
2014
|
+
const netPeerPort = span.attributes[semanticConventions.SemanticAttributes.NET_PEER_PORT];
|
|
2015
|
+
if (netPeerPort) {
|
|
2016
|
+
const netPeerName = span.attributes[semanticConventions.SemanticAttributes.NET_PEER_NAME];
|
|
2017
|
+
if (netPeerName) {
|
|
2018
|
+
return `${httpScheme}://${netPeerName}:${netPeerPort}${httpTarget}`;
|
|
2019
|
+
}
|
|
2020
|
+
else {
|
|
2021
|
+
const netPeerIp = span.attributes[semanticConventions.SemanticAttributes.NET_PEER_IP];
|
|
2022
|
+
if (netPeerIp) {
|
|
2023
|
+
return `${httpScheme}://${netPeerIp}:${netPeerPort}${httpTarget}`;
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
return "";
|
|
2032
|
+
}
|
|
2033
|
+
function getDependencyTarget(span) {
|
|
2034
|
+
const peerService = span.attributes[semanticConventions.SemanticAttributes.PEER_SERVICE];
|
|
2035
|
+
const httpHost = span.attributes[semanticConventions.SemanticAttributes.HTTP_HOST];
|
|
2036
|
+
const httpUrl = span.attributes[semanticConventions.SemanticAttributes.HTTP_URL];
|
|
2037
|
+
const netPeerName = span.attributes[semanticConventions.SemanticAttributes.NET_PEER_NAME];
|
|
2038
|
+
const netPeerIp = span.attributes[semanticConventions.SemanticAttributes.NET_PEER_IP];
|
|
2039
|
+
if (peerService) {
|
|
2040
|
+
return String(peerService);
|
|
2041
|
+
}
|
|
2042
|
+
else if (httpHost) {
|
|
2043
|
+
return String(httpHost);
|
|
2044
|
+
}
|
|
2045
|
+
else if (httpUrl) {
|
|
2046
|
+
return String(httpUrl);
|
|
2047
|
+
}
|
|
2048
|
+
else if (netPeerName) {
|
|
2049
|
+
return String(netPeerName);
|
|
2050
|
+
}
|
|
2051
|
+
else if (netPeerIp) {
|
|
2052
|
+
return String(netPeerIp);
|
|
2053
|
+
}
|
|
2054
|
+
return "";
|
|
2055
|
+
}
|
|
1758
2056
|
function createDependencyData(span) {
|
|
1759
|
-
const
|
|
2057
|
+
const remoteDependencyData = {
|
|
1760
2058
|
name: span.name,
|
|
1761
|
-
id:
|
|
1762
|
-
success: span.status.code
|
|
1763
|
-
resultCode:
|
|
1764
|
-
target: span.attributes[HTTP_URL],
|
|
2059
|
+
id: `${span.spanContext().spanId}`,
|
|
2060
|
+
success: span.status.code != api.SpanStatusCode.ERROR,
|
|
2061
|
+
resultCode: "0",
|
|
1765
2062
|
type: "Dependency",
|
|
1766
2063
|
duration: msToTimeSpan(core.hrTimeToMilliseconds(span.duration)),
|
|
1767
|
-
version:
|
|
2064
|
+
version: 2,
|
|
1768
2065
|
};
|
|
1769
|
-
if (span.
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
2066
|
+
if (span.kind === api.SpanKind.PRODUCER) {
|
|
2067
|
+
remoteDependencyData.type = DependencyTypes.QueueMessage;
|
|
2068
|
+
}
|
|
2069
|
+
if (span.kind === api.SpanKind.INTERNAL && span.parentSpanId) {
|
|
2070
|
+
remoteDependencyData.type = DependencyTypes.InProc;
|
|
2071
|
+
}
|
|
2072
|
+
const httpMethod = span.attributes[semanticConventions.SemanticAttributes.HTTP_METHOD];
|
|
2073
|
+
const dbSystem = span.attributes[semanticConventions.SemanticAttributes.DB_SYSTEM];
|
|
2074
|
+
const rpcSystem = span.attributes[semanticConventions.SemanticAttributes.RPC_SYSTEM];
|
|
2075
|
+
// HTTP Dependency
|
|
2076
|
+
if (httpMethod) {
|
|
2077
|
+
const httpUrl = span.attributes[semanticConventions.SemanticAttributes.HTTP_URL];
|
|
2078
|
+
if (httpUrl) {
|
|
2079
|
+
try {
|
|
2080
|
+
let dependencyUrl = new url.URL(String(httpUrl));
|
|
2081
|
+
remoteDependencyData.name = `${httpMethod} ${dependencyUrl.pathname}`;
|
|
2082
|
+
}
|
|
2083
|
+
catch (ex) { }
|
|
2084
|
+
}
|
|
2085
|
+
remoteDependencyData.type = DependencyTypes.Http;
|
|
2086
|
+
remoteDependencyData.data = getUrl(span);
|
|
2087
|
+
const httpStatusCode = span.attributes[semanticConventions.SemanticAttributes.HTTP_STATUS_CODE];
|
|
2088
|
+
if (httpStatusCode) {
|
|
2089
|
+
remoteDependencyData.resultCode = String(httpStatusCode);
|
|
2090
|
+
}
|
|
2091
|
+
let target = getDependencyTarget(span);
|
|
2092
|
+
if (target) {
|
|
2093
|
+
try {
|
|
2094
|
+
// Remove default port
|
|
2095
|
+
let portRegex = new RegExp(/(https?)(:\/\/.*)(:\d+)(\S*)/);
|
|
2096
|
+
let res = portRegex.exec(target);
|
|
2097
|
+
if (res != null) {
|
|
2098
|
+
let protocol = res[1];
|
|
2099
|
+
let port = res[3];
|
|
2100
|
+
if ((protocol == "https" && port == ":443") || (protocol == "http" && port == ":80")) {
|
|
2101
|
+
// Drop port
|
|
2102
|
+
target = res[1] + res[2] + res[4];
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
catch (error) { }
|
|
2107
|
+
remoteDependencyData.target = `${target}`;
|
|
2108
|
+
}
|
|
1780
2109
|
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
2110
|
+
// DB Dependency
|
|
2111
|
+
else if (dbSystem) {
|
|
2112
|
+
// TODO: Remove special logic when Azure UX supports OpenTelemetry dbSystem
|
|
2113
|
+
if (String(dbSystem) === semanticConventions.DbSystemValues.MYSQL) {
|
|
2114
|
+
remoteDependencyData.type = "mysql";
|
|
2115
|
+
}
|
|
2116
|
+
else if (String(dbSystem) === semanticConventions.DbSystemValues.POSTGRESQL) {
|
|
2117
|
+
remoteDependencyData.type = "postgresql";
|
|
2118
|
+
}
|
|
2119
|
+
else if (String(dbSystem) === semanticConventions.DbSystemValues.MONGODB) {
|
|
2120
|
+
remoteDependencyData.type = "mongodb";
|
|
2121
|
+
}
|
|
2122
|
+
else if (String(dbSystem) === semanticConventions.DbSystemValues.REDIS) {
|
|
2123
|
+
remoteDependencyData.type = "redis";
|
|
2124
|
+
}
|
|
2125
|
+
else if (isSqlDB(String(dbSystem))) {
|
|
2126
|
+
remoteDependencyData.type = "SQL";
|
|
2127
|
+
}
|
|
2128
|
+
else {
|
|
2129
|
+
remoteDependencyData.type = String(dbSystem);
|
|
2130
|
+
}
|
|
2131
|
+
const dbStatement = span.attributes[semanticConventions.SemanticAttributes.DB_STATEMENT];
|
|
2132
|
+
const dbOperation = span.attributes[semanticConventions.SemanticAttributes.DB_OPERATION];
|
|
2133
|
+
if (dbStatement) {
|
|
2134
|
+
remoteDependencyData.data = String(dbStatement);
|
|
2135
|
+
}
|
|
2136
|
+
else if (dbOperation) {
|
|
2137
|
+
remoteDependencyData.data = String(dbOperation);
|
|
2138
|
+
}
|
|
2139
|
+
let target = getDependencyTarget(span);
|
|
2140
|
+
const dbName = span.attributes[semanticConventions.SemanticAttributes.DB_NAME];
|
|
2141
|
+
if (target) {
|
|
2142
|
+
remoteDependencyData.target = dbName ? `${target}|${dbName}` : `${target}`;
|
|
2143
|
+
}
|
|
2144
|
+
else {
|
|
2145
|
+
remoteDependencyData.target = dbName ? `${dbName}` : `${dbSystem}`;
|
|
1787
2146
|
}
|
|
1788
2147
|
}
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
if (
|
|
1794
|
-
|
|
2148
|
+
// grpc Dependency
|
|
2149
|
+
else if (rpcSystem) {
|
|
2150
|
+
remoteDependencyData.type = DependencyTypes.Grpc;
|
|
2151
|
+
const grpcStatusCode = span.attributes[semanticConventions.SemanticAttributes.RPC_GRPC_STATUS_CODE];
|
|
2152
|
+
if (grpcStatusCode) {
|
|
2153
|
+
remoteDependencyData.resultCode = String(grpcStatusCode);
|
|
2154
|
+
}
|
|
2155
|
+
let target = getDependencyTarget(span);
|
|
2156
|
+
if (target) {
|
|
2157
|
+
remoteDependencyData.target = `${target}`;
|
|
2158
|
+
}
|
|
2159
|
+
else if (rpcSystem) {
|
|
2160
|
+
remoteDependencyData.target = String(rpcSystem);
|
|
1795
2161
|
}
|
|
1796
2162
|
}
|
|
1797
|
-
return
|
|
2163
|
+
return remoteDependencyData;
|
|
1798
2164
|
}
|
|
1799
2165
|
function createRequestData(span) {
|
|
1800
|
-
const
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
responseCode: String(span.status.code),
|
|
2166
|
+
const requestData = {
|
|
2167
|
+
id: `${span.spanContext().spanId}`,
|
|
2168
|
+
success: span.status.code != api.SpanStatusCode.ERROR,
|
|
2169
|
+
responseCode: "0",
|
|
1805
2170
|
duration: msToTimeSpan(core.hrTimeToMilliseconds(span.duration)),
|
|
1806
|
-
version:
|
|
1807
|
-
source: undefined
|
|
2171
|
+
version: 2,
|
|
2172
|
+
source: undefined,
|
|
1808
2173
|
};
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
if (
|
|
1815
|
-
|
|
1816
|
-
}
|
|
1817
|
-
if (span.attributes[HTTP_ROUTE]) {
|
|
1818
|
-
data.name = `${span.attributes[HTTP_METHOD]} ${span.attributes[HTTP_ROUTE]}`;
|
|
2174
|
+
const httpMethod = span.attributes[semanticConventions.SemanticAttributes.HTTP_METHOD];
|
|
2175
|
+
const grpcStatusCode = span.attributes[semanticConventions.SemanticAttributes.RPC_GRPC_STATUS_CODE];
|
|
2176
|
+
if (httpMethod) {
|
|
2177
|
+
requestData.url = getUrl(span);
|
|
2178
|
+
const httpStatusCode = span.attributes[semanticConventions.SemanticAttributes.HTTP_STATUS_CODE];
|
|
2179
|
+
if (httpStatusCode) {
|
|
2180
|
+
requestData.responseCode = String(httpStatusCode);
|
|
1819
2181
|
}
|
|
1820
|
-
else if (span.attributes[HTTP_URL]) {
|
|
1821
|
-
const url$1 = new url.URL(span.attributes[HTTP_URL]);
|
|
1822
|
-
data.name = `${span.attributes[HTTP_METHOD]} ${url$1.pathname}`;
|
|
1823
|
-
}
|
|
1824
|
-
}
|
|
1825
|
-
if (span.attributes[GRPC_STATUS_CODE]) {
|
|
1826
|
-
data.responseCode = String(span.attributes[GRPC_STATUS_CODE]);
|
|
1827
2182
|
}
|
|
1828
|
-
if (
|
|
1829
|
-
|
|
2183
|
+
else if (grpcStatusCode) {
|
|
2184
|
+
requestData.responseCode = String(grpcStatusCode);
|
|
1830
2185
|
}
|
|
1831
|
-
return
|
|
1832
|
-
}
|
|
1833
|
-
function createInProcData(span) {
|
|
1834
|
-
const data = createDependencyData(span);
|
|
1835
|
-
data.type = INPROC;
|
|
1836
|
-
data.success = true;
|
|
1837
|
-
return data;
|
|
2186
|
+
return requestData;
|
|
1838
2187
|
}
|
|
1839
2188
|
/**
|
|
1840
2189
|
* Span to Azure envelope parsing.
|
|
@@ -1852,6 +2201,7 @@ function readableSpanToEnvelope(span, ikey) {
|
|
|
1852
2201
|
switch (span.kind) {
|
|
1853
2202
|
case api.SpanKind.CLIENT:
|
|
1854
2203
|
case api.SpanKind.PRODUCER:
|
|
2204
|
+
case api.SpanKind.INTERNAL:
|
|
1855
2205
|
name = "Microsoft.ApplicationInsights.RemoteDependency";
|
|
1856
2206
|
baseType = "RemoteDependencyData";
|
|
1857
2207
|
baseData = createDependencyData(span);
|
|
@@ -1861,25 +2211,20 @@ function readableSpanToEnvelope(span, ikey) {
|
|
|
1861
2211
|
name = "Microsoft.ApplicationInsights.Request";
|
|
1862
2212
|
baseType = "RequestData";
|
|
1863
2213
|
baseData = createRequestData(span);
|
|
1864
|
-
|
|
1865
|
-
case api.SpanKind.INTERNAL:
|
|
1866
|
-
baseType = "RemoteDependencyData";
|
|
1867
|
-
name = "Microsoft.ApplicationInsights.RemoteDependency";
|
|
1868
|
-
baseData = createInProcData(span);
|
|
2214
|
+
baseData.name = tags[KnownContextTagKeys.AiOperationName];
|
|
1869
2215
|
break;
|
|
1870
2216
|
default:
|
|
1871
2217
|
// never
|
|
1872
2218
|
api.diag.error(`Unsupported span kind ${span.kind}`);
|
|
1873
2219
|
throw new Error(`Unsupported span kind ${span.kind}`);
|
|
1874
2220
|
}
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
break;
|
|
2221
|
+
// Azure SDK
|
|
2222
|
+
if (span.attributes[AzNamespace]) {
|
|
2223
|
+
if (span.kind === api.SpanKind.INTERNAL) {
|
|
2224
|
+
baseData.type = `${DependencyTypes.InProc} | ${span.attributes[AzNamespace]}`;
|
|
2225
|
+
}
|
|
2226
|
+
if (span.attributes[AzNamespace] === MicrosoftEventHub) {
|
|
2227
|
+
parseEventHubSpan(span, baseData);
|
|
1883
2228
|
}
|
|
1884
2229
|
}
|
|
1885
2230
|
return {
|
|
@@ -1892,8 +2237,8 @@ function readableSpanToEnvelope(span, ikey) {
|
|
|
1892
2237
|
data: {
|
|
1893
2238
|
baseType,
|
|
1894
2239
|
baseData: Object.assign(Object.assign({}, baseData), { properties,
|
|
1895
|
-
measurements })
|
|
1896
|
-
}
|
|
2240
|
+
measurements }),
|
|
2241
|
+
},
|
|
1897
2242
|
};
|
|
1898
2243
|
}
|
|
1899
2244
|
|
|
@@ -1912,6 +2257,7 @@ class AzureMonitorTraceExporter {
|
|
|
1912
2257
|
const connectionString = options.connectionString || process.env[ENV_CONNECTION_STRING];
|
|
1913
2258
|
this._options = Object.assign({}, DEFAULT_EXPORTER_CONFIG);
|
|
1914
2259
|
this._options.apiVersion = (_a = options.apiVersion) !== null && _a !== void 0 ? _a : this._options.apiVersion;
|
|
2260
|
+
this._options.aadTokenCredential = options.aadTokenCredential;
|
|
1915
2261
|
if (connectionString) {
|
|
1916
2262
|
const parsedConnectionString = ConnectionStringParser.parse(connectionString);
|
|
1917
2263
|
this._options.instrumentationKey =
|
|
@@ -1937,7 +2283,7 @@ class AzureMonitorTraceExporter {
|
|
|
1937
2283
|
? { code: core.ExportResultCode.SUCCESS }
|
|
1938
2284
|
: {
|
|
1939
2285
|
code: core.ExportResultCode.FAILED,
|
|
1940
|
-
error: new Error("Failed to persist envelope in disk.")
|
|
2286
|
+
error: new Error("Failed to persist envelope in disk."),
|
|
1941
2287
|
};
|
|
1942
2288
|
}
|
|
1943
2289
|
catch (ex) {
|
|
@@ -1977,7 +2323,7 @@ class AzureMonitorTraceExporter {
|
|
|
1977
2323
|
}
|
|
1978
2324
|
// Failed -- not retriable
|
|
1979
2325
|
return {
|
|
1980
|
-
code: core.ExportResultCode.FAILED
|
|
2326
|
+
code: core.ExportResultCode.FAILED,
|
|
1981
2327
|
};
|
|
1982
2328
|
}
|
|
1983
2329
|
else {
|
|
@@ -1988,7 +2334,7 @@ class AzureMonitorTraceExporter {
|
|
|
1988
2334
|
else {
|
|
1989
2335
|
// Failed -- not retriable
|
|
1990
2336
|
return {
|
|
1991
|
-
code: core.ExportResultCode.FAILED
|
|
2337
|
+
code: core.ExportResultCode.FAILED,
|
|
1992
2338
|
};
|
|
1993
2339
|
}
|
|
1994
2340
|
}
|