Repository: microsoft/ApplicationInsights-node.js
Pull request #1021 (2022-10-17 22:53:04)

[Preview] Standard Metrics Updates
Fix issue with Exceptions/Traces not exporting all dimensions, using BatchObservableResult
Fix issue with Perf Counters reporting trace/exceptions counts instead of rates
Added prefix in all Standard Metrics for easy discoverability in Azure Monitor Exporter
Azure Monitor Exporter will add extra attributes to Standard Metrics
Add sampleRate attribute in Spans for Exporter to use




Patch:
diff --git a/src/autoCollection/metrics/collection/azureHttpMetricsInstrumentation.ts b/src/autoCollection/metrics/collection/azureHttpMetricsInstrumentation.ts
index afef411..d45677c 100644
--- a/src/autoCollection/metrics/collection/azureHttpMetricsInstrumentation.ts
+++ b/src/autoCollection/metrics/collection/azureHttpMetricsInstrumentation.ts
@@ -15,7 +15,7 @@ import { getRequestInfo } from '@opentelemetry/instrumentation-http';
 import { Histogram, MeterProvider, ValueType } from '@opentelemetry/api-metrics';
 
 import { APPLICATION_INSIGHTS_SDK_VERSION } from "../../../declarations/constants";
-import { HttpMetricsInstrumentationConfig, IHttpStandardMetric, MetricId, MetricName } from '../types';
+import { HttpMetricsInstrumentationConfig, IHttpStandardMetric, MetricName } from '../types';
 import { Logger } from '../../../library/logging';
 import { SpanKind, TracerProvider } from '@opentelemetry/api';
 import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
