@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-esm/src/config.js
CHANGED
|
@@ -1,15 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
const DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS = 60000;
|
|
3
|
-
const DEFAULT_MAX_CONSECUTIVE_FAILURES_BEFORE_WARNING = 10;
|
|
4
|
-
/**
|
|
5
|
-
* Internal default Azure exporter configuration
|
|
6
|
-
* @internal
|
|
7
|
-
*/
|
|
8
|
-
export const DEFAULT_EXPORTER_CONFIG = {
|
|
9
|
-
instrumentationKey: "",
|
|
10
|
-
endpointUrl: DEFAULT_BREEZE_ENDPOINT,
|
|
11
|
-
batchSendRetryIntervalMs: DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS,
|
|
12
|
-
maxConsecutiveFailuresBeforeWarning: DEFAULT_MAX_CONSECUTIVE_FAILURES_BEFORE_WARNING,
|
|
13
|
-
apiVersion: DEFAULT_BREEZE_API_VERSION,
|
|
14
|
-
};
|
|
1
|
+
export {};
|
|
15
2
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { TokenCredential } from \"@azure/core-auth\";\nimport { ServiceApiVersion } from \"./Declarations/Constants\";\nimport { ApplicationInsightsClientOptionalParams } from \"./generated\";\n\n/**\n * Provides configuration options for AzureMonitorTraceExporter.\n */\nexport interface AzureMonitorExporterOptions extends ApplicationInsightsClientOptionalParams {\n /**\n * Azure Monitor Connection String, if not provided the exporter will try to use environment variable APPLICATIONINSIGHTS_CONNECTION_STRING\n * Ex: \"InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://dc.services.visualstudio.com\"\n */\n connectionString?: string;\n /**\n * Azure service API version.\n */\n apiVersion?: ServiceApiVersion;\n /**\n * Azure Active Directory Credential\n */\n aadTokenCredential?: TokenCredential;\n /**\n * Directory to store retriable telemetry when it fails to export.\n */\n storageDirectory?: string;\n /**\n * Disable offline storage when telemetry cannot be exported.\n */\n disableOfflineStorage?: boolean;\n}\n"]}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { diag } from "@opentelemetry/api";
|
|
4
|
+
import { ExportResultCode } from "@opentelemetry/core";
|
|
5
|
+
import { ConnectionStringParser } from "../utils/connectionStringParser";
|
|
6
|
+
import { HttpSender, FileSystemPersist } from "../platform";
|
|
7
|
+
import { isRetriable } from "../utils/breezeUtils";
|
|
8
|
+
import { DEFAULT_BREEZE_ENDPOINT, ENV_CONNECTION_STRING } from "../Declarations/Constants";
|
|
9
|
+
const DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS = 60000;
|
|
10
|
+
/**
|
|
11
|
+
* Azure Monitor OpenTelemetry Trace Exporter.
|
|
12
|
+
*/
|
|
13
|
+
export class AzureMonitorBaseExporter {
|
|
14
|
+
/**
|
|
15
|
+
* Initializes a new instance of the AzureMonitorBaseExporter class.
|
|
16
|
+
* @param AzureMonitorExporterOptions - Exporter configuration.
|
|
17
|
+
*/
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
var _a;
|
|
20
|
+
this._batchSendRetryIntervalMs = DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS;
|
|
21
|
+
this._options = options;
|
|
22
|
+
this._numConsecutiveRedirects = 0;
|
|
23
|
+
this._instrumentationKey = "";
|
|
24
|
+
this._endpointUrl = DEFAULT_BREEZE_ENDPOINT;
|
|
25
|
+
const connectionString = this._options.connectionString || process.env[ENV_CONNECTION_STRING];
|
|
26
|
+
if (connectionString) {
|
|
27
|
+
const parsedConnectionString = ConnectionStringParser.parse(connectionString);
|
|
28
|
+
this._instrumentationKey =
|
|
29
|
+
parsedConnectionString.instrumentationkey || this._instrumentationKey;
|
|
30
|
+
this._endpointUrl = ((_a = parsedConnectionString.ingestionendpoint) === null || _a === void 0 ? void 0 : _a.trim()) || this._endpointUrl;
|
|
31
|
+
}
|
|
32
|
+
// Instrumentation key is required
|
|
33
|
+
if (!this._instrumentationKey) {
|
|
34
|
+
const message = "No instrumentation key or connection string was provided to the Azure Monitor Exporter";
|
|
35
|
+
diag.error(message);
|
|
36
|
+
throw new Error(message);
|
|
37
|
+
}
|
|
38
|
+
this._sender = new HttpSender(this._endpointUrl, this._options);
|
|
39
|
+
this._persister = new FileSystemPersist(this._instrumentationKey, this._options);
|
|
40
|
+
this._retryTimer = null;
|
|
41
|
+
diag.debug("AzureMonitorExporter was successfully setup");
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Persist envelopes to disk
|
|
45
|
+
*/
|
|
46
|
+
async _persist(envelopes) {
|
|
47
|
+
try {
|
|
48
|
+
const success = await this._persister.push(envelopes);
|
|
49
|
+
return success
|
|
50
|
+
? { code: ExportResultCode.SUCCESS }
|
|
51
|
+
: {
|
|
52
|
+
code: ExportResultCode.FAILED,
|
|
53
|
+
error: new Error("Failed to persist envelope in disk."),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
catch (ex) {
|
|
57
|
+
return { code: ExportResultCode.FAILED, error: ex };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Shutdown exporter
|
|
62
|
+
*/
|
|
63
|
+
async _shutdown() {
|
|
64
|
+
return this._sender.shutdown();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Export envelopes
|
|
68
|
+
*/
|
|
69
|
+
async _exportEnvelopes(envelopes) {
|
|
70
|
+
diag.info(`Exporting ${envelopes.length} envelope(s)`);
|
|
71
|
+
if (envelopes.length < 1) {
|
|
72
|
+
return { code: ExportResultCode.SUCCESS };
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const { result, statusCode } = await this._sender.send(envelopes);
|
|
76
|
+
this._numConsecutiveRedirects = 0;
|
|
77
|
+
if (statusCode === 200) {
|
|
78
|
+
// Success -- @todo: start retry timer
|
|
79
|
+
if (!this._retryTimer) {
|
|
80
|
+
this._retryTimer = setTimeout(() => {
|
|
81
|
+
this._retryTimer = null;
|
|
82
|
+
this._sendFirstPersistedFile();
|
|
83
|
+
}, this._batchSendRetryIntervalMs);
|
|
84
|
+
this._retryTimer.unref();
|
|
85
|
+
}
|
|
86
|
+
return { code: ExportResultCode.SUCCESS };
|
|
87
|
+
}
|
|
88
|
+
else if (statusCode && isRetriable(statusCode)) {
|
|
89
|
+
// Failed -- persist failed data
|
|
90
|
+
if (result) {
|
|
91
|
+
diag.info(result);
|
|
92
|
+
const breezeResponse = JSON.parse(result);
|
|
93
|
+
const filteredEnvelopes = [];
|
|
94
|
+
if (breezeResponse.errors) {
|
|
95
|
+
breezeResponse.errors.forEach((error) => {
|
|
96
|
+
if (error.statusCode && isRetriable(error.statusCode)) {
|
|
97
|
+
filteredEnvelopes.push(envelopes[error.index]);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (filteredEnvelopes.length > 0) {
|
|
102
|
+
// calls resultCallback(ExportResult) based on result of persister.push
|
|
103
|
+
return await this._persist(filteredEnvelopes);
|
|
104
|
+
}
|
|
105
|
+
// Failed -- not retriable
|
|
106
|
+
return {
|
|
107
|
+
code: ExportResultCode.FAILED,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// calls resultCallback(ExportResult) based on result of persister.push
|
|
112
|
+
return await this._persist(envelopes);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Failed -- not retriable
|
|
117
|
+
return {
|
|
118
|
+
code: ExportResultCode.FAILED,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
const restError = error;
|
|
124
|
+
if (restError.statusCode &&
|
|
125
|
+
(restError.statusCode === 307 || // Temporary redirect
|
|
126
|
+
restError.statusCode === 308)) {
|
|
127
|
+
// Permanent redirect
|
|
128
|
+
this._numConsecutiveRedirects++;
|
|
129
|
+
// To prevent circular redirects
|
|
130
|
+
if (this._numConsecutiveRedirects < 10) {
|
|
131
|
+
if (restError.response && restError.response.headers) {
|
|
132
|
+
const location = restError.response.headers.get("location");
|
|
133
|
+
if (location) {
|
|
134
|
+
// Update sender URL
|
|
135
|
+
this._sender.handlePermanentRedirect(location);
|
|
136
|
+
// Send to redirect endpoint as HTTPs library doesn't handle redirect automatically
|
|
137
|
+
return this._exportEnvelopes(envelopes);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
return { code: ExportResultCode.FAILED, error: new Error("Circular redirect") };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else if (restError.statusCode && isRetriable(restError.statusCode)) {
|
|
146
|
+
return await this._persist(envelopes);
|
|
147
|
+
}
|
|
148
|
+
if (this._isNetworkError(restError)) {
|
|
149
|
+
diag.error("Retrying due to transient client side error. Error message:", restError.message);
|
|
150
|
+
return await this._persist(envelopes);
|
|
151
|
+
}
|
|
152
|
+
diag.error("Envelopes could not be exported and are not retriable. Error message:", restError.message);
|
|
153
|
+
return { code: ExportResultCode.FAILED, error: restError };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async _sendFirstPersistedFile() {
|
|
157
|
+
try {
|
|
158
|
+
const envelopes = (await this._persister.shift());
|
|
159
|
+
if (envelopes) {
|
|
160
|
+
await this._sender.send(envelopes);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
diag.warn(`Failed to fetch persisted file`, err);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
_isNetworkError(error) {
|
|
168
|
+
if (error && error.code && error.code === "REQUEST_SEND_ERROR") {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/export/base.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { diag } from \"@opentelemetry/api\";\nimport { ExportResult, ExportResultCode } from \"@opentelemetry/core\";\nimport { RestError } from \"@azure/core-rest-pipeline\";\nimport { ConnectionStringParser } from \"../utils/connectionStringParser\";\nimport { HttpSender, FileSystemPersist } from \"../platform\";\nimport { AzureMonitorExporterOptions } from \"../config\";\nimport { PersistentStorage, Sender } from \"../types\";\nimport { isRetriable, BreezeResponse } from \"../utils/breezeUtils\";\nimport { DEFAULT_BREEZE_ENDPOINT, ENV_CONNECTION_STRING } from \"../Declarations/Constants\";\nimport { TelemetryItem as Envelope } from \"../generated\";\n\nconst DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS = 60_000;\n/**\n * Azure Monitor OpenTelemetry Trace Exporter.\n */\nexport abstract class AzureMonitorBaseExporter {\n /**\n * Instrumentation key to be used for exported envelopes\n */\n protected _instrumentationKey: string;\n private readonly _persister: PersistentStorage;\n private readonly _sender: Sender;\n private _numConsecutiveRedirects: number;\n private _retryTimer: NodeJS.Timer | null;\n private _endpointUrl: string;\n\n private _batchSendRetryIntervalMs: number = DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS;\n /**\n * Exporter internal configuration\n */\n private readonly _options: AzureMonitorExporterOptions;\n\n /**\n * Initializes a new instance of the AzureMonitorBaseExporter class.\n * @param AzureMonitorExporterOptions - Exporter configuration.\n */\n constructor(options: AzureMonitorExporterOptions = {}) {\n this._options = options;\n this._numConsecutiveRedirects = 0;\n this._instrumentationKey = \"\";\n this._endpointUrl = DEFAULT_BREEZE_ENDPOINT;\n const connectionString = this._options.connectionString || process.env[ENV_CONNECTION_STRING];\n if (connectionString) {\n const parsedConnectionString = ConnectionStringParser.parse(connectionString);\n this._instrumentationKey =\n parsedConnectionString.instrumentationkey || this._instrumentationKey;\n this._endpointUrl = parsedConnectionString.ingestionendpoint?.trim() || this._endpointUrl;\n }\n\n // Instrumentation key is required\n if (!this._instrumentationKey) {\n const message =\n \"No instrumentation key or connection string was provided to the Azure Monitor Exporter\";\n diag.error(message);\n throw new Error(message);\n }\n\n this._sender = new HttpSender(this._endpointUrl, this._options);\n this._persister = new FileSystemPersist(this._instrumentationKey, this._options);\n this._retryTimer = null;\n diag.debug(\"AzureMonitorExporter was successfully setup\");\n }\n\n /**\n * Persist envelopes to disk\n */\n private async _persist(envelopes: unknown[]): Promise<ExportResult> {\n try {\n const success = await this._persister.push(envelopes);\n return success\n ? { code: ExportResultCode.SUCCESS }\n : {\n code: ExportResultCode.FAILED,\n error: new Error(\"Failed to persist envelope in disk.\"),\n };\n } catch (ex: any) {\n return { code: ExportResultCode.FAILED, error: ex };\n }\n }\n\n /**\n * Shutdown exporter\n */\n protected async _shutdown(): Promise<void> {\n return this._sender.shutdown();\n }\n\n /**\n * Export envelopes\n */\n protected async _exportEnvelopes(envelopes: Envelope[]): Promise<ExportResult> {\n diag.info(`Exporting ${envelopes.length} envelope(s)`);\n if (envelopes.length < 1) {\n return { code: ExportResultCode.SUCCESS };\n }\n try {\n const { result, statusCode } = await this._sender.send(envelopes);\n this._numConsecutiveRedirects = 0;\n if (statusCode === 200) {\n // Success -- @todo: start retry timer\n if (!this._retryTimer) {\n this._retryTimer = setTimeout(() => {\n this._retryTimer = null;\n this._sendFirstPersistedFile();\n }, this._batchSendRetryIntervalMs);\n this._retryTimer.unref();\n }\n return { code: ExportResultCode.SUCCESS };\n } else if (statusCode && isRetriable(statusCode)) {\n // Failed -- persist failed data\n if (result) {\n diag.info(result);\n const breezeResponse = JSON.parse(result) as BreezeResponse;\n const filteredEnvelopes: Envelope[] = [];\n if (breezeResponse.errors) {\n breezeResponse.errors.forEach((error) => {\n if (error.statusCode && isRetriable(error.statusCode)) {\n filteredEnvelopes.push(envelopes[error.index]);\n }\n });\n }\n if (filteredEnvelopes.length > 0) {\n // calls resultCallback(ExportResult) based on result of persister.push\n return await this._persist(filteredEnvelopes);\n }\n // Failed -- not retriable\n return {\n code: ExportResultCode.FAILED,\n };\n } else {\n // calls resultCallback(ExportResult) based on result of persister.push\n return await this._persist(envelopes);\n }\n } else {\n // Failed -- not retriable\n return {\n code: ExportResultCode.FAILED,\n };\n }\n } catch (error: any) {\n const restError = error as RestError;\n if (\n restError.statusCode &&\n (restError.statusCode === 307 || // Temporary redirect\n restError.statusCode === 308)\n ) {\n // Permanent redirect\n this._numConsecutiveRedirects++;\n // To prevent circular redirects\n if (this._numConsecutiveRedirects < 10) {\n if (restError.response && restError.response.headers) {\n const location = restError.response.headers.get(\"location\");\n if (location) {\n // Update sender URL\n this._sender.handlePermanentRedirect(location);\n // Send to redirect endpoint as HTTPs library doesn't handle redirect automatically\n return this._exportEnvelopes(envelopes);\n }\n }\n } else {\n return { code: ExportResultCode.FAILED, error: new Error(\"Circular redirect\") };\n }\n } else if (restError.statusCode && isRetriable(restError.statusCode)) {\n return await this._persist(envelopes);\n }\n if (this._isNetworkError(restError)) {\n diag.error(\n \"Retrying due to transient client side error. Error message:\",\n restError.message\n );\n return await this._persist(envelopes);\n }\n\n diag.error(\n \"Envelopes could not be exported and are not retriable. Error message:\",\n restError.message\n );\n return { code: ExportResultCode.FAILED, error: restError };\n }\n }\n\n private async _sendFirstPersistedFile(): Promise<void> {\n try {\n const envelopes = (await this._persister.shift()) as Envelope[] | null;\n if (envelopes) {\n await this._sender.send(envelopes);\n }\n } catch (err: any) {\n diag.warn(`Failed to fetch persisted file`, err);\n }\n }\n\n private _isNetworkError(error: RestError): boolean {\n if (error && error.code && error.code === \"REQUEST_SEND_ERROR\") {\n return true;\n }\n return false;\n }\n}\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { context, diag } from "@opentelemetry/api";
|
|
4
|
+
import { AggregationTemporality, } from "@opentelemetry/sdk-metrics";
|
|
5
|
+
import { ExportResultCode, suppressTracing } from "@opentelemetry/core";
|
|
6
|
+
import { AzureMonitorBaseExporter } from "./base";
|
|
7
|
+
import { resourceMetricsToEnvelope } from "../utils/metricUtils";
|
|
8
|
+
/**
|
|
9
|
+
* Azure Monitor OpenTelemetry Metric Exporter.
|
|
10
|
+
*/
|
|
11
|
+
export class AzureMonitorMetricExporter extends AzureMonitorBaseExporter {
|
|
12
|
+
/**
|
|
13
|
+
* Initializes a new instance of the AzureMonitorMetricExporter class.
|
|
14
|
+
* @param AzureExporterConfig - Exporter configuration.
|
|
15
|
+
*/
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
super(options);
|
|
18
|
+
/**
|
|
19
|
+
* Flag to determine if Exporter is shutdown.
|
|
20
|
+
*/
|
|
21
|
+
this._isShutdown = false;
|
|
22
|
+
this._aggregationTemporality = AggregationTemporality.CUMULATIVE;
|
|
23
|
+
diag.debug("AzureMonitorMetricExporter was successfully setup");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Export OpenTelemetry resource metrics.
|
|
27
|
+
* @param metrics - Resource metrics to export.
|
|
28
|
+
* @param resultCallback - Result callback.
|
|
29
|
+
*/
|
|
30
|
+
async export(metrics, resultCallback) {
|
|
31
|
+
if (this._isShutdown) {
|
|
32
|
+
diag.info("Exporter shut down. Failed to export spans.");
|
|
33
|
+
setTimeout(() => resultCallback({ code: ExportResultCode.FAILED }), 0);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
diag.info(`Exporting ${metrics.scopeMetrics.length} metrics(s). Converting to envelopes...`);
|
|
37
|
+
let envelopes = resourceMetricsToEnvelope(metrics, this._instrumentationKey);
|
|
38
|
+
// Supress tracing until OpenTelemetry Metrics SDK support it
|
|
39
|
+
context.with(suppressTracing(context.active()), async () => {
|
|
40
|
+
resultCallback(await this._exportEnvelopes(envelopes));
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Shutdown AzureMonitorMetricExporter.
|
|
45
|
+
*/
|
|
46
|
+
async shutdown() {
|
|
47
|
+
this._isShutdown = true;
|
|
48
|
+
diag.info("AzureMonitorMetricExporter shutting down");
|
|
49
|
+
return this._shutdown();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Select aggregation temporality
|
|
53
|
+
*/
|
|
54
|
+
selectAggregationTemporality(_instrumentType) {
|
|
55
|
+
return this._aggregationTemporality;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Force flush
|
|
59
|
+
*/
|
|
60
|
+
async forceFlush() {
|
|
61
|
+
return Promise.resolve();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=metric.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metric.js","sourceRoot":"","sources":["../../../src/export/metric.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EACL,sBAAsB,GAIvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAgB,gBAAgB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAC;AAGlD,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAEjE;;GAEG;AACH,MAAM,OAAO,0BACX,SAAQ,wBAAwB;IAYhC;;;OAGG;IACH,YAAY,UAAuC,EAAE;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QAdjB;;WAEG;QACK,gBAAW,GAAG,KAAK,CAAC;QAY1B,IAAI,CAAC,uBAAuB,GAAG,sBAAsB,CAAC,UAAU,CAAC;QACjE,IAAI,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CACV,OAAwB,EACxB,cAA8C;QAE9C,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,IAAI,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YACzD,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACvE,OAAO;SACR;QACD,IAAI,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,YAAY,CAAC,MAAM,yCAAyC,CAAC,CAAC;QAE7F,IAAI,SAAS,GAAe,yBAAyB,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACzF,6DAA6D;QAC7D,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE;YACzD,cAAc,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,QAAQ;QACnB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACI,4BAA4B,CAAC,eAA+B;QACjE,OAAO,IAAI,CAAC,uBAAuB,CAAC;IACtC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,UAAU;QACrB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { context, diag } from \"@opentelemetry/api\";\nimport {\n AggregationTemporality,\n InstrumentType,\n PushMetricExporter,\n ResourceMetrics,\n} from \"@opentelemetry/sdk-metrics\";\nimport { ExportResult, ExportResultCode, suppressTracing } from \"@opentelemetry/core\";\nimport { AzureMonitorBaseExporter } from \"./base\";\nimport { AzureMonitorExporterOptions } from \"../config\";\nimport { TelemetryItem as Envelope } from \"../generated\";\nimport { resourceMetricsToEnvelope } from \"../utils/metricUtils\";\n\n/**\n * Azure Monitor OpenTelemetry Metric Exporter.\n */\nexport class AzureMonitorMetricExporter\n extends AzureMonitorBaseExporter\n implements PushMetricExporter\n{\n /**\n * Flag to determine if Exporter is shutdown.\n */\n private _isShutdown = false;\n /**\n * Aggregation temporality.\n */\n private _aggregationTemporality: AggregationTemporality;\n\n /**\n * Initializes a new instance of the AzureMonitorMetricExporter class.\n * @param AzureExporterConfig - Exporter configuration.\n */\n constructor(options: AzureMonitorExporterOptions = {}) {\n super(options);\n this._aggregationTemporality = AggregationTemporality.CUMULATIVE;\n diag.debug(\"AzureMonitorMetricExporter was successfully setup\");\n }\n\n /**\n * Export OpenTelemetry resource metrics.\n * @param metrics - Resource metrics to export.\n * @param resultCallback - Result callback.\n */\n async export(\n metrics: ResourceMetrics,\n resultCallback: (result: ExportResult) => void\n ): Promise<void> {\n if (this._isShutdown) {\n diag.info(\"Exporter shut down. Failed to export spans.\");\n setTimeout(() => resultCallback({ code: ExportResultCode.FAILED }), 0);\n return;\n }\n diag.info(`Exporting ${metrics.scopeMetrics.length} metrics(s). Converting to envelopes...`);\n\n let envelopes: Envelope[] = resourceMetricsToEnvelope(metrics, this._instrumentationKey);\n // Supress tracing until OpenTelemetry Metrics SDK support it\n context.with(suppressTracing(context.active()), async () => {\n resultCallback(await this._exportEnvelopes(envelopes));\n });\n }\n\n /**\n * Shutdown AzureMonitorMetricExporter.\n */\n public async shutdown(): Promise<void> {\n this._isShutdown = true;\n diag.info(\"AzureMonitorMetricExporter shutting down\");\n return this._shutdown();\n }\n\n /**\n * Select aggregation temporality\n */\n public selectAggregationTemporality(_instrumentType: InstrumentType): AggregationTemporality {\n return this._aggregationTemporality;\n }\n\n /**\n * Force flush\n */\n public async forceFlush() {\n return Promise.resolve();\n }\n}\n"]}
|
|
@@ -2,174 +2,53 @@
|
|
|
2
2
|
// Licensed under the MIT license.
|
|
3
3
|
import { diag } from "@opentelemetry/api";
|
|
4
4
|
import { ExportResultCode } from "@opentelemetry/core";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { DEFAULT_EXPORTER_CONFIG, } from "../config";
|
|
8
|
-
import { isRetriable } from "../utils/breezeUtils";
|
|
9
|
-
import { ENV_CONNECTION_STRING } from "../Declarations/Constants";
|
|
10
|
-
import { readableSpanToEnvelope } from "../utils/spanUtils";
|
|
5
|
+
import { AzureMonitorBaseExporter } from "./base";
|
|
6
|
+
import { readableSpanToEnvelope, spanEventsToEnvelopes } from "../utils/spanUtils";
|
|
11
7
|
/**
|
|
12
8
|
* Azure Monitor OpenTelemetry Trace Exporter.
|
|
13
9
|
*/
|
|
14
|
-
export class AzureMonitorTraceExporter {
|
|
10
|
+
export class AzureMonitorTraceExporter extends AzureMonitorBaseExporter {
|
|
15
11
|
/**
|
|
16
12
|
* Initializes a new instance of the AzureMonitorTraceExporter class.
|
|
17
13
|
* @param AzureExporterConfig - Exporter configuration.
|
|
18
14
|
*/
|
|
19
15
|
constructor(options = {}) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
this.
|
|
25
|
-
this._options.aadTokenCredential = options.aadTokenCredential;
|
|
26
|
-
if (connectionString) {
|
|
27
|
-
const parsedConnectionString = ConnectionStringParser.parse(connectionString);
|
|
28
|
-
this._options.instrumentationKey =
|
|
29
|
-
(_b = parsedConnectionString.instrumentationkey) !== null && _b !== void 0 ? _b : this._options.instrumentationKey;
|
|
30
|
-
this._options.endpointUrl =
|
|
31
|
-
(_d = (_c = parsedConnectionString.ingestionendpoint) === null || _c === void 0 ? void 0 : _c.trim()) !== null && _d !== void 0 ? _d : this._options.endpointUrl;
|
|
32
|
-
}
|
|
33
|
-
// Instrumentation key is required
|
|
34
|
-
if (!this._options.instrumentationKey) {
|
|
35
|
-
const message = "No instrumentation key or connection string was provided to the Azure Monitor Exporter";
|
|
36
|
-
diag.error(message);
|
|
37
|
-
throw new Error(message);
|
|
38
|
-
}
|
|
39
|
-
this._sender = new HttpSender(this._options);
|
|
40
|
-
this._persister = new FileSystemPersist(this._options);
|
|
41
|
-
this._retryTimer = null;
|
|
16
|
+
super(options);
|
|
17
|
+
/**
|
|
18
|
+
* Flag to determine if Exporter is shutdown.
|
|
19
|
+
*/
|
|
20
|
+
this._isShutdown = false;
|
|
42
21
|
diag.debug("AzureMonitorTraceExporter was successfully setup");
|
|
43
22
|
}
|
|
44
|
-
async _persist(envelopes) {
|
|
45
|
-
try {
|
|
46
|
-
const success = await this._persister.push(envelopes);
|
|
47
|
-
return success
|
|
48
|
-
? { code: ExportResultCode.SUCCESS }
|
|
49
|
-
: {
|
|
50
|
-
code: ExportResultCode.FAILED,
|
|
51
|
-
error: new Error("Failed to persist envelope in disk."),
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
catch (ex) {
|
|
55
|
-
return { code: ExportResultCode.FAILED, error: ex };
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
async exportEnvelopes(envelopes) {
|
|
59
|
-
diag.info(`Exporting ${envelopes.length} envelope(s)`);
|
|
60
|
-
try {
|
|
61
|
-
const { result, statusCode } = await this._sender.send(envelopes);
|
|
62
|
-
this._numConsecutiveRedirects = 0;
|
|
63
|
-
if (statusCode === 200) {
|
|
64
|
-
// Success -- @todo: start retry timer
|
|
65
|
-
if (!this._retryTimer) {
|
|
66
|
-
this._retryTimer = setTimeout(() => {
|
|
67
|
-
this._retryTimer = null;
|
|
68
|
-
this._sendFirstPersistedFile();
|
|
69
|
-
}, this._options.batchSendRetryIntervalMs);
|
|
70
|
-
this._retryTimer.unref();
|
|
71
|
-
}
|
|
72
|
-
return { code: ExportResultCode.SUCCESS };
|
|
73
|
-
}
|
|
74
|
-
else if (statusCode && isRetriable(statusCode)) {
|
|
75
|
-
// Failed -- persist failed data
|
|
76
|
-
if (result) {
|
|
77
|
-
diag.info(result);
|
|
78
|
-
const breezeResponse = JSON.parse(result);
|
|
79
|
-
const filteredEnvelopes = [];
|
|
80
|
-
breezeResponse.errors.forEach((error) => {
|
|
81
|
-
if (error.statusCode && isRetriable(error.statusCode)) {
|
|
82
|
-
filteredEnvelopes.push(envelopes[error.index]);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
if (filteredEnvelopes.length > 0) {
|
|
86
|
-
// calls resultCallback(ExportResult) based on result of persister.push
|
|
87
|
-
return await this._persist(filteredEnvelopes);
|
|
88
|
-
}
|
|
89
|
-
// Failed -- not retriable
|
|
90
|
-
return {
|
|
91
|
-
code: ExportResultCode.FAILED,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
// calls resultCallback(ExportResult) based on result of persister.push
|
|
96
|
-
return await this._persist(envelopes);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
// Failed -- not retriable
|
|
101
|
-
return {
|
|
102
|
-
code: ExportResultCode.FAILED,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
const restError = error;
|
|
108
|
-
if (restError.statusCode &&
|
|
109
|
-
(restError.statusCode === 307 || // Temporary redirect
|
|
110
|
-
restError.statusCode === 308)) {
|
|
111
|
-
// Permanent redirect
|
|
112
|
-
this._numConsecutiveRedirects++;
|
|
113
|
-
// To prevent circular redirects
|
|
114
|
-
if (this._numConsecutiveRedirects < 10) {
|
|
115
|
-
if (restError.response && restError.response.headers) {
|
|
116
|
-
const location = restError.response.headers.get("location");
|
|
117
|
-
if (location) {
|
|
118
|
-
// Update sender URL
|
|
119
|
-
this._sender.handlePermanentRedirect(location);
|
|
120
|
-
// Send to redirect endpoint as HTTPs library doesn't handle redirect automatically
|
|
121
|
-
return this.exportEnvelopes(envelopes);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
return { code: ExportResultCode.FAILED, error: new Error("Circular redirect") };
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
else if (restError.statusCode && isRetriable(restError.statusCode)) {
|
|
130
|
-
return await this._persist(envelopes);
|
|
131
|
-
}
|
|
132
|
-
if (this._isNetworkError(restError)) {
|
|
133
|
-
diag.error("Retrying due to transient client side error. Error message:", restError.message);
|
|
134
|
-
return await this._persist(envelopes);
|
|
135
|
-
}
|
|
136
|
-
diag.error("Envelopes could not be exported and are not retriable. Error message:", restError.message);
|
|
137
|
-
return { code: ExportResultCode.FAILED, error: restError };
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
23
|
/**
|
|
141
24
|
* Export OpenTelemetry spans.
|
|
142
25
|
* @param spans - Spans to export.
|
|
143
26
|
* @param resultCallback - Result callback.
|
|
144
27
|
*/
|
|
145
28
|
async export(spans, resultCallback) {
|
|
29
|
+
if (this._isShutdown) {
|
|
30
|
+
diag.info("Exporter shut down. Failed to export spans.");
|
|
31
|
+
setTimeout(() => resultCallback({ code: ExportResultCode.FAILED }), 0);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
146
34
|
diag.info(`Exporting ${spans.length} span(s). Converting to envelopes...`);
|
|
147
|
-
|
|
148
|
-
|
|
35
|
+
let envelopes = [];
|
|
36
|
+
spans.forEach((span) => {
|
|
37
|
+
envelopes.push(readableSpanToEnvelope(span, this._instrumentationKey));
|
|
38
|
+
let spanEventEnvelopes = spanEventsToEnvelopes(span, this._instrumentationKey);
|
|
39
|
+
if (spanEventEnvelopes.length > 0) {
|
|
40
|
+
envelopes.push(...spanEventEnvelopes);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
resultCallback(await this._exportEnvelopes(envelopes));
|
|
149
44
|
}
|
|
150
45
|
/**
|
|
151
46
|
* Shutdown AzureMonitorTraceExporter.
|
|
152
47
|
*/
|
|
153
48
|
async shutdown() {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
async _sendFirstPersistedFile() {
|
|
158
|
-
try {
|
|
159
|
-
const envelopes = (await this._persister.shift());
|
|
160
|
-
if (envelopes) {
|
|
161
|
-
await this._sender.send(envelopes);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
catch (err) {
|
|
165
|
-
diag.warn(`Failed to fetch persisted file`, err);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
_isNetworkError(error) {
|
|
169
|
-
if (error && error.code && error.code === "REQUEST_SEND_ERROR") {
|
|
170
|
-
return true;
|
|
171
|
-
}
|
|
172
|
-
return false;
|
|
49
|
+
this._isShutdown = true;
|
|
50
|
+
diag.info("AzureMonitorTraceExporter shutting down");
|
|
51
|
+
return this._shutdown();
|
|
173
52
|
}
|
|
174
53
|
}
|
|
175
54
|
//# sourceMappingURL=trace.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/export/trace.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { diag } from \"@opentelemetry/api\";\nimport { ExportResult, ExportResultCode } from \"@opentelemetry/core\";\nimport { ReadableSpan, SpanExporter } from \"@opentelemetry/sdk-trace-base\";\nimport { RestError } from \"@azure/core-rest-pipeline\";\nimport { ConnectionStringParser } from \"../utils/connectionStringParser\";\nimport { HttpSender, FileSystemPersist } from \"../platform\";\nimport {\n DEFAULT_EXPORTER_CONFIG,\n AzureExporterConfig,\n AzureExporterInternalConfig,\n} from \"../config\";\nimport { PersistentStorage, Sender } from \"../types\";\nimport { isRetriable, BreezeResponse } from \"../utils/breezeUtils\";\nimport { ENV_CONNECTION_STRING } from \"../Declarations/Constants\";\nimport { TelemetryItem as Envelope } from \"../generated\";\nimport { readableSpanToEnvelope } from \"../utils/spanUtils\";\n\n/**\n * Azure Monitor OpenTelemetry Trace Exporter.\n */\nexport class AzureMonitorTraceExporter implements SpanExporter {\n private readonly _persister: PersistentStorage;\n private readonly _sender: Sender;\n private _numConsecutiveRedirects: number;\n private _retryTimer: NodeJS.Timer | null;\n private readonly _options: AzureExporterInternalConfig;\n\n /**\n * Initializes a new instance of the AzureMonitorTraceExporter class.\n * @param AzureExporterConfig - Exporter configuration.\n */\n constructor(options: AzureExporterConfig = {}) {\n this._numConsecutiveRedirects = 0;\n const connectionString = options.connectionString || process.env[ENV_CONNECTION_STRING];\n this._options = {\n ...DEFAULT_EXPORTER_CONFIG,\n };\n this._options.apiVersion = options.apiVersion ?? this._options.apiVersion;\n this._options.aadTokenCredential = options.aadTokenCredential;\n\n if (connectionString) {\n const parsedConnectionString = ConnectionStringParser.parse(connectionString);\n this._options.instrumentationKey =\n parsedConnectionString.instrumentationkey ?? this._options.instrumentationKey;\n this._options.endpointUrl =\n parsedConnectionString.ingestionendpoint?.trim() ?? this._options.endpointUrl;\n }\n // Instrumentation key is required\n if (!this._options.instrumentationKey) {\n const message =\n \"No instrumentation key or connection string was provided to the Azure Monitor Exporter\";\n diag.error(message);\n throw new Error(message);\n }\n\n this._sender = new HttpSender(this._options);\n this._persister = new FileSystemPersist(this._options);\n this._retryTimer = null;\n diag.debug(\"AzureMonitorTraceExporter was successfully setup\");\n }\n\n private async _persist(envelopes: unknown[]): Promise<ExportResult> {\n try {\n const success = await this._persister.push(envelopes);\n return success\n ? { code: ExportResultCode.SUCCESS }\n : {\n code: ExportResultCode.FAILED,\n error: new Error(\"Failed to persist envelope in disk.\"),\n };\n } catch (ex) {\n return { code: ExportResultCode.FAILED, error: ex };\n }\n }\n\n private async exportEnvelopes(envelopes: Envelope[]): Promise<ExportResult> {\n diag.info(`Exporting ${envelopes.length} envelope(s)`);\n\n try {\n const { result, statusCode } = await this._sender.send(envelopes);\n this._numConsecutiveRedirects = 0;\n if (statusCode === 200) {\n // Success -- @todo: start retry timer\n if (!this._retryTimer) {\n this._retryTimer = setTimeout(() => {\n this._retryTimer = null;\n this._sendFirstPersistedFile();\n }, this._options.batchSendRetryIntervalMs);\n this._retryTimer.unref();\n }\n return { code: ExportResultCode.SUCCESS };\n } else if (statusCode && isRetriable(statusCode)) {\n // Failed -- persist failed data\n if (result) {\n diag.info(result);\n const breezeResponse = JSON.parse(result) as BreezeResponse;\n const filteredEnvelopes: Envelope[] = [];\n breezeResponse.errors.forEach((error) => {\n if (error.statusCode && isRetriable(error.statusCode)) {\n filteredEnvelopes.push(envelopes[error.index]);\n }\n });\n if (filteredEnvelopes.length > 0) {\n // calls resultCallback(ExportResult) based on result of persister.push\n return await this._persist(filteredEnvelopes);\n }\n // Failed -- not retriable\n return {\n code: ExportResultCode.FAILED,\n };\n } else {\n // calls resultCallback(ExportResult) based on result of persister.push\n return await this._persist(envelopes);\n }\n } else {\n // Failed -- not retriable\n return {\n code: ExportResultCode.FAILED,\n };\n }\n } catch (error) {\n const restError = error as RestError;\n if (\n restError.statusCode &&\n (restError.statusCode === 307 || // Temporary redirect\n restError.statusCode === 308)\n ) {\n // Permanent redirect\n this._numConsecutiveRedirects++;\n // To prevent circular redirects\n if (this._numConsecutiveRedirects < 10) {\n if (restError.response && restError.response.headers) {\n const location = restError.response.headers.get(\"location\");\n if (location) {\n // Update sender URL\n this._sender.handlePermanentRedirect(location);\n // Send to redirect endpoint as HTTPs library doesn't handle redirect automatically\n return this.exportEnvelopes(envelopes);\n }\n }\n } else {\n return { code: ExportResultCode.FAILED, error: new Error(\"Circular redirect\") };\n }\n } else if (restError.statusCode && isRetriable(restError.statusCode)) {\n return await this._persist(envelopes);\n }\n if (this._isNetworkError(restError)) {\n diag.error(\n \"Retrying due to transient client side error. Error message:\",\n restError.message\n );\n return await this._persist(envelopes);\n }\n\n diag.error(\n \"Envelopes could not be exported and are not retriable. Error message:\",\n restError.message\n );\n return { code: ExportResultCode.FAILED, error: restError };\n }\n }\n\n /**\n * Export OpenTelemetry spans.\n * @param spans - Spans to export.\n * @param resultCallback - Result callback.\n */\n async export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void\n ): Promise<void> {\n diag.info(`Exporting ${spans.length} span(s). Converting to envelopes...`);\n const envelopes = spans.map((span) =>\n readableSpanToEnvelope(span, this._options.instrumentationKey)\n );\n resultCallback(await this.exportEnvelopes(envelopes));\n }\n\n /**\n * Shutdown AzureMonitorTraceExporter.\n */\n async shutdown(): Promise<void> {\n diag.info(\"Azure Monitor Trace Exporter shutting down\");\n return this._sender.shutdown();\n }\n\n private async _sendFirstPersistedFile(): Promise<void> {\n try {\n const envelopes = (await this._persister.shift()) as Envelope[] | null;\n if (envelopes) {\n await this._sender.send(envelopes);\n }\n } catch (err) {\n diag.warn(`Failed to fetch persisted file`, err);\n }\n }\n\n private _isNetworkError(error: RestError): boolean {\n if (error && error.code && error.code === \"REQUEST_SEND_ERROR\") {\n return true;\n }\n return false;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/export/trace.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAgB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAC;AAGlD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEnF;;GAEG;AACH,MAAM,OAAO,yBAA0B,SAAQ,wBAAwB;IAMrE;;;OAGG;IACH,YAAY,UAAuC,EAAE;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QAVjB;;WAEG;QACK,gBAAW,GAAG,KAAK,CAAC;QAQ1B,IAAI,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACjE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CACV,KAAqB,EACrB,cAA8C;QAE9C,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,IAAI,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YACzD,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACvE,OAAO;SACR;QAED,IAAI,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,MAAM,sCAAsC,CAAC,CAAC;QAE3E,IAAI,SAAS,GAAe,EAAE,CAAC;QAC/B,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACrB,SAAS,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACvE,IAAI,kBAAkB,GAAG,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC/E,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE;gBACjC,SAAS,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC;aACvC;QACH,CAAC,CAAC,CAAC;QACH,cAAc,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;IAC1B,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { diag } from \"@opentelemetry/api\";\nimport { ExportResult, ExportResultCode } from \"@opentelemetry/core\";\nimport { ReadableSpan, SpanExporter } from \"@opentelemetry/sdk-trace-base\";\nimport { AzureMonitorBaseExporter } from \"./base\";\nimport { AzureMonitorExporterOptions } from \"../config\";\nimport { TelemetryItem as Envelope } from \"../generated\";\nimport { readableSpanToEnvelope, spanEventsToEnvelopes } from \"../utils/spanUtils\";\n\n/**\n * Azure Monitor OpenTelemetry Trace Exporter.\n */\nexport class AzureMonitorTraceExporter extends AzureMonitorBaseExporter implements SpanExporter {\n /**\n * Flag to determine if Exporter is shutdown.\n */\n private _isShutdown = false;\n\n /**\n * Initializes a new instance of the AzureMonitorTraceExporter class.\n * @param AzureExporterConfig - Exporter configuration.\n */\n constructor(options: AzureMonitorExporterOptions = {}) {\n super(options);\n diag.debug(\"AzureMonitorTraceExporter was successfully setup\");\n }\n\n /**\n * Export OpenTelemetry spans.\n * @param spans - Spans to export.\n * @param resultCallback - Result callback.\n */\n async export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void\n ): Promise<void> {\n if (this._isShutdown) {\n diag.info(\"Exporter shut down. Failed to export spans.\");\n setTimeout(() => resultCallback({ code: ExportResultCode.FAILED }), 0);\n return;\n }\n\n diag.info(`Exporting ${spans.length} span(s). Converting to envelopes...`);\n\n let envelopes: Envelope[] = [];\n spans.forEach((span) => {\n envelopes.push(readableSpanToEnvelope(span, this._instrumentationKey));\n let spanEventEnvelopes = spanEventsToEnvelopes(span, this._instrumentationKey);\n if (spanEventEnvelopes.length > 0) {\n envelopes.push(...spanEventEnvelopes);\n }\n });\n resultCallback(await this._exportEnvelopes(envelopes));\n }\n\n /**\n * Shutdown AzureMonitorTraceExporter.\n */\n async shutdown(): Promise<void> {\n this._isShutdown = true;\n diag.info(\"AzureMonitorTraceExporter shutting down\");\n return this._shutdown();\n }\n}\n"]}
|
|
@@ -6,16 +6,49 @@
|
|
|
6
6
|
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
7
7
|
*/
|
|
8
8
|
import * as coreClient from "@azure/core-client";
|
|
9
|
+
import * as coreRestPipeline from "@azure/core-rest-pipeline";
|
|
9
10
|
import * as Parameters from "./models/parameters";
|
|
10
11
|
import * as Mappers from "./models/mappers";
|
|
11
|
-
|
|
12
|
-
export class ApplicationInsightsClient extends ApplicationInsightsClientContext {
|
|
12
|
+
export class ApplicationInsightsClient extends coreClient.ServiceClient {
|
|
13
13
|
/**
|
|
14
14
|
* Initializes a new instance of the ApplicationInsightsClient class.
|
|
15
15
|
* @param options The parameter options
|
|
16
16
|
*/
|
|
17
17
|
constructor(options) {
|
|
18
|
-
|
|
18
|
+
var _a, _b;
|
|
19
|
+
// Initializing default values for options
|
|
20
|
+
if (!options) {
|
|
21
|
+
options = {};
|
|
22
|
+
}
|
|
23
|
+
const defaults = {
|
|
24
|
+
requestContentType: "application/json; charset=utf-8"
|
|
25
|
+
};
|
|
26
|
+
const packageDetails = `azsdk-js-monitor-opentelemetry-exporter/1.0.0-beta.9`;
|
|
27
|
+
const userAgentPrefix = options.userAgentOptions && options.userAgentOptions.userAgentPrefix
|
|
28
|
+
? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
|
|
29
|
+
: `${packageDetails}`;
|
|
30
|
+
const optionsWithDefaults = Object.assign(Object.assign(Object.assign({}, defaults), options), { userAgentOptions: {
|
|
31
|
+
userAgentPrefix
|
|
32
|
+
}, baseUri: (_b = (_a = options.endpoint) !== null && _a !== void 0 ? _a : options.baseUri) !== null && _b !== void 0 ? _b : "{Host}/v2.1" });
|
|
33
|
+
super(optionsWithDefaults);
|
|
34
|
+
if ((options === null || options === void 0 ? void 0 : options.pipeline) && options.pipeline.getOrderedPolicies().length > 0) {
|
|
35
|
+
const pipelinePolicies = options.pipeline.getOrderedPolicies();
|
|
36
|
+
const bearerTokenAuthenticationPolicyFound = pipelinePolicies.some((pipelinePolicy) => pipelinePolicy.name ===
|
|
37
|
+
coreRestPipeline.bearerTokenAuthenticationPolicyName);
|
|
38
|
+
if (!bearerTokenAuthenticationPolicyFound) {
|
|
39
|
+
this.pipeline.removePolicy({
|
|
40
|
+
name: coreRestPipeline.bearerTokenAuthenticationPolicyName
|
|
41
|
+
});
|
|
42
|
+
this.pipeline.addPolicy(coreRestPipeline.bearerTokenAuthenticationPolicy({
|
|
43
|
+
scopes: `${optionsWithDefaults.baseUri}/.default`,
|
|
44
|
+
challengeCallbacks: {
|
|
45
|
+
authorizeRequestOnChallenge: coreClient.authorizeRequestOnClaimChallenge
|
|
46
|
+
}
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Assigning values to Constant parameters
|
|
51
|
+
this.host = options.host || "https://dc.services.visualstudio.com";
|
|
19
52
|
}
|
|
20
53
|
/**
|
|
21
54
|
* This operation sends a sequence of telemetry events that will be monitored by Azure Monitor.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applicationInsightsClient.js","sourceRoot":"","sources":["../../../src/generated/applicationInsightsClient.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,UAAU,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"applicationInsightsClient.js","sourceRoot":"","sources":["../../../src/generated/applicationInsightsClient.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n *\n * Code generated by Microsoft (R) AutoRest Code Generator.\n * Changes may cause incorrect behavior and will be lost if the code is regenerated.\n */\n\nimport * as coreClient from \"@azure/core-client\";\nimport * as coreRestPipeline from \"@azure/core-rest-pipeline\";\nimport * as Parameters from \"./models/parameters\";\nimport * as Mappers from \"./models/mappers\";\nimport {\n ApplicationInsightsClientOptionalParams,\n TelemetryItem,\n TrackOptionalParams,\n TrackOperationResponse\n} from \"./models\";\n\nexport class ApplicationInsightsClient extends coreClient.ServiceClient {\n host: string;\n\n /**\n * Initializes a new instance of the ApplicationInsightsClient class.\n * @param options The parameter options\n */\n constructor(options?: ApplicationInsightsClientOptionalParams) {\n // Initializing default values for options\n if (!options) {\n options = {};\n }\n const defaults: ApplicationInsightsClientOptionalParams = {\n requestContentType: \"application/json; charset=utf-8\"\n };\n\n const packageDetails = `azsdk-js-monitor-opentelemetry-exporter/1.0.0-beta.9`;\n const userAgentPrefix =\n options.userAgentOptions && options.userAgentOptions.userAgentPrefix\n ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`\n : `${packageDetails}`;\n\n const optionsWithDefaults = {\n ...defaults,\n ...options,\n userAgentOptions: {\n userAgentPrefix\n },\n baseUri: options.endpoint ?? options.baseUri ?? \"{Host}/v2.1\"\n };\n super(optionsWithDefaults);\n\n if (options?.pipeline && options.pipeline.getOrderedPolicies().length > 0) {\n const pipelinePolicies: coreRestPipeline.PipelinePolicy[] = options.pipeline.getOrderedPolicies();\n const bearerTokenAuthenticationPolicyFound = pipelinePolicies.some(\n (pipelinePolicy) =>\n pipelinePolicy.name ===\n coreRestPipeline.bearerTokenAuthenticationPolicyName\n );\n if (!bearerTokenAuthenticationPolicyFound) {\n this.pipeline.removePolicy({\n name: coreRestPipeline.bearerTokenAuthenticationPolicyName\n });\n this.pipeline.addPolicy(\n coreRestPipeline.bearerTokenAuthenticationPolicy({\n scopes: `${optionsWithDefaults.baseUri}/.default`,\n challengeCallbacks: {\n authorizeRequestOnChallenge:\n coreClient.authorizeRequestOnClaimChallenge\n }\n })\n );\n }\n }\n\n // Assigning values to Constant parameters\n this.host = options.host || \"https://dc.services.visualstudio.com\";\n }\n\n /**\n * This operation sends a sequence of telemetry events that will be monitored by Azure Monitor.\n * @param body The list of telemetry events to track.\n * @param options The options parameters.\n */\n track(\n body: TelemetryItem[],\n options?: TrackOptionalParams\n ): Promise<TrackOperationResponse> {\n return this.sendOperationRequest({ body, options }, trackOperationSpec);\n }\n}\n// Operation Specifications\nconst serializer = coreClient.createSerializer(Mappers, /* isXml */ false);\n\nconst trackOperationSpec: coreClient.OperationSpec = {\n path: \"/track\",\n httpMethod: \"POST\",\n responses: {\n 200: {\n bodyMapper: Mappers.TrackResponse\n },\n 206: {\n bodyMapper: Mappers.TrackResponse\n },\n 400: {\n bodyMapper: Mappers.TrackResponse,\n isError: true\n },\n 402: {\n bodyMapper: Mappers.TrackResponse,\n isError: true\n },\n 429: {\n bodyMapper: Mappers.TrackResponse,\n isError: true\n },\n 500: {\n bodyMapper: Mappers.TrackResponse,\n isError: true\n },\n 503: {\n bodyMapper: Mappers.TrackResponse,\n isError: true\n }\n },\n requestBody: Parameters.body,\n urlParameters: [Parameters.host],\n headerParameters: [Parameters.contentType, Parameters.accept],\n mediaType: \"json\",\n serializer\n};\n"]}
|