@azure/monitor-opentelemetry-exporter 1.0.0-beta.7 → 1.0.0-beta.9
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/README.md +47 -9
- package/dist/index.js +656 -261
- package/dist-esm/src/config.js +1 -14
- package/dist-esm/src/config.js.map +1 -1
- package/dist-esm/src/export/base.js +174 -0
- package/dist-esm/src/export/base.js.map +1 -0
- package/dist-esm/src/export/metric.js +64 -0
- package/dist-esm/src/export/metric.js.map +1 -0
- package/dist-esm/src/export/trace.js +25 -146
- package/dist-esm/src/export/trace.js.map +1 -1
- package/dist-esm/src/generated/applicationInsightsClient.js +36 -3
- package/dist-esm/src/generated/applicationInsightsClient.js.map +1 -1
- package/dist-esm/src/generated/index.js +0 -1
- package/dist-esm/src/generated/index.js.map +1 -1
- package/dist-esm/src/generated/models/index.js +35 -0
- package/dist-esm/src/generated/models/index.js.map +1 -1
- package/dist-esm/src/index.js +3 -0
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/platform/nodejs/httpSender.js +5 -8
- package/dist-esm/src/platform/nodejs/httpSender.js.map +1 -1
- package/dist-esm/src/platform/nodejs/persist/fileAccessControl.js.map +1 -1
- package/dist-esm/src/platform/nodejs/persist/fileSystemHelpers.js +2 -1
- package/dist-esm/src/platform/nodejs/persist/fileSystemHelpers.js.map +1 -1
- package/dist-esm/src/platform/nodejs/persist/fileSystemPersist.js +10 -5
- package/dist-esm/src/platform/nodejs/persist/fileSystemPersist.js.map +1 -1
- package/dist-esm/src/sampling.js +81 -0
- package/dist-esm/src/sampling.js.map +1 -0
- package/dist-esm/src/utils/breezeUtils.js +3 -1
- package/dist-esm/src/utils/breezeUtils.js.map +1 -1
- package/dist-esm/src/utils/constants/applicationinsights.js +2 -1
- package/dist-esm/src/utils/constants/applicationinsights.js.map +1 -1
- package/dist-esm/src/utils/metricUtils.js +67 -0
- package/dist-esm/src/utils/metricUtils.js.map +1 -0
- package/dist-esm/src/utils/resourceUtils.js +35 -0
- package/dist-esm/src/utils/resourceUtils.js.map +1 -0
- package/dist-esm/src/utils/spanUtils.js +123 -44
- package/dist-esm/src/utils/spanUtils.js.map +1 -1
- package/package.json +20 -19
- package/types/monitor-opentelemetry-exporter.d.ts +181 -13
- package/CHANGELOG.md +0 -51
- package/dist-esm/src/generated/applicationInsightsClientContext.js +0 -34
- package/dist-esm/src/generated/applicationInsightsClientContext.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
|
|
5
6
|
var api = require('@opentelemetry/api');
|
|
6
7
|
var core = require('@opentelemetry/core');
|
|
7
|
-
var os = require('os');
|
|
8
8
|
var url = require('url');
|
|
9
|
-
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
10
9
|
var coreRestPipeline = require('@azure/core-rest-pipeline');
|
|
11
10
|
var coreClient = require('@azure/core-client');
|
|
12
11
|
var fs = require('fs');
|
|
12
|
+
var os = require('os');
|
|
13
13
|
var path = require('path');
|
|
14
14
|
var child_process = require('child_process');
|
|
15
15
|
var util = require('util');
|
|
16
|
+
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
17
|
+
var sdkMetrics = require('@opentelemetry/sdk-metrics');
|
|
16
18
|
|
|
17
19
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
18
20
|
|
|
@@ -34,14 +36,126 @@ function _interopNamespace(e) {
|
|
|
34
36
|
return Object.freeze(n);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
38
|
-
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
39
39
|
var url__default = /*#__PURE__*/_interopDefaultLegacy(url);
|
|
40
|
+
var coreRestPipeline__namespace = /*#__PURE__*/_interopNamespace(coreRestPipeline);
|
|
40
41
|
var coreClient__namespace = /*#__PURE__*/_interopNamespace(coreClient);
|
|
41
42
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
43
|
+
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
44
|
+
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
42
45
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
43
46
|
var child_process__namespace = /*#__PURE__*/_interopNamespace(child_process);
|
|
44
47
|
|
|
48
|
+
// Copyright (c) Microsoft Corporation.
|
|
49
|
+
// Licensed under the MIT license.
|
|
50
|
+
/**
|
|
51
|
+
* AI MS Links.
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
const MS_LINKS = "_MS.links";
|
|
55
|
+
/**
|
|
56
|
+
* AI enqueued time attribute.
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
const ENQUEUED_TIME = "enqueuedTime";
|
|
60
|
+
/**
|
|
61
|
+
* AI time since enqueued attribute.
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
const TIME_SINCE_ENQUEUED = "timeSinceEnqueued";
|
|
65
|
+
/**
|
|
66
|
+
* AzureMonitorTraceExporter version.
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
const packageVersion = "1.0.0-beta.9";
|
|
70
|
+
var DependencyTypes;
|
|
71
|
+
(function (DependencyTypes) {
|
|
72
|
+
DependencyTypes["InProc"] = "InProc";
|
|
73
|
+
DependencyTypes["QueueMessage"] = "Queue Message";
|
|
74
|
+
DependencyTypes["Sql"] = "SQL";
|
|
75
|
+
DependencyTypes["Http"] = "Http";
|
|
76
|
+
DependencyTypes["Grpc"] = "GRPC";
|
|
77
|
+
})(DependencyTypes || (DependencyTypes = {}));
|
|
78
|
+
const AzureMonitorSampleRate = "_MS.sampleRate";
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* ApplicationInsightsSampler is responsible for the following:
|
|
82
|
+
* Implements same trace id hashing algorithm so that traces are sampled the same across multiple nodes
|
|
83
|
+
* Adds item count to span attribute if span is sampled (needed for ingestion service)
|
|
84
|
+
* @param samplingRatio - 0 to 1 value.
|
|
85
|
+
*/
|
|
86
|
+
class ApplicationInsightsSampler {
|
|
87
|
+
constructor(samplingRatio = 1) {
|
|
88
|
+
this._samplingRatio = samplingRatio;
|
|
89
|
+
if (this._samplingRatio > 1) {
|
|
90
|
+
throw new Error("Wrong sampling rate, data will not be sampled out");
|
|
91
|
+
}
|
|
92
|
+
this._sampleRate = Math.round(this._samplingRatio * 100);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Checks whether span needs to be created and tracked.
|
|
96
|
+
*
|
|
97
|
+
* @param context Parent Context which may contain a span.
|
|
98
|
+
* @param traceId of the span to be created. It can be different from the
|
|
99
|
+
* traceId in the {@link SpanContext}. Typically in situations when the
|
|
100
|
+
* span to be created starts a new trace.
|
|
101
|
+
* @param spanName of the span to be created.
|
|
102
|
+
* @param spanKind of the span to be created.
|
|
103
|
+
* @param attributes Initial set of SpanAttributes for the Span being constructed.
|
|
104
|
+
* @param links Collection of links that will be associated with the Span to
|
|
105
|
+
* be created. Typically useful for batch operations.
|
|
106
|
+
* @returns a {@link SamplingResult}.
|
|
107
|
+
*/
|
|
108
|
+
shouldSample(
|
|
109
|
+
// @ts-ignore
|
|
110
|
+
context, traceId,
|
|
111
|
+
// @ts-ignore
|
|
112
|
+
spanName,
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
spanKind, attributes,
|
|
115
|
+
// @ts-ignore
|
|
116
|
+
links) {
|
|
117
|
+
let isSampledIn = false;
|
|
118
|
+
if (this._sampleRate == 100) {
|
|
119
|
+
isSampledIn = true;
|
|
120
|
+
}
|
|
121
|
+
else if (this._sampleRate == 0) {
|
|
122
|
+
isSampledIn = false;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
isSampledIn = this._getSamplingHashCode(traceId) < this._sampleRate;
|
|
126
|
+
}
|
|
127
|
+
// Add sample rate as span attribute
|
|
128
|
+
attributes = attributes || {};
|
|
129
|
+
attributes[AzureMonitorSampleRate] = this._sampleRate;
|
|
130
|
+
return isSampledIn
|
|
131
|
+
? { decision: sdkTraceBase.SamplingDecision.RECORD_AND_SAMPLED, attributes: attributes }
|
|
132
|
+
: { decision: sdkTraceBase.SamplingDecision.NOT_RECORD, attributes: attributes };
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Return Sampler description
|
|
136
|
+
*/
|
|
137
|
+
toString() {
|
|
138
|
+
return `ApplicationInsightsSampler{${this._samplingRatio}}`;
|
|
139
|
+
}
|
|
140
|
+
_getSamplingHashCode(input) {
|
|
141
|
+
var csharpMin = -2147483648;
|
|
142
|
+
var csharpMax = 2147483647;
|
|
143
|
+
var hash = 5381;
|
|
144
|
+
if (!input) {
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
while (input.length < 8) {
|
|
148
|
+
input = input + input;
|
|
149
|
+
}
|
|
150
|
+
for (var i = 0; i < input.length; i++) {
|
|
151
|
+
// JS doesn't respond to integer overflow by wrapping around. Simulate it with bitwise operators ( | 0)
|
|
152
|
+
hash = ((((hash << 5) + hash) | 0) + input.charCodeAt(i)) | 0;
|
|
153
|
+
}
|
|
154
|
+
hash = hash <= csharpMin ? csharpMax : Math.abs(hash);
|
|
155
|
+
return (hash / csharpMax) * 100;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
45
159
|
// Copyright (c) Microsoft Corporation.
|
|
46
160
|
// Licensed under the MIT license.
|
|
47
161
|
/**
|
|
@@ -63,7 +177,7 @@ const DEFAULT_BREEZE_ENDPOINT = "https://dc.services.visualstudio.com";
|
|
|
63
177
|
* Default Breeze API version.
|
|
64
178
|
* @internal
|
|
65
179
|
*/
|
|
66
|
-
|
|
180
|
+
exports.ServiceApiVersion.V2;
|
|
67
181
|
/**
|
|
68
182
|
* Default Live Metrics endpoint.
|
|
69
183
|
* @internal
|
|
@@ -193,20 +307,6 @@ class ConnectionStringParser {
|
|
|
193
307
|
ConnectionStringParser.FIELDS_SEPARATOR = ";";
|
|
194
308
|
ConnectionStringParser.FIELD_KEY_VALUE_SEPARATOR = "=";
|
|
195
309
|
|
|
196
|
-
const DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS = 60000;
|
|
197
|
-
const DEFAULT_MAX_CONSECUTIVE_FAILURES_BEFORE_WARNING = 10;
|
|
198
|
-
/**
|
|
199
|
-
* Internal default Azure exporter configuration
|
|
200
|
-
* @internal
|
|
201
|
-
*/
|
|
202
|
-
const DEFAULT_EXPORTER_CONFIG = {
|
|
203
|
-
instrumentationKey: "",
|
|
204
|
-
endpointUrl: DEFAULT_BREEZE_ENDPOINT,
|
|
205
|
-
batchSendRetryIntervalMs: DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS,
|
|
206
|
-
maxConsecutiveFailuresBeforeWarning: DEFAULT_MAX_CONSECUTIVE_FAILURES_BEFORE_WARNING,
|
|
207
|
-
apiVersion: DEFAULT_BREEZE_API_VERSION,
|
|
208
|
-
};
|
|
209
|
-
|
|
210
310
|
// Copyright (c) Microsoft Corporation.
|
|
211
311
|
class FileAccessControl {
|
|
212
312
|
// Check if file access control could be enabled
|
|
@@ -409,7 +509,8 @@ const confirmDirExists = async (directory) => {
|
|
|
409
509
|
catch (err) {
|
|
410
510
|
if (err && err.code === "ENOENT") {
|
|
411
511
|
try {
|
|
412
|
-
|
|
512
|
+
const options = { recursive: true };
|
|
513
|
+
await mkdirAsync(directory, options);
|
|
413
514
|
}
|
|
414
515
|
catch (mkdirErr) {
|
|
415
516
|
if (mkdirErr && mkdirErr.code !== "EEXIST") {
|
|
@@ -432,25 +533,31 @@ const writeFileAsync = util.promisify(fs__namespace.writeFile);
|
|
|
432
533
|
* @internal
|
|
433
534
|
*/
|
|
434
535
|
class FileSystemPersist {
|
|
435
|
-
constructor(
|
|
536
|
+
constructor(instrumentationKey, _options) {
|
|
537
|
+
var _a, _b;
|
|
538
|
+
this._options = _options;
|
|
436
539
|
this.fileRetemptionPeriod = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
437
540
|
this.cleanupTimeOut = 60 * 60 * 1000; // 1 hour
|
|
438
541
|
this.maxBytesOnDisk = 50000000; // ~50MB
|
|
439
542
|
this._tempDirectory = "";
|
|
440
543
|
this._fileCleanupTimer = null;
|
|
441
|
-
this.
|
|
544
|
+
this._instrumentationKey = instrumentationKey;
|
|
545
|
+
if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.disableOfflineStorage) {
|
|
546
|
+
this._enabled = false;
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
442
549
|
this._enabled = true;
|
|
443
550
|
FileAccessControl.checkFileProtection();
|
|
444
551
|
if (!FileAccessControl.OS_PROVIDES_FILE_PROTECTION) {
|
|
445
552
|
this._enabled = false;
|
|
446
553
|
api.diag.error("Sufficient file protection capabilities were not detected. Files will not be persisted");
|
|
447
554
|
}
|
|
448
|
-
if (!this.
|
|
555
|
+
if (!this._instrumentationKey) {
|
|
449
556
|
this._enabled = false;
|
|
450
557
|
api.diag.error(`No instrumentation key was provided to FileSystemPersister. Files will not be persisted`);
|
|
451
558
|
}
|
|
452
559
|
if (this._enabled) {
|
|
453
|
-
this._tempDirectory = path__namespace.join(os__namespace.tmpdir(), FileSystemPersist.TEMPDIR_PREFIX + this.
|
|
560
|
+
this._tempDirectory = path__namespace.join(((_b = this._options) === null || _b === void 0 ? void 0 : _b.storageDirectory) || os__namespace.tmpdir(), "Microsoft", "AzureMonitor", FileSystemPersist.TEMPDIR_PREFIX + this._instrumentationKey);
|
|
454
561
|
// Starts file cleanup task
|
|
455
562
|
if (!this._fileCleanupTimer) {
|
|
456
563
|
this._fileCleanupTimer = setTimeout(() => {
|
|
@@ -596,48 +703,83 @@ FileSystemPersist.FILENAME_SUFFIX = ".ai.json";
|
|
|
596
703
|
/** Known values of {@link DataPointType} that the service accepts. */
|
|
597
704
|
var KnownDataPointType;
|
|
598
705
|
(function (KnownDataPointType) {
|
|
706
|
+
/** Measurement */
|
|
599
707
|
KnownDataPointType["Measurement"] = "Measurement";
|
|
708
|
+
/** Aggregation */
|
|
600
709
|
KnownDataPointType["Aggregation"] = "Aggregation";
|
|
601
710
|
})(KnownDataPointType || (KnownDataPointType = {}));
|
|
602
711
|
/** Known values of {@link SeverityLevel} that the service accepts. */
|
|
603
712
|
var KnownSeverityLevel;
|
|
604
713
|
(function (KnownSeverityLevel) {
|
|
714
|
+
/** Verbose */
|
|
605
715
|
KnownSeverityLevel["Verbose"] = "Verbose";
|
|
716
|
+
/** Information */
|
|
606
717
|
KnownSeverityLevel["Information"] = "Information";
|
|
718
|
+
/** Warning */
|
|
607
719
|
KnownSeverityLevel["Warning"] = "Warning";
|
|
720
|
+
/** Error */
|
|
608
721
|
KnownSeverityLevel["Error"] = "Error";
|
|
722
|
+
/** Critical */
|
|
609
723
|
KnownSeverityLevel["Critical"] = "Critical";
|
|
610
724
|
})(KnownSeverityLevel || (KnownSeverityLevel = {}));
|
|
611
725
|
/** Known values of {@link ContextTagKeys} that the service accepts. */
|
|
612
726
|
var KnownContextTagKeys;
|
|
613
727
|
(function (KnownContextTagKeys) {
|
|
728
|
+
/** AiApplicationVer */
|
|
614
729
|
KnownContextTagKeys["AiApplicationVer"] = "ai.application.ver";
|
|
730
|
+
/** AiDeviceId */
|
|
615
731
|
KnownContextTagKeys["AiDeviceId"] = "ai.device.id";
|
|
732
|
+
/** AiDeviceLocale */
|
|
616
733
|
KnownContextTagKeys["AiDeviceLocale"] = "ai.device.locale";
|
|
734
|
+
/** AiDeviceModel */
|
|
617
735
|
KnownContextTagKeys["AiDeviceModel"] = "ai.device.model";
|
|
736
|
+
/** AiDeviceOemName */
|
|
618
737
|
KnownContextTagKeys["AiDeviceOemName"] = "ai.device.oemName";
|
|
738
|
+
/** AiDeviceOsVersion */
|
|
619
739
|
KnownContextTagKeys["AiDeviceOsVersion"] = "ai.device.osVersion";
|
|
740
|
+
/** AiDeviceType */
|
|
620
741
|
KnownContextTagKeys["AiDeviceType"] = "ai.device.type";
|
|
742
|
+
/** AiLocationIp */
|
|
621
743
|
KnownContextTagKeys["AiLocationIp"] = "ai.location.ip";
|
|
744
|
+
/** AiLocationCountry */
|
|
622
745
|
KnownContextTagKeys["AiLocationCountry"] = "ai.location.country";
|
|
746
|
+
/** AiLocationProvince */
|
|
623
747
|
KnownContextTagKeys["AiLocationProvince"] = "ai.location.province";
|
|
748
|
+
/** AiLocationCity */
|
|
624
749
|
KnownContextTagKeys["AiLocationCity"] = "ai.location.city";
|
|
750
|
+
/** AiOperationId */
|
|
625
751
|
KnownContextTagKeys["AiOperationId"] = "ai.operation.id";
|
|
752
|
+
/** AiOperationName */
|
|
626
753
|
KnownContextTagKeys["AiOperationName"] = "ai.operation.name";
|
|
754
|
+
/** AiOperationParentId */
|
|
627
755
|
KnownContextTagKeys["AiOperationParentId"] = "ai.operation.parentId";
|
|
756
|
+
/** AiOperationSyntheticSource */
|
|
628
757
|
KnownContextTagKeys["AiOperationSyntheticSource"] = "ai.operation.syntheticSource";
|
|
758
|
+
/** AiOperationCorrelationVector */
|
|
629
759
|
KnownContextTagKeys["AiOperationCorrelationVector"] = "ai.operation.correlationVector";
|
|
760
|
+
/** AiSessionId */
|
|
630
761
|
KnownContextTagKeys["AiSessionId"] = "ai.session.id";
|
|
762
|
+
/** AiSessionIsFirst */
|
|
631
763
|
KnownContextTagKeys["AiSessionIsFirst"] = "ai.session.isFirst";
|
|
764
|
+
/** AiUserAccountId */
|
|
632
765
|
KnownContextTagKeys["AiUserAccountId"] = "ai.user.accountId";
|
|
766
|
+
/** AiUserId */
|
|
633
767
|
KnownContextTagKeys["AiUserId"] = "ai.user.id";
|
|
768
|
+
/** AiUserAuthUserId */
|
|
634
769
|
KnownContextTagKeys["AiUserAuthUserId"] = "ai.user.authUserId";
|
|
770
|
+
/** AiCloudRole */
|
|
635
771
|
KnownContextTagKeys["AiCloudRole"] = "ai.cloud.role";
|
|
772
|
+
/** AiCloudRoleVer */
|
|
636
773
|
KnownContextTagKeys["AiCloudRoleVer"] = "ai.cloud.roleVer";
|
|
774
|
+
/** AiCloudRoleInstance */
|
|
637
775
|
KnownContextTagKeys["AiCloudRoleInstance"] = "ai.cloud.roleInstance";
|
|
776
|
+
/** AiCloudLocation */
|
|
638
777
|
KnownContextTagKeys["AiCloudLocation"] = "ai.cloud.location";
|
|
778
|
+
/** AiInternalSdkVersion */
|
|
639
779
|
KnownContextTagKeys["AiInternalSdkVersion"] = "ai.internal.sdkVersion";
|
|
780
|
+
/** AiInternalAgentVersion */
|
|
640
781
|
KnownContextTagKeys["AiInternalAgentVersion"] = "ai.internal.agentVersion";
|
|
782
|
+
/** AiInternalNodeName */
|
|
641
783
|
KnownContextTagKeys["AiInternalNodeName"] = "ai.internal.nodeName";
|
|
642
784
|
})(KnownContextTagKeys || (KnownContextTagKeys = {}));
|
|
643
785
|
|
|
@@ -1571,12 +1713,13 @@ var Mappers = /*#__PURE__*/Object.freeze({
|
|
|
1571
1713
|
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
1572
1714
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
1573
1715
|
*/
|
|
1574
|
-
class
|
|
1716
|
+
class ApplicationInsightsClient extends coreClient__namespace.ServiceClient {
|
|
1575
1717
|
/**
|
|
1576
|
-
* Initializes a new instance of the
|
|
1718
|
+
* Initializes a new instance of the ApplicationInsightsClient class.
|
|
1577
1719
|
* @param options The parameter options
|
|
1578
1720
|
*/
|
|
1579
1721
|
constructor(options) {
|
|
1722
|
+
var _a, _b;
|
|
1580
1723
|
// Initializing default values for options
|
|
1581
1724
|
if (!options) {
|
|
1582
1725
|
options = {};
|
|
@@ -1584,34 +1727,33 @@ class ApplicationInsightsClientContext extends coreClient__namespace.ServiceClie
|
|
|
1584
1727
|
const defaults = {
|
|
1585
1728
|
requestContentType: "application/json; charset=utf-8"
|
|
1586
1729
|
};
|
|
1587
|
-
const packageDetails = `azsdk-js-monitor-opentelemetry-exporter/1.0.0-beta.
|
|
1730
|
+
const packageDetails = `azsdk-js-monitor-opentelemetry-exporter/1.0.0-beta.9`;
|
|
1588
1731
|
const userAgentPrefix = options.userAgentOptions && options.userAgentOptions.userAgentPrefix
|
|
1589
1732
|
? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
|
|
1590
1733
|
: `${packageDetails}`;
|
|
1591
1734
|
const optionsWithDefaults = Object.assign(Object.assign(Object.assign({}, defaults), options), { userAgentOptions: {
|
|
1592
1735
|
userAgentPrefix
|
|
1593
|
-
}, baseUri: options.endpoint
|
|
1736
|
+
}, baseUri: (_b = (_a = options.endpoint) !== null && _a !== void 0 ? _a : options.baseUri) !== null && _b !== void 0 ? _b : "{Host}/v2.1" });
|
|
1594
1737
|
super(optionsWithDefaults);
|
|
1738
|
+
if ((options === null || options === void 0 ? void 0 : options.pipeline) && options.pipeline.getOrderedPolicies().length > 0) {
|
|
1739
|
+
const pipelinePolicies = options.pipeline.getOrderedPolicies();
|
|
1740
|
+
const bearerTokenAuthenticationPolicyFound = pipelinePolicies.some((pipelinePolicy) => pipelinePolicy.name ===
|
|
1741
|
+
coreRestPipeline__namespace.bearerTokenAuthenticationPolicyName);
|
|
1742
|
+
if (!bearerTokenAuthenticationPolicyFound) {
|
|
1743
|
+
this.pipeline.removePolicy({
|
|
1744
|
+
name: coreRestPipeline__namespace.bearerTokenAuthenticationPolicyName
|
|
1745
|
+
});
|
|
1746
|
+
this.pipeline.addPolicy(coreRestPipeline__namespace.bearerTokenAuthenticationPolicy({
|
|
1747
|
+
scopes: `${optionsWithDefaults.baseUri}/.default`,
|
|
1748
|
+
challengeCallbacks: {
|
|
1749
|
+
authorizeRequestOnChallenge: coreClient__namespace.authorizeRequestOnClaimChallenge
|
|
1750
|
+
}
|
|
1751
|
+
}));
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1595
1754
|
// Assigning values to Constant parameters
|
|
1596
1755
|
this.host = options.host || "https://dc.services.visualstudio.com";
|
|
1597
1756
|
}
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
|
-
/*
|
|
1601
|
-
* Copyright (c) Microsoft Corporation.
|
|
1602
|
-
* Licensed under the MIT License.
|
|
1603
|
-
*
|
|
1604
|
-
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
1605
|
-
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
1606
|
-
*/
|
|
1607
|
-
class ApplicationInsightsClient extends ApplicationInsightsClientContext {
|
|
1608
|
-
/**
|
|
1609
|
-
* Initializes a new instance of the ApplicationInsightsClient class.
|
|
1610
|
-
* @param options The parameter options
|
|
1611
|
-
*/
|
|
1612
|
-
constructor(options) {
|
|
1613
|
-
super(options);
|
|
1614
|
-
}
|
|
1615
1757
|
/**
|
|
1616
1758
|
* This operation sends a sequence of telemetry events that will be monitored by Azure Monitor.
|
|
1617
1759
|
* @param body The list of telemetry events to track.
|
|
@@ -1668,19 +1810,16 @@ const applicationInsightsResource = "https://monitor.azure.com//.default";
|
|
|
1668
1810
|
* @internal
|
|
1669
1811
|
*/
|
|
1670
1812
|
class HttpSender {
|
|
1671
|
-
constructor(
|
|
1672
|
-
this._exporterOptions = _exporterOptions;
|
|
1813
|
+
constructor(endpointUrl, options) {
|
|
1673
1814
|
// Build endpoint using provided configuration or default values
|
|
1674
|
-
this._appInsightsClientOptions = {
|
|
1675
|
-
|
|
1676
|
-
};
|
|
1677
|
-
this._appInsightsClient = new ApplicationInsightsClient(Object.assign({}, this._appInsightsClientOptions));
|
|
1815
|
+
this._appInsightsClientOptions = Object.assign({ host: endpointUrl }, options);
|
|
1816
|
+
this._appInsightsClient = new ApplicationInsightsClient(this._appInsightsClientOptions);
|
|
1678
1817
|
// Handle redirects in HTTP Sender
|
|
1679
1818
|
this._appInsightsClient.pipeline.removePolicy({ name: coreRestPipeline.redirectPolicyName });
|
|
1680
|
-
if (
|
|
1819
|
+
if (options === null || options === void 0 ? void 0 : options.aadTokenCredential) {
|
|
1681
1820
|
let scopes = [applicationInsightsResource];
|
|
1682
1821
|
this._appInsightsClient.pipeline.addPolicy(coreRestPipeline.bearerTokenAuthenticationPolicy({
|
|
1683
|
-
credential:
|
|
1822
|
+
credential: options === null || options === void 0 ? void 0 : options.aadTokenCredential,
|
|
1684
1823
|
scopes: scopes,
|
|
1685
1824
|
}));
|
|
1686
1825
|
}
|
|
@@ -1724,37 +1863,6 @@ class HttpSender {
|
|
|
1724
1863
|
}
|
|
1725
1864
|
}
|
|
1726
1865
|
|
|
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
|
-
|
|
1758
1866
|
// Copyright (c) Microsoft Corporation.
|
|
1759
1867
|
let instance = null;
|
|
1760
1868
|
/**
|
|
@@ -1805,7 +1913,9 @@ function isRetriable(statusCode) {
|
|
|
1805
1913
|
statusCode === 408 || // Timeout
|
|
1806
1914
|
statusCode === 429 || // Too many requests
|
|
1807
1915
|
statusCode === 500 || // Server Error
|
|
1808
|
-
statusCode ===
|
|
1916
|
+
statusCode === 502 || // Bad Gateway
|
|
1917
|
+
statusCode === 503 || // Server Unavailable
|
|
1918
|
+
statusCode === 504 // Gateway Timeout
|
|
1809
1919
|
);
|
|
1810
1920
|
}
|
|
1811
1921
|
/**
|
|
@@ -1828,6 +1938,203 @@ function msToTimeSpan(ms) {
|
|
|
1828
1938
|
return `${daysText + hour}:${min}:${sec}`;
|
|
1829
1939
|
}
|
|
1830
1940
|
|
|
1941
|
+
// Copyright (c) Microsoft Corporation.
|
|
1942
|
+
const DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS = 60000;
|
|
1943
|
+
/**
|
|
1944
|
+
* Azure Monitor OpenTelemetry Trace Exporter.
|
|
1945
|
+
*/
|
|
1946
|
+
class AzureMonitorBaseExporter {
|
|
1947
|
+
/**
|
|
1948
|
+
* Initializes a new instance of the AzureMonitorBaseExporter class.
|
|
1949
|
+
* @param AzureMonitorExporterOptions - Exporter configuration.
|
|
1950
|
+
*/
|
|
1951
|
+
constructor(options = {}) {
|
|
1952
|
+
var _a;
|
|
1953
|
+
this._batchSendRetryIntervalMs = DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS;
|
|
1954
|
+
this._options = options;
|
|
1955
|
+
this._numConsecutiveRedirects = 0;
|
|
1956
|
+
this._instrumentationKey = "";
|
|
1957
|
+
this._endpointUrl = DEFAULT_BREEZE_ENDPOINT;
|
|
1958
|
+
const connectionString = this._options.connectionString || process.env[ENV_CONNECTION_STRING];
|
|
1959
|
+
if (connectionString) {
|
|
1960
|
+
const parsedConnectionString = ConnectionStringParser.parse(connectionString);
|
|
1961
|
+
this._instrumentationKey =
|
|
1962
|
+
parsedConnectionString.instrumentationkey || this._instrumentationKey;
|
|
1963
|
+
this._endpointUrl = ((_a = parsedConnectionString.ingestionendpoint) === null || _a === void 0 ? void 0 : _a.trim()) || this._endpointUrl;
|
|
1964
|
+
}
|
|
1965
|
+
// Instrumentation key is required
|
|
1966
|
+
if (!this._instrumentationKey) {
|
|
1967
|
+
const message = "No instrumentation key or connection string was provided to the Azure Monitor Exporter";
|
|
1968
|
+
api.diag.error(message);
|
|
1969
|
+
throw new Error(message);
|
|
1970
|
+
}
|
|
1971
|
+
this._sender = new HttpSender(this._endpointUrl, this._options);
|
|
1972
|
+
this._persister = new FileSystemPersist(this._instrumentationKey, this._options);
|
|
1973
|
+
this._retryTimer = null;
|
|
1974
|
+
api.diag.debug("AzureMonitorExporter was successfully setup");
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* Persist envelopes to disk
|
|
1978
|
+
*/
|
|
1979
|
+
async _persist(envelopes) {
|
|
1980
|
+
try {
|
|
1981
|
+
const success = await this._persister.push(envelopes);
|
|
1982
|
+
return success
|
|
1983
|
+
? { code: core.ExportResultCode.SUCCESS }
|
|
1984
|
+
: {
|
|
1985
|
+
code: core.ExportResultCode.FAILED,
|
|
1986
|
+
error: new Error("Failed to persist envelope in disk."),
|
|
1987
|
+
};
|
|
1988
|
+
}
|
|
1989
|
+
catch (ex) {
|
|
1990
|
+
return { code: core.ExportResultCode.FAILED, error: ex };
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
/**
|
|
1994
|
+
* Shutdown exporter
|
|
1995
|
+
*/
|
|
1996
|
+
async _shutdown() {
|
|
1997
|
+
return this._sender.shutdown();
|
|
1998
|
+
}
|
|
1999
|
+
/**
|
|
2000
|
+
* Export envelopes
|
|
2001
|
+
*/
|
|
2002
|
+
async _exportEnvelopes(envelopes) {
|
|
2003
|
+
api.diag.info(`Exporting ${envelopes.length} envelope(s)`);
|
|
2004
|
+
if (envelopes.length < 1) {
|
|
2005
|
+
return { code: core.ExportResultCode.SUCCESS };
|
|
2006
|
+
}
|
|
2007
|
+
try {
|
|
2008
|
+
const { result, statusCode } = await this._sender.send(envelopes);
|
|
2009
|
+
this._numConsecutiveRedirects = 0;
|
|
2010
|
+
if (statusCode === 200) {
|
|
2011
|
+
// Success -- @todo: start retry timer
|
|
2012
|
+
if (!this._retryTimer) {
|
|
2013
|
+
this._retryTimer = setTimeout(() => {
|
|
2014
|
+
this._retryTimer = null;
|
|
2015
|
+
this._sendFirstPersistedFile();
|
|
2016
|
+
}, this._batchSendRetryIntervalMs);
|
|
2017
|
+
this._retryTimer.unref();
|
|
2018
|
+
}
|
|
2019
|
+
return { code: core.ExportResultCode.SUCCESS };
|
|
2020
|
+
}
|
|
2021
|
+
else if (statusCode && isRetriable(statusCode)) {
|
|
2022
|
+
// Failed -- persist failed data
|
|
2023
|
+
if (result) {
|
|
2024
|
+
api.diag.info(result);
|
|
2025
|
+
const breezeResponse = JSON.parse(result);
|
|
2026
|
+
const filteredEnvelopes = [];
|
|
2027
|
+
if (breezeResponse.errors) {
|
|
2028
|
+
breezeResponse.errors.forEach((error) => {
|
|
2029
|
+
if (error.statusCode && isRetriable(error.statusCode)) {
|
|
2030
|
+
filteredEnvelopes.push(envelopes[error.index]);
|
|
2031
|
+
}
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
if (filteredEnvelopes.length > 0) {
|
|
2035
|
+
// calls resultCallback(ExportResult) based on result of persister.push
|
|
2036
|
+
return await this._persist(filteredEnvelopes);
|
|
2037
|
+
}
|
|
2038
|
+
// Failed -- not retriable
|
|
2039
|
+
return {
|
|
2040
|
+
code: core.ExportResultCode.FAILED,
|
|
2041
|
+
};
|
|
2042
|
+
}
|
|
2043
|
+
else {
|
|
2044
|
+
// calls resultCallback(ExportResult) based on result of persister.push
|
|
2045
|
+
return await this._persist(envelopes);
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
else {
|
|
2049
|
+
// Failed -- not retriable
|
|
2050
|
+
return {
|
|
2051
|
+
code: core.ExportResultCode.FAILED,
|
|
2052
|
+
};
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
catch (error) {
|
|
2056
|
+
const restError = error;
|
|
2057
|
+
if (restError.statusCode &&
|
|
2058
|
+
(restError.statusCode === 307 || // Temporary redirect
|
|
2059
|
+
restError.statusCode === 308)) {
|
|
2060
|
+
// Permanent redirect
|
|
2061
|
+
this._numConsecutiveRedirects++;
|
|
2062
|
+
// To prevent circular redirects
|
|
2063
|
+
if (this._numConsecutiveRedirects < 10) {
|
|
2064
|
+
if (restError.response && restError.response.headers) {
|
|
2065
|
+
const location = restError.response.headers.get("location");
|
|
2066
|
+
if (location) {
|
|
2067
|
+
// Update sender URL
|
|
2068
|
+
this._sender.handlePermanentRedirect(location);
|
|
2069
|
+
// Send to redirect endpoint as HTTPs library doesn't handle redirect automatically
|
|
2070
|
+
return this._exportEnvelopes(envelopes);
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
else {
|
|
2075
|
+
return { code: core.ExportResultCode.FAILED, error: new Error("Circular redirect") };
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
else if (restError.statusCode && isRetriable(restError.statusCode)) {
|
|
2079
|
+
return await this._persist(envelopes);
|
|
2080
|
+
}
|
|
2081
|
+
if (this._isNetworkError(restError)) {
|
|
2082
|
+
api.diag.error("Retrying due to transient client side error. Error message:", restError.message);
|
|
2083
|
+
return await this._persist(envelopes);
|
|
2084
|
+
}
|
|
2085
|
+
api.diag.error("Envelopes could not be exported and are not retriable. Error message:", restError.message);
|
|
2086
|
+
return { code: core.ExportResultCode.FAILED, error: restError };
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
async _sendFirstPersistedFile() {
|
|
2090
|
+
try {
|
|
2091
|
+
const envelopes = (await this._persister.shift());
|
|
2092
|
+
if (envelopes) {
|
|
2093
|
+
await this._sender.send(envelopes);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
catch (err) {
|
|
2097
|
+
api.diag.warn(`Failed to fetch persisted file`, err);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
_isNetworkError(error) {
|
|
2101
|
+
if (error && error.code && error.code === "REQUEST_SEND_ERROR") {
|
|
2102
|
+
return true;
|
|
2103
|
+
}
|
|
2104
|
+
return false;
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
// Copyright (c) Microsoft Corporation.
|
|
2109
|
+
function createTagsFromResource(resource) {
|
|
2110
|
+
const context = getInstance();
|
|
2111
|
+
const tags = Object.assign({}, context.tags);
|
|
2112
|
+
if (resource && resource.attributes) {
|
|
2113
|
+
const serviceName = resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_NAME];
|
|
2114
|
+
const serviceNamespace = resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_NAMESPACE];
|
|
2115
|
+
if (serviceName) {
|
|
2116
|
+
if (serviceNamespace) {
|
|
2117
|
+
tags[KnownContextTagKeys.AiCloudRole] = `${serviceNamespace}.${serviceName}`;
|
|
2118
|
+
}
|
|
2119
|
+
else {
|
|
2120
|
+
tags[KnownContextTagKeys.AiCloudRole] = String(serviceName);
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
const serviceInstanceId = resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_INSTANCE_ID];
|
|
2124
|
+
if (serviceInstanceId) {
|
|
2125
|
+
tags[KnownContextTagKeys.AiCloudRoleInstance] = String(serviceInstanceId);
|
|
2126
|
+
}
|
|
2127
|
+
else {
|
|
2128
|
+
tags[KnownContextTagKeys.AiCloudRoleInstance] = os__default["default"] && os__default["default"].hostname();
|
|
2129
|
+
}
|
|
2130
|
+
const endUserId = resource.attributes[semanticConventions.SemanticAttributes.ENDUSER_ID];
|
|
2131
|
+
if (endUserId) {
|
|
2132
|
+
tags[KnownContextTagKeys.AiUserId] = String(endUserId);
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
return tags;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
1831
2138
|
// Copyright (c) Microsoft Corporation.
|
|
1832
2139
|
// Licensed under the MIT license.
|
|
1833
2140
|
/**
|
|
@@ -1894,34 +2201,15 @@ const parseEventHubSpan = (span, baseData) => {
|
|
|
1894
2201
|
|
|
1895
2202
|
// Copyright (c) Microsoft Corporation.
|
|
1896
2203
|
function createTagsFromSpan(span) {
|
|
1897
|
-
const
|
|
1898
|
-
const tags = Object.assign({}, context.tags);
|
|
2204
|
+
const tags = createTagsFromResource(span.resource);
|
|
1899
2205
|
tags[KnownContextTagKeys.AiOperationId] = span.spanContext().traceId;
|
|
1900
2206
|
if (span.parentSpanId) {
|
|
1901
2207
|
tags[KnownContextTagKeys.AiOperationParentId] = span.parentSpanId;
|
|
1902
2208
|
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
if (serviceNamespace) {
|
|
1908
|
-
tags[KnownContextTagKeys.AiCloudRole] = `${serviceNamespace}.${serviceName}`;
|
|
1909
|
-
}
|
|
1910
|
-
else {
|
|
1911
|
-
tags[KnownContextTagKeys.AiCloudRole] = String(serviceName);
|
|
1912
|
-
}
|
|
1913
|
-
}
|
|
1914
|
-
const serviceInstanceId = span.resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_INSTANCE_ID];
|
|
1915
|
-
if (serviceInstanceId) {
|
|
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);
|
|
1924
|
-
}
|
|
2209
|
+
const httpUserAgent = span.attributes[semanticConventions.SemanticAttributes.HTTP_USER_AGENT];
|
|
2210
|
+
if (httpUserAgent) {
|
|
2211
|
+
// TODO: Not exposed in Swagger, need to update def
|
|
2212
|
+
tags["ai.user.userAgent"] = String(httpUserAgent);
|
|
1925
2213
|
}
|
|
1926
2214
|
if (span.kind === api.SpanKind.SERVER) {
|
|
1927
2215
|
const httpMethod = span.attributes[semanticConventions.SemanticAttributes.HTTP_METHOD];
|
|
@@ -1956,25 +2244,34 @@ function createTagsFromSpan(span) {
|
|
|
1956
2244
|
}
|
|
1957
2245
|
}
|
|
1958
2246
|
// 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);
|
|
1963
|
-
}
|
|
1964
2247
|
return tags;
|
|
1965
2248
|
}
|
|
1966
|
-
function
|
|
2249
|
+
function createPropertiesFromSpanAttributes(attributes) {
|
|
1967
2250
|
const properties = {};
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
2251
|
+
if (attributes) {
|
|
2252
|
+
for (const key of Object.keys(attributes)) {
|
|
2253
|
+
if (!(key.startsWith("http.") ||
|
|
2254
|
+
key.startsWith("rpc.") ||
|
|
2255
|
+
key.startsWith("db.") ||
|
|
2256
|
+
key.startsWith("peer.") ||
|
|
2257
|
+
key.startsWith("message.") ||
|
|
2258
|
+
key.startsWith("messaging.") ||
|
|
2259
|
+
key.startsWith("enduser.") ||
|
|
2260
|
+
key.startsWith("net.") ||
|
|
2261
|
+
key.startsWith("exception.") ||
|
|
2262
|
+
key.startsWith("thread.") ||
|
|
2263
|
+
key.startsWith("faas.") ||
|
|
2264
|
+
key.startsWith("code.") ||
|
|
2265
|
+
key.startsWith("_MS."))) {
|
|
2266
|
+
properties[key] = attributes[key];
|
|
2267
|
+
}
|
|
1976
2268
|
}
|
|
1977
2269
|
}
|
|
2270
|
+
return properties;
|
|
2271
|
+
}
|
|
2272
|
+
function createPropertiesFromSpan(span) {
|
|
2273
|
+
const properties = createPropertiesFromSpanAttributes(span.attributes);
|
|
2274
|
+
const measurements = {};
|
|
1978
2275
|
const links = span.links.map((link) => ({
|
|
1979
2276
|
operation_Id: link.context.traceId,
|
|
1980
2277
|
id: link.context.spanId,
|
|
@@ -2103,7 +2400,7 @@ function createDependencyData(span) {
|
|
|
2103
2400
|
}
|
|
2104
2401
|
}
|
|
2105
2402
|
}
|
|
2106
|
-
catch (
|
|
2403
|
+
catch (ex) { }
|
|
2107
2404
|
remoteDependencyData.target = `${target}`;
|
|
2108
2405
|
}
|
|
2109
2406
|
}
|
|
@@ -2192,7 +2489,6 @@ function createRequestData(span) {
|
|
|
2192
2489
|
function readableSpanToEnvelope(span, ikey) {
|
|
2193
2490
|
let name;
|
|
2194
2491
|
let baseType;
|
|
2195
|
-
const sampleRate = 100;
|
|
2196
2492
|
let baseData;
|
|
2197
2493
|
const time = new Date(core.hrTimeToMilliseconds(span.startTime));
|
|
2198
2494
|
const instrumentationKey = ikey;
|
|
@@ -2218,6 +2514,10 @@ function readableSpanToEnvelope(span, ikey) {
|
|
|
2218
2514
|
api.diag.error(`Unsupported span kind ${span.kind}`);
|
|
2219
2515
|
throw new Error(`Unsupported span kind ${span.kind}`);
|
|
2220
2516
|
}
|
|
2517
|
+
let sampleRate = 100;
|
|
2518
|
+
if (span.attributes[AzureMonitorSampleRate]) {
|
|
2519
|
+
sampleRate = Number(span.attributes[AzureMonitorSampleRate]);
|
|
2520
|
+
}
|
|
2221
2521
|
// Azure SDK
|
|
2222
2522
|
if (span.attributes[AzNamespace]) {
|
|
2223
2523
|
if (span.kind === api.SpanKind.INTERNAL) {
|
|
@@ -2241,172 +2541,267 @@ function readableSpanToEnvelope(span, ikey) {
|
|
|
2241
2541
|
},
|
|
2242
2542
|
};
|
|
2243
2543
|
}
|
|
2544
|
+
/**
|
|
2545
|
+
* Span Events to Azure envelopes parsing.
|
|
2546
|
+
* @internal
|
|
2547
|
+
*/
|
|
2548
|
+
function spanEventsToEnvelopes(span, ikey) {
|
|
2549
|
+
let envelopes = [];
|
|
2550
|
+
if (span.events) {
|
|
2551
|
+
span.events.forEach((event) => {
|
|
2552
|
+
var _a;
|
|
2553
|
+
let baseType;
|
|
2554
|
+
let time = new Date(core.hrTimeToMilliseconds(event.time));
|
|
2555
|
+
let name = "";
|
|
2556
|
+
let baseData;
|
|
2557
|
+
const properties = createPropertiesFromSpanAttributes(event.attributes);
|
|
2558
|
+
let tags = createTagsFromResource(span.resource);
|
|
2559
|
+
tags[KnownContextTagKeys.AiOperationId] = span.spanContext().traceId;
|
|
2560
|
+
let spanId = (_a = span.spanContext()) === null || _a === void 0 ? void 0 : _a.spanId;
|
|
2561
|
+
if (spanId) {
|
|
2562
|
+
tags[KnownContextTagKeys.AiOperationParentId] = spanId;
|
|
2563
|
+
}
|
|
2564
|
+
// Only generate exception telemetry for incoming requests
|
|
2565
|
+
if (event.name == "exception" && span.kind == api.SpanKind.SERVER) {
|
|
2566
|
+
name = "Microsoft.ApplicationInsights.Exception";
|
|
2567
|
+
baseType = "ExceptionData";
|
|
2568
|
+
let typeName = "";
|
|
2569
|
+
let message = "Exception";
|
|
2570
|
+
let stack = "";
|
|
2571
|
+
let hasFullStack = false;
|
|
2572
|
+
if (event.attributes) {
|
|
2573
|
+
typeName = String(event.attributes[semanticConventions.SemanticAttributes.EXCEPTION_TYPE]);
|
|
2574
|
+
stack = String(event.attributes[semanticConventions.SemanticAttributes.EXCEPTION_STACKTRACE]);
|
|
2575
|
+
if (stack) {
|
|
2576
|
+
hasFullStack = true;
|
|
2577
|
+
}
|
|
2578
|
+
let exceptionMsg = event.attributes[semanticConventions.SemanticAttributes.EXCEPTION_MESSAGE];
|
|
2579
|
+
if (exceptionMsg) {
|
|
2580
|
+
message = String(exceptionMsg);
|
|
2581
|
+
}
|
|
2582
|
+
let escaped = event.attributes[semanticConventions.SemanticAttributes.EXCEPTION_ESCAPED];
|
|
2583
|
+
if (escaped != undefined) {
|
|
2584
|
+
properties[semanticConventions.SemanticAttributes.EXCEPTION_ESCAPED] = String(escaped);
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
let exceptionDetails = {
|
|
2588
|
+
typeName: typeName,
|
|
2589
|
+
message: message,
|
|
2590
|
+
stack: stack,
|
|
2591
|
+
hasFullStack: hasFullStack,
|
|
2592
|
+
};
|
|
2593
|
+
let exceptionData = {
|
|
2594
|
+
exceptions: [exceptionDetails],
|
|
2595
|
+
version: 2,
|
|
2596
|
+
properties: properties,
|
|
2597
|
+
};
|
|
2598
|
+
baseData = exceptionData;
|
|
2599
|
+
}
|
|
2600
|
+
else {
|
|
2601
|
+
name = "Microsoft.ApplicationInsights.Message";
|
|
2602
|
+
baseType = "MessageData";
|
|
2603
|
+
let messageData = {
|
|
2604
|
+
message: event.name,
|
|
2605
|
+
version: 2,
|
|
2606
|
+
properties: properties,
|
|
2607
|
+
};
|
|
2608
|
+
baseData = messageData;
|
|
2609
|
+
}
|
|
2610
|
+
let sampleRate = 100;
|
|
2611
|
+
if (span.attributes[AzureMonitorSampleRate]) {
|
|
2612
|
+
sampleRate = Number(span.attributes[AzureMonitorSampleRate]);
|
|
2613
|
+
}
|
|
2614
|
+
let env = {
|
|
2615
|
+
name: name,
|
|
2616
|
+
time: time,
|
|
2617
|
+
instrumentationKey: ikey,
|
|
2618
|
+
version: 1,
|
|
2619
|
+
sampleRate: sampleRate,
|
|
2620
|
+
data: {
|
|
2621
|
+
baseType: baseType,
|
|
2622
|
+
baseData: baseData,
|
|
2623
|
+
},
|
|
2624
|
+
tags: tags,
|
|
2625
|
+
};
|
|
2626
|
+
envelopes.push(env);
|
|
2627
|
+
});
|
|
2628
|
+
}
|
|
2629
|
+
return envelopes;
|
|
2630
|
+
}
|
|
2244
2631
|
|
|
2245
2632
|
// Copyright (c) Microsoft Corporation.
|
|
2246
2633
|
/**
|
|
2247
2634
|
* Azure Monitor OpenTelemetry Trace Exporter.
|
|
2248
2635
|
*/
|
|
2249
|
-
class AzureMonitorTraceExporter {
|
|
2636
|
+
class AzureMonitorTraceExporter extends AzureMonitorBaseExporter {
|
|
2250
2637
|
/**
|
|
2251
2638
|
* Initializes a new instance of the AzureMonitorTraceExporter class.
|
|
2252
2639
|
* @param AzureExporterConfig - Exporter configuration.
|
|
2253
2640
|
*/
|
|
2254
2641
|
constructor(options = {}) {
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
this.
|
|
2260
|
-
this._options.aadTokenCredential = options.aadTokenCredential;
|
|
2261
|
-
if (connectionString) {
|
|
2262
|
-
const parsedConnectionString = ConnectionStringParser.parse(connectionString);
|
|
2263
|
-
this._options.instrumentationKey =
|
|
2264
|
-
(_b = parsedConnectionString.instrumentationkey) !== null && _b !== void 0 ? _b : this._options.instrumentationKey;
|
|
2265
|
-
this._options.endpointUrl =
|
|
2266
|
-
(_d = (_c = parsedConnectionString.ingestionendpoint) === null || _c === void 0 ? void 0 : _c.trim()) !== null && _d !== void 0 ? _d : this._options.endpointUrl;
|
|
2267
|
-
}
|
|
2268
|
-
// Instrumentation key is required
|
|
2269
|
-
if (!this._options.instrumentationKey) {
|
|
2270
|
-
const message = "No instrumentation key or connection string was provided to the Azure Monitor Exporter";
|
|
2271
|
-
api.diag.error(message);
|
|
2272
|
-
throw new Error(message);
|
|
2273
|
-
}
|
|
2274
|
-
this._sender = new HttpSender(this._options);
|
|
2275
|
-
this._persister = new FileSystemPersist(this._options);
|
|
2276
|
-
this._retryTimer = null;
|
|
2642
|
+
super(options);
|
|
2643
|
+
/**
|
|
2644
|
+
* Flag to determine if Exporter is shutdown.
|
|
2645
|
+
*/
|
|
2646
|
+
this._isShutdown = false;
|
|
2277
2647
|
api.diag.debug("AzureMonitorTraceExporter was successfully setup");
|
|
2278
2648
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2649
|
+
/**
|
|
2650
|
+
* Export OpenTelemetry spans.
|
|
2651
|
+
* @param spans - Spans to export.
|
|
2652
|
+
* @param resultCallback - Result callback.
|
|
2653
|
+
*/
|
|
2654
|
+
async export(spans, resultCallback) {
|
|
2655
|
+
if (this._isShutdown) {
|
|
2656
|
+
api.diag.info("Exporter shut down. Failed to export spans.");
|
|
2657
|
+
setTimeout(() => resultCallback({ code: core.ExportResultCode.FAILED }), 0);
|
|
2658
|
+
return;
|
|
2288
2659
|
}
|
|
2289
|
-
|
|
2290
|
-
|
|
2660
|
+
api.diag.info(`Exporting ${spans.length} span(s). Converting to envelopes...`);
|
|
2661
|
+
let envelopes = [];
|
|
2662
|
+
spans.forEach((span) => {
|
|
2663
|
+
envelopes.push(readableSpanToEnvelope(span, this._instrumentationKey));
|
|
2664
|
+
let spanEventEnvelopes = spanEventsToEnvelopes(span, this._instrumentationKey);
|
|
2665
|
+
if (spanEventEnvelopes.length > 0) {
|
|
2666
|
+
envelopes.push(...spanEventEnvelopes);
|
|
2667
|
+
}
|
|
2668
|
+
});
|
|
2669
|
+
resultCallback(await this._exportEnvelopes(envelopes));
|
|
2670
|
+
}
|
|
2671
|
+
/**
|
|
2672
|
+
* Shutdown AzureMonitorTraceExporter.
|
|
2673
|
+
*/
|
|
2674
|
+
async shutdown() {
|
|
2675
|
+
this._isShutdown = true;
|
|
2676
|
+
api.diag.info("AzureMonitorTraceExporter shutting down");
|
|
2677
|
+
return this._shutdown();
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
|
|
2681
|
+
// Copyright (c) Microsoft Corporation.
|
|
2682
|
+
function createPropertiesFromMetricAttributes(attributes) {
|
|
2683
|
+
const properties = {};
|
|
2684
|
+
if (attributes) {
|
|
2685
|
+
for (const key of Object.keys(attributes)) {
|
|
2686
|
+
properties[key] = attributes[key];
|
|
2291
2687
|
}
|
|
2292
2688
|
}
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
if (result) {
|
|
2312
|
-
api.diag.info(result);
|
|
2313
|
-
const breezeResponse = JSON.parse(result);
|
|
2314
|
-
const filteredEnvelopes = [];
|
|
2315
|
-
breezeResponse.errors.forEach((error) => {
|
|
2316
|
-
if (error.statusCode && isRetriable(error.statusCode)) {
|
|
2317
|
-
filteredEnvelopes.push(envelopes[error.index]);
|
|
2318
|
-
}
|
|
2319
|
-
});
|
|
2320
|
-
if (filteredEnvelopes.length > 0) {
|
|
2321
|
-
// calls resultCallback(ExportResult) based on result of persister.push
|
|
2322
|
-
return await this._persist(filteredEnvelopes);
|
|
2323
|
-
}
|
|
2324
|
-
// Failed -- not retriable
|
|
2325
|
-
return {
|
|
2326
|
-
code: core.ExportResultCode.FAILED,
|
|
2327
|
-
};
|
|
2328
|
-
}
|
|
2329
|
-
else {
|
|
2330
|
-
// calls resultCallback(ExportResult) based on result of persister.push
|
|
2331
|
-
return await this._persist(envelopes);
|
|
2332
|
-
}
|
|
2333
|
-
}
|
|
2334
|
-
else {
|
|
2335
|
-
// Failed -- not retriable
|
|
2336
|
-
return {
|
|
2337
|
-
code: core.ExportResultCode.FAILED,
|
|
2689
|
+
return properties;
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Metric to Azure envelope parsing.
|
|
2693
|
+
* @internal
|
|
2694
|
+
*/
|
|
2695
|
+
function resourceMetricsToEnvelope(metrics, ikey) {
|
|
2696
|
+
let envelopes = [];
|
|
2697
|
+
const time = new Date();
|
|
2698
|
+
const instrumentationKey = ikey;
|
|
2699
|
+
const tags = createTagsFromResource(metrics.resource);
|
|
2700
|
+
metrics.scopeMetrics.forEach((scopeMetric) => {
|
|
2701
|
+
scopeMetric.metrics.forEach((metric) => {
|
|
2702
|
+
metric.dataPoints.forEach((dataPoint) => {
|
|
2703
|
+
let baseData = {
|
|
2704
|
+
metrics: [],
|
|
2705
|
+
version: 2,
|
|
2706
|
+
properties: {},
|
|
2338
2707
|
};
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
if (this._numConsecutiveRedirects < 10) {
|
|
2350
|
-
if (restError.response && restError.response.headers) {
|
|
2351
|
-
const location = restError.response.headers.get("location");
|
|
2352
|
-
if (location) {
|
|
2353
|
-
// Update sender URL
|
|
2354
|
-
this._sender.handlePermanentRedirect(location);
|
|
2355
|
-
// Send to redirect endpoint as HTTPs library doesn't handle redirect automatically
|
|
2356
|
-
return this.exportEnvelopes(envelopes);
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2708
|
+
baseData.properties = createPropertiesFromMetricAttributes(dataPoint.attributes);
|
|
2709
|
+
var metricDataPoint = {
|
|
2710
|
+
name: metric.descriptor.name,
|
|
2711
|
+
value: 0,
|
|
2712
|
+
dataPointType: "Aggregation",
|
|
2713
|
+
};
|
|
2714
|
+
if (metric.dataPointType == sdkMetrics.DataPointType.SUM ||
|
|
2715
|
+
metric.dataPointType == sdkMetrics.DataPointType.GAUGE) {
|
|
2716
|
+
metricDataPoint.value = dataPoint.value;
|
|
2717
|
+
metricDataPoint.count = 1;
|
|
2359
2718
|
}
|
|
2360
2719
|
else {
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2720
|
+
metricDataPoint.value = dataPoint.value.sum || 0;
|
|
2721
|
+
metricDataPoint.count = dataPoint.value.count;
|
|
2722
|
+
metricDataPoint.max = dataPoint.value.max;
|
|
2723
|
+
metricDataPoint.min = dataPoint.value.min;
|
|
2724
|
+
}
|
|
2725
|
+
baseData.metrics.push(metricDataPoint);
|
|
2726
|
+
let envelope = {
|
|
2727
|
+
name: "Microsoft.ApplicationInsights.Metric",
|
|
2728
|
+
time: time,
|
|
2729
|
+
sampleRate: 100,
|
|
2730
|
+
instrumentationKey: instrumentationKey,
|
|
2731
|
+
tags: tags,
|
|
2732
|
+
version: 1,
|
|
2733
|
+
data: {
|
|
2734
|
+
baseType: "MetricData",
|
|
2735
|
+
baseData: Object.assign({}, baseData),
|
|
2736
|
+
},
|
|
2737
|
+
};
|
|
2738
|
+
envelopes.push(envelope);
|
|
2739
|
+
});
|
|
2740
|
+
});
|
|
2741
|
+
});
|
|
2742
|
+
return envelopes;
|
|
2743
|
+
}
|
|
2744
|
+
|
|
2745
|
+
// Copyright (c) Microsoft Corporation.
|
|
2746
|
+
/**
|
|
2747
|
+
* Azure Monitor OpenTelemetry Metric Exporter.
|
|
2748
|
+
*/
|
|
2749
|
+
class AzureMonitorMetricExporter extends AzureMonitorBaseExporter {
|
|
2750
|
+
/**
|
|
2751
|
+
* Initializes a new instance of the AzureMonitorMetricExporter class.
|
|
2752
|
+
* @param AzureExporterConfig - Exporter configuration.
|
|
2753
|
+
*/
|
|
2754
|
+
constructor(options = {}) {
|
|
2755
|
+
super(options);
|
|
2756
|
+
/**
|
|
2757
|
+
* Flag to determine if Exporter is shutdown.
|
|
2758
|
+
*/
|
|
2759
|
+
this._isShutdown = false;
|
|
2760
|
+
this._aggregationTemporality = sdkMetrics.AggregationTemporality.CUMULATIVE;
|
|
2761
|
+
api.diag.debug("AzureMonitorMetricExporter was successfully setup");
|
|
2374
2762
|
}
|
|
2375
2763
|
/**
|
|
2376
|
-
* Export OpenTelemetry
|
|
2377
|
-
* @param
|
|
2764
|
+
* Export OpenTelemetry resource metrics.
|
|
2765
|
+
* @param metrics - Resource metrics to export.
|
|
2378
2766
|
* @param resultCallback - Result callback.
|
|
2379
2767
|
*/
|
|
2380
|
-
async export(
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2768
|
+
async export(metrics, resultCallback) {
|
|
2769
|
+
if (this._isShutdown) {
|
|
2770
|
+
api.diag.info("Exporter shut down. Failed to export spans.");
|
|
2771
|
+
setTimeout(() => resultCallback({ code: core.ExportResultCode.FAILED }), 0);
|
|
2772
|
+
return;
|
|
2773
|
+
}
|
|
2774
|
+
api.diag.info(`Exporting ${metrics.scopeMetrics.length} metrics(s). Converting to envelopes...`);
|
|
2775
|
+
let envelopes = resourceMetricsToEnvelope(metrics, this._instrumentationKey);
|
|
2776
|
+
// Supress tracing until OpenTelemetry Metrics SDK support it
|
|
2777
|
+
api.context.with(core.suppressTracing(api.context.active()), async () => {
|
|
2778
|
+
resultCallback(await this._exportEnvelopes(envelopes));
|
|
2779
|
+
});
|
|
2384
2780
|
}
|
|
2385
2781
|
/**
|
|
2386
|
-
* Shutdown
|
|
2782
|
+
* Shutdown AzureMonitorMetricExporter.
|
|
2387
2783
|
*/
|
|
2388
2784
|
async shutdown() {
|
|
2389
|
-
|
|
2390
|
-
|
|
2785
|
+
this._isShutdown = true;
|
|
2786
|
+
api.diag.info("AzureMonitorMetricExporter shutting down");
|
|
2787
|
+
return this._shutdown();
|
|
2391
2788
|
}
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
catch (err) {
|
|
2400
|
-
api.diag.warn(`Failed to fetch persisted file`, err);
|
|
2401
|
-
}
|
|
2789
|
+
/**
|
|
2790
|
+
* Select aggregation temporality
|
|
2791
|
+
*/
|
|
2792
|
+
selectAggregationTemporality(_instrumentType) {
|
|
2793
|
+
return this._aggregationTemporality;
|
|
2402
2794
|
}
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
return
|
|
2795
|
+
/**
|
|
2796
|
+
* Force flush
|
|
2797
|
+
*/
|
|
2798
|
+
async forceFlush() {
|
|
2799
|
+
return Promise.resolve();
|
|
2408
2800
|
}
|
|
2409
2801
|
}
|
|
2410
2802
|
|
|
2803
|
+
exports.ApplicationInsightsSampler = ApplicationInsightsSampler;
|
|
2804
|
+
exports.AzureMonitorBaseExporter = AzureMonitorBaseExporter;
|
|
2805
|
+
exports.AzureMonitorMetricExporter = AzureMonitorMetricExporter;
|
|
2411
2806
|
exports.AzureMonitorTraceExporter = AzureMonitorTraceExporter;
|
|
2412
2807
|
//# sourceMappingURL=index.js.map
|