Skip to content

Commit

Permalink
Task 7017105: Identify whether the script is being consumed via the C…
Browse files Browse the repository at this point in the history
…DN or NPM package
  • Loading branch information
Nev Wylie committed Apr 21, 2020
1 parent 0271cda commit bc2ef2a
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 60 deletions.
63 changes: 63 additions & 0 deletions AISKU/src/Initialization.ts
Expand Up @@ -10,6 +10,8 @@ import * as Common from "@microsoft/applicationinsights-common"

"use strict";

let _internalSdkSrc: string;

/**
*
* @export
Expand All @@ -18,6 +20,7 @@ import * as Common from "@microsoft/applicationinsights-common"
export interface Snippet {
config: IConfiguration & Common.IConfig;
queue?: Array<() => void>;
snipVer?: number;
version?: number;
}

Expand Down Expand Up @@ -46,10 +49,12 @@ export class Initialization implements IApplicationInsights {

private dependencies: DependenciesPlugin;
private properties: PropertiesPlugin;
private _snippetVersion: string;

constructor(snippet: Snippet) {
let _this = this;
// initialize the queue and config in case they are undefined
_this._snippetVersion = "" + (snippet.snipVer || snippet.version || "");
snippet.queue = snippet.queue || [];
snippet.version = snippet.version || 2.0; // Default to new version
let config: IConfiguration & Common.IConfig = snippet.config || ({} as any);
Expand Down Expand Up @@ -269,6 +274,15 @@ export class Initialization implements IApplicationInsights {

function _updateSnippetProperties(snippet: Snippet) {
if (snippet) {
let snippetVer = "";
if (!CoreUtils.isNullOrUndefined(_this._snippetVersion)) {
snippetVer += _this._snippetVersion;
}
if (legacyMode) {
snippetVer += ".lg";
}
_this.properties.context.internal.snippetVer = snippetVer || "-";

// apply updated properties to the global instance (snippet)
for (const field in _this) {
if (CoreUtils.isString(field) &&
Expand Down Expand Up @@ -296,6 +310,9 @@ export class Initialization implements IApplicationInsights {
// initialize core
_this.core.initialize(_this.config, extensions);
_this.context = _this.properties.context;
if (_internalSdkSrc) {
_this.context.internal.sdkSrc = _internalSdkSrc;
}
_updateSnippetProperties(_this.snippet);

// Empty queue of all api calls logged prior to sdk download
Expand Down Expand Up @@ -411,3 +428,49 @@ export class Initialization implements IApplicationInsights {
_this.config.diagnosticLogInterval && _this.config.diagnosticLogInterval > 0 ? _this.config.diagnosticLogInterval : 10000;
}
}

// tslint:disable-next-line
(function () {
let sdkSrc = null;
let isModule = false;

try {
// Try and determine whether the sdk is being loaded from the CDN
// currentScript is only valid during initial processing
let scrpt = (document ||{} as any).currentScript;
if (scrpt) {
sdkSrc = scrpt.src;
// } else {
// // We need to update to at least typescript 2.9 for this to work :-(
// // Leaving as a stub for now so after we upgrade this breadcrumb is available
// let meta = import.meta;
// sdkSrc = (meta || {}).url;
// isModule = true;
}
} catch (e) {
}

if (sdkSrc) {
try {
let url = sdkSrc.toLowerCase();
if (url) {
let src = "";
if (url.indexOf("://az416426.vo.msecnd.net/") !== -1) {
src = "cdn1";
if (url.indexOf("/scripts/") === -1) {
if (url.indexOf("/next/") !== -1) {
src += "-next";
} else if (url.indexOf("/beta/") !== -1) {
src += "-beta";
}
}
}

if (src) {
_internalSdkSrc = src + (isModule ? ".mod" : "");
}
}
} catch (e) {
}
}
})();
Expand Up @@ -18,6 +18,21 @@ export class Internal implements IInternal {
*/
public agentVersion: string;

/**
* The Snippet version used to initialize the sdk instance, this will contain either
* undefined/null - Snippet not used
* '-' - Version and legacy mode not determined
* # - Version # of the snippet
* #.l - Version # in legacy mode
* .l - No defined version, but used legacy mode initialization
*/
public snippetVer: string;

/**
* Identifies the source of the sdk script
*/
public sdkSrc: string;

/**
* Constructs a new instance of the internal telemetry data class.
*/
Expand Down
139 changes: 79 additions & 60 deletions extensions/applicationinsights-properties-js/src/TelemetryContext.ts
Expand Up @@ -3,9 +3,9 @@
* @copyright Microsoft 2018
*/