@@ -79,7 +79,6 @@ export class AzureHttpMetricsInstrumentation extends InstrumentationBase<Http> {
         success = (0 < statusCode) && (statusCode < 500);
       }
       if (metric.spanKind == SpanKind.SERVER) {
-        metric.attributes["_MS.MetricId"] = MetricId.REQUESTS_DURATION;
         this._httpServerDurationHistogram.record(durationMs, metric.attributes);
         this.intervalRequestExecutionTime += durationMs;
         if (!success) {
@@ -88,7 +87,6 @@ export class AzureHttpMetricsInstrumentation extends InstrumentationBase<Http> {
         this.totalRequestCount++;
       }
       else {
-        metric.attributes["_MS.MetricId"] = MetricId.DEPENDENCIES_DURATION;
         this._httpClientDurationHistogram.record(durationMs, metric.attributes);
         this.intervalDependencyExecutionTime += durationMs;
         if (!success) {
diff --git a/src/autoCollection/metrics/collection/exceptionMetrics.ts b/src/autoCollection/metrics/collection/exceptionMetrics.ts
index 6026865..a15320c 100644
--- a/src/autoCollection/metrics/collection/exceptionMetrics.ts
+++ b/src/autoCollection/metrics/collection/exceptionMetrics.ts
@@ -1,36 +1,25 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT license.
-import { Meter, MetricAttributes, ObservableCallback, ObservableGauge, ObservableResult, ValueType } from "@opentelemetry/api-metrics";
-import { AggregatedMetricCounter, IStandardMetricBaseDimensions, IMetricExceptionDimensions, MetricId, MetricName } from "../types";
+import { BatchObservableResult, Meter, ObservableGauge, ValueType } from "@opentelemetry/api-metrics";
+import { AggregatedMetricCounter, IStandardMetricBaseDimensions, IMetricExceptionDimensions, MetricName } from "../types";
 
 
 export class ExceptionMetrics {
-    private _isEnabled: boolean;
     private _meter: Meter;
     private _exceptionCountersCollection: Array<AggregatedMetricCounter>;
-    private _exceptionsGauge: ObservableGauge;
-    private _exceptionsGaugeCallback: ObservableCallback;
+    private _exceptionsCountGauge: ObservableGauge;
+    private _exceptionsRateGauge: ObservableGauge;
 
     constructor(meter: Meter) {
         this._meter = meter;
         this._exceptionCountersCollection = [];
-        this._exceptionsGauge = this._meter.createObservableGauge(MetricName.EXCEPTION_RATE, { valueType: ValueType.DOUBLE });
-        this._exceptionsGaugeCallback = this._getExceptions.bind(this);
-    }
-
-    public enable(isEnabled: boolean) {
-        this._isEnabled = isEnabled;
-        if (this._isEnabled) {
-            this._exceptionsGauge.addCallback(this._exceptionsGaugeCallback);
-        } else {
-            this._exceptionsGauge.removeCallback(this._exceptionsGaugeCallback);
-        }
+        this._exceptionsCountGauge = this._meter.createObservableGauge(MetricName.EXCEPTION_COUNT, { valueType: ValueType.INT });
+        this._exceptionsRateGauge = this._meter.createObservableGauge(MetricName.EXCEPTION_RATE, { valueType: ValueType.DOUBLE });
+        this._meter.addBatchObservableCallback(this._getExceptionCount.bind(this), [this._exceptionsCountGauge,]);
+        this._meter.addBatchObservableCallback(this._getExceptionRate.bind(this), [this._exceptionsRateGauge,]);
     }
 
     public countException(dimensions: IMetricExceptionDimensions) {
-        if (!this._isEnabled) {
-            return;
-        }
         let counter: AggregatedMetricCounter = this._getAggregatedCounter(
             dimensions,
             this._exceptionCountersCollection
@@ -75,15 +64,22 @@ export class ExceptionMetrics {
         return newCounter;
     }
 
-    private _getExceptions(observableResult: ObservableResult) {
+    private _getExceptionRate(observableResult: BatchObservableResult) {
         for (let i = 0; i < this._exceptionCountersCollection.length; i++) {
             var currentCounter = this._exceptionCountersCollection[i];
             currentCounter.time = +new Date();
             var intervalExceptions = currentCounter.totalCount - currentCounter.lastTotalCount || 0;
             var elapsedMs = currentCounter.time - currentCounter.lastTime;
             if (elapsedMs > 0 && intervalExceptions > 0) {
-                let attributes = this._getMetricAttributes(currentCounter.dimensions, elapsedMs, MetricId.TRACES_COUNT);
-                observableResult.observe(intervalExceptions, attributes);
+                var elapsedSeconds = elapsedMs / 1000;
+                var exceptionsPerSec = intervalExceptions / elapsedSeconds;
+                observableResult.observe(
+                    this._exceptionsRateGauge,
+                    exceptionsPerSec,
+                    {
+                        ...currentCounter.dimensions,
+                    }
+                );
             }
             // Set last counters
             currentCounter.lastTotalCount = currentCounter.totalCount;
@@ -91,14 +87,24 @@ export class ExceptionMetrics {
         }
     }
 
-    private _getMetricAttributes(dimensions: IStandardMetricBaseDimensions, aggregationInterval: number, metricType: string): MetricAttributes {
-        let attributes: MetricAttributes = {};
-        attributes = {
-            ...dimensions,
-            "_MS.MetricId": metricType,
-            "_MS.AggregationIntervalMs": String(aggregationInterval),
-            "_MS.IsAutocollected": "True",
-        };
-        return attributes;
+    private _getExceptionCount(observableResult: BatchObservableResult) {
+        for (let i = 0; i < this._exceptionCountersCollection.length; i++) {
+            var currentCounter = this._exceptionCountersCollection[i];
+            currentCounter.time = +new Date();
+            var intervalExceptions = currentCounter.totalCount - currentCounter.lastTotalCount || 0;
+            var elapsedMs = currentCounter.time - currentCounter.lastTime;
+            if (elapsedMs > 0 && intervalExceptions > 0) {
+                observableResult.observe(
+                    this._exceptionsCountGauge,
+                    intervalExceptions,
+                    {
+                        ...currentCounter.dimensions,
+                    }
+                );
+            }
+            // Set last counters
+            currentCounter.lastTotalCount = currentCounter.totalCount;
+            currentCounter.lastTime = currentCounter.time;
+        }
     }
 }
diff --git a/src/autoCollection/metrics/collection/traceMetrics.ts b/src/autoCollection/metrics/collection/traceMetrics.ts
index 2d15ff7..6449a46 100644
--- a/src/autoCollection/metrics/collection/traceMetrics.ts
+++ b/src/autoCollection/metrics/collection/traceMetrics.ts
@@ -1,36 +1,25 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT license.
-import { Meter, MetricAttributes, ObservableCallback, ObservableGauge, ObservableResult, ValueType } from "@opentelemetry/api-metrics";
-import { AggregatedMetricCounter, IStandardMetricBaseDimensions, IMetricTraceDimensions, MetricId, MetricName } from "../types";
+import { BatchObservableResult, Meter, ObservableGauge, ValueType } from "@opentelemetry/api-metrics";
+import { AggregatedMetricCounter, IMetricTraceDimensions, IStandardMetricBaseDimensions, MetricName } from "../types";
 
 
 export class TraceMetrics {
-    private _isEnabled: boolean;
     private _meter: Meter;
     private _traceCountersCollection: Array<AggregatedMetricCounter>;
-    private _tracesGauge: ObservableGauge;
-    private _tracesGaugeCallback: ObservableCallback;
+    private _tracesCountGauge: ObservableGauge;
+    private _tracesRateGauge: ObservableGauge;
 
     constructor(meter: Meter) {
         this._meter = meter;
         this._traceCountersCollection = [];
-        this._tracesGauge = this._meter.createObservableGauge(MetricName.TRACE_RATE, { valueType: ValueType.DOUBLE });
-        this._tracesGaugeCallback = this._getTraces.bind(this);
-    }
-
-    public enable(isEnabled: boolean) {
-        this._isEnabled = isEnabled;
-        if (this._isEnabled) {
-            this._tracesGauge.addCallback(this._tracesGaugeCallback);
-        } else {
-            this._tracesGauge.removeCallback(this._tracesGaugeCallback);
-        }
+        this._tracesCountGauge = this._meter.createObservableGauge(MetricName.TRACE_COUNT, { valueType: ValueType.INT });
+        this._tracesRateGauge = this._meter.createObservableGauge(MetricName.TRACE_RATE, { valueType: ValueType.DOUBLE });
+        this._meter.addBatchObservableCallback(this._getTraceCount.bind(this), [this._tracesCountGauge,]);
+        this._meter.addBatchObservableCallback(this._getTraceRate.bind(this), [this._tracesRateGauge,]);
     }
 
     public countTrace(dimensions: IMetricTraceDimensions) {
-        if (!this._isEnabled) {
-            return;
-        }
         let counter: AggregatedMetricCounter = this._getAggregatedCounter(
             dimensions,
             this._traceCountersCollection
@@ -75,15 +64,22 @@ export class TraceMetrics {
         return newCounter;
     }
 
-    private _getTraces(observableResult: ObservableResult) {
+    private _getTraceRate(observableResult: BatchObservableResult) {
         for (let i = 0; i < this._traceCountersCollection.length; i++) {
             var currentCounter = this._traceCountersCollection[i];
             currentCounter.time = +new Date();
             var intervalTraces = currentCounter.totalCount - currentCounter.lastTotalCount || 0;
             var elapsedMs = currentCounter.time - currentCounter.lastTime;
             if (elapsedMs > 0 && intervalTraces > 0) {
-                let attributes = this._getMetricAttributes(currentCounter.dimensions, elapsedMs, MetricId.TRACES_COUNT);
-                observableResult.observe(intervalTraces, attributes);
+                var elapsedSeconds = elapsedMs / 1000;
+                var tracesPerSec = intervalTraces / elapsedSeconds;
+                observableResult.observe(
+                    this._tracesRateGauge,
+                    tracesPerSec,
+                    {
+                        ...currentCounter.dimensions,
+                    }
+                );
             }
             // Set last counters
             currentCounter.lastTotalCount = currentCounter.totalCount;
@@ -91,14 +87,24 @@ export class TraceMetrics {
         }
     }
 
-    private _getMetricAttributes(dimensions: IStandardMetricBaseDimensions, aggregationInterval: number, metricType: string): MetricAttributes {
-        let attributes: MetricAttributes = {};
-        attributes = {
-            ...dimensions,
-            "_MS.MetricId": metricType,
-            "_MS.AggregationIntervalMs": String(aggregationInterval),
-            "_MS.IsAutocollected": "True",
-        };
-        return attributes;
+    private _getTraceCount(observableResult: BatchObservableResult) {
+        for (let i = 0; i < this._traceCountersCollection.length; i++) {
+            var currentCounter = this._traceCountersCollection[i];
+            currentCounter.time = +new Date();
+            var intervalTraces = currentCounter.totalCount - currentCounter.lastTotalCount || 0;
+            var elapsedMs = currentCounter.time - currentCounter.lastTime;
+            if (elapsedMs > 0 && intervalTraces > 0) {
+                observableResult.observe(
+                    this._tracesCountGauge,
+                    intervalTraces,
+                    {
+                        ...currentCounter.dimensions,
+                    }
+                );
+            }
+            // Set last counters
+            currentCounter.lastTotalCount = currentCounter.totalCount;
+            currentCounter.lastTime = currentCounter.time;
+        }
     }
 }
diff --git a/src/autoCollection/metrics/handlers/liveMetricsHandler.ts b/src/autoCollection/metrics/handlers/liveMetricsHandler.ts
index 69e4007..21081bc 100644
--- a/src/autoCollection/metrics/handlers/liveMetricsHandler.ts
+++ b/src/autoCollection/metrics/handlers/liveMetricsHandler.ts
@@ -61,7 +61,6 @@ export class LiveMetricsHandler {
 
     public start() {
         this._processMetrics.enable(true);
-        this._exceptionMetrics.enable(true);
         this._requestMetrics.enable(true);
         this._dependencyMetrics.enable(true);
     }
@@ -149,6 +148,14 @@ export class LiveMetricsHandler {
             instrumentName: MetricName.PROCESS_TIME,
             aggregation: new DropAggregation(),
         }));
+        views.push(new View({
+            instrumentName: MetricName.EXCEPTION_COUNT,
+            aggregation: new DropAggregation(),
+        }));
+        views.push(new View({
+            instrumentName: MetricName.TRACE_COUNT,
+            aggregation: new DropAggregation(),
+        }));
         return views;
     }
 }
diff --git a/src/autoCollection/metrics/handlers/standardMetricsHandler.ts b/src/autoCollection/metrics/handlers/standardMetricsHandler.ts
index d031364..7a3d6ae 100644
--- a/src/autoCollection/metrics/handlers/standardMetricsHandler.ts
+++ b/src/autoCollection/metrics/handlers/standardMetricsHandler.ts
@@ -1,6 +1,6 @@
 import { AzureExporterConfig, AzureMonitorMetricExporter } from "@azure/monitor-opentelemetry-exporter";
 import { Meter } from "@opentelemetry/api-metrics";
-import { MeterProvider, MeterProviderOptions, PeriodicExportingMetricReader, PeriodicExportingMetricReaderOptions, View } from "@opentelemetry/sdk-metrics";
+import { DropAggregation, MeterProvider, MeterProviderOptions, PeriodicExportingMetricReader, PeriodicExportingMetricReaderOptions, View } from "@opentelemetry/sdk-metrics";
 import { Config } from "../../../library";
 import { ResourceManager } from "../../../library/handlers";
 import { ExceptionMetrics } from "../collection/exceptionMetrics";
@@ -42,11 +42,6 @@ export class StandardMetricsHandler {
         this._traceMetrics = new TraceMetrics(this._meter);
     }
 
-    public start() {
-        this._exceptionMetrics.enable(true);
-        this._traceMetrics.enable(true);
-    }
-
     public shutdown() {
         this._meterProvider.shutdown();
     }
@@ -66,22 +61,29 @@ export class StandardMetricsHandler {
     private _getViews(): View[] {
         let views = [];
         views.push(new View({
-            name: StandardMetric.REQUESTS,
-            instrumentName: MetricName.REQUEST_DURATION,
-            attributeKeys: []
+            name: StandardMetric.HTTP_REQUEST_DURATION,
+            instrumentName: "http.server.duration" // Metric semantic conventions not available yet
+        }));
+        views.push(new View({
+            name: StandardMetric.HTTP_DEPENDENCY_DURATION,
+            instrumentName: "http.client.duration" // Metric semantic conventions not available yet
+        }));
+        views.push(new View({
+            name: StandardMetric.EXCEPTION_COUNT,
+            instrumentName: MetricName.EXCEPTION_COUNT
         }));
         views.push(new View({
-            name: StandardMetric.DEPENDENCIES,
-            instrumentName: MetricName.DEPENDENCY_DURATION,
-            attributeKeys: []
+            name: StandardMetric.TRACE_COUNT,
+            instrumentName: MetricName.TRACE_COUNT
         }));
+        // Ignore list
         views.push(new View({
-            name: StandardMetric.EXCEPTIONS,
-            instrumentName: MetricName.EXCEPTION_RATE
+            instrumentName: MetricName.EXCEPTION_RATE,
+            aggregation: new DropAggregation(),
         }));
         views.push(new View({
-            name: StandardMetric.TRACES,
-            instrumentName: MetricName.TRACE_RATE
+            instrumentName: MetricName.TRACE_RATE,
+            aggregation: new DropAggregation(),
         }));
         return views;
     }
diff --git a/src/autoCollection/metrics/types.ts b/src/autoCollection/metrics/types.ts
index 53241e7..08003ad 100644
--- a/src/autoCollection/metrics/types.ts
+++ b/src/autoCollection/metrics/types.ts
@@ -25,8 +25,10 @@ export enum MetricName {
   DEPENDENCY_DURATION = "DEPENDENCY_DURATION",
   // Exceptions
   EXCEPTION_RATE = "EXCEPTION_RATE",
+  EXCEPTION_COUNT = "EXCEPTION_COUNT",
   // Traces
   TRACE_RATE = "TRACE_RATE",
+  TRACE_COUNT = "TRACE_COUNT",
 }
 
 export enum PerformanceCounter {
@@ -59,10 +61,10 @@ export enum QuickPulseCounter {
 }
 
 export enum StandardMetric {
-  REQUESTS = "http.server.duration",
-  DEPENDENCIES = "http.client.duration",
-  EXCEPTIONS = "Exceptions",
-  TRACES = "Traces",
+  HTTP_REQUEST_DURATION = "azureMonitor.http.requestDuration",
+  HTTP_DEPENDENCY_DURATION = "azureMonitor.http.dependencyDuration",
+  EXCEPTION_COUNT = "azureMonitor.exceptionCount",
+  TRACE_COUNT = "azureMonitor.traceCount",
 }
 
 export enum NativeMetricsCounter {
@@ -81,16 +83,8 @@ export enum GarbageCollectionType {
   IncrementalMarking = "IncrementalMarking"
 }
 
-export enum MetricId {
-  REQUESTS_DURATION = "requests/duration",
-  DEPENDENCIES_DURATION = "dependencies/duration",
-  EXCEPTIONS_COUNT = "exceptions/count",
-  TRACES_COUNT = "traces/count",
-}
-
 export class AggregatedMetric {
   public name: string;
-  public metricType: MetricId;
   public dimensions: { [key: string]: any };
   public value: number;
   public count: number;
diff --git a/src/library/handlers/metricHandler.ts b/src/library/handlers/metricHandler.ts
index e221113..002ed44 100644
--- a/src/library/handlers/metricHandler.ts
+++ b/src/library/handlers/metricHandler.ts
@@ -42,7 +42,6 @@ export class MetricHandler {
     public start() {
         this._perfCounterMetricsHandler?.start();
         this._liveMetricsHandler?.start();
-        this._standardMetricsHandler?.start();
         this._heartbeatHandler?.start();
     }
 
diff --git a/src/library/handlers/sampler.ts b/src/library/handlers/sampler.ts
index 33be6f1..dfa347d 100644
--- a/src/library/handlers/sampler.ts
+++ b/src/library/handlers/sampler.ts
@@ -4,6 +4,8 @@ import { Link, Attributes, SpanKind, Context } from '@opentelemetry/api';
 import { Sampler, SamplingDecision, SamplingResult } from '@opentelemetry/sdk-trace-base';
 
 
+const AzureMonitorSampleRate = "_MS.sampleRate"; 
+
 export class ApplicationInsightsSampler implements Sampler {
 
     private readonly _samplingPercentage: number
@@ -31,7 +33,7 @@ export class ApplicationInsightsSampler implements Sampler {
         }
         // Add sample rate as span attribute
         attributes = attributes || {};
-        attributes["sampleRate"] = this._samplingPercentage;
+        attributes[AzureMonitorSampleRate] = this._samplingPercentage;
         return isSampledIn ? { decision: SamplingDecision.RECORD_AND_SAMPLED, attributes: attributes } : { decision: SamplingDecision.NOT_RECORD, attributes: attributes };
     }
 
diff --git a/src/library/handlers/traceHandler.ts b/src/library/handlers/traceHandler.ts
index 354f9fa..e237bf6 100644
--- a/src/library/handlers/traceHandler.ts
+++ b/src/library/handlers/traceHandler.ts
@@ -102,7 +102,9 @@ export class TraceHandler {
         }
         if (!this._httpInstrumentation) {
             this._httpInstrumentation = new HttpInstrumentation(this._config.instrumentations.http);
-            this._httpInstrumentation.setMeterProvider(this._metricHandler.getStandardMetricsHandler().getMeterProvider());
+            if (this._metricHandler) {
+                this._httpInstrumentation.setMeterProvider(this._metricHandler.getStandardMetricsHandler().getMeterProvider());
+            }
             this.addInstrumentation(this._httpInstrumentation);
         }
         if (!this._azureSdkInstrumentation) {


Test patch:
diff --git a/test/unitTests/autoCollection/liveMetricsHandler.tests.ts b/test/unitTests/autoCollection/liveMetricsHandler.tests.ts
index 3f70e8e..7b45d02 100644
--- a/test/unitTests/autoCollection/liveMetricsHandler.tests.ts
+++ b/test/unitTests/autoCollection/liveMetricsHandler.tests.ts
@@ -27,7 +27,7 @@ describe("#LiveMetricsHandler", () => {
     });
 
     it("should create instruments", () => {
-        assert.ok(autoCollect.getExceptionMetrics()["_exceptionsGauge"], "_exceptionsGauge not available");
+        assert.ok(autoCollect.getExceptionMetrics()["_exceptionsRateGauge"], "_exceptionsRateGauge not available");
         assert.ok(autoCollect.getRequestMetrics()["_requestRateGauge"], "_requestRateGauge not available");
         assert.ok(autoCollect.getRequestMetrics()["_requestFailureRateGauge"], "_requestFailureRateGauge not available");
         assert.ok(autoCollect.getDependencyMetrics()["_dependencyRateGauge"], "_dependencyRateGauge not available");
diff --git a/test/unitTests/autoCollection/standardMetrics.tests.ts b/test/unitTests/autoCollection/standardMetrics.tests.ts
index 3d001a8..5c1406e 100644
--- a/test/unitTests/autoCollection/standardMetrics.tests.ts
+++ b/test/unitTests/autoCollection/standardMetrics.tests.ts
@@ -27,19 +27,28 @@ describe("#StandardMetricsHandler", () => {
     });
 
     it("should create instruments", () => {
-        assert.ok(autoCollect.getExceptionMetrics()["_exceptionsGauge"], "_exceptionsGauge not available");
-        assert.ok(autoCollect.getTraceMetrics()["_tracesGauge"], "_tracesGauge not available");
+        assert.ok(autoCollect.getExceptionMetrics()["_exceptionsRateGauge"], "_exceptionsRateGauge not available");
+        assert.ok(autoCollect.getTraceMetrics()["_tracesRateGauge"], "_tracesRateGauge not available");
     });
 
     it("should observe instruments during collection", async () => {
         let mockExport = sandbox.stub(autoCollect["_azureExporter"], "export");
-        autoCollect.start();
+        // autoCollect.start();
         let dimensions: IMetricExceptionDimensions = {
             cloudRoleInstance: "testcloudRoleInstance",
             cloudRoleName: "testcloudRoleName"
         };
         autoCollect.getExceptionMetrics().countException(dimensions);
         autoCollect.getTraceMetrics().countTrace(dimensions);
+        dimensions = {
+            cloudRoleInstance: "testcloudRoleInstance2",
+            cloudRoleName: "testcloudRoleName2"
+        };
+        for (let i = 0; i < 10; i++) {
+            autoCollect.getExceptionMetrics().countException(dimensions);
+            autoCollect.getTraceMetrics().countTrace(dimensions);
+        }
+
         await new Promise(resolve => setTimeout(resolve, 120));
         assert.ok(mockExport.called);
         let resourceMetrics = mockExport.args[0][0];
@@ -47,13 +56,27 @@ describe("#StandardMetricsHandler", () => {
         assert.strictEqual(scopeMetrics.length, 1, 'scopeMetrics count');
         let metrics = scopeMetrics[0].metrics;
         assert.strictEqual(metrics.length, 2, 'metrics count');
-        assert.equal(metrics[0].descriptor.name, StandardMetric.EXCEPTIONS);
-        assert.equal(metrics[1].descriptor.name, StandardMetric.TRACES);
+        assert.equal(metrics[0].descriptor.name, StandardMetric.EXCEPTION_COUNT);
+        assert.equal(metrics[1].descriptor.name, StandardMetric.TRACE_COUNT);
+        assert.strictEqual(metrics[0].dataPoints.length, 2, 'dataPoints count');
+        // Exceptions
+        assert.strictEqual(metrics[0].dataPoints[0].value, 1, 'dataPoint value');
+        assert.strictEqual(metrics[0].dataPoints[0].attributes["cloudRoleInstance"], "testcloudRoleInstance");
+        assert.strictEqual(metrics[0].dataPoints[0].attributes["cloudRoleName"], "testcloudRoleName");
+        assert.strictEqual(metrics[0].dataPoints[1].value, 10, 'dataPoint value');
+        assert.strictEqual(metrics[0].dataPoints[1].attributes["cloudRoleInstance"], "testcloudRoleInstance2");
+        assert.strictEqual(metrics[0].dataPoints[1].attributes["cloudRoleName"], "testcloudRoleName2");
+        // Traces
+        assert.strictEqual(metrics[1].dataPoints[0].value, 1, 'dataPoint value');
+        assert.strictEqual(metrics[1].dataPoints[0].attributes["cloudRoleInstance"], "testcloudRoleInstance");
+        assert.strictEqual(metrics[1].dataPoints[0].attributes["cloudRoleName"], "testcloudRoleName");
+        assert.strictEqual(metrics[1].dataPoints[1].value, 10, 'dataPoint value');
+        assert.strictEqual(metrics[1].dataPoints[1].attributes["cloudRoleInstance"], "testcloudRoleInstance2");
+        assert.strictEqual(metrics[1].dataPoints[1].attributes["cloudRoleName"], "testcloudRoleName2");
     });
 
     it("should not collect when disabled", async () => {
         let mockExport = sandbox.stub(autoCollect["_azureExporter"], "export");
-        autoCollect.start();
         autoCollect.shutdown();
         await new Promise(resolve => setTimeout(resolve, 120));
         assert.ok(mockExport.notCalled);
@@ -136,7 +159,6 @@ describe("#StandardMetricsHandler", () => {
 
         it("http outgoing/incoming requests", async () => {
             let mockExport = sandbox.stub(autoCollect["_azureExporter"], "export");
-            autoCollect.start();
             await makeHttpRequest();
             await new Promise(resolve => setTimeout(resolve, 120));
             assert.ok(mockExport.called);
@@ -145,12 +167,12 @@ describe("#StandardMetricsHandler", () => {
             assert.strictEqual(scopeMetrics.length, 2, 'scopeMetrics count');
             let metrics = scopeMetrics[0].metrics;
             assert.strictEqual(metrics.length, 2, 'metrics count');
-            assert.equal(metrics[0].descriptor.name, StandardMetric.EXCEPTIONS);
-            assert.equal(metrics[1].descriptor.name, StandardMetric.TRACES);
+            assert.equal(metrics[0].descriptor.name, StandardMetric.EXCEPTION_COUNT);
+            assert.equal(metrics[1].descriptor.name, StandardMetric.TRACE_COUNT);
             metrics = scopeMetrics[1].metrics;
             assert.strictEqual(metrics.length, 2, 'metrics count');
-            assert.equal(metrics[0].descriptor.name, "http.server.duration");
-            assert.equal(metrics[1].descriptor.name, "http.client.duration");
+            assert.equal(metrics[0].descriptor.name, StandardMetric.HTTP_REQUEST_DURATION);
+            assert.equal(metrics[1].descriptor.name, StandardMetric.HTTP_DEPENDENCY_DURATION);
         });
     });
 });
\ No newline at end of file
diff --git a/test/unitTests/library/metricHandler.tests.ts b/test/unitTests/library/metricHandler.tests.ts
index e4db501..e9a953e 100644
--- a/test/unitTests/library/metricHandler.tests.ts
+++ b/test/unitTests/library/metricHandler.tests.ts
@@ -35,9 +35,8 @@ describe("Library/MetricHandler", () => {
             _config.enableAutoCollectPreAggregatedMetrics = true;
             let handler = new MetricHandler(_config);
             handler["_perfCounterMetricsHandler"]["_nativeMetrics"]["_metricsAvailable"] = false;
-            let stub = sinon.stub(handler["_standardMetricsHandler"], "start");
             handler.start();
-            assert.ok(stub.calledOnce, "start called");
+            assert.ok(handler.getStandardMetricsHandler());
         });
 
         it("heartbeat metrics enablement during start", () => {
diff --git a/test/unitTests/library/sampler.tests.ts b/test/unitTests/library/sampler.tests.ts
index 6f48f53..29b952a 100644
--- a/test/unitTests/library/sampler.tests.ts
+++ b/test/unitTests/library/sampler.tests.ts
@@ -1,5 +1,5 @@
 import * as assert from "assert";
-import { SamplingDecision } from "@opentelemetry/api";
+import { SamplingDecision } from "@opentelemetry/sdk-trace-base";
 import { ApplicationInsightsSampler } from "../../../src/library/handlers/sampler";