@azure/monitor-opentelemetry-exporter 1.0.0-beta.21 → 1.0.0-beta.23
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 +2 -0
- package/dist/index.js +174 -110
- package/dist-esm/src/export/statsbeat/longIntervalStatsbeatMetrics.js +16 -14
- package/dist-esm/src/export/statsbeat/longIntervalStatsbeatMetrics.js.map +1 -1
- package/dist-esm/src/generated/applicationInsightsClient.js +1 -1
- package/dist-esm/src/generated/applicationInsightsClient.js.map +1 -1
- package/dist-esm/src/types.js +26 -1
- package/dist-esm/src/types.js.map +1 -1
- package/dist-esm/src/utils/common.js +44 -39
- package/dist-esm/src/utils/common.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/eventhub.js +2 -2
- package/dist-esm/src/utils/eventhub.js.map +1 -1
- package/dist-esm/src/utils/logUtils.js +22 -13
- package/dist-esm/src/utils/logUtils.js.map +1 -1
- package/dist-esm/src/utils/metricUtils.js +14 -1
- package/dist-esm/src/utils/metricUtils.js.map +1 -1
- package/dist-esm/src/utils/spanUtils.js +50 -43
- package/dist-esm/src/utils/spanUtils.js.map +1 -1
- package/package.json +23 -25
package/README.md
CHANGED
|
@@ -115,6 +115,8 @@ You can enable sampling to limit the amount of telemetry records you receive. In
|
|
|
115
115
|
const { ApplicationInsightsSampler } = require("@azure/monitor-opentelemetry-exporter");
|
|
116
116
|
const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base");
|
|
117
117
|
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
|
|
118
|
+
const { Resource } = require("@opentelemetry/resources");
|
|
119
|
+
const { SemanticResourceAttributes } = require("@opentelemetry/semantic-conventions");
|
|
118
120
|
|
|
119
121
|
// Sampler expects a sample rate of between 0 and 1 inclusive
|
|
120
122
|
// A rate of 0.75 means approximately 75 % of your traces will be sent
|
package/dist/index.js
CHANGED
|
@@ -60,7 +60,7 @@ const TIME_SINCE_ENQUEUED = "timeSinceEnqueued";
|
|
|
60
60
|
* AzureMonitorTraceExporter version.
|
|
61
61
|
* @internal
|
|
62
62
|
*/
|
|
63
|
-
const packageVersion = "1.0.0-beta.
|
|
63
|
+
const packageVersion = "1.0.0-beta.23";
|
|
64
64
|
var DependencyTypes;
|
|
65
65
|
(function (DependencyTypes) {
|
|
66
66
|
DependencyTypes["InProc"] = "InProc";
|
|
@@ -1814,7 +1814,7 @@ class ApplicationInsightsClient extends coreClient__namespace.ServiceClient {
|
|
|
1814
1814
|
const defaults = {
|
|
1815
1815
|
requestContentType: "application/json; charset=utf-8",
|
|
1816
1816
|
};
|
|
1817
|
-
const packageDetails = `azsdk-js-monitor-opentelemetry-exporter/1.0.0-beta.
|
|
1817
|
+
const packageDetails = `azsdk-js-monitor-opentelemetry-exporter/1.0.0-beta.23`;
|
|
1818
1818
|
const userAgentPrefix = options.userAgentOptions && options.userAgentOptions.userAgentPrefix
|
|
1819
1819
|
? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
|
|
1820
1820
|
: `${packageDetails}`;
|
|
@@ -2038,6 +2038,43 @@ class StatsbeatMetrics {
|
|
|
2038
2038
|
|
|
2039
2039
|
// Copyright (c) Microsoft Corporation.
|
|
2040
2040
|
// Licensed under the MIT license.
|
|
2041
|
+
/**
|
|
2042
|
+
* Performance Counter OpenTelemetry compliant names.
|
|
2043
|
+
* @internal
|
|
2044
|
+
*/
|
|
2045
|
+
var OTelPerformanceCounterNames;
|
|
2046
|
+
(function (OTelPerformanceCounterNames) {
|
|
2047
|
+
OTelPerformanceCounterNames["PRIVATE_BYTES"] = "Private_Bytes";
|
|
2048
|
+
OTelPerformanceCounterNames["AVAILABLE_BYTES"] = "Available_Bytes";
|
|
2049
|
+
OTelPerformanceCounterNames["PROCESSOR_TIME"] = "Processor_Time";
|
|
2050
|
+
OTelPerformanceCounterNames["PROCESS_TIME"] = "Process_Time";
|
|
2051
|
+
OTelPerformanceCounterNames["REQUEST_RATE"] = "Request_Rate";
|
|
2052
|
+
OTelPerformanceCounterNames["REQUEST_DURATION"] = "Request_Execution_Time";
|
|
2053
|
+
})(OTelPerformanceCounterNames || (OTelPerformanceCounterNames = {}));
|
|
2054
|
+
/**
|
|
2055
|
+
* Breeze Performance Counter names.
|
|
2056
|
+
* @internal
|
|
2057
|
+
*/
|
|
2058
|
+
var BreezePerformanceCounterNames;
|
|
2059
|
+
(function (BreezePerformanceCounterNames) {
|
|
2060
|
+
BreezePerformanceCounterNames["PRIVATE_BYTES"] = "\\Process(??APP_WIN32_PROC??)\\Private Bytes";
|
|
2061
|
+
BreezePerformanceCounterNames["AVAILABLE_BYTES"] = "\\Memory\\Available Bytes";
|
|
2062
|
+
BreezePerformanceCounterNames["PROCESSOR_TIME"] = "\\Processor(_Total)\\% Processor Time";
|
|
2063
|
+
BreezePerformanceCounterNames["PROCESS_TIME"] = "\\Process(??APP_WIN32_PROC??)\\% Processor Time";
|
|
2064
|
+
BreezePerformanceCounterNames["REQUEST_RATE"] = "\\ASP.NET Applications(??APP_W3SVC_PROC??)\\Requests/Sec";
|
|
2065
|
+
BreezePerformanceCounterNames["REQUEST_DURATION"] = "\\ASP.NET Applications(??APP_W3SVC_PROC??)\\Request Execution Time";
|
|
2066
|
+
})(BreezePerformanceCounterNames || (BreezePerformanceCounterNames = {}));
|
|
2067
|
+
|
|
2068
|
+
// Copyright (c) Microsoft Corporation.
|
|
2069
|
+
// Licensed under the MIT license.
|
|
2070
|
+
const breezePerformanceCountersMap = new Map([
|
|
2071
|
+
[OTelPerformanceCounterNames.PRIVATE_BYTES, BreezePerformanceCounterNames.PRIVATE_BYTES],
|
|
2072
|
+
[OTelPerformanceCounterNames.AVAILABLE_BYTES, BreezePerformanceCounterNames.AVAILABLE_BYTES],
|
|
2073
|
+
[OTelPerformanceCounterNames.PROCESSOR_TIME, BreezePerformanceCounterNames.PROCESSOR_TIME],
|
|
2074
|
+
[OTelPerformanceCounterNames.PROCESS_TIME, BreezePerformanceCounterNames.PROCESS_TIME],
|
|
2075
|
+
[OTelPerformanceCounterNames.REQUEST_RATE, BreezePerformanceCounterNames.REQUEST_RATE],
|
|
2076
|
+
[OTelPerformanceCounterNames.REQUEST_DURATION, BreezePerformanceCounterNames.REQUEST_DURATION],
|
|
2077
|
+
]);
|
|
2041
2078
|
function createPropertiesFromMetricAttributes(attributes) {
|
|
2042
2079
|
const properties = {};
|
|
2043
2080
|
if (attributes) {
|
|
@@ -2072,8 +2109,12 @@ function resourceMetricsToEnvelope(metrics, ikey, isStatsbeat) {
|
|
|
2072
2109
|
properties: {},
|
|
2073
2110
|
};
|
|
2074
2111
|
baseData.properties = createPropertiesFromMetricAttributes(dataPoint.attributes);
|
|
2112
|
+
let perfCounterName;
|
|
2113
|
+
if (breezePerformanceCountersMap.has(metric.descriptor.name)) {
|
|
2114
|
+
perfCounterName = breezePerformanceCountersMap.get(metric.descriptor.name);
|
|
2115
|
+
}
|
|
2075
2116
|
const metricDataPoint = {
|
|
2076
|
-
name: metric.descriptor.name,
|
|
2117
|
+
name: perfCounterName ? perfCounterName : metric.descriptor.name,
|
|
2077
2118
|
value: 0,
|
|
2078
2119
|
dataPointType: "Aggregation",
|
|
2079
2120
|
};
|
|
@@ -2411,7 +2452,6 @@ let instance$1 = null;
|
|
|
2411
2452
|
class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
2412
2453
|
constructor(options) {
|
|
2413
2454
|
super();
|
|
2414
|
-
this.AZURE_MONITOR_STATSBEAT_FEATURES = process.env.AZURE_MONITOR_STATSBEAT_FEATURES;
|
|
2415
2455
|
this.statsCollectionLongInterval = 86400000; // 1 day
|
|
2416
2456
|
this.attach = "Manual";
|
|
2417
2457
|
this.feature = 0;
|
|
@@ -2421,15 +2461,7 @@ class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
|
2421
2461
|
const exporterConfig = {
|
|
2422
2462
|
connectionString: this.connectionString,
|
|
2423
2463
|
};
|
|
2424
|
-
|
|
2425
|
-
try {
|
|
2426
|
-
this.feature = JSON.parse(this.AZURE_MONITOR_STATSBEAT_FEATURES).feature;
|
|
2427
|
-
this.instrumentation = JSON.parse(this.AZURE_MONITOR_STATSBEAT_FEATURES).instrumentation;
|
|
2428
|
-
}
|
|
2429
|
-
catch (error) {
|
|
2430
|
-
api.diag.error(`LongIntervalStatsbeat: Failed to parse features/instrumentations (error ${error})`);
|
|
2431
|
-
}
|
|
2432
|
-
}
|
|
2464
|
+
this.setFeatures();
|
|
2433
2465
|
this.longIntervalStatsbeatMeterProvider = new sdkMetrics.MeterProvider();
|
|
2434
2466
|
this.longIntervalAzureExporter = new AzureMonitorStatsbeatExporter(exporterConfig);
|
|
2435
2467
|
// Export Long Interval Statsbeats every day
|
|
@@ -2467,9 +2499,7 @@ class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
|
2467
2499
|
await this.getResourceProvider();
|
|
2468
2500
|
// Add long interval observable callbacks
|
|
2469
2501
|
this.attachStatsbeatGauge.addCallback(this.attachCallback.bind(this));
|
|
2470
|
-
this.longIntervalStatsbeatMeter.addBatchObservableCallback(this.
|
|
2471
|
-
this.featureStatsbeatGauge,
|
|
2472
|
-
]);
|
|
2502
|
+
this.longIntervalStatsbeatMeter.addBatchObservableCallback(this.getEnvironmentStatus.bind(this), [this.featureStatsbeatGauge]);
|
|
2473
2503
|
// Export Feature/Attach Statsbeat once upon app initialization
|
|
2474
2504
|
this.longIntervalAzureExporter.export((await this.longIntervalMetricReader.collect()).resourceMetrics, (result) => {
|
|
2475
2505
|
if (result.code !== core.ExportResultCode.SUCCESS) {
|
|
@@ -2481,7 +2511,8 @@ class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
|
2481
2511
|
api.diag.debug("Call to get the resource provider failed.");
|
|
2482
2512
|
}
|
|
2483
2513
|
}
|
|
2484
|
-
|
|
2514
|
+
getEnvironmentStatus(observableResult) {
|
|
2515
|
+
this.setFeatures();
|
|
2485
2516
|
let attributes;
|
|
2486
2517
|
if (this.instrumentation) {
|
|
2487
2518
|
attributes = Object.assign(Object.assign({}, this.commonProperties), { feature: this.instrumentation, type: StatsbeatFeatureType.INSTRUMENTATION });
|
|
@@ -2492,6 +2523,18 @@ class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
|
2492
2523
|
observableResult.observe(this.featureStatsbeatGauge, 1, Object.assign({}, attributes));
|
|
2493
2524
|
}
|
|
2494
2525
|
}
|
|
2526
|
+
setFeatures() {
|
|
2527
|
+
let statsbeatFeatures = process.env.AZURE_MONITOR_STATSBEAT_FEATURES;
|
|
2528
|
+
if (statsbeatFeatures) {
|
|
2529
|
+
try {
|
|
2530
|
+
this.feature = JSON.parse(statsbeatFeatures).feature;
|
|
2531
|
+
this.instrumentation = JSON.parse(statsbeatFeatures).instrumentation;
|
|
2532
|
+
}
|
|
2533
|
+
catch (error) {
|
|
2534
|
+
api.diag.error(`LongIntervalStatsbeat: Failed to parse features/instrumentations (error ${error})`);
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2495
2538
|
attachCallback(observableResult) {
|
|
2496
2539
|
const attributes = Object.assign(Object.assign({}, this.commonProperties), this.attachProperties);
|
|
2497
2540
|
observableResult.observe(1, attributes);
|
|
@@ -2869,9 +2912,14 @@ function createTagsFromResource(resource) {
|
|
|
2869
2912
|
if (resource && resource.attributes) {
|
|
2870
2913
|
tags[KnownContextTagKeys.AiCloudRole] = getCloudRole(resource);
|
|
2871
2914
|
tags[KnownContextTagKeys.AiCloudRoleInstance] = getCloudRoleInstance(resource);
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2915
|
+
if (resource.attributes[semanticConventions.SEMRESATTRS_DEVICE_ID]) {
|
|
2916
|
+
tags[KnownContextTagKeys.AiDeviceId] = String(resource.attributes[semanticConventions.SEMRESATTRS_DEVICE_ID]);
|
|
2917
|
+
}
|
|
2918
|
+
if (resource.attributes[semanticConventions.SEMRESATTRS_DEVICE_MODEL_NAME]) {
|
|
2919
|
+
tags[KnownContextTagKeys.AiDeviceModel] = String(resource.attributes[semanticConventions.SEMRESATTRS_DEVICE_MODEL_NAME]);
|
|
2920
|
+
}
|
|
2921
|
+
if (resource.attributes[semanticConventions.SEMRESATTRS_SERVICE_VERSION]) {
|
|
2922
|
+
tags[KnownContextTagKeys.AiApplicationVer] = String(resource.attributes[semanticConventions.SEMRESATTRS_SERVICE_VERSION]);
|
|
2875
2923
|
}
|
|
2876
2924
|
}
|
|
2877
2925
|
return tags;
|
|
@@ -2879,8 +2927,8 @@ function createTagsFromResource(resource) {
|
|
|
2879
2927
|
function getCloudRole(resource) {
|
|
2880
2928
|
let cloudRole = "";
|
|
2881
2929
|
// Service attributes
|
|
2882
|
-
const serviceName = resource.attributes[semanticConventions.
|
|
2883
|
-
const serviceNamespace = resource.attributes[semanticConventions.
|
|
2930
|
+
const serviceName = resource.attributes[semanticConventions.SEMRESATTRS_SERVICE_NAME];
|
|
2931
|
+
const serviceNamespace = resource.attributes[semanticConventions.SEMRESATTRS_SERVICE_NAMESPACE];
|
|
2884
2932
|
if (serviceName) {
|
|
2885
2933
|
// Custom Service name provided by customer is highest precedence
|
|
2886
2934
|
if (!String(serviceName).startsWith("unknown_service")) {
|
|
@@ -2902,27 +2950,27 @@ function getCloudRole(resource) {
|
|
|
2902
2950
|
}
|
|
2903
2951
|
}
|
|
2904
2952
|
// Kubernetes attributes should take precedence
|
|
2905
|
-
const kubernetesDeploymentName = resource.attributes[semanticConventions.
|
|
2953
|
+
const kubernetesDeploymentName = resource.attributes[semanticConventions.SEMRESATTRS_K8S_DEPLOYMENT_NAME];
|
|
2906
2954
|
if (kubernetesDeploymentName) {
|
|
2907
2955
|
return String(kubernetesDeploymentName);
|
|
2908
2956
|
}
|
|
2909
|
-
const kuberneteReplicasetName = resource.attributes[semanticConventions.
|
|
2957
|
+
const kuberneteReplicasetName = resource.attributes[semanticConventions.SEMRESATTRS_K8S_REPLICASET_NAME];
|
|
2910
2958
|
if (kuberneteReplicasetName) {
|
|
2911
2959
|
return String(kuberneteReplicasetName);
|
|
2912
2960
|
}
|
|
2913
|
-
const kubernetesStatefulSetName = resource.attributes[semanticConventions.
|
|
2961
|
+
const kubernetesStatefulSetName = resource.attributes[semanticConventions.SEMRESATTRS_K8S_STATEFULSET_NAME];
|
|
2914
2962
|
if (kubernetesStatefulSetName) {
|
|
2915
2963
|
return String(kubernetesStatefulSetName);
|
|
2916
2964
|
}
|
|
2917
|
-
const kubernetesJobName = resource.attributes[semanticConventions.
|
|
2965
|
+
const kubernetesJobName = resource.attributes[semanticConventions.SEMRESATTRS_K8S_JOB_NAME];
|
|
2918
2966
|
if (kubernetesJobName) {
|
|
2919
2967
|
return String(kubernetesJobName);
|
|
2920
2968
|
}
|
|
2921
|
-
const kubernetesCronjobName = resource.attributes[semanticConventions.
|
|
2969
|
+
const kubernetesCronjobName = resource.attributes[semanticConventions.SEMRESATTRS_K8S_CRONJOB_NAME];
|
|
2922
2970
|
if (kubernetesCronjobName) {
|
|
2923
2971
|
return String(kubernetesCronjobName);
|
|
2924
2972
|
}
|
|
2925
|
-
const kubernetesDaemonsetName = resource.attributes[semanticConventions.
|
|
2973
|
+
const kubernetesDaemonsetName = resource.attributes[semanticConventions.SEMRESATTRS_K8S_DAEMONSET_NAME];
|
|
2926
2974
|
if (kubernetesDaemonsetName) {
|
|
2927
2975
|
return String(kubernetesDaemonsetName);
|
|
2928
2976
|
}
|
|
@@ -2930,12 +2978,12 @@ function getCloudRole(resource) {
|
|
|
2930
2978
|
}
|
|
2931
2979
|
function getCloudRoleInstance(resource) {
|
|
2932
2980
|
// Kubernetes attributes should take precedence
|
|
2933
|
-
const kubernetesPodName = resource.attributes[semanticConventions.
|
|
2981
|
+
const kubernetesPodName = resource.attributes[semanticConventions.SEMRESATTRS_K8S_POD_NAME];
|
|
2934
2982
|
if (kubernetesPodName) {
|
|
2935
2983
|
return String(kubernetesPodName);
|
|
2936
2984
|
}
|
|
2937
2985
|
// Service attributes
|
|
2938
|
-
const serviceInstanceId = resource.attributes[semanticConventions.
|
|
2986
|
+
const serviceInstanceId = resource.attributes[semanticConventions.SEMRESATTRS_SERVICE_INSTANCE_ID];
|
|
2939
2987
|
if (serviceInstanceId) {
|
|
2940
2988
|
return String(serviceInstanceId);
|
|
2941
2989
|
}
|
|
@@ -2943,43 +2991,43 @@ function getCloudRoleInstance(resource) {
|
|
|
2943
2991
|
return os$1 && os$1.hostname();
|
|
2944
2992
|
}
|
|
2945
2993
|
function isSqlDB(dbSystem) {
|
|
2946
|
-
return (dbSystem === semanticConventions.
|
|
2947
|
-
dbSystem === semanticConventions.
|
|
2948
|
-
dbSystem === semanticConventions.
|
|
2949
|
-
dbSystem === semanticConventions.
|
|
2950
|
-
dbSystem === semanticConventions.
|
|
2951
|
-
dbSystem === semanticConventions.
|
|
2952
|
-
dbSystem === semanticConventions.
|
|
2953
|
-
dbSystem === semanticConventions.
|
|
2954
|
-
dbSystem === semanticConventions.
|
|
2994
|
+
return (dbSystem === semanticConventions.DBSYSTEMVALUES_DB2 ||
|
|
2995
|
+
dbSystem === semanticConventions.DBSYSTEMVALUES_DERBY ||
|
|
2996
|
+
dbSystem === semanticConventions.DBSYSTEMVALUES_MARIADB ||
|
|
2997
|
+
dbSystem === semanticConventions.DBSYSTEMVALUES_MSSQL ||
|
|
2998
|
+
dbSystem === semanticConventions.DBSYSTEMVALUES_ORACLE ||
|
|
2999
|
+
dbSystem === semanticConventions.DBSYSTEMVALUES_SQLITE ||
|
|
3000
|
+
dbSystem === semanticConventions.DBSYSTEMVALUES_OTHER_SQL ||
|
|
3001
|
+
dbSystem === semanticConventions.DBSYSTEMVALUES_HSQLDB ||
|
|
3002
|
+
dbSystem === semanticConventions.DBSYSTEMVALUES_H2);
|
|
2955
3003
|
}
|
|
2956
3004
|
function getUrl(attributes) {
|
|
2957
3005
|
if (!attributes) {
|
|
2958
3006
|
return "";
|
|
2959
3007
|
}
|
|
2960
|
-
const httpMethod = attributes[semanticConventions.
|
|
3008
|
+
const httpMethod = attributes[semanticConventions.SEMATTRS_HTTP_METHOD];
|
|
2961
3009
|
if (httpMethod) {
|
|
2962
|
-
const httpUrl = attributes[semanticConventions.
|
|
3010
|
+
const httpUrl = attributes[semanticConventions.SEMATTRS_HTTP_URL];
|
|
2963
3011
|
if (httpUrl) {
|
|
2964
3012
|
return String(httpUrl);
|
|
2965
3013
|
}
|
|
2966
3014
|
else {
|
|
2967
|
-
const httpScheme = attributes[semanticConventions.
|
|
2968
|
-
const httpTarget = attributes[semanticConventions.
|
|
3015
|
+
const httpScheme = attributes[semanticConventions.SEMATTRS_HTTP_SCHEME];
|
|
3016
|
+
const httpTarget = attributes[semanticConventions.SEMATTRS_HTTP_TARGET];
|
|
2969
3017
|
if (httpScheme && httpTarget) {
|
|
2970
|
-
const httpHost = attributes[semanticConventions.
|
|
3018
|
+
const httpHost = attributes[semanticConventions.SEMATTRS_HTTP_HOST];
|
|
2971
3019
|
if (httpHost) {
|
|
2972
3020
|
return `${httpScheme}://${httpHost}${httpTarget}`;
|
|
2973
3021
|
}
|
|
2974
3022
|
else {
|
|
2975
|
-
const netPeerPort = attributes[semanticConventions.
|
|
3023
|
+
const netPeerPort = attributes[semanticConventions.SEMATTRS_NET_PEER_PORT];
|
|
2976
3024
|
if (netPeerPort) {
|
|
2977
|
-
const netPeerName = attributes[semanticConventions.
|
|
3025
|
+
const netPeerName = attributes[semanticConventions.SEMATTRS_NET_PEER_NAME];
|
|
2978
3026
|
if (netPeerName) {
|
|
2979
3027
|
return `${httpScheme}://${netPeerName}:${netPeerPort}${httpTarget}`;
|
|
2980
3028
|
}
|
|
2981
3029
|
else {
|
|
2982
|
-
const netPeerIp = attributes[semanticConventions.
|
|
3030
|
+
const netPeerIp = attributes[semanticConventions.SEMATTRS_NET_PEER_IP];
|
|
2983
3031
|
if (netPeerIp) {
|
|
2984
3032
|
return `${httpScheme}://${netPeerIp}:${netPeerPort}${httpTarget}`;
|
|
2985
3033
|
}
|
|
@@ -2995,11 +3043,11 @@ function getDependencyTarget(attributes) {
|
|
|
2995
3043
|
if (!attributes) {
|
|
2996
3044
|
return "";
|
|
2997
3045
|
}
|
|
2998
|
-
const peerService = attributes[semanticConventions.
|
|
2999
|
-
const httpHost = attributes[semanticConventions.
|
|
3000
|
-
const httpUrl = attributes[semanticConventions.
|
|
3001
|
-
const netPeerName = attributes[semanticConventions.
|
|
3002
|
-
const netPeerIp = attributes[semanticConventions.
|
|
3046
|
+
const peerService = attributes[semanticConventions.SEMATTRS_PEER_SERVICE];
|
|
3047
|
+
const httpHost = attributes[semanticConventions.SEMATTRS_HTTP_HOST];
|
|
3048
|
+
const httpUrl = attributes[semanticConventions.SEMATTRS_HTTP_URL];
|
|
3049
|
+
const netPeerName = attributes[semanticConventions.SEMATTRS_NET_PEER_NAME];
|
|
3050
|
+
const netPeerIp = attributes[semanticConventions.SEMATTRS_NET_PEER_IP];
|
|
3003
3051
|
if (peerService) {
|
|
3004
3052
|
return String(peerService);
|
|
3005
3053
|
}
|
|
@@ -3024,9 +3072,9 @@ function createResourceMetricEnvelope(resource, instrumentationKey) {
|
|
|
3024
3072
|
for (const key of Object.keys(resource.attributes)) {
|
|
3025
3073
|
// Avoid duplication ignoring fields already mapped.
|
|
3026
3074
|
if (!(key.startsWith("_MS.") ||
|
|
3027
|
-
key === semanticConventions.
|
|
3028
|
-
key === semanticConventions.
|
|
3029
|
-
key === semanticConventions.
|
|
3075
|
+
key === semanticConventions.SEMRESATTRS_TELEMETRY_SDK_VERSION ||
|
|
3076
|
+
key === semanticConventions.SEMRESATTRS_TELEMETRY_SDK_LANGUAGE ||
|
|
3077
|
+
key === semanticConventions.SEMRESATTRS_TELEMETRY_SDK_NAME)) {
|
|
3030
3078
|
resourceAttributes[key] = resource.attributes[key];
|
|
3031
3079
|
}
|
|
3032
3080
|
}
|
|
@@ -3099,7 +3147,7 @@ const getTimeSinceEnqueued = (span) => {
|
|
|
3099
3147
|
*/
|
|
3100
3148
|
const parseEventHubSpan = (span, baseData) => {
|
|
3101
3149
|
const namespace = span.attributes[AzNamespace];
|
|
3102
|
-
const peerAddress = (span.attributes[semanticConventions.
|
|
3150
|
+
const peerAddress = (span.attributes[semanticConventions.SEMATTRS_NET_PEER_NAME] ||
|
|
3103
3151
|
span.attributes["peer.address"] ||
|
|
3104
3152
|
"unknown").replace(/\/$/g, ""); // remove trailing "/"
|
|
3105
3153
|
const messageBusDestination = (span.attributes[MessageBusDestination] || "unknown");
|
|
@@ -3128,18 +3176,22 @@ function createTagsFromSpan(span) {
|
|
|
3128
3176
|
if (span.parentSpanId) {
|
|
3129
3177
|
tags[KnownContextTagKeys.AiOperationParentId] = span.parentSpanId;
|
|
3130
3178
|
}
|
|
3131
|
-
const
|
|
3179
|
+
const endUserId = span.attributes[semanticConventions.SEMATTRS_ENDUSER_ID];
|
|
3180
|
+
if (endUserId) {
|
|
3181
|
+
tags[KnownContextTagKeys.AiUserId] = String(endUserId);
|
|
3182
|
+
}
|
|
3183
|
+
const httpUserAgent = span.attributes[semanticConventions.SEMATTRS_HTTP_USER_AGENT];
|
|
3132
3184
|
if (httpUserAgent) {
|
|
3133
3185
|
// TODO: Not exposed in Swagger, need to update def
|
|
3134
3186
|
tags["ai.user.userAgent"] = String(httpUserAgent);
|
|
3135
3187
|
}
|
|
3136
3188
|
if (span.kind === api.SpanKind.SERVER) {
|
|
3137
|
-
const httpMethod = span.attributes[semanticConventions.
|
|
3138
|
-
const httpClientIp = span.attributes[semanticConventions.
|
|
3139
|
-
const netPeerIp = span.attributes[semanticConventions.
|
|
3189
|
+
const httpMethod = span.attributes[semanticConventions.SEMATTRS_HTTP_METHOD];
|
|
3190
|
+
const httpClientIp = span.attributes[semanticConventions.SEMATTRS_HTTP_CLIENT_IP];
|
|
3191
|
+
const netPeerIp = span.attributes[semanticConventions.SEMATTRS_NET_PEER_IP];
|
|
3140
3192
|
if (httpMethod) {
|
|
3141
|
-
const httpRoute = span.attributes[semanticConventions.
|
|
3142
|
-
const httpUrl = span.attributes[semanticConventions.
|
|
3193
|
+
const httpRoute = span.attributes[semanticConventions.SEMATTRS_HTTP_ROUTE];
|
|
3194
|
+
const httpUrl = span.attributes[semanticConventions.SEMATTRS_HTTP_URL];
|
|
3143
3195
|
tags[KnownContextTagKeys.AiOperationName] = span.name; // Default
|
|
3144
3196
|
if (httpRoute) {
|
|
3145
3197
|
tags[KnownContextTagKeys.AiOperationName] = `${httpMethod} ${httpRoute}`;
|
|
@@ -3174,21 +3226,24 @@ function createPropertiesFromSpanAttributes(attributes) {
|
|
|
3174
3226
|
for (const key of Object.keys(attributes)) {
|
|
3175
3227
|
// Avoid duplication ignoring fields already mapped.
|
|
3176
3228
|
if (!(key.startsWith("_MS.") ||
|
|
3177
|
-
key === semanticConventions.
|
|
3178
|
-
key === semanticConventions.
|
|
3179
|
-
key === semanticConventions.
|
|
3180
|
-
key === semanticConventions.
|
|
3181
|
-
key === semanticConventions.
|
|
3182
|
-
key === semanticConventions.
|
|
3183
|
-
key === semanticConventions.
|
|
3184
|
-
key === semanticConventions.
|
|
3185
|
-
key === semanticConventions.
|
|
3186
|
-
key === semanticConventions.
|
|
3187
|
-
key === semanticConventions.
|
|
3188
|
-
key === semanticConventions.
|
|
3189
|
-
key === semanticConventions.
|
|
3190
|
-
key === semanticConventions.
|
|
3191
|
-
key === semanticConventions.
|
|
3229
|
+
key === semanticConventions.SEMATTRS_NET_PEER_IP ||
|
|
3230
|
+
key === semanticConventions.SEMATTRS_NET_PEER_NAME ||
|
|
3231
|
+
key === semanticConventions.SEMATTRS_PEER_SERVICE ||
|
|
3232
|
+
key === semanticConventions.SEMATTRS_HTTP_METHOD ||
|
|
3233
|
+
key === semanticConventions.SEMATTRS_HTTP_URL ||
|
|
3234
|
+
key === semanticConventions.SEMATTRS_HTTP_STATUS_CODE ||
|
|
3235
|
+
key === semanticConventions.SEMATTRS_HTTP_ROUTE ||
|
|
3236
|
+
key === semanticConventions.SEMATTRS_HTTP_HOST ||
|
|
3237
|
+
key === semanticConventions.SEMATTRS_HTTP_URL ||
|
|
3238
|
+
key === semanticConventions.SEMATTRS_DB_SYSTEM ||
|
|
3239
|
+
key === semanticConventions.SEMATTRS_DB_STATEMENT ||
|
|
3240
|
+
key === semanticConventions.SEMATTRS_DB_OPERATION ||
|
|
3241
|
+
key === semanticConventions.SEMATTRS_DB_NAME ||
|
|
3242
|
+
key === semanticConventions.SEMATTRS_RPC_SYSTEM ||
|
|
3243
|
+
key === semanticConventions.SEMATTRS_RPC_GRPC_STATUS_CODE ||
|
|
3244
|
+
key === semanticConventions.SEMATTRS_EXCEPTION_TYPE ||
|
|
3245
|
+
key === semanticConventions.SEMATTRS_EXCEPTION_MESSAGE ||
|
|
3246
|
+
key === semanticConventions.SEMATTRS_EXCEPTION_STACKTRACE)) {
|
|
3192
3247
|
properties[key] = attributes[key];
|
|
3193
3248
|
}
|
|
3194
3249
|
}
|
|
@@ -3224,12 +3279,12 @@ function createDependencyData(span) {
|
|
|
3224
3279
|
if (span.kind === api.SpanKind.INTERNAL && span.parentSpanId) {
|
|
3225
3280
|
remoteDependencyData.type = DependencyTypes.InProc;
|
|
3226
3281
|
}
|
|
3227
|
-
const httpMethod = span.attributes[semanticConventions.
|
|
3228
|
-
const dbSystem = span.attributes[semanticConventions.
|
|
3229
|
-
const rpcSystem = span.attributes[semanticConventions.
|
|
3282
|
+
const httpMethod = span.attributes[semanticConventions.SEMATTRS_HTTP_METHOD];
|
|
3283
|
+
const dbSystem = span.attributes[semanticConventions.SEMATTRS_DB_SYSTEM];
|
|
3284
|
+
const rpcSystem = span.attributes[semanticConventions.SEMATTRS_RPC_SYSTEM];
|
|
3230
3285
|
// HTTP Dependency
|
|
3231
3286
|
if (httpMethod) {
|
|
3232
|
-
const httpUrl = span.attributes[semanticConventions.
|
|
3287
|
+
const httpUrl = span.attributes[semanticConventions.SEMATTRS_HTTP_URL];
|
|
3233
3288
|
if (httpUrl) {
|
|
3234
3289
|
try {
|
|
3235
3290
|
const dependencyUrl = new url.URL(String(httpUrl));
|
|
@@ -3239,7 +3294,7 @@ function createDependencyData(span) {
|
|
|
3239
3294
|
}
|
|
3240
3295
|
remoteDependencyData.type = DependencyTypes.Http;
|
|
3241
3296
|
remoteDependencyData.data = getUrl(span.attributes);
|
|
3242
|
-
const httpStatusCode = span.attributes[semanticConventions.
|
|
3297
|
+
const httpStatusCode = span.attributes[semanticConventions.SEMATTRS_HTTP_STATUS_CODE];
|
|
3243
3298
|
if (httpStatusCode) {
|
|
3244
3299
|
remoteDependencyData.resultCode = String(httpStatusCode);
|
|
3245
3300
|
}
|
|
@@ -3266,16 +3321,16 @@ function createDependencyData(span) {
|
|
|
3266
3321
|
// DB Dependency
|
|
3267
3322
|
else if (dbSystem) {
|
|
3268
3323
|
// TODO: Remove special logic when Azure UX supports OpenTelemetry dbSystem
|
|
3269
|
-
if (String(dbSystem) === semanticConventions.
|
|
3324
|
+
if (String(dbSystem) === semanticConventions.DBSYSTEMVALUES_MYSQL) {
|
|
3270
3325
|
remoteDependencyData.type = "mysql";
|
|
3271
3326
|
}
|
|
3272
|
-
else if (String(dbSystem) === semanticConventions.
|
|
3327
|
+
else if (String(dbSystem) === semanticConventions.DBSYSTEMVALUES_POSTGRESQL) {
|
|
3273
3328
|
remoteDependencyData.type = "postgresql";
|
|
3274
3329
|
}
|
|
3275
|
-
else if (String(dbSystem) === semanticConventions.
|
|
3330
|
+
else if (String(dbSystem) === semanticConventions.DBSYSTEMVALUES_MONGODB) {
|
|
3276
3331
|
remoteDependencyData.type = "mongodb";
|
|
3277
3332
|
}
|
|
3278
|
-
else if (String(dbSystem) === semanticConventions.
|
|
3333
|
+
else if (String(dbSystem) === semanticConventions.DBSYSTEMVALUES_REDIS) {
|
|
3279
3334
|
remoteDependencyData.type = "redis";
|
|
3280
3335
|
}
|
|
3281
3336
|
else if (isSqlDB(String(dbSystem))) {
|
|
@@ -3284,8 +3339,8 @@ function createDependencyData(span) {
|
|
|
3284
3339
|
else {
|
|
3285
3340
|
remoteDependencyData.type = String(dbSystem);
|
|
3286
3341
|
}
|
|
3287
|
-
const dbStatement = span.attributes[semanticConventions.
|
|
3288
|
-
const dbOperation = span.attributes[semanticConventions.
|
|
3342
|
+
const dbStatement = span.attributes[semanticConventions.SEMATTRS_DB_STATEMENT];
|
|
3343
|
+
const dbOperation = span.attributes[semanticConventions.SEMATTRS_DB_OPERATION];
|
|
3289
3344
|
if (dbStatement) {
|
|
3290
3345
|
remoteDependencyData.data = String(dbStatement);
|
|
3291
3346
|
}
|
|
@@ -3293,7 +3348,7 @@ function createDependencyData(span) {
|
|
|
3293
3348
|
remoteDependencyData.data = String(dbOperation);
|
|
3294
3349
|
}
|
|
3295
3350
|
const target = getDependencyTarget(span.attributes);
|
|
3296
|
-
const dbName = span.attributes[semanticConventions.
|
|
3351
|
+
const dbName = span.attributes[semanticConventions.SEMATTRS_DB_NAME];
|
|
3297
3352
|
if (target) {
|
|
3298
3353
|
remoteDependencyData.target = dbName ? `${target}|${dbName}` : `${target}`;
|
|
3299
3354
|
}
|
|
@@ -3309,7 +3364,7 @@ function createDependencyData(span) {
|
|
|
3309
3364
|
else {
|
|
3310
3365
|
remoteDependencyData.type = DependencyTypes.Grpc;
|
|
3311
3366
|
}
|
|
3312
|
-
const grpcStatusCode = span.attributes[semanticConventions.
|
|
3367
|
+
const grpcStatusCode = span.attributes[semanticConventions.SEMATTRS_RPC_GRPC_STATUS_CODE];
|
|
3313
3368
|
if (grpcStatusCode) {
|
|
3314
3369
|
remoteDependencyData.resultCode = String(grpcStatusCode);
|
|
3315
3370
|
}
|
|
@@ -3332,11 +3387,11 @@ function createRequestData(span) {
|
|
|
3332
3387
|
version: 2,
|
|
3333
3388
|
source: undefined,
|
|
3334
3389
|
};
|
|
3335
|
-
const httpMethod = span.attributes[semanticConventions.
|
|
3336
|
-
const grpcStatusCode = span.attributes[semanticConventions.
|
|
3390
|
+
const httpMethod = span.attributes[semanticConventions.SEMATTRS_HTTP_METHOD];
|
|
3391
|
+
const grpcStatusCode = span.attributes[semanticConventions.SEMATTRS_RPC_GRPC_STATUS_CODE];
|
|
3337
3392
|
if (httpMethod) {
|
|
3338
3393
|
requestData.url = getUrl(span.attributes);
|
|
3339
|
-
const httpStatusCode = span.attributes[semanticConventions.
|
|
3394
|
+
const httpStatusCode = span.attributes[semanticConventions.SEMATTRS_HTTP_STATUS_CODE];
|
|
3340
3395
|
if (httpStatusCode) {
|
|
3341
3396
|
requestData.responseCode = String(httpStatusCode);
|
|
3342
3397
|
}
|
|
@@ -3434,18 +3489,18 @@ function spanEventsToEnvelopes(span, ikey) {
|
|
|
3434
3489
|
let stack = "";
|
|
3435
3490
|
let hasFullStack = false;
|
|
3436
3491
|
if (event.attributes) {
|
|
3437
|
-
typeName = String(event.attributes[semanticConventions.
|
|
3438
|
-
stack = String(event.attributes[semanticConventions.
|
|
3492
|
+
typeName = String(event.attributes[semanticConventions.SEMATTRS_EXCEPTION_TYPE]);
|
|
3493
|
+
stack = String(event.attributes[semanticConventions.SEMATTRS_EXCEPTION_STACKTRACE]);
|
|
3439
3494
|
if (stack) {
|
|
3440
3495
|
hasFullStack = true;
|
|
3441
3496
|
}
|
|
3442
|
-
const exceptionMsg = event.attributes[semanticConventions.
|
|
3497
|
+
const exceptionMsg = event.attributes[semanticConventions.SEMATTRS_EXCEPTION_MESSAGE];
|
|
3443
3498
|
if (exceptionMsg) {
|
|
3444
3499
|
message = String(exceptionMsg);
|
|
3445
3500
|
}
|
|
3446
|
-
const escaped = event.attributes[semanticConventions.
|
|
3501
|
+
const escaped = event.attributes[semanticConventions.SEMATTRS_EXCEPTION_ESCAPED];
|
|
3447
3502
|
if (escaped !== undefined) {
|
|
3448
|
-
properties[semanticConventions.
|
|
3503
|
+
properties[semanticConventions.SEMATTRS_EXCEPTION_ESCAPED] = String(escaped);
|
|
3449
3504
|
}
|
|
3450
3505
|
}
|
|
3451
3506
|
const exceptionDetails = {
|
|
@@ -3638,16 +3693,16 @@ function logToEnvelope(log, ikey) {
|
|
|
3638
3693
|
const sampleRate = 100;
|
|
3639
3694
|
const instrumentationKey = ikey;
|
|
3640
3695
|
const tags = createTagsFromLog(log);
|
|
3641
|
-
|
|
3696
|
+
let [properties, measurements] = createPropertiesFromLog(log);
|
|
3642
3697
|
let name;
|
|
3643
3698
|
let baseType;
|
|
3644
3699
|
let baseData;
|
|
3645
3700
|
if (!log.attributes[ApplicationInsightsBaseType]) {
|
|
3646
3701
|
// Get Exception attributes if available
|
|
3647
|
-
const exceptionType = log.attributes[semanticConventions.
|
|
3702
|
+
const exceptionType = log.attributes[semanticConventions.SEMATTRS_EXCEPTION_TYPE];
|
|
3648
3703
|
if (exceptionType) {
|
|
3649
|
-
const exceptionMessage = log.attributes[semanticConventions.
|
|
3650
|
-
const exceptionStacktrace = log.attributes[semanticConventions.
|
|
3704
|
+
const exceptionMessage = log.attributes[semanticConventions.SEMATTRS_EXCEPTION_MESSAGE];
|
|
3705
|
+
const exceptionStacktrace = log.attributes[semanticConventions.SEMATTRS_EXCEPTION_STACKTRACE];
|
|
3651
3706
|
name = ApplicationInsightsExceptionName;
|
|
3652
3707
|
baseType = ApplicationInsightsExceptionBaseType;
|
|
3653
3708
|
const exceptionDetails = {
|
|
@@ -3679,6 +3734,7 @@ function logToEnvelope(log, ikey) {
|
|
|
3679
3734
|
baseType = String(log.attributes[ApplicationInsightsBaseType]);
|
|
3680
3735
|
name = getLegacyApplicationInsightsName(log);
|
|
3681
3736
|
baseData = getLegacyApplicationInsightsBaseData(log);
|
|
3737
|
+
measurements = getLegacyApplicationInsightsMeasurements(log);
|
|
3682
3738
|
if (!baseData) {
|
|
3683
3739
|
// Failed to parse log
|
|
3684
3740
|
return;
|
|
@@ -3716,9 +3772,9 @@ function createPropertiesFromLog(log) {
|
|
|
3716
3772
|
for (const key of Object.keys(log.attributes)) {
|
|
3717
3773
|
// Avoid duplication ignoring fields already mapped.
|
|
3718
3774
|
if (!(key.startsWith("_MS.") ||
|
|
3719
|
-
key === semanticConventions.
|
|
3720
|
-
key === semanticConventions.
|
|
3721
|
-
key === semanticConventions.
|
|
3775
|
+
key === semanticConventions.SEMATTRS_EXCEPTION_TYPE ||
|
|
3776
|
+
key === semanticConventions.SEMATTRS_EXCEPTION_MESSAGE ||
|
|
3777
|
+
key === semanticConventions.SEMATTRS_EXCEPTION_STACKTRACE)) {
|
|
3722
3778
|
properties[key] = log.attributes[key];
|
|
3723
3779
|
}
|
|
3724
3780
|
}
|
|
@@ -3767,6 +3823,14 @@ function getLegacyApplicationInsightsName(log) {
|
|
|
3767
3823
|
}
|
|
3768
3824
|
return name;
|
|
3769
3825
|
}
|
|
3826
|
+
function getLegacyApplicationInsightsMeasurements(log) {
|
|
3827
|
+
var _a;
|
|
3828
|
+
let measurements = {};
|
|
3829
|
+
if ((_a = log.body) === null || _a === void 0 ? void 0 : _a.measurements) {
|
|
3830
|
+
measurements = Object.assign({}, log.body.measurements);
|
|
3831
|
+
}
|
|
3832
|
+
return measurements;
|
|
3833
|
+
}
|
|
3770
3834
|
function getLegacyApplicationInsightsBaseData(log) {
|
|
3771
3835
|
let baseData = {
|
|
3772
3836
|
version: 2,
|
|
@@ -3775,19 +3839,19 @@ function getLegacyApplicationInsightsBaseData(log) {
|
|
|
3775
3839
|
try {
|
|
3776
3840
|
switch (log.attributes[ApplicationInsightsBaseType]) {
|
|
3777
3841
|
case ApplicationInsightsAvailabilityBaseType:
|
|
3778
|
-
baseData =
|
|
3842
|
+
baseData = log.body;
|
|
3779
3843
|
break;
|
|
3780
3844
|
case ApplicationInsightsExceptionBaseType:
|
|
3781
|
-
baseData =
|
|
3845
|
+
baseData = log.body;
|
|
3782
3846
|
break;
|
|
3783
3847
|
case ApplicationInsightsMessageBaseType:
|
|
3784
|
-
baseData =
|
|
3848
|
+
baseData = log.body;
|
|
3785
3849
|
break;
|
|
3786
3850
|
case ApplicationInsightsPageViewBaseType:
|
|
3787
|
-
baseData =
|
|
3851
|
+
baseData = log.body;
|
|
3788
3852
|
break;
|
|
3789
3853
|
case ApplicationInsightsEventBaseType:
|
|
3790
|
-
baseData =
|
|
3854
|
+
baseData = log.body;
|
|
3791
3855
|
break;
|
|
3792
3856
|
}
|
|
3793
3857
|
if (typeof (baseData === null || baseData === void 0 ? void 0 : baseData.message) === "object") {
|
|
@@ -15,7 +15,6 @@ let instance = null;
|
|
|
15
15
|
class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
16
16
|
constructor(options) {
|
|
17
17
|
super();
|
|
18
|
-
this.AZURE_MONITOR_STATSBEAT_FEATURES = process.env.AZURE_MONITOR_STATSBEAT_FEATURES;
|
|
19
18
|
this.statsCollectionLongInterval = 86400000; // 1 day
|
|
20
19
|
this.attach = "Manual";
|
|
21
20
|
this.feature = 0;
|
|
@@ -25,15 +24,7 @@ class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
|
25
24
|
const exporterConfig = {
|
|
26
25
|
connectionString: this.connectionString,
|
|
27
26
|
};
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
this.feature = JSON.parse(this.AZURE_MONITOR_STATSBEAT_FEATURES).feature;
|
|
31
|
-
this.instrumentation = JSON.parse(this.AZURE_MONITOR_STATSBEAT_FEATURES).instrumentation;
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
diag.error(`LongIntervalStatsbeat: Failed to parse features/instrumentations (error ${error})`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
27
|
+
this.setFeatures();
|
|
37
28
|
this.longIntervalStatsbeatMeterProvider = new MeterProvider();
|
|
38
29
|
this.longIntervalAzureExporter = new AzureMonitorStatsbeatExporter(exporterConfig);
|
|
39
30
|
// Export Long Interval Statsbeats every day
|
|
@@ -71,9 +62,7 @@ class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
|
71
62
|
await this.getResourceProvider();
|
|
72
63
|
// Add long interval observable callbacks
|
|
73
64
|
this.attachStatsbeatGauge.addCallback(this.attachCallback.bind(this));
|
|
74
|
-
this.longIntervalStatsbeatMeter.addBatchObservableCallback(this.
|
|
75
|
-
this.featureStatsbeatGauge,
|
|
76
|
-
]);
|
|
65
|
+
this.longIntervalStatsbeatMeter.addBatchObservableCallback(this.getEnvironmentStatus.bind(this), [this.featureStatsbeatGauge]);
|
|
77
66
|
// Export Feature/Attach Statsbeat once upon app initialization
|
|
78
67
|
this.longIntervalAzureExporter.export((await this.longIntervalMetricReader.collect()).resourceMetrics, (result) => {
|
|
79
68
|
if (result.code !== ExportResultCode.SUCCESS) {
|
|
@@ -85,7 +74,8 @@ class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
|
85
74
|
diag.debug("Call to get the resource provider failed.");
|
|
86
75
|
}
|
|
87
76
|
}
|
|
88
|
-
|
|
77
|
+
getEnvironmentStatus(observableResult) {
|
|
78
|
+
this.setFeatures();
|
|
89
79
|
let attributes;
|
|
90
80
|
if (this.instrumentation) {
|
|
91
81
|
attributes = Object.assign(Object.assign({}, this.commonProperties), { feature: this.instrumentation, type: StatsbeatFeatureType.INSTRUMENTATION });
|
|
@@ -96,6 +86,18 @@ class LongIntervalStatsbeatMetrics extends StatsbeatMetrics {
|
|
|
96
86
|
observableResult.observe(this.featureStatsbeatGauge, 1, Object.assign({}, attributes));
|
|
97
87
|
}
|
|
98
88
|
}
|
|
89
|
+
setFeatures() {
|
|
90
|
+
let statsbeatFeatures = process.env.AZURE_MONITOR_STATSBEAT_FEATURES;
|
|
91
|
+
if (statsbeatFeatures) {
|
|
92
|
+
try {
|
|
93
|
+
this.feature = JSON.parse(statsbeatFeatures).feature;
|
|
94
|
+
this.instrumentation = JSON.parse(statsbeatFeatures).instrumentation;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
diag.error(`LongIntervalStatsbeat: Failed to parse features/instrumentations (error ${error})`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
99
101
|
attachCallback(observableResult) {
|
|
100
102
|
const attributes = Object.assign(Object.assign({}, this.commonProperties), this.attachProperties);
|
|
101
103
|
observableResult.observe(1, attributes);
|