import { ITelemetryItem, IProcessTelemetryContext, IDiagnosticLogger, CoreUtils, hasWindow } from '@microsoft/applicationinsights-core-js';
import { ITelemetryItem, IProcessTelemetryContext, IDiagnosticLogger, CoreUtils, hasWindow, _InternalLogMessage } from '@microsoft/applicationinsights-core-js';
import { Session, _SessionManager } from './Context/Session';
import { Extensions, ITelemetryContext, IOperatingSystem, ITelemetryTrace, IWeb, SampleRate, CtxTagKeys } from '@microsoft/applicationinsights-common';
import { Extensions, ITelemetryContext, IOperatingSystem, ITelemetryTrace, IWeb, SampleRate, CtxTagKeys, PageView } from '@microsoft/applicationinsights-common';
import { Application } from './Context/Application';
import { Device } from './Context/Device';
import { Internal } from './Context/Internal';
Expand All @@ -29,140 +29,159 @@ export class TelemetryContext implements ITelemetryContext {
public appId: () => string;

constructor(logger: IDiagnosticLogger, defaultConfig: ITelemetryConfig) {
let _self = this;
if (hasWindow()) {
this.sessionManager = new _SessionManager(defaultConfig, logger);
this.application = new Application();
this.device = new Device();
this.internal = new Internal(defaultConfig);
this.location = new Location();
this.user = new User(defaultConfig, logger);
this.telemetryTrace = new TelemetryTrace(undefined, undefined, undefined, logger);
this.session = new Session();
}
this.appId = () => null;
_self.sessionManager = new _SessionManager(defaultConfig, logger);
_self.application = new Application();
_self.device = new Device();
_self.internal = new Internal(defaultConfig);
_self.location = new Location();
_self.user = new User(defaultConfig, logger);
_self.telemetryTrace = new TelemetryTrace(undefined, undefined, undefined, logger);
_self.session = new Session();
}
_self.appId = () => null;
}

