diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/Declarations/Contracts/Generated/Envelope.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/Declarations/Contracts/Generated/Envelope.ts deleted file mode 100644 index ec03cf3101bb..000000000000 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/Declarations/Contracts/Generated/Envelope.ts +++ /dev/null @@ -1,55 +0,0 @@ -// THIS FILE WAS AUTOGENERATED -import Base = require("./Base"); -"use strict"; - -/** - * System variables for a telemetry item. - */ -class Envelope { - /** - * Envelope version. For internal use only. By assigning this the default, it will not be serialized within the payload unless changed to a value other than #1. - */ - public ver: number; - - /** - * Type name of telemetry data item. - */ - public name: string | undefined; - - /** - * Event date time when telemetry item was created. This is the wall clock time on the client when the event was generated. There is no guarantee that the client's time is accurate. This field must be formatted in UTC ISO 8601 format, with a trailing 'Z' character, as described publicly on https://en.wikipedia.org/wiki/ISO_8601#UTC. Note: the number of decimal seconds digits provided are variable (and unspecified). Consumers should handle this, i.e. managed code consumers should not use format 'O' for parsing as it specifies a fixed length. Example: 2009-06-15T13:45:30.0000000Z. - */ - public time: string | undefined; - - /** - * Sampling rate used in application. This telemetry item represents 1 / sampleRate actual telemetry items. - */ - public sampleRate: number; - - /** - * Sequence field used to track absolute order of uploaded events. - */ - public seq: string | undefined; - - /** - * The application's instrumentation key. The key is typically represented as a GUID, but there are cases when it is not a guid. No code should rely on iKey being a GUID. Instrumentation key is case insensitive. - */ - public iKey: string | undefined; - - /** - * Key/value collection of context properties. See ContextTagKeys for information on available properties. - */ - public tags: any; - - /** - * Telemetry data item. - */ - public data: Base | undefined; - - constructor() { - this.ver = 1; - this.sampleRate = 100.0; - this.tags = {}; - } -} -export = Envelope; diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/Declarations/Contracts/Generated/index.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/Declarations/Contracts/Generated/index.ts index b5f2bd14709e..5a7686fb0f9a 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/Declarations/Contracts/Generated/index.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/src/Declarations/Contracts/Generated/index.ts @@ -4,4 +4,3 @@ export import Base = require("./Base"); export import ContextTagKeys = require("./ContextTagKeys"); export import Data = require("./Data"); export import Domain = require("./Domain"); -export import Envelope = require("./Envelope"); diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/export/exporter.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/export/exporter.ts index bf25a7341796..bea48953256e 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/export/exporter.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/src/export/exporter.ts @@ -3,13 +3,13 @@ import { Logger } from "@opentelemetry/api"; import { ConsoleLogger, LogLevel, ExportResult } from "@opentelemetry/core"; -import { Envelope } from "../Declarations/Contracts"; import { ConnectionStringParser } from "../utils/connectionStringParser"; import { HttpSender, FileSystemPersist } from "../platform"; import { DEFAULT_EXPORTER_CONFIG, AzureExporterConfig } from "../config"; import { BaseExporter, TelemetryProcessor, PersistentStorage, Sender } from "../types"; import { isRetriable, BreezeResponse } from "../utils/breezeUtils"; import { ENV_CONNECTION_STRING, ENV_INSTRUMENTATION_KEY } from "../Declarations/Constants"; +import { TelemetryItem as Envelope } from "../generated"; export abstract class AzureMonitorBaseExporter implements BaseExporter { protected readonly _persister: PersistentStorage; diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/generated/applicationInsightsClient.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/generated/applicationInsightsClient.ts index adc482835895..33dea89acc02 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/generated/applicationInsightsClient.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/src/generated/applicationInsightsClient.ts @@ -26,11 +26,8 @@ export class ApplicationInsightsClient extends ApplicationInsightsClientContext } /** - * This operation generates a model using an entire series, each point is detected with the same model. - * With this method, points before and after a certain point are used to determine whether it is an - * anomaly. The entire detection can give user an overall status of the time series. - * @param body Time series points and period if needed. Advanced model parameters can also be set in - * the request. + * This operation sends a sequence of telemetry events that will be monitored by Azure Monitor. + * @param body The list of telemetry events to track. * @param options The options parameters. */ track( diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/generated/models/index.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/generated/models/index.ts index f993f333b3fa..992703831040 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/generated/models/index.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/src/generated/models/index.ts @@ -23,7 +23,7 @@ export interface TelemetryItem { /** * Event date time when telemetry item was created. This is the wall clock time on the client when the event was generated. There is no guarantee that the client's time is accurate. This field must be formatted in UTC ISO 8601 format, with a trailing 'Z' character, as described publicly on https://en.wikipedia.org/wiki/ISO_8601#UTC. Note: the number of decimal seconds digits provided are variable (and unspecified). Consumers should handle this, i.e. managed code consumers should not use format 'O' for parsing as it specifies a fixed length. Example: 2009-06-15T13:45:30.0000000Z. */ - time: Date; + time: string; /** * Sampling rate used in application. This telemetry item represents 1 / sampleRate actual telemetry items. */ @@ -65,9 +65,13 @@ export interface MonitorBase { */ export interface MonitorDomain { /** - * Ignored value. + * Describes unknown properties. The value of an unknown property can be of "any" type. */ - test?: string; + [property: string]: any; + /** + * Schema version + */ + version: number; } /** @@ -205,10 +209,6 @@ export interface StackFrame { * Instances of AvailabilityData represent the result of executing an availability test. */ export type AvailabilityData = MonitorDomain & { - /** - * Schema version - */ - version: number; /** * Identifier of a test run. Use it to correlate steps of test run and telemetry generated by the service. */ @@ -247,10 +247,6 @@ export type AvailabilityData = MonitorDomain & { * Instances of Event represent structured event records that can be grouped and searched by their properties. Event data item also creates a metric of event count by name. */ export type TelemetryEventData = MonitorDomain & { - /** - * Schema version - */ - version: number; /** * Event name. Keep it low cardinality to allow proper grouping and useful metrics. */ @@ -269,14 +265,10 @@ export type TelemetryEventData = MonitorDomain & { * An instance of Exception represents a handled or unhandled exception that occurred during execution of the monitored application. */ export type TelemetryExceptionData = MonitorDomain & { - /** - * Schema version - */ - version: number; /** * Exception chain - list of inner exceptions. */ - exceptions?: TelemetryExceptionDetails[]; + exceptions: TelemetryExceptionDetails[]; /** * Severity level. Mostly used to indicate exception severity level when it is reported by logging library. */ @@ -296,13 +288,9 @@ export type TelemetryExceptionData = MonitorDomain & { }; /** - * Instances of Message represent printf-like trace statements that are text-searched. Log4Net, NLog and other text-based log file entries are translated into intances of this type. The message does not have measurements. + * Instances of Message represent printf-like trace statements that are text-searched. Log4Net, NLog and other text-based log file entries are translated into instances of this type. The message does not have measurements. */ export type MessageData = MonitorDomain & { - /** - * Schema version - */ - version: number; /** * Trace message */ @@ -325,10 +313,6 @@ export type MessageData = MonitorDomain & { * An instance of the Metric item is a list of measurements (single data points) and/or aggregations. */ export type MetricsData = MonitorDomain & { - /** - * Schema version - */ - version: number; /** * List of metrics. Only one metric in the list is currently supported by Application Insights storage. If multiple data points were sent only the first one will be used. */ @@ -343,10 +327,6 @@ export type MetricsData = MonitorDomain & { * An instance of PageView represents a generic action on a page like a button click. It is also the base type for PageView. */ export type PageViewData = MonitorDomain & { - /** - * Schema version - */ - version: number; /** * Identifier of a page view instance. Used for correlation between page view and other telemetry items. */ @@ -381,10 +361,6 @@ export type PageViewData = MonitorDomain & { * An instance of PageViewPerf represents: a page view with no performance data, a page view with performance data, or just the performance data of an earlier page request. */ export type PageViewPerfData = MonitorDomain & { - /** - * Schema version - */ - version: number; /** * Identifier of a page view instance. Used for correlation between page view and other telemetry items. */ @@ -435,10 +411,6 @@ export type PageViewPerfData = MonitorDomain & { * An instance of Remote Dependency represents an interaction of the monitored component with a remote component/service like SQL or an HTTP endpoint. */ export type RemoteDependencyData = MonitorDomain & { - /** - * Schema version - */ - version: number; /** * Identifier of a dependency call instance. Used for correlation with the request telemetry item corresponding to this dependency call. */ @@ -452,7 +424,7 @@ export type RemoteDependencyData = MonitorDomain & { */ resultCode?: string; /** - * Command initiated by this dependency call. Examples are SQL statement and HTTP URL's with all query parameters. + * Command initiated by this dependency call. Examples are SQL statement and HTTP URL with all query parameters. */ data?: string; /** @@ -468,7 +440,7 @@ export type RemoteDependencyData = MonitorDomain & { */ duration: string; /** - * Indication of successfull or unsuccessfull call. + * Indication of successful or unsuccessful call. */ success?: boolean; /** @@ -482,13 +454,9 @@ export type RemoteDependencyData = MonitorDomain & { }; /** - * An instance of PageView represents a generic action on a page like a button click. It is also the base type for PageView. + * An instance of Request represents completion of an external request to the application to do work and contains a summary of that request execution and the results. */ export type RequestData = MonitorDomain & { - /** - * Schema version - */ - version: number; /** * Identifier of a request call instance. Used for correlation between request and other telemetry items. */ @@ -502,7 +470,7 @@ export type RequestData = MonitorDomain & { */ duration: string; /** - * Indication of successfull or unsuccessfull call. + * Indication of successful or unsuccessful call. */ success: boolean; /** diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/generated/models/mappers.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/generated/models/mappers.ts index d7e585c7c8ed..1bdd1eded469 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/generated/models/mappers.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/src/generated/models/mappers.ts @@ -31,7 +31,7 @@ export const TelemetryItem: coreHttp.CompositeMapper = { serializedName: "time", required: true, type: { - name: "DateTime" + name: "String" } }, sampleRate: { @@ -100,11 +100,14 @@ export const MonitorDomain: coreHttp.CompositeMapper = { type: { name: "Composite", className: "MonitorDomain", + additionalProperties: { type: { name: "Object" } }, modelProperties: { - test: { - serializedName: "test", + version: { + defaultValue: 2, + serializedName: "ver", + required: true, type: { - name: "String" + name: "Number" } } } @@ -350,16 +353,9 @@ export const AvailabilityData: coreHttp.CompositeMapper = { type: { name: "Composite", className: "AvailabilityData", + additionalProperties: { type: { name: "Object" } }, modelProperties: { ...MonitorDomain.type.modelProperties, - version: { - defaultValue: 2, - serializedName: "ver", - required: true, - type: { - name: "Number" - } - }, id: { constraints: { MaxLength: 512 @@ -434,16 +430,9 @@ export const TelemetryEventData: coreHttp.CompositeMapper = { type: { name: "Composite", className: "TelemetryEventData", + additionalProperties: { type: { name: "Object" } }, modelProperties: { ...MonitorDomain.type.modelProperties, - version: { - defaultValue: 2, - serializedName: "ver", - required: true, - type: { - name: "Number" - } - }, name: { constraints: { MaxLength: 512 @@ -476,18 +465,12 @@ export const TelemetryExceptionData: coreHttp.CompositeMapper = { type: { name: "Composite", className: "TelemetryExceptionData", + additionalProperties: { type: { name: "Object" } }, modelProperties: { ...MonitorDomain.type.modelProperties, - version: { - defaultValue: 2, - serializedName: "ver", - required: true, - type: { - name: "Number" - } - }, exceptions: { serializedName: "exceptions", + required: true, type: { name: "Sequence", element: { @@ -532,16 +515,9 @@ export const MessageData: coreHttp.CompositeMapper = { type: { name: "Composite", className: "MessageData", + additionalProperties: { type: { name: "Object" } }, modelProperties: { ...MonitorDomain.type.modelProperties, - version: { - defaultValue: 2, - serializedName: "ver", - required: true, - type: { - name: "Number" - } - }, message: { constraints: { MaxLength: 32768 @@ -580,16 +556,9 @@ export const MetricsData: coreHttp.CompositeMapper = { type: { name: "Composite", className: "MetricsData", + additionalProperties: { type: { name: "Object" } }, modelProperties: { ...MonitorDomain.type.modelProperties, - version: { - defaultValue: 2, - serializedName: "ver", - required: true, - type: { - name: "Number" - } - }, metrics: { serializedName: "metrics", required: true, @@ -613,16 +582,9 @@ export const PageViewData: coreHttp.CompositeMapper = { type: { name: "Composite", className: "PageViewData", + additionalProperties: { type: { name: "Object" } }, modelProperties: { ...MonitorDomain.type.modelProperties, - version: { - defaultValue: 2, - serializedName: "ver", - required: true, - type: { - name: "Number" - } - }, id: { constraints: { MaxLength: 512 @@ -689,16 +651,9 @@ export const PageViewPerfData: coreHttp.CompositeMapper = { type: { name: "Composite", className: "PageViewPerfData", + additionalProperties: { type: { name: "Object" } }, modelProperties: { ...MonitorDomain.type.modelProperties, - version: { - defaultValue: 2, - serializedName: "ver", - required: true, - type: { - name: "Number" - } - }, id: { constraints: { MaxLength: 512 @@ -786,16 +741,9 @@ export const RemoteDependencyData: coreHttp.CompositeMapper = { type: { name: "Composite", className: "RemoteDependencyData", + additionalProperties: { type: { name: "Object" } }, modelProperties: { ...MonitorDomain.type.modelProperties, - version: { - defaultValue: 2, - serializedName: "ver", - required: true, - type: { - name: "Number" - } - }, id: { constraints: { MaxLength: 512 @@ -887,16 +835,9 @@ export const RequestData: coreHttp.CompositeMapper = { type: { name: "Composite", className: "RequestData", + additionalProperties: { type: { name: "Object" } }, modelProperties: { ...MonitorDomain.type.modelProperties, - version: { - defaultValue: 2, - serializedName: "ver", - required: true, - type: { - name: "Number" - } - }, id: { constraints: { MaxLength: 512 diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/platform/nodejs/httpSender.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/platform/nodejs/httpSender.ts index c3e77e64a638..ba009f4b96b9 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/platform/nodejs/httpSender.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/src/platform/nodejs/httpSender.ts @@ -1,53 +1,33 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import * as zlib from "zlib"; import { Logger } from "@opentelemetry/api"; import { ConsoleLogger, LogLevel } from "@opentelemetry/core"; import { Sender, SenderResult } from "../../types"; -import { Envelope } from "../../Declarations/Contracts"; -import { DEFAULT_SENDER_OPTIONS, NodejsPlatformConfig } from "../types"; -import { promisify } from "util"; -import { DefaultHttpClient, HttpClient, HttpHeaders, WebResource } from "@azure/core-http"; - -const gzipAsync = promisify(zlib.gzip); +import { + TelemetryItem as Envelope, + ApplicationInsightsClient, + ApplicationInsightsClientOptionalParams +} from "../../generated"; +import { AzureExporterConfig } from "../../config"; export class HttpSender implements Sender { private readonly _logger: Logger; - private readonly _httpClient: HttpClient; + private readonly _appInsightsClient: ApplicationInsightsClient; - constructor(private _options: NodejsPlatformConfig = DEFAULT_SENDER_OPTIONS) { - this._logger = _options.logger || new ConsoleLogger(LogLevel.ERROR); - this._httpClient = new DefaultHttpClient(); + constructor( + private _exporterOptions: Partial = {}, + private _appInsightsClientOptions: ApplicationInsightsClientOptionalParams = {} + ) { + this._logger = this._exporterOptions.logger || new ConsoleLogger(LogLevel.ERROR); + this._appInsightsClient = new ApplicationInsightsClient({ + ...this._appInsightsClientOptions + }); } async send(envelopes: Envelope[]): Promise { - const endpointUrl = `${this._options.endpointUrl}/v2/track`; - const payload = Buffer.from(JSON.stringify(envelopes)); - - const headers = new HttpHeaders({ "Content-Type": "application/x-json-stream" }); - - let dataToSend: Buffer; - try { - dataToSend = await gzipAsync(payload); - headers.set("Content-Encoding", "gzip"); - } catch (err) { - this._logger.warn(`Failed to gzip payload: ${err.message}. Sending payload uncompressed`); - dataToSend = payload; // something went wrong so send without gzip - } - headers.set("Content-Length", dataToSend.length); - - const options = new WebResource( - endpointUrl, - "POST", - dataToSend, - undefined, - headers, - undefined, - false // withCredentials: false - ); - const res = await this._httpClient.sendRequest(options); + const { _response: res } = await this._appInsightsClient.track(envelopes); return { statusCode: res.status, result: res.bodyAsText || "" }; } diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/platform/types.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/platform/types.ts deleted file mode 100644 index d06238b660ff..000000000000 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/platform/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import * as http from "http"; -import * as https from "https"; -import { DEFAULT_EXPORTER_CONFIG, AzureExporterConfig } from "../config"; - -/** - * Node.js and platform specific - */ -export interface NodejsPlatformConfig extends AzureExporterConfig { - proxyHttpsUrl?: string; - proxyHttpUrl?: string; - httpAgent?: http.Agent; - httpsAgent?: https.Agent; -} - -// Noop for now until sender requires -export const DEFAULT_SENDER_OPTIONS: NodejsPlatformConfig = { - ...DEFAULT_EXPORTER_CONFIG, -}; diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/types.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/types.ts index 60f912607320..c2afb7249b7c 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/types.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/src/types.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { ExportResult } from "@opentelemetry/core"; -import { Envelope } from "./Declarations/Contracts"; +import { TelemetryItem as Envelope } from "./generated"; export type Tags = { [key: string]: string }; export type PropertyType = string | number | boolean | object | Array; diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/utils/eventhub.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/utils/eventhub.ts index 1872685a5c5c..af8eacab0bd5 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/utils/eventhub.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/src/utils/eventhub.ts @@ -5,7 +5,7 @@ import { SpanKind } from "@opentelemetry/api"; import { hrTimeToMilliseconds } from "@opentelemetry/core"; import { GeneralAttribute } from "@opentelemetry/semantic-conventions"; import { ReadableSpan } from "@opentelemetry/tracing"; -import { Envelope } from "../Declarations/Contracts"; +import { RemoteDependencyData, RequestData } from "../generated"; import { TIME_SINCE_ENQUEUED, ENQUEUED_TIME } from "./constants/applicationinsights"; import { AzNamespace, @@ -37,9 +37,10 @@ const getTimeSinceEnqueued = (span: ReadableSpan) => { * * https://gist.github.com/lmolkova/e4215c0f44a49ef824983382762e6b92#mapping-to-azure-monitor-application-insights-telemetry */ -export const parseEventHubSpan = (span: ReadableSpan, envelope: Envelope): void => { - if (!envelope.data?.baseData) return; - +export const parseEventHubSpan = ( + span: ReadableSpan, + baseData: RequestData | RemoteDependencyData +): void => { const namespace = span.attributes[AzNamespace] as typeof MicrosoftEventHub; const peerAddress = ((span.attributes[GeneralAttribute.NET_PEER_ADDRESS] || span.attributes["peer.address"] || @@ -48,18 +49,18 @@ export const parseEventHubSpan = (span: ReadableSpan, envelope: Envelope): void switch (span.kind) { case SpanKind.CLIENT: - envelope.data.baseData.type = namespace; - envelope.data.baseData.target = `${peerAddress}/${messageBusDestination}`; + baseData.type = namespace; + baseData.target = `${peerAddress}/${messageBusDestination}`; break; case SpanKind.PRODUCER: - envelope.data.baseData.type = `Queue Message | ${namespace}`; - envelope.data.baseData.target = `${peerAddress}/${messageBusDestination}`; + baseData.type = `Queue Message | ${namespace}`; + baseData.target = `${peerAddress}/${messageBusDestination}`; break; case SpanKind.CONSUMER: - envelope.data.baseData.type = `Queue Message | ${namespace}`; - envelope.data.baseData.source = `${peerAddress}/${messageBusDestination}`; - envelope.data.baseData.measurements = { - ...envelope.data.baseData.measurements, + baseData.type = `Queue Message | ${namespace}`; + (baseData as any).source = `${peerAddress}/${messageBusDestination}`; + baseData.measurements = { + ...baseData.measurements, [TIME_SINCE_ENQUEUED]: getTimeSinceEnqueued(span) }; break; diff --git a/sdk/monitor/monitor-opentelemetry-exporter/src/utils/spanUtils.ts b/sdk/monitor/monitor-opentelemetry-exporter/src/utils/spanUtils.ts index a5ee6aeae95a..f65b0e370685 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/src/utils/spanUtils.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/src/utils/spanUtils.ts @@ -5,7 +5,6 @@ import { URL } from "url"; import { ReadableSpan } from "@opentelemetry/tracing"; import { hrTimeToMilliseconds } from "@opentelemetry/core"; import { SpanKind, Logger, CanonicalCode, Link } from "@opentelemetry/api"; -import { Envelope, Base } from "../Declarations/Contracts"; import { Tags, Properties, MSLink, Measurements } from "../types"; import { HTTP_METHOD, @@ -31,7 +30,7 @@ import { getInstance } from "../platform"; import { DB_STATEMENT, DB_TYPE, DB_INSTANCE } from "./constants/span/dbAttributes"; import { parseEventHubSpan } from "./eventhub"; import { AzNamespace, MicrosoftEventHub } from "./constants/span/azAttributes"; -import { RemoteDependencyData, RequestData } from "../generated"; +import { RemoteDependencyData, RequestData, TelemetryItem as Envelope } from "../generated"; function createTagsFromSpan(span: ReadableSpan): Tags { const context = getInstance(); @@ -190,31 +189,35 @@ function createInProcData(span: ReadableSpan): RemoteDependencyData { export function readableSpanToEnvelope( span: ReadableSpan, - instrumentationKey: string, + ikey: string, logger?: Logger ): Envelope { - const envelope = new Envelope(); - envelope.data = new Base(); + let name: string; + let baseType: "RemoteDependencyData" | "RequestData"; + const sampleRate = 100; + let baseData: RemoteDependencyData | RequestData; + + const time = new Date(hrTimeToMilliseconds(span.startTime)).toISOString(); + const instrumentationKey = ikey; const tags = createTagsFromSpan(span); const [properties, measurements] = createPropertiesFromSpan(span); - let data; switch (span.kind) { case SpanKind.CLIENT: case SpanKind.PRODUCER: - envelope.name = "Microsoft.ApplicationInsights.RemoteDependency"; - envelope.data.baseType = "RemoteDependencyData"; - data = createDependencyData(span); + name = "Microsoft.ApplicationInsights.RemoteDependency"; + baseType = "RemoteDependencyData"; + baseData = createDependencyData(span); break; case SpanKind.SERVER: case SpanKind.CONSUMER: - envelope.name = "Microsoft.ApplicationInsights.Request"; - envelope.data.baseType = "RequestData"; - data = createRequestData(span); + name = "Microsoft.ApplicationInsights.Request"; + baseType = "RequestData"; + baseData = createRequestData(span); break; case SpanKind.INTERNAL: - envelope.data.baseType = "RemoteDependencyData"; - envelope.name = "Microsoft.ApplicationInsights.RemoteDependency"; - data = createInProcData(span); + baseType = "RemoteDependencyData"; + name = "Microsoft.ApplicationInsights.RemoteDependency"; + baseData = createInProcData(span); break; default: // never @@ -224,22 +227,31 @@ export function readableSpanToEnvelope( throw new Error(`Unsupported span kind ${span.kind}`); } - envelope.data.baseData = { ...data, properties, measurements }; - envelope.tags = tags; - envelope.time = new Date(hrTimeToMilliseconds(span.startTime)).toISOString(); - envelope.iKey = instrumentationKey; - envelope.ver = 1; - if (span.attributes[AzNamespace] === MicrosoftEventHub) { - parseEventHubSpan(span, envelope); + parseEventHubSpan(span, baseData); } else if (span.attributes[AzNamespace]) { switch (span.kind) { case SpanKind.INTERNAL: - envelope.data.baseData.type = `${INPROC} | ${span.attributes[AzNamespace]}`; + (baseData as RemoteDependencyData).type = `${INPROC} | ${span.attributes[AzNamespace]}`; break; default: // no op } } - return envelope; + return { + name, + sampleRate, + time, + instrumentationKey, + tags, + version: 1, + data: { + baseType, + baseData: { + ...baseData, + properties, + measurements + } + } + }; } diff --git a/sdk/monitor/monitor-opentelemetry-exporter/swagger/README.md b/sdk/monitor/monitor-opentelemetry-exporter/swagger/README.md index aa548ba771e4..f70fd71200b2 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/swagger/README.md +++ b/sdk/monitor/monitor-opentelemetry-exporter/swagger/README.md @@ -21,7 +21,7 @@ generate-metadata: false license-header: MICROSOFT_MIT_NO_VERSION output-folder: ../ source-code-folder-path: ./src/generated -input-file: https://github.com/srnagar/swagger/blob/master/application-insights.json +input-file: https://github.com/azure/azure-rest-api-specs/blob/master/specification/applicationinsights/data-plane/Monitor.Exporters/preview/2020-09-15_Preview/swagger.json add-credentials: false use-extension: "@autorest/typescript": "6.0.0-dev.20200826.1" diff --git a/sdk/monitor/monitor-opentelemetry-exporter/test/common/assert.ts b/sdk/monitor/monitor-opentelemetry-exporter/test/common/assert.ts index 55f04c42c7e1..10b7a2d012cd 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/test/common/assert.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/test/common/assert.ts @@ -2,12 +2,14 @@ // Licensed under the MIT license. import * as assert from "assert"; -import { Base, Envelope } from "../../src/Declarations/Contracts"; +import { Base } from "../../src/Declarations/Contracts"; import { AI_OPERATION_ID, AI_OPERATION_PARENT_ID } from "../../src/utils/constants/applicationinsights"; import { Expectation } from "./scenario/types"; +import { RequestData, TelemetryItem as Envelope } from "../../src/generated"; +import { TelemetryItem as EnvelopeMapper } from "../../src/generated/models/mappers"; export const assertData = (actual: Base, expected: Base): void => { assert.strictEqual(actual.baseType, expected.baseType); @@ -16,19 +18,25 @@ export const assertData = (actual: Base, expected: Base): void => { if (expected.baseData) { assert.ok(actual.baseData); for (const [key, value] of Object.entries(expected.baseData)) { - assert.deepStrictEqual(actual.baseData![key], value, `baseData.${key} should be equal`); + const serializedKey = EnvelopeMapper.type.modelProperties![key]?.serializedName ?? key; + assert.deepStrictEqual( + actual.baseData![serializedKey], + value, + `baseData.${serializedKey} should be equal` + ); } } }; export const assertTrace = (actual: Envelope[], expectation: Expectation): void => { const envelope = actual.filter( - (e) => e.data!.baseData!.name === expectation.data!.baseData!.name + (e) => + (e.data!.baseData as RequestData).name === (expectation.data!.baseData as RequestData).name ); if (envelope.length !== 1) { assert.ok(false, `assertTrace: could not find exported envelope: ${expectation.name}`); } - const operationId = envelope[0].tags[AI_OPERATION_ID]; + const operationId = envelope[0].tags![AI_OPERATION_ID]; const parseId = (id: string): { traceId: string; spanId: string } => { const parts = id.replace("|", "").split("."); @@ -40,18 +48,18 @@ export const assertTrace = (actual: Envelope[], expectation: Expectation): void for (const child of expectation.children) { const childEnvelopes = actual.filter((e) => { - const { spanId } = parseId(envelope[0].data!.baseData!.id); + const { spanId } = parseId((envelope[0].data!.baseData as RequestData).id); return ( - e.tags[AI_OPERATION_ID] === operationId && - e.tags[AI_OPERATION_PARENT_ID] === spanId && - e.data!.baseData!.name === child.data!.baseData!.name + e.tags![AI_OPERATION_ID] === operationId && + e.tags![AI_OPERATION_PARENT_ID] === spanId && + (e.data!.baseData as RequestData).name === (child.data!.baseData as RequestData).name ); }); assert.strictEqual( childEnvelopes.length, 1, - `Could not find a child envelope for ${envelope[0].data!.baseData!.name}` + `Could not find a child envelope for ${(envelope[0].data!.baseData as RequestData).name}` ); } }; @@ -69,13 +77,20 @@ export const assertCount = (actual: Envelope[], expectations: Expectation[]): vo export const assertExpectation = (actual: Envelope[], expectations: Expectation[]): void => { for (const expectation of expectations) { const envelope = actual.filter( - (e) => e.data!.baseData!.name === expectation.data!.baseData!.name + (e) => + (e.data!.baseData as RequestData).name === (expectation.data!.baseData as RequestData).name ); if (envelope.length !== 1) { - assert.ok(false, `assertExpectation: could not find exported envelope: ${expectation.name}`); + assert.ok( + false, + `assertExpectation: could not find exported envelope: ${ + (expectation.data?.baseData as RequestData).name + }` + ); } for (const [key, value] of Object.entries(expectation) as [keyof Expectation, unknown][]) { + const serializedKey = EnvelopeMapper.type.modelProperties![key]?.serializedName ?? undefined; switch (key) { case "children": assertTrace(actual, expectation); @@ -83,11 +98,16 @@ export const assertExpectation = (actual: Envelope[], expectations: Expectation[ break; case "data": if (envelope[0].data) { - assertData(envelope[0].data, value as Base); + assertData(envelope[0].data as Base, value as Base); } break; default: - assert.strictEqual(envelope[0][key], value, `envelope.${key} should be equal`); + assert.ok(serializedKey, `Serialized key for ${key}`); + assert.strictEqual( + envelope[0][serializedKey as keyof Envelope], // as keyof Serialized(Envelope) + value, + `envelope.${serializedKey} should be equal\nActual: ${envelope[0][key]}\nExpected: ${value}` + ); } } } diff --git a/sdk/monitor/monitor-opentelemetry-exporter/test/common/scenario/basic.ts b/sdk/monitor/monitor-opentelemetry-exporter/test/common/scenario/basic.ts index 8ccbfeb94465..7d19c6804573 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/test/common/scenario/basic.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/test/common/scenario/basic.ts @@ -5,20 +5,19 @@ import * as opentelemetry from "@opentelemetry/api"; import { BasicTracerProvider } from "@opentelemetry/tracing"; import { AzureMonitorTraceExporter } from "../../../src"; import { Expectation, Scenario } from "./types"; -import { Envelope } from "../../../src/Declarations/Contracts"; import { msToTimeSpan } from "../../../src/utils/breezeUtils"; import { CanonicalCode } from "@opentelemetry/api"; import { FlushSpanProcessor } from "../flushSpanProcessor"; import { delay } from "@azure/core-http"; -import { RemoteDependencyData, RequestData } from "../../../src/generated"; +import { TelemetryItem as Envelope } from "../../../src/generated"; const COMMON_ENVELOPE_PARAMS: Partial = { - iKey: process.env.APPINSIGHTS_INSTRUMENTATIONKEY || "ikey", + instrumentationKey: process.env.APPINSIGHTS_INSTRUMENTATIONKEY || "ikey", sampleRate: 100 }; const exporter = new AzureMonitorTraceExporter({ - instrumentationKey: COMMON_ENVELOPE_PARAMS.iKey + instrumentationKey: COMMON_ENVELOPE_PARAMS.instrumentationKey }); const processor = new FlushSpanProcessor(exporter); @@ -44,7 +43,7 @@ export class BasicScenario implements Scenario { parent: root, kind: opentelemetry.SpanKind.CLIENT, attributes: { - numbers: 123 + numbers: "123" } }); @@ -53,7 +52,7 @@ export class BasicScenario implements Scenario { parent: root, kind: opentelemetry.SpanKind.CLIENT, attributes: { - numbers: 1234 + numbers: "1234" } }); @@ -85,6 +84,7 @@ export class BasicScenario implements Scenario { data: { baseType: "RequestData", baseData: { + version: 1, name: "BasicScenario.Root", duration: msToTimeSpan(600), responseCode: "0", @@ -92,8 +92,7 @@ export class BasicScenario implements Scenario { properties: { foo: "bar" } - } as Partial, - properties: undefined + } as any }, children: [ { @@ -101,15 +100,15 @@ export class BasicScenario implements Scenario { data: { baseType: "RemoteDependencyData", baseData: { + version: 1, name: "BasicScenario.Child.1", duration: msToTimeSpan(100), success: true, resultCode: "0", properties: { - numbers: 123 as any + numbers: "123" } - } as Partial, - properties: undefined + } as any }, children: [] }, @@ -118,15 +117,15 @@ export class BasicScenario implements Scenario { data: { baseType: "RemoteDependencyData", baseData: { + version: 1, name: "BasicScenario.Child.2", duration: msToTimeSpan(100), success: true, resultCode: "0", properties: { - numbers: 1234 as any + numbers: "1234" } - } as Partial, - properties: undefined + } as any }, children: [] } diff --git a/sdk/monitor/monitor-opentelemetry-exporter/test/common/scenario/types.ts b/sdk/monitor/monitor-opentelemetry-exporter/test/common/scenario/types.ts index 96c061d5a854..5b5eeb784978 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/test/common/scenario/types.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/test/common/scenario/types.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { Envelope } from "../../../src/Declarations/Contracts"; +import { TelemetryItem as Envelope } from "../../../src/generated"; export interface Expectation extends Partial { children: Expectation[]; diff --git a/sdk/monitor/monitor-opentelemetry-exporter/test/functional/trace.test.ts b/sdk/monitor/monitor-opentelemetry-exporter/test/functional/trace.test.ts index bdc2eac0afd8..b189bb7514d1 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/test/functional/trace.test.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/test/functional/trace.test.ts @@ -6,8 +6,7 @@ import { BasicScenario } from "../common/scenario/basic"; import { DEFAULT_BREEZE_ENDPOINT } from "../../src/Declarations/Constants"; import nock from "nock"; import { successfulBreezeResponse } from "../unit/breezeTestUtils"; -import { Envelope } from "../../src/Declarations/Contracts"; -import { gunzipSync } from "zlib"; +import { TelemetryItem as Envelope } from "../../src/generated"; describe("Trace Exporter Scenarios", () => { describe(BasicScenario.prototype.constructor.name, () => { @@ -15,10 +14,12 @@ describe("Trace Exporter Scenarios", () => { let ingest: Envelope[] = []; nock(DEFAULT_BREEZE_ENDPOINT) - .post("/v2/track", (body) => { - const buffer = gunzipSync(Buffer.from(body, "hex")); - ingest.push(...(JSON.parse(buffer.toString("utf8")) as Envelope[])); - return body; + .post("/v2/track", (body: Envelope[]) => { + // todo: gzip is not supported by generated applicationInsightsClient + // const buffer = gunzipSync(Buffer.from(body, "hex")); + // ingest.push(...(JSON.parse(buffer.toString("utf8")) as Envelope[])); + ingest.push(...body); + return true; }) .reply(200, successfulBreezeResponse(1)) .persist(); diff --git a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/export/export.test.ts b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/export/export.test.ts index 31352670eefe..47e7644170a4 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/export/export.test.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/export/export.test.ts @@ -5,7 +5,6 @@ import * as assert from "assert"; import { ExportResult } from "@opentelemetry/core"; import { AzureMonitorBaseExporter } from "../../../src/export/exporter"; import { TelemetryProcessor } from "../../../src/types"; -import { Envelope } from "../../../src/Declarations/Contracts"; import { DEFAULT_BREEZE_ENDPOINT } from "../../../src/Declarations/Constants"; import { failedBreezeResponse, @@ -13,6 +12,7 @@ import { successfulBreezeResponse } from "../breezeTestUtils"; import { FileSystemPersist } from "../../../src/platform"; +import { TelemetryItem as Envelope } from "../../../src/generated"; import nock = require("nock"); function toObject(obj: T): T { @@ -23,7 +23,7 @@ describe("#AzureMonitorBaseExporter", () => { class TestExporter extends AzureMonitorBaseExporter { constructor() { super({ - instrumentationKey: "foo" + instrumentationKey: "foo-ikey" }); } @@ -48,7 +48,14 @@ describe("#AzureMonitorBaseExporter", () => { describe("Sender/Persister Controller", () => { describe("#exportEnvelopes()", () => { const scope = nock(DEFAULT_BREEZE_ENDPOINT).post("/v2/track"); - const envelope = new Envelope(); + const envelope = { + name: "Name", + time: new Date().toISOString() + }; + + before(() => { + nock.cleanAll(); + }); after(() => { nock.cleanAll(); @@ -56,8 +63,8 @@ describe("#AzureMonitorBaseExporter", () => { it("should persist retriable failed telemetry", async () => { const exporter = new TestExporter(); - const response = failedBreezeResponse(1, 408); - scope.reply(408, JSON.stringify(response)); + const response = failedBreezeResponse(1, 429); + scope.reply(429, JSON.stringify(response)); const result = await exporter.exportEnvelopes([envelope]); assert.strictEqual(result, ExportResult.FAILED_RETRYABLE); @@ -158,10 +165,14 @@ describe("#AzureMonitorBaseExporter", () => { describe("#_applyTelemetryProcessors()", () => { it("should filter envelopes", () => { - const fooEnvelope = new Envelope(); - const barEnvelope = new Envelope(); - fooEnvelope.name = "foo"; - barEnvelope.name = "bar"; + const fooEnvelope = { + name: "foo", + time: new Date().toISOString() + }; + const barEnvelope = { + name: "bar", + time: new Date().toISOString() + }; const exporter = new TestExporter(); assert.strictEqual(exporter.getTelemetryProcesors().length, 0); @@ -175,10 +186,14 @@ describe("#AzureMonitorBaseExporter", () => { }); it("should filter modified envelopes", () => { - const fooEnvelope = new Envelope(); - const barEnvelope = new Envelope(); - fooEnvelope.name = "foo"; - barEnvelope.name = "bar"; + const fooEnvelope = { + name: "foo", + time: new Date().toISOString() + }; + const barEnvelope = { + name: "bar", + time: new Date().toISOString() + }; const exporter = new TestExporter(); assert.strictEqual(exporter.getTelemetryProcesors().length, 0); diff --git a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/platform/nodejs/httpSender.test.ts b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/platform/nodejs/httpSender.test.ts index fec353d7b3ad..ff17e178ce55 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/platform/nodejs/httpSender.test.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/platform/nodejs/httpSender.test.ts @@ -3,13 +3,13 @@ import * as assert from "assert"; import { HttpSender } from "../../../../src/platform/nodejs/httpSender"; -import { Envelope } from "../../../../src/Declarations/Contracts"; import { DEFAULT_BREEZE_ENDPOINT } from "../../../../src/Declarations/Constants"; import { successfulBreezeResponse, failedBreezeResponse, partialBreezeResponse } from "../../breezeTestUtils"; +import { TelemetryItem as Envelope } from "../../../../src/generated"; import nock = require("nock"); describe("HttpSender", () => { @@ -29,7 +29,10 @@ describe("HttpSender", () => { }); describe("#send()", () => { - const envelope = new Envelope(); + const envelope: Envelope = { + name: "name", + time: new Date().toISOString() + }; it("should send a valid envelope", async () => { const sender = new HttpSender(); scope.reply(200, JSON.stringify(successfulBreezeResponse(1))); diff --git a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/platform/nodejs/persist/fileSystemPersist.test.ts b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/platform/nodejs/persist/fileSystemPersist.test.ts index 9f17eecae737..8cbd5783c869 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/platform/nodejs/persist/fileSystemPersist.test.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/platform/nodejs/persist/fileSystemPersist.test.ts @@ -6,7 +6,7 @@ import * as fs from "fs"; import * as os from "os"; import * as path from "path"; import { FileSystemPersist } from "../../../../../src/platform/nodejs/persist/fileSystemPersist"; -import { Envelope } from "../../../../../src/Declarations/Contracts"; +import { TelemetryItem as Envelope } from "../../../../../src/generated"; import { promisify } from "util"; const statAsync = promisify(fs.stat); @@ -73,8 +73,12 @@ describe("FileSystemPersist", () => { describe("#push()", () => { it("should store to disk the value provided", async () => { + const envelope: Envelope = { + name: "name", + time: new Date().toISOString() + }; const persister = new FileSystemPersist({ instrumentationKey }); - const envelopes = [new Envelope()]; + const envelopes = [envelope]; const success = await persister.push(envelopes); assert.strictEqual(success, true); diff --git a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/utils/eventhub.test.ts b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/utils/eventhub.test.ts index 0670244ac83b..d3a8fb4cc213 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/utils/eventhub.test.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/utils/eventhub.test.ts @@ -5,7 +5,6 @@ import { Attributes, HrTime, SpanContext, SpanKind } from "@opentelemetry/api"; import { NoopLogger, timeInputToHrTime } from "@opentelemetry/core"; import { BasicTracerProvider, Span } from "@opentelemetry/tracing"; import * as assert from "assert"; -import { Envelope } from "../../../src/Declarations/Contracts"; import { ENQUEUED_TIME, TIME_SINCE_ENQUEUED @@ -16,6 +15,7 @@ import { MicrosoftEventHub } from "../../../src/utils/constants/span/azAttributes"; import { parseEventHubSpan } from "../../../src/utils/eventhub"; +import { RemoteDependencyData, TelemetryItem as Envelope } from "../../../src/generated"; const tracer = new BasicTracerProvider({ logger: new NoopLogger() @@ -30,18 +30,6 @@ describe("#parseEventHubSpan(...)", () => { [MessageBusDestination]: destination }; - it("should not crash when provided an incomplete envelope", () => { - const span = new Span( - tracer, - "parent span", - { traceId: "traceid", spanId: "spanId", traceFlags: 0 }, - SpanKind.CLIENT, - "parentSpanId" - ); - - assert.doesNotThrow(() => parseEventHubSpan(span, ({ data: null } as unknown) as Envelope)); - }); - it("should correctly parse SpanKind.CLIENT", () => { const envelope = { data: { baseData: {} } } as Envelope; const span = new Span( @@ -52,12 +40,14 @@ describe("#parseEventHubSpan(...)", () => { ); span.setAttributes(attributes); - parseEventHubSpan(span, envelope); - assert.strictEqual(envelope.data?.baseData?.type, attributes[AzNamespace]); - assert.strictEqual(envelope.data?.baseData?.target, `${peerAddress}/${destination}`); + const baseData = envelope.data?.baseData as RemoteDependencyData; + parseEventHubSpan(span, baseData); - assert.strictEqual(envelope.data?.baseData?.source, undefined); - assert.strictEqual(envelope.data?.baseData?.measurements, undefined); + assert.strictEqual(baseData.type, attributes[AzNamespace]); + assert.strictEqual(baseData.target, `${peerAddress}/${destination}`); + + assert.strictEqual((baseData as any).source, undefined); + assert.strictEqual(baseData.measurements, undefined); }); it("should correctly parse SpanKind.PRODUCER", () => { @@ -70,12 +60,14 @@ describe("#parseEventHubSpan(...)", () => { ); span.setAttributes(attributes); - parseEventHubSpan(span, envelope); - assert.strictEqual(envelope.data?.baseData?.type, `Queue Message | ${attributes[AzNamespace]}`); - assert.strictEqual(envelope.data?.baseData?.target, `${peerAddress}/${destination}`); + const baseData = envelope.data?.baseData as RemoteDependencyData; + parseEventHubSpan(span, baseData); + + assert.strictEqual(baseData.type, `Queue Message | ${attributes[AzNamespace]}`); + assert.strictEqual(baseData.target, `${peerAddress}/${destination}`); - assert.strictEqual(envelope.data?.baseData?.source, undefined); - assert.strictEqual(envelope.data?.baseData?.measurements, undefined); + assert.strictEqual((baseData as any).source, undefined); + assert.strictEqual(baseData.measurements, undefined); }); it("should correctly parse SpanKind.CONSUMER", () => { @@ -107,13 +99,14 @@ describe("#parseEventHubSpan(...)", () => { (span as { startTime: HrTime }).startTime = timeInputToHrTime(startTime); span.setAttributes(attributes); - parseEventHubSpan(span, envelope); - assert.strictEqual(envelope.data?.baseData?.type, `Queue Message | ${attributes[AzNamespace]}`); - assert.strictEqual(envelope.data?.baseData?.source, `${peerAddress}/${destination}`); - assert.deepStrictEqual(envelope.data?.baseData?.measurements, { + const baseData = envelope.data?.baseData as RemoteDependencyData; + parseEventHubSpan(span, baseData); + assert.strictEqual(baseData.type, `Queue Message | ${attributes[AzNamespace]}`); + assert.strictEqual((baseData as any).source, `${peerAddress}/${destination}`); + assert.deepStrictEqual(baseData.measurements, { [TIME_SINCE_ENQUEUED]: 148 }); - assert.strictEqual(envelope.data?.baseData?.target, undefined); + assert.strictEqual(baseData.target, undefined); }); }); diff --git a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/utils/spanUtils.test.ts b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/utils/spanUtils.test.ts index 06443c2b54d9..7241d1be2c69 100644 --- a/sdk/monitor/monitor-opentelemetry-exporter/test/unit/utils/spanUtils.test.ts +++ b/sdk/monitor/monitor-opentelemetry-exporter/test/unit/utils/spanUtils.test.ts @@ -7,7 +7,6 @@ import * as assert from "assert"; import { NoopLogger, hrTimeToMilliseconds } from "@opentelemetry/core"; import { Tags, Properties, Measurements } from "../../../src/types"; -import { Envelope } from "../../../src/Declarations/Contracts"; import * as http from "../../../src/utils/constants/span/httpAttributes"; import * as grpc from "../../../src/utils/constants/span/grpcAttributes"; import * as ai from "../../../src/utils/constants/applicationinsights"; @@ -15,6 +14,7 @@ import { Context, getInstance } from "../../../src/platform"; import { msToTimeSpan } from "../../../src/utils/breezeUtils"; import { readableSpanToEnvelope } from "../../../src/utils/spanUtils"; import { RemoteDependencyData, RequestData } from "../../../src/generated"; +import { TelemetryItem as Envelope } from "../../../src/generated"; const context = getInstance(undefined, "./", "../../"); @@ -30,8 +30,8 @@ function assertEnvelope( expectedProperties: Properties, expectedMeasurements: Measurements | undefined, expectedBaseData: Partial, - expectedTime?: string -) { + expectedTime?: Date +): void { assert.strictEqual(Context.sdkVersion, ai.packageVersion); assert.strictEqual(Object.keys(Context.appVersion).length, 1); assert.notDeepStrictEqual(Context.appVersion, "unknown"); @@ -40,18 +40,21 @@ function assertEnvelope( assert.strictEqual(envelope.name, name); assert.deepStrictEqual(envelope.data?.baseType, baseType); - assert.strictEqual(envelope.iKey, "ikey"); + assert.strictEqual(envelope.instrumentationKey, "ikey"); assert.ok(envelope.time); - assert.ok(envelope.ver); + assert.ok(envelope.version); assert.ok(envelope.data); if (expectedTime) { - assert.strictEqual(envelope.time, expectedTime); + assert.strictEqual(envelope.time, expectedTime.toISOString()); } assert.deepStrictEqual(envelope.tags, { ...context.tags, ...expectedTags }); - assert.deepStrictEqual(envelope?.data?.baseData?.properties, expectedProperties); - assert.deepStrictEqual(envelope?.data?.baseData?.measurements, expectedMeasurements); + assert.deepStrictEqual((envelope?.data?.baseData as RequestData).properties, expectedProperties); + assert.deepStrictEqual( + (envelope?.data?.baseData as RequestData).measurements, + expectedMeasurements + ); assert.deepStrictEqual(envelope.data?.baseData, expectedBaseData); } @@ -187,7 +190,7 @@ describe("spanUtils.ts", () => { code: CanonicalCode.OK }); span.end(); - const expectedTime = new Date(hrTimeToMilliseconds(span.startTime)).toISOString(); + const expectedTime = new Date(hrTimeToMilliseconds(span.startTime)); const expectedTags: Tags = { [ai.AI_OPERATION_ID]: "traceid", [ai.AI_OPERATION_PARENT_ID]: "parentSpanId"