@azure/monitor-opentelemetry-exporter 1.0.0-beta.7 → 1.0.0-beta.8
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/dist/index.js +416 -181
- package/dist-esm/src/config.js.map +1 -1
- package/dist-esm/src/export/base.js +172 -0
- package/dist-esm/src/export/base.js.map +1 -0
- package/dist-esm/src/export/metric.js +50 -0
- package/dist-esm/src/export/metric.js.map +1 -0
- package/dist-esm/src/export/trace.js +14 -146
- package/dist-esm/src/export/trace.js.map +1 -1
- package/dist-esm/src/index.js +2 -0
- package/dist-esm/src/index.js.map +1 -1
- 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.map +1 -1
- package/dist-esm/src/platform/nodejs/persist/fileSystemPersist.js.map +1 -1
- package/dist-esm/src/utils/constants/applicationinsights.js +1 -1
- package/dist-esm/src/utils/constants/applicationinsights.js.map +1 -1
- package/dist-esm/src/utils/metricUtils.js +53 -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 +112 -43
- package/dist-esm/src/utils/spanUtils.js.map +1 -1
- package/package.json +18 -17
- package/types/monitor-opentelemetry-exporter.d.ts +104 -6
- package/CHANGELOG.md +0 -51
package/dist/index.js
CHANGED
|
@@ -4,15 +4,16 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var api = require('@opentelemetry/api');
|
|
6
6
|
var core = require('@opentelemetry/core');
|
|
7
|
-
var os = require('os');
|
|
8
7
|
var url = require('url');
|
|
9
|
-
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
10
8
|
var coreRestPipeline = require('@azure/core-rest-pipeline');
|
|
11
9
|
var coreClient = require('@azure/core-client');
|
|
12
10
|
var fs = require('fs');
|
|
11
|
+
var os = require('os');
|
|
13
12
|
var path = require('path');
|
|
14
13
|
var child_process = require('child_process');
|
|
15
14
|
var util = require('util');
|
|
15
|
+
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
16
|
+
var sdkMetricsBase = require('@opentelemetry/sdk-metrics-base');
|
|
16
17
|
|
|
17
18
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
18
19
|
|
|
@@ -34,11 +35,11 @@ function _interopNamespace(e) {
|
|
|
34
35
|
return Object.freeze(n);
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
38
|
-
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
39
38
|
var url__default = /*#__PURE__*/_interopDefaultLegacy(url);
|
|
40
39
|
var coreClient__namespace = /*#__PURE__*/_interopNamespace(coreClient);
|
|
41
40
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
41
|
+
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
42
|
+
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
42
43
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
43
44
|
var child_process__namespace = /*#__PURE__*/_interopNamespace(child_process);
|
|
44
45
|
|
|
@@ -1745,7 +1746,7 @@ const TIME_SINCE_ENQUEUED = "timeSinceEnqueued";
|
|
|
1745
1746
|
* AzureMonitorTraceExporter version.
|
|
1746
1747
|
* @internal
|
|
1747
1748
|
*/
|
|
1748
|
-
const packageVersion = "1.0.0-beta.
|
|
1749
|
+
const packageVersion = "1.0.0-beta.8";
|
|
1749
1750
|
var DependencyTypes;
|
|
1750
1751
|
(function (DependencyTypes) {
|
|
1751
1752
|
DependencyTypes["InProc"] = "InProc";
|
|
@@ -1828,6 +1829,200 @@ function msToTimeSpan(ms) {
|
|
|
1828
1829
|
return `${daysText + hour}:${min}:${sec}`;
|
|
1829
1830
|
}
|
|
1830
1831
|
|
|
1832
|
+
// Copyright (c) Microsoft Corporation.
|
|
1833
|
+
/**
|
|
1834
|
+
* Azure Monitor OpenTelemetry Trace Exporter.
|
|
1835
|
+
*/
|
|
1836
|
+
class AzureMonitorBaseExporter {
|
|
1837
|
+
/**
|
|
1838
|
+
* Initializes a new instance of the AzureMonitorBaseExporter class.
|
|
1839
|
+
* @param AzureExporterConfig - Exporter configuration.
|
|
1840
|
+
*/
|
|
1841
|
+
constructor(options = {}) {
|
|
1842
|
+
var _a, _b, _c, _d;
|
|
1843
|
+
this._numConsecutiveRedirects = 0;
|
|
1844
|
+
const connectionString = options.connectionString || process.env[ENV_CONNECTION_STRING];
|
|
1845
|
+
this._options = Object.assign({}, DEFAULT_EXPORTER_CONFIG);
|
|
1846
|
+
this._options.apiVersion = (_a = options.apiVersion) !== null && _a !== void 0 ? _a : this._options.apiVersion;
|
|
1847
|
+
this._options.aadTokenCredential = options.aadTokenCredential;
|
|
1848
|
+
if (connectionString) {
|
|
1849
|
+
const parsedConnectionString = ConnectionStringParser.parse(connectionString);
|
|
1850
|
+
this._options.instrumentationKey =
|
|
1851
|
+
(_b = parsedConnectionString.instrumentationkey) !== null && _b !== void 0 ? _b : this._options.instrumentationKey;
|
|
1852
|
+
this._options.endpointUrl =
|
|
1853
|
+
(_d = (_c = parsedConnectionString.ingestionendpoint) === null || _c === void 0 ? void 0 : _c.trim()) !== null && _d !== void 0 ? _d : this._options.endpointUrl;
|
|
1854
|
+
}
|
|
1855
|
+
// Instrumentation key is required
|
|
1856
|
+
if (!this._options.instrumentationKey) {
|
|
1857
|
+
const message = "No instrumentation key or connection string was provided to the Azure Monitor Exporter";
|
|
1858
|
+
api.diag.error(message);
|
|
1859
|
+
throw new Error(message);
|
|
1860
|
+
}
|
|
1861
|
+
this._instrumentationKey = this._options.instrumentationKey;
|
|
1862
|
+
this._sender = new HttpSender(this._options);
|
|
1863
|
+
this._persister = new FileSystemPersist(this._options);
|
|
1864
|
+
this._retryTimer = null;
|
|
1865
|
+
api.diag.debug("AzureMonitorTraceExporter was successfully setup");
|
|
1866
|
+
}
|
|
1867
|
+
/**
|
|
1868
|
+
* Persist envelopes to disk
|
|
1869
|
+
*/
|
|
1870
|
+
async _persist(envelopes) {
|
|
1871
|
+
try {
|
|
1872
|
+
const success = await this._persister.push(envelopes);
|
|
1873
|
+
return success
|
|
1874
|
+
? { code: core.ExportResultCode.SUCCESS }
|
|
1875
|
+
: {
|
|
1876
|
+
code: core.ExportResultCode.FAILED,
|
|
1877
|
+
error: new Error("Failed to persist envelope in disk."),
|
|
1878
|
+
};
|
|
1879
|
+
}
|
|
1880
|
+
catch (ex) {
|
|
1881
|
+
return { code: core.ExportResultCode.FAILED, error: ex };
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
/**
|
|
1885
|
+
* Shutdown exporter
|
|
1886
|
+
*/
|
|
1887
|
+
async _shutdown() {
|
|
1888
|
+
return this._sender.shutdown();
|
|
1889
|
+
}
|
|
1890
|
+
/**
|
|
1891
|
+
* Export envelopes
|
|
1892
|
+
*/
|
|
1893
|
+
async _exportEnvelopes(envelopes) {
|
|
1894
|
+
api.diag.info(`Exporting ${envelopes.length} envelope(s)`);
|
|
1895
|
+
try {
|
|
1896
|
+
const { result, statusCode } = await this._sender.send(envelopes);
|
|
1897
|
+
this._numConsecutiveRedirects = 0;
|
|
1898
|
+
if (statusCode === 200) {
|
|
1899
|
+
// Success -- @todo: start retry timer
|
|
1900
|
+
if (!this._retryTimer) {
|
|
1901
|
+
this._retryTimer = setTimeout(() => {
|
|
1902
|
+
this._retryTimer = null;
|
|
1903
|
+
this._sendFirstPersistedFile();
|
|
1904
|
+
}, this._options.batchSendRetryIntervalMs);
|
|
1905
|
+
this._retryTimer.unref();
|
|
1906
|
+
}
|
|
1907
|
+
return { code: core.ExportResultCode.SUCCESS };
|
|
1908
|
+
}
|
|
1909
|
+
else if (statusCode && isRetriable(statusCode)) {
|
|
1910
|
+
// Failed -- persist failed data
|
|
1911
|
+
if (result) {
|
|
1912
|
+
api.diag.info(result);
|
|
1913
|
+
const breezeResponse = JSON.parse(result);
|
|
1914
|
+
const filteredEnvelopes = [];
|
|
1915
|
+
if (breezeResponse.errors) {
|
|
1916
|
+
breezeResponse.errors.forEach((error) => {
|
|
1917
|
+
if (error.statusCode && isRetriable(error.statusCode)) {
|
|
1918
|
+
filteredEnvelopes.push(envelopes[error.index]);
|
|
1919
|
+
}
|
|
1920
|
+
});
|
|
1921
|
+
}
|
|
1922
|
+
if (filteredEnvelopes.length > 0) {
|
|
1923
|
+
// calls resultCallback(ExportResult) based on result of persister.push
|
|
1924
|
+
return await this._persist(filteredEnvelopes);
|
|
1925
|
+
}
|
|
1926
|
+
// Failed -- not retriable
|
|
1927
|
+
return {
|
|
1928
|
+
code: core.ExportResultCode.FAILED,
|
|
1929
|
+
};
|
|
1930
|
+
}
|
|
1931
|
+
else {
|
|
1932
|
+
// calls resultCallback(ExportResult) based on result of persister.push
|
|
1933
|
+
return await this._persist(envelopes);
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
else {
|
|
1937
|
+
// Failed -- not retriable
|
|
1938
|
+
return {
|
|
1939
|
+
code: core.ExportResultCode.FAILED,
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
catch (error) {
|
|
1944
|
+
const restError = error;
|
|
1945
|
+
if (restError.statusCode &&
|
|
1946
|
+
(restError.statusCode === 307 || // Temporary redirect
|
|
1947
|
+
restError.statusCode === 308)) {
|
|
1948
|
+
// Permanent redirect
|
|
1949
|
+
this._numConsecutiveRedirects++;
|
|
1950
|
+
// To prevent circular redirects
|
|
1951
|
+
if (this._numConsecutiveRedirects < 10) {
|
|
1952
|
+
if (restError.response && restError.response.headers) {
|
|
1953
|
+
const location = restError.response.headers.get("location");
|
|
1954
|
+
if (location) {
|
|
1955
|
+
// Update sender URL
|
|
1956
|
+
this._sender.handlePermanentRedirect(location);
|
|
1957
|
+
// Send to redirect endpoint as HTTPs library doesn't handle redirect automatically
|
|
1958
|
+
return this._exportEnvelopes(envelopes);
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
else {
|
|
1963
|
+
return { code: core.ExportResultCode.FAILED, error: new Error("Circular redirect") };
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
else if (restError.statusCode && isRetriable(restError.statusCode)) {
|
|
1967
|
+
return await this._persist(envelopes);
|
|
1968
|
+
}
|
|
1969
|
+
if (this._isNetworkError(restError)) {
|
|
1970
|
+
api.diag.error("Retrying due to transient client side error. Error message:", restError.message);
|
|
1971
|
+
return await this._persist(envelopes);
|
|
1972
|
+
}
|
|
1973
|
+
api.diag.error("Envelopes could not be exported and are not retriable. Error message:", restError.message);
|
|
1974
|
+
return { code: core.ExportResultCode.FAILED, error: restError };
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
async _sendFirstPersistedFile() {
|
|
1978
|
+
try {
|
|
1979
|
+
const envelopes = (await this._persister.shift());
|
|
1980
|
+
if (envelopes) {
|
|
1981
|
+
await this._sender.send(envelopes);
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
catch (err) {
|
|
1985
|
+
api.diag.warn(`Failed to fetch persisted file`, err);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
_isNetworkError(error) {
|
|
1989
|
+
if (error && error.code && error.code === "REQUEST_SEND_ERROR") {
|
|
1990
|
+
return true;
|
|
1991
|
+
}
|
|
1992
|
+
return false;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
// Copyright (c) Microsoft Corporation.
|
|
1997
|
+
function createTagsFromResource(resource) {
|
|
1998
|
+
const context = getInstance();
|
|
1999
|
+
const tags = Object.assign({}, context.tags);
|
|
2000
|
+
if (resource && resource.attributes) {
|
|
2001
|
+
const serviceName = resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_NAME];
|
|
2002
|
+
const serviceNamespace = resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_NAMESPACE];
|
|
2003
|
+
if (serviceName) {
|
|
2004
|
+
if (serviceNamespace) {
|
|
2005
|
+
tags[KnownContextTagKeys.AiCloudRole] = `${serviceNamespace}.${serviceName}`;
|
|
2006
|
+
}
|
|
2007
|
+
else {
|
|
2008
|
+
tags[KnownContextTagKeys.AiCloudRole] = String(serviceName);
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
const serviceInstanceId = resource.attributes[semanticConventions.SemanticResourceAttributes.SERVICE_INSTANCE_ID];
|
|
2012
|
+
if (serviceInstanceId) {
|
|
2013
|
+
tags[KnownContextTagKeys.AiCloudRoleInstance] = String(serviceInstanceId);
|
|
2014
|
+
}
|
|
2015
|
+
else {
|
|
2016
|
+
tags[KnownContextTagKeys.AiCloudRoleInstance] = os__default["default"] && os__default["default"].hostname();
|
|
2017
|
+
}
|
|
2018
|
+
const endUserId = resource.attributes[semanticConventions.SemanticAttributes.ENDUSER_ID];
|
|
2019
|
+
if (endUserId) {
|
|
2020
|
+
tags[KnownContextTagKeys.AiUserId] = String(endUserId);
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
return tags;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
1831
2026
|
// Copyright (c) Microsoft Corporation.
|
|
1832
2027
|
// Licensed under the MIT license.
|
|
1833
2028
|
/**
|
|
@@ -1893,36 +2088,21 @@ const parseEventHubSpan = (span, baseData) => {
|
|
|
1893
2088
|
};
|
|
1894
2089
|
|
|
1895
2090
|
// Copyright (c) Microsoft Corporation.
|
|
1896
|
-
function
|
|
1897
|
-
const
|
|
1898
|
-
const tags = Object.assign({}, context.tags);
|
|
2091
|
+
function createGenericTagsFromSpan(span) {
|
|
2092
|
+
const tags = createTagsFromResource(span.resource);
|
|
1899
2093
|
tags[KnownContextTagKeys.AiOperationId] = span.spanContext().traceId;
|
|
1900
2094
|
if (span.parentSpanId) {
|
|
1901
2095
|
tags[KnownContextTagKeys.AiOperationParentId] = span.parentSpanId;
|
|
1902
2096
|
}
|
|
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
|
-
}
|
|
2097
|
+
const httpUserAgent = span.attributes[semanticConventions.SemanticAttributes.HTTP_USER_AGENT];
|
|
2098
|
+
if (httpUserAgent) {
|
|
2099
|
+
// TODO: Not exposed in Swagger, need to update def
|
|
2100
|
+
tags["ai.user.userAgent"] = String(httpUserAgent);
|
|
1925
2101
|
}
|
|
2102
|
+
return tags;
|
|
2103
|
+
}
|
|
2104
|
+
function createTagsFromSpan(span) {
|
|
2105
|
+
const tags = createGenericTagsFromSpan(span);
|
|
1926
2106
|
if (span.kind === api.SpanKind.SERVER) {
|
|
1927
2107
|
const httpMethod = span.attributes[semanticConventions.SemanticAttributes.HTTP_METHOD];
|
|
1928
2108
|
const httpClientIp = span.attributes[semanticConventions.SemanticAttributes.HTTP_CLIENT_IP];
|
|
@@ -1956,25 +2136,33 @@ function createTagsFromSpan(span) {
|
|
|
1956
2136
|
}
|
|
1957
2137
|
}
|
|
1958
2138
|
// 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
2139
|
return tags;
|
|
1965
2140
|
}
|
|
1966
|
-
function
|
|
2141
|
+
function createPropertiesFromSpanAttributes(attributes) {
|
|
1967
2142
|
const properties = {};
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
2143
|
+
if (attributes) {
|
|
2144
|
+
for (const key of Object.keys(attributes)) {
|
|
2145
|
+
if (!(key.startsWith("http.") ||
|
|
2146
|
+
key.startsWith("rpc.") ||
|
|
2147
|
+
key.startsWith("db.") ||
|
|
2148
|
+
key.startsWith("peer.") ||
|
|
2149
|
+
key.startsWith("message.") ||
|
|
2150
|
+
key.startsWith("messaging.") ||
|
|
2151
|
+
key.startsWith("enduser.") ||
|
|
2152
|
+
key.startsWith("net.") ||
|
|
2153
|
+
key.startsWith("exception.") ||
|
|
2154
|
+
key.startsWith("thread.") ||
|
|
2155
|
+
key.startsWith("faas.") ||
|
|
2156
|
+
key.startsWith("code."))) {
|
|
2157
|
+
properties[key] = attributes[key];
|
|
2158
|
+
}
|
|
1976
2159
|
}
|
|
1977
2160
|
}
|
|
2161
|
+
return properties;
|
|
2162
|
+
}
|
|
2163
|
+
function createPropertiesFromSpan(span) {
|
|
2164
|
+
const properties = createPropertiesFromSpanAttributes(span.attributes);
|
|
2165
|
+
const measurements = {};
|
|
1978
2166
|
const links = span.links.map((link) => ({
|
|
1979
2167
|
operation_Id: link.context.traceId,
|
|
1980
2168
|
id: link.context.spanId,
|
|
@@ -2103,7 +2291,7 @@ function createDependencyData(span) {
|
|
|
2103
2291
|
}
|
|
2104
2292
|
}
|
|
2105
2293
|
}
|
|
2106
|
-
catch (
|
|
2294
|
+
catch (ex) { }
|
|
2107
2295
|
remoteDependencyData.target = `${target}`;
|
|
2108
2296
|
}
|
|
2109
2297
|
}
|
|
@@ -2241,172 +2429,219 @@ function readableSpanToEnvelope(span, ikey) {
|
|
|
2241
2429
|
},
|
|
2242
2430
|
};
|
|
2243
2431
|
}
|
|
2432
|
+
/**
|
|
2433
|
+
* Span Events to Azure envelopes parsing.
|
|
2434
|
+
* @internal
|
|
2435
|
+
*/
|
|
2436
|
+
function spanEventsToEnvelopes(span, ikey) {
|
|
2437
|
+
let envelopes = [];
|
|
2438
|
+
if (span.events) {
|
|
2439
|
+
span.events.forEach((event) => {
|
|
2440
|
+
let baseType;
|
|
2441
|
+
const sampleRate = 100;
|
|
2442
|
+
let time = new Date(core.hrTimeToMilliseconds(event.time));
|
|
2443
|
+
let name = "";
|
|
2444
|
+
let baseData;
|
|
2445
|
+
const properties = createPropertiesFromSpanAttributes(event.attributes);
|
|
2446
|
+
const tags = createGenericTagsFromSpan(span);
|
|
2447
|
+
if (event.name == "exception") {
|
|
2448
|
+
name = "Microsoft.ApplicationInsights.Exception";
|
|
2449
|
+
baseType = "ExceptionData";
|
|
2450
|
+
let typeName = "";
|
|
2451
|
+
let message = "Exception";
|
|
2452
|
+
let stack = "";
|
|
2453
|
+
let hasFullStack = false;
|
|
2454
|
+
if (event.attributes) {
|
|
2455
|
+
typeName = String(event.attributes[semanticConventions.SemanticAttributes.EXCEPTION_TYPE]);
|
|
2456
|
+
stack = String(event.attributes[semanticConventions.SemanticAttributes.EXCEPTION_STACKTRACE]);
|
|
2457
|
+
if (stack) {
|
|
2458
|
+
hasFullStack = true;
|
|
2459
|
+
}
|
|
2460
|
+
let exceptionMsg = event.attributes[semanticConventions.SemanticAttributes.EXCEPTION_MESSAGE];
|
|
2461
|
+
if (exceptionMsg) {
|
|
2462
|
+
message = String(exceptionMsg);
|
|
2463
|
+
}
|
|
2464
|
+
let escaped = event.attributes[semanticConventions.SemanticAttributes.EXCEPTION_ESCAPED];
|
|
2465
|
+
if (escaped != undefined) {
|
|
2466
|
+
properties[semanticConventions.SemanticAttributes.EXCEPTION_ESCAPED] = String(escaped);
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
let exceptionDetails = {
|
|
2470
|
+
typeName: typeName,
|
|
2471
|
+
message: message,
|
|
2472
|
+
stack: stack,
|
|
2473
|
+
hasFullStack: hasFullStack,
|
|
2474
|
+
};
|
|
2475
|
+
let exceptionData = {
|
|
2476
|
+
exceptions: [exceptionDetails],
|
|
2477
|
+
version: 2,
|
|
2478
|
+
properties: properties,
|
|
2479
|
+
};
|
|
2480
|
+
baseData = exceptionData;
|
|
2481
|
+
}
|
|
2482
|
+
else {
|
|
2483
|
+
name = "Microsoft.ApplicationInsights.Message";
|
|
2484
|
+
baseType = "MessageData";
|
|
2485
|
+
let messageData = {
|
|
2486
|
+
message: event.name,
|
|
2487
|
+
version: 2,
|
|
2488
|
+
properties: properties,
|
|
2489
|
+
};
|
|
2490
|
+
baseData = messageData;
|
|
2491
|
+
}
|
|
2492
|
+
let env = {
|
|
2493
|
+
name: name,
|
|
2494
|
+
time: time,
|
|
2495
|
+
instrumentationKey: ikey,
|
|
2496
|
+
version: 1,
|
|
2497
|
+
sampleRate: sampleRate,
|
|
2498
|
+
data: {
|
|
2499
|
+
baseType: baseType,
|
|
2500
|
+
baseData: baseData,
|
|
2501
|
+
},
|
|
2502
|
+
tags: tags,
|
|
2503
|
+
};
|
|
2504
|
+
envelopes.push(env);
|
|
2505
|
+
});
|
|
2506
|
+
}
|
|
2507
|
+
return envelopes;
|
|
2508
|
+
}
|
|
2244
2509
|
|
|
2245
2510
|
// Copyright (c) Microsoft Corporation.
|
|
2246
2511
|
/**
|
|
2247
2512
|
* Azure Monitor OpenTelemetry Trace Exporter.
|
|
2248
2513
|
*/
|
|
2249
|
-
class AzureMonitorTraceExporter {
|
|
2514
|
+
class AzureMonitorTraceExporter extends AzureMonitorBaseExporter {
|
|
2250
2515
|
/**
|
|
2251
2516
|
* Initializes a new instance of the AzureMonitorTraceExporter class.
|
|
2252
2517
|
* @param AzureExporterConfig - Exporter configuration.
|
|
2253
2518
|
*/
|
|
2254
2519
|
constructor(options = {}) {
|
|
2255
|
-
|
|
2256
|
-
this._numConsecutiveRedirects = 0;
|
|
2257
|
-
const connectionString = options.connectionString || process.env[ENV_CONNECTION_STRING];
|
|
2258
|
-
this._options = Object.assign({}, DEFAULT_EXPORTER_CONFIG);
|
|
2259
|
-
this._options.apiVersion = (_a = options.apiVersion) !== null && _a !== void 0 ? _a : this._options.apiVersion;
|
|
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;
|
|
2520
|
+
super(options);
|
|
2277
2521
|
api.diag.debug("AzureMonitorTraceExporter was successfully setup");
|
|
2278
2522
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
}
|
|
2293
|
-
async exportEnvelopes(envelopes) {
|
|
2294
|
-
api.diag.info(`Exporting ${envelopes.length} envelope(s)`);
|
|
2295
|
-
try {
|
|
2296
|
-
const { result, statusCode } = await this._sender.send(envelopes);
|
|
2297
|
-
this._numConsecutiveRedirects = 0;
|
|
2298
|
-
if (statusCode === 200) {
|
|
2299
|
-
// Success -- @todo: start retry timer
|
|
2300
|
-
if (!this._retryTimer) {
|
|
2301
|
-
this._retryTimer = setTimeout(() => {
|
|
2302
|
-
this._retryTimer = null;
|
|
2303
|
-
this._sendFirstPersistedFile();
|
|
2304
|
-
}, this._options.batchSendRetryIntervalMs);
|
|
2305
|
-
this._retryTimer.unref();
|
|
2306
|
-
}
|
|
2307
|
-
return { code: core.ExportResultCode.SUCCESS };
|
|
2308
|
-
}
|
|
2309
|
-
else if (statusCode && isRetriable(statusCode)) {
|
|
2310
|
-
// Failed -- persist failed data
|
|
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
|
-
}
|
|
2523
|
+
/**
|
|
2524
|
+
* Export OpenTelemetry spans.
|
|
2525
|
+
* @param spans - Spans to export.
|
|
2526
|
+
* @param resultCallback - Result callback.
|
|
2527
|
+
*/
|
|
2528
|
+
async export(spans, resultCallback) {
|
|
2529
|
+
api.diag.info(`Exporting ${spans.length} span(s). Converting to envelopes...`);
|
|
2530
|
+
let envelopes = [];
|
|
2531
|
+
spans.forEach((span) => {
|
|
2532
|
+
envelopes.push(readableSpanToEnvelope(span, this._instrumentationKey));
|
|
2533
|
+
let spanEventEnvelopes = spanEventsToEnvelopes(span, this._instrumentationKey);
|
|
2534
|
+
if (spanEventEnvelopes.length > 0) {
|
|
2535
|
+
envelopes.push(...spanEventEnvelopes);
|
|
2333
2536
|
}
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2537
|
+
});
|
|
2538
|
+
resultCallback(await this._exportEnvelopes(envelopes));
|
|
2539
|
+
}
|
|
2540
|
+
/**
|
|
2541
|
+
* Shutdown AzureMonitorTraceExporter.
|
|
2542
|
+
*/
|
|
2543
|
+
async shutdown() {
|
|
2544
|
+
api.diag.info("Azure Monitor Trace Exporter shutting down");
|
|
2545
|
+
return this._shutdown();
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
// Copyright (c) Microsoft Corporation.
|
|
2550
|
+
/**
|
|
2551
|
+
* Metric to Azure envelope parsing.
|
|
2552
|
+
* @internal
|
|
2553
|
+
*/
|
|
2554
|
+
function resourceMetricsToEnvelope(metrics, ikey) {
|
|
2555
|
+
let envelopes = [];
|
|
2556
|
+
const time = new Date();
|
|
2557
|
+
const instrumentationKey = ikey;
|
|
2558
|
+
const tags = createTagsFromResource(metrics.resource);
|
|
2559
|
+
metrics.scopeMetrics.forEach((scopeMetric) => {
|
|
2560
|
+
let baseData = {
|
|
2561
|
+
metrics: [],
|
|
2562
|
+
version: 2,
|
|
2563
|
+
};
|
|
2564
|
+
scopeMetric.metrics.forEach((metric) => {
|
|
2565
|
+
metric.dataPoints.forEach((dataPoint) => {
|
|
2566
|
+
var metricDataPoint = {
|
|
2567
|
+
name: metric.descriptor.name,
|
|
2568
|
+
value: 0,
|
|
2569
|
+
dataPointType: "Aggregation",
|
|
2338
2570
|
};
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
const restError = error;
|
|
2343
|
-
if (restError.statusCode &&
|
|
2344
|
-
(restError.statusCode === 307 || // Temporary redirect
|
|
2345
|
-
restError.statusCode === 308)) {
|
|
2346
|
-
// Permanent redirect
|
|
2347
|
-
this._numConsecutiveRedirects++;
|
|
2348
|
-
// To prevent circular redirects
|
|
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
|
-
}
|
|
2571
|
+
if (metric.dataPointType == sdkMetricsBase.DataPointType.SINGULAR) {
|
|
2572
|
+
metricDataPoint.value = dataPoint.value;
|
|
2573
|
+
metricDataPoint.count = 1;
|
|
2359
2574
|
}
|
|
2360
2575
|
else {
|
|
2361
|
-
|
|
2576
|
+
metricDataPoint.value = dataPoint.value.sum;
|
|
2577
|
+
metricDataPoint.count = dataPoint.value.count;
|
|
2362
2578
|
}
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2579
|
+
baseData.metrics.push(metricDataPoint);
|
|
2580
|
+
});
|
|
2581
|
+
});
|
|
2582
|
+
let envelope = {
|
|
2583
|
+
name: "Microsoft.ApplicationInsights.Metric",
|
|
2584
|
+
time: time,
|
|
2585
|
+
sampleRate: 100,
|
|
2586
|
+
instrumentationKey: instrumentationKey,
|
|
2587
|
+
tags: tags,
|
|
2588
|
+
version: 1,
|
|
2589
|
+
data: {
|
|
2590
|
+
baseType: "MetricData",
|
|
2591
|
+
baseData: Object.assign({}, baseData),
|
|
2592
|
+
},
|
|
2593
|
+
};
|
|
2594
|
+
envelopes.push(envelope);
|
|
2595
|
+
});
|
|
2596
|
+
return envelopes;
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
// Copyright (c) Microsoft Corporation.
|
|
2600
|
+
/**
|
|
2601
|
+
* Azure Monitor OpenTelemetry Metric Exporter.
|
|
2602
|
+
*/
|
|
2603
|
+
class AzureMonitorMetricExporter extends AzureMonitorBaseExporter {
|
|
2604
|
+
/**
|
|
2605
|
+
* Initializes a new instance of the AzureMonitorMetricExporter class.
|
|
2606
|
+
* @param AzureExporterConfig - Exporter configuration.
|
|
2607
|
+
*/
|
|
2608
|
+
constructor(options = {}) {
|
|
2609
|
+
super(options);
|
|
2610
|
+
api.diag.debug("AzureMonitorMetricExporter was successfully setup");
|
|
2374
2611
|
}
|
|
2375
2612
|
/**
|
|
2376
|
-
* Export OpenTelemetry
|
|
2377
|
-
* @param
|
|
2613
|
+
* Export OpenTelemetry resource metrics.
|
|
2614
|
+
* @param metrics - Resource metrics to export.
|
|
2378
2615
|
* @param resultCallback - Result callback.
|
|
2379
2616
|
*/
|
|
2380
|
-
async export(
|
|
2381
|
-
api.diag.info(`Exporting ${
|
|
2382
|
-
|
|
2383
|
-
resultCallback(await this.
|
|
2617
|
+
async export(metrics, resultCallback) {
|
|
2618
|
+
api.diag.info(`Exporting ${metrics.scopeMetrics.length} metrics(s). Converting to envelopes...`);
|
|
2619
|
+
let envelopes = resourceMetricsToEnvelope(metrics, this._instrumentationKey);
|
|
2620
|
+
resultCallback(await this._exportEnvelopes(envelopes));
|
|
2384
2621
|
}
|
|
2385
2622
|
/**
|
|
2386
|
-
* Shutdown
|
|
2623
|
+
* Shutdown AzureMonitorMetricExporter.
|
|
2387
2624
|
*/
|
|
2388
2625
|
async shutdown() {
|
|
2389
2626
|
api.diag.info("Azure Monitor Trace Exporter shutting down");
|
|
2390
|
-
return this.
|
|
2627
|
+
return this._shutdown();
|
|
2391
2628
|
}
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
catch (err) {
|
|
2400
|
-
api.diag.warn(`Failed to fetch persisted file`, err);
|
|
2401
|
-
}
|
|
2629
|
+
/**
|
|
2630
|
+
* Select aggregation temporality
|
|
2631
|
+
*/
|
|
2632
|
+
selectAggregationTemporality() {
|
|
2633
|
+
return sdkMetricsBase.AggregationTemporality.CUMULATIVE;
|
|
2402
2634
|
}
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2635
|
+
/**
|
|
2636
|
+
* Force flush
|
|
2637
|
+
*/
|
|
2638
|
+
async forceFlush() {
|
|
2639
|
+
// TODO: https://github.com/open-telemetry/opentelemetry-js/issues/3060
|
|
2640
|
+
throw new Error("Method not implemented.");
|
|
2408
2641
|
}
|
|
2409
2642
|
}
|
|
2410
2643
|
|
|
2644
|
+
exports.AzureMonitorBaseExporter = AzureMonitorBaseExporter;
|
|
2645
|
+
exports.AzureMonitorMetricExporter = AzureMonitorMetricExporter;
|
|
2411
2646
|
exports.AzureMonitorTraceExporter = AzureMonitorTraceExporter;
|
|
2412
2647
|
//# sourceMappingURL=index.js.map
|