public applySessionContext(event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) {
const sessionContext = this.session || (this.sessionManager && this.sessionManager.automaticSession);
let session = this.session;
let sessionManager = this.sessionManager;
const sessionContext = session || (sessionManager && sessionManager.automaticSession);
if (sessionContext) {
if (typeof sessionContext.id === "string") {
if (CoreUtils.isString(sessionContext.id)) {
event.ext.app.sesId = sessionContext.id;
}
}

if (this.session) {
if (session) {
// If customer set session info, apply his context; otherwise apply context automatically generated
if (typeof this.session.id === "string") {
event.ext.app.sesId = this.session.id;
if (CoreUtils.isString(session.id)) {
event.ext.app.sesId = session.id;
} else {
event.ext.app.sesId = this.sessionManager.automaticSession.id;
event.ext.app.sesId = sessionManager.automaticSession.id;
}
}
}

public applyOperatingSystemContxt(event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) {
if (this.os && this.os.name) {
event.ext.os = this.os;
let os = this.os;
if (os && os.name) {
event.ext.os = os;
}
}

public applyApplicationContext(event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) {
if (this.application) {
let application = this.application;
if (application) {

if (typeof this.application.ver === "string") {
event.tags[CtxTagKeys.applicationVersion] = this.application.ver;
if (CoreUtils.isString(application.ver)) {
event.tags[CtxTagKeys.applicationVersion] = application.ver;
}
if (typeof this.application.build === "string") {
event.tags[CtxTagKeys.applicationBuild] = this.application.build;
if (CoreUtils.isString(application.build)) {
event.tags[CtxTagKeys.applicationBuild] = application.build;
}
}
}

public applyDeviceContext(event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) {

if (this.device) {
if (typeof this.device.id === "string") {
event.ext.device.localId = this.device.id;
let device = this.device;
if (device) {
if (CoreUtils.isString(device.id)) {
event.ext.device.localId = device.id;
}

if (typeof this.device.ip === "string") {
event.ext.device.ip = this.device.ip;
if (CoreUtils.isString(device.ip)) {
event.ext.device.ip = device.ip;
}

if (typeof this.device.model === "string") {
event.ext.device.model = this.device.model;
if (CoreUtils.isString(device.model)) {
event.ext.device.model = device.model;
}

if (typeof this.device.deviceClass === "string") {
event.ext.device.deviceClass = this.device.deviceClass;
if (CoreUtils.isString(device.deviceClass)) {
event.ext.device.deviceClass = device.deviceClass;
}
}
}

public applyInternalContext(event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) {
if (this.internal) {
if (typeof this.internal.agentVersion === "string") {
event.tags[CtxTagKeys.internalAgentVersion] = this.internal.agentVersion; // not mapped in CS 4.0
let internal = this.internal;
if (internal) {
if (CoreUtils.isString(internal.agentVersion)) {
event.tags[CtxTagKeys.internalAgentVersion] = internal.agentVersion; // not mapped in CS 4.0
}
if (CoreUtils.isString(internal.sdkVersion)) {
event.tags[CtxTagKeys.internalSdkVersion] = internal.sdkVersion;
}
if (typeof this.internal.sdkVersion === "string") {
event.tags[CtxTagKeys.internalSdkVersion] = this.internal.sdkVersion;

if (event.baseType === _InternalLogMessage.dataType || event.baseType === PageView.dataType) {
if (CoreUtils.isString(internal.snippetVer)) {
event.tags[CtxTagKeys.internalSnippet] = internal.snippetVer;
}

if (CoreUtils.isString(internal.sdkSrc)) {
event.tags[CtxTagKeys.internalSdkSrc] = internal.sdkSrc;
}
}
}
}

public applyLocationContext(event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) {
if (this.location) {
if (typeof this.location.ip === "string") {
event.tags[CtxTagKeys.locationIp] = this.location.ip;
let location = this.location;
if (location) {
if (CoreUtils.isString(location.ip)) {
event.tags[CtxTagKeys.locationIp] = location.ip;
}
}
}

public applyOperationContext(event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) {
if (this.telemetryTrace) {
let telemetryTrace = this.telemetryTrace;
if (telemetryTrace) {
const trace = event.ext.trace || ({traceID: undefined, parentID: undefined} as ITelemetryTrace);
if (typeof this.telemetryTrace.traceID === "string") {
trace.traceID = this.telemetryTrace.traceID;
if (CoreUtils.isString(telemetryTrace.traceID)) {
trace.traceID = telemetryTrace.traceID;
}

if (typeof this.telemetryTrace.name === "string") {
trace.name = this.telemetryTrace.name;
if (CoreUtils.isString(telemetryTrace.name)) {
trace.name = telemetryTrace.name;
}

if (typeof this.telemetryTrace.parentID === "string") {
trace.parentID = this.telemetryTrace.parentID;
if (CoreUtils.isString(telemetryTrace.parentID)) {
trace.parentID = telemetryTrace.parentID;
}

event.ext.trace = trace;
}
}

public applyWebContext(event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) {
if (this.web) {
let web = this.web;
if (web) {
event.ext.web = event.ext.web || {};
event.ext.web = this.web;
event.ext.web = web;
}
}

public applyUserContext(event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) {
if (this.user) {
let user = this.user;
if (user) {
if (!event.tags) {
event.tags = [];
}

// stays in tags
if (typeof this.user.accountId === "string") {
const item = {};
event.tags[CtxTagKeys.userAccountId] = this.user.accountId;
if (CoreUtils.isString(user.accountId)) {
event.tags[CtxTagKeys.userAccountId] = user.accountId;
}

// CS 4.0
if (typeof this.user.id === "string") {
event.ext.user.id = this.user.id;
if (CoreUtils.isString( user.id)) {
event.ext.user.id = user.id;
}

if (typeof this.user.authenticatedId === "string") {
event.ext.user.authId = this.user.authenticatedId;
if (CoreUtils.isString(user.authenticatedId)) {
event.ext.user.authId = user.authenticatedId;
}
}
}
Expand Down
Expand Up @@ -199,6 +199,16 @@ export class ContextTagKeys {
*/
public internalNodeName: string;

/**
* This identifies the version of the snippet that was used to initialize the SDK
*/
public internalSnippet: string;

/**
* This identifies the source of the Sdk script (used to identify whether the SDK was loaded via the CDN)
*/
public internalSdkSrc: string;

constructor() {
this.applicationVersion = "ai.application.ver";
this.applicationBuild = "ai.application.build";
Expand Down Expand Up @@ -257,5 +267,7 @@ export class ContextTagKeys {
this.internalNodeName = "ai.internal.nodeName";
this.internalSdkVersion = "ai.internal.sdkVersion";
this.internalAgentVersion = "ai.internal.agentVersion";
this.internalSnippet = "ai.internal.snippet";
this.internalSdkSrc = "ai.internal.sdkSrc";
}
}

0 comments on commit bc2ef2a

Please sign in to comment.