Merge branch 'master' into modify_test

This commit is contained in:
siyuniu-ms 2023-02-27 23:49:31 -08:00 коммит произвёл GitHub
Родитель 0567b0cca9 fcadeec422
Коммит 3398b1756c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
20 изменённых файлов: 1396 добавлений и 398 удалений

Просмотреть файл

@ -15,11 +15,11 @@
ms.topic="article"
ms.date="08/24/2015"/>
[![Build Status](https://dev.azure.com/mseng/AppInsights/_apis/build/status/AppInsights%20-%20DevTools/1DS%20JavaScript%20SDK%20web%20SKU%20vNext?branchName=master)](https://dev.azure.com/mseng/AppInsights/_build/latest?definitionId=8184&branchName=master)
[![Build Status](https://travis-ci.org/microsoft/ApplicationInsights-JS.svg?branch=master)](https://travis-ci.org/microsoft/ApplicationInsights-JS)
![GitHub Workflow Status (main)](https://img.shields.io/github/actions/workflow/status/microsoft/ApplicationInsights-JS/ci.yml?branch=master)
[![npm version](https://badge.fury.io/js/%40microsoft%2Fapplicationinsights-web.svg)](https://badge.fury.io/js/%40microsoft%2Fapplicationinsights-web)
[![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.min.js.svg?label=minified%20size)](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.min.js.svg?label=minified%20size)
[![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.min.js.svg?compression=gzip&softmax=30000&max=35000)](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.min.js.svg?compression=gzip&softmax=30000&max=35000)
[![Build Status](https://dev.azure.com/mseng/AppInsights/_apis/build/status/AppInsights%20-%20DevTools/1DS%20JavaScript%20SDK%20web%20SKU%20vNext?branchName=master)](https://dev.azure.com/mseng/AppInsights/_build/latest?definitionId=8184&branchName=master)
[![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.min.js.svg?label=minified%20size)](https://js.monitor.azure.com/scripts/b/ai.2.min.js)
[![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.min.js.svg?compression=gzip&softmax=30000&max=35000)](https://js.monitor.azure.com/scripts/b/ai.2.min.js)
> ***Note:*** The documentation for `applicationinsights-js@1.0.20` has moved [here](./legacy/README.md). If you are looking to upgrade to the new version of the SDK, please see the [Upgrade Guide](#upgrading-from-the-old-version-of-application-insights).

701
common/config/rush/npm-shrinkwrap.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

31
examples/README.md Normal file
Просмотреть файл

@ -0,0 +1,31 @@
# Microsoft Application Insights JavaScript SDK Examples
A collection of examples using the ApplicationInsights SDK, these examples are compiled as part of every build (unless otherwise stated),
but may not be executed as part of any automated test pass -- this may change/vary.
## Examples
[Shared Worker](./shared-worker/README.md)
## Contributing
This project welcomes contributions and suggestions. Most contributions require you to
agree to a Contributor License Agreement (CLA) declaring that you have the right to,
and actually do, grant us the rights to use your contribution. For details, visit
https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need
to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the
instructions provided by the bot. You will only need to do this once across all repositories using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsofts Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-partys policies.
## License
[MIT](LICENSE)

Просмотреть файл

@ -0,0 +1,49 @@
# Microsoft Application Insights JavaScript SDK Example - Shared Worker
![GitHub Workflow Status (main)](https://img.shields.io/github/actions/workflow/status/microsoft/ApplicationInsights-JS/ci.yml?branch=master)
Example to instrument a Shared-Worker
## Simple Instrumented Shared Worker Example
This is a simple example that uses 2 Shared Workers as defined by
- [worker.ts](./src/worker.ts)
- [worker2.ts](./src/worker2.ts)
You WILL NEED to have compiled the repository before running this example as it loads the compiled scripts, and you will also NEED to start the
local web server via `npm run serve` from the root of repository.
You can load the Shared Worker example via the [SharedWorker.html](SharedWorker.html).
This implements a VERY simple Shared Worker example that passes messages between the
current page and the workers using the type in the [IExampleMessage](./src/interfaces/IExampleMessage.ts),
And the support functions for the Web page are located in [example-shared-worker.ts](./src/example-shared-worker.ts)
## Contributing
This project welcomes contributions and suggestions. Most contributions require you to
agree to a Contributor License Agreement (CLA) declaring that you have the right to,
and actually do, grant us the rights to use your contribution. For details, visit
https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need
to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the
instructions provided by the bot. You will only need to do this once across all repositories using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Data Collection
As this SDK is designed to enable applications to perform data collection which is sent to the Microsoft collection endpoints the following is required to identify our privacy statement.
The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsofts privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
## Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsofts Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-partys policies.
## License
[MIT](LICENSE)

Просмотреть файл

@ -0,0 +1,124 @@
<html>
<head>
<script src="./browser/example-shared-worker.gbl.js"></script>
</head>
<body>
<h1>Simple Instrumented Shared Worker Example</h1>
<p>Please make sure that you have compiled the repository before running this example as it loads the compiled scripts.</p>
<p>This script also needs to be run from the hosted `localhost` instance which can be started by running<br/> &gt; <code>npm run serve</code><br/>
from the root folder of the repository.
</p>
<p>
And then re-laoding this page from <a href="http://localhost:9001/examples/shared-worker/SharedWorker.html">http://localhost:9001/examples/shared-worker/SharedWorker.html</a>
</p>
<p>
Work is sent to the worker(s) and any responses are returned and displayed on the main console, if you want to inspect
the console of the workers you can access and debug the worker code via these links. You will need to manually open as accessing
local resources is generally prohibited.
<ul>
<li>Chrome: <code>chrome://inspect/#workers</code></li>
<li>MS Edge: <code>edge://inspect/#workers</code></li>
</ul>
</p>
<hr />
<h2>Worker 1 - Instrumented</h2>
<p>You must use the <code>Initialize SDK</code> button at least once to initialize Application Insights within the worker.
The <code>Unload SDK</code> will cause the SDK instance in the worker to unload and this will disable the reporting of fetch calls.<br/>
Once the SDK in initialized it will report back when events are sent from the Workers SDK instance.
</p>
<div>
<div style="display:inline-block; width:50%; vertical-align: top;">
<div>
<div style="display:inline-block; width:10%">
<label for="connectionString">Connection String</label>
</div>
<input id="connectionString" style="width:50%" value="YourConnectionString" />
</div>
<div style="margin-top:10px">
<div style="display:inline-block; width:10%">
</div>
<button onclick="javascript:Microsoft.ApplicationInsights.Example.loadSdk('connectionString')">Initialize SDK</button>
<button onclick="javascript:Microsoft.ApplicationInsights.Example.unloadSdk()">Unload SDK</button>
</div>
<hr style="margin-top:10px"/>
<div>
<div style="display:inline-block; width:10%">
<label for="fetchUrl">Fetch URL</label>
</div>
<input id="fetchUrl" style="width:50%" value="https://js.monitor.azure.com/scripts/b/ai.2.integrity.json" />
</div>
<div style="margin-top:10px">
<div style="display:inline-block; width:10%">
</div>
<div style="display:inline-block">
<div>
This will cause the worker (if the SDK is initialized) to send a RemoteDependency event.
</div>
<button onclick="javascript:Microsoft.ApplicationInsights.Example.fetchUrl('fetchUrl')">Fetch the URL</button> (Contents will be sent to the main page console via a post)
</div>
</div>
<div style="margin-top:10px">
<div style="display:inline-block; width:10%">
</div>
<div style="display:inline-block">
<div style="margin-bottom:2px">
This will cause the worker (if the SDK is initialized) to send a new PageView event.
</div>
<button onclick="javascript:Microsoft.ApplicationInsights.Example.trackPageView()">Track Page View</button>
</div>
</div>
<div style="margin-top:10px">
<div style="display:inline-block; width:10%">
</div>
<div style="display:inline-block">
<div style="margin-bottom:2px">
Send an invalid request to the worker
</div>
<button onclick="javascript:Microsoft.ApplicationInsights.Example.sendInvalidRequest()">Send Invalid Request</button>
</div>
</div>
</div>
<div style="display:inline-table; width:45%; margin-left: 10px">
<p>This is the information returned by the worker, when the SDK is initialized you will see an "Events Sent"
message when the SDK has sent the events to Azure Monitor, if the connection string is valid you will
see the generated events in the Azure Monitor Portal.
</p>
<textarea id="_logContainer-log" style="width:100%; min-height: 200px;"></textarea>
<button onclick="javascript:Microsoft.ApplicationInsights.Example.clearLog('log')">Clear Log</button>
</div>
</div>
<hr/>
<h2>Worker 2 - Not Instrumented</h2>
<div>
<div style="display:inline-block; width:50%; vertical-align: top;">
<div>
<div style="display:inline-block; width:10%">
<label for="fetch2Url">Fetch URL</label>
</div>
<input id="fetch2Url" style="width:50%" value="https://js.monitor.azure.com/scripts/b/ai.2.integrity.json" />
</div>
<div style="margin-top:10px">
<div style="display:inline-block; width:10%">
</div>
<button onclick="javascript:Microsoft.ApplicationInsights.Example.fetch2Url('fetch2Url')">Fetch the URL</button> (Contents will be sent to the main page console via a post)
</div>
<div style="margin-top:10px">
<div style="display:inline-block; width:10%">
</div>
<div style="display:inline-block">
<div style="margin-bottom:2px">
Send an invalid request to the worker
</div>
<button onclick="javascript:Microsoft.ApplicationInsights.Example.sendInvalidRequest2()">Send Invalid Request</button>
</div>
</div>
</div>
<div style="display:inline-block; width:45%; margin-left: 10px">
<p>This is the information returned by the worker 2.
</p>
<textarea id="_logContainer-log2" style="width:100%; min-height: 200px;"></textarea>
<button onclick="javascript:Microsoft.ApplicationInsights.Example.clearLog('log2')">Clear Log</button>
</div>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,71 @@
{
"name": "@microsoft/applicationinsights-example-shared-worker",
"author": "Microsoft Application Insights Team",
"version": "2.8.10",
"description": "Microsoft Application Insights Shared Worker Example",
"homepage": "https://github.com/microsoft/ApplicationInsights-JS#readme",
"keywords": [
"azure",
"cloud",
"script errors",
"microsoft",
"application insights",
"browser performance monitoring",
"web analytics",
"example"
],
"main": "dist/applicationinsights-example-shared-worker.js",
"module": "dist-esm/applicationinsights-example-shared-worker.js",
"types": "types/applicationinsights-example-shared-worker.d.ts",
"scripts": {
"clean": "grunt clean",
"build": "npm run build:esm && npm run build:browser",
"build:esm": "grunt example-shared-worker",
"build:browser": "rollup -c rollup.config.js",
"rebuild": "npm run build",
"test": "",
"mintest": "",
"perftest": "",
"lint": "tslint -p tsconfig.json",
"ai-min": "grunt example-shared-worker-min",
"ai-restore": "grunt example-shared-worker-restore"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/ApplicationInsights-JS/tree/master/shared/AppInsightsCore"
},
"license": "MIT",
"sideEffects": false,
"devDependencies": {
"@microsoft/ai-test-framework": "0.0.1",
"@microsoft/applicationinsights-rollup-plugin-uglify3-js": "1.0.0",
"@microsoft/applicationinsights-rollup-es3": "1.1.3",
"grunt": "^1.5.3",
"grunt-cli": "^1.4.3",
"grunt-contrib-qunit": "^6.2.1",
"@nevware21/grunt-ts-plugin": "^0.4.3",
"@nevware21/grunt-eslint-ts": "^0.2.2",
"globby": "^11.0.0",
"magic-string": "^0.25.7",
"pako": "^2.0.3",
"@rollup/plugin-commonjs": "^18.0.0",
"@rollup/plugin-node-resolve": "^11.2.1",
"@rollup/plugin-replace": "^2.3.3",
"rollup-plugin-cleanup": "^3.2.1",
"rollup": "^2.32.0",
"typescript": "^4.9.3",
"tslib": "^2.0.0",
"qunit": "^2.11.2",
"sinon": "^7.3.1"
},
"peerDependencies": {
"tslib": "*"
},
"dependencies": {
"@microsoft/applicationinsights-shims": "2.0.2",
"@microsoft/dynamicproto-js": "^1.1.7",
"@microsoft/applicationinsights-web": "2.8.10",
"@microsoft/applicationinsights-web-snippet": "1.0.1",
"@nevware21/ts-utils": ">= 0.7 < 2.x"
}
}

Просмотреть файл

@ -0,0 +1,102 @@
import nodeResolve from "@rollup/plugin-node-resolve";
import { uglify } from "@microsoft/applicationinsights-rollup-plugin-uglify3-js";
import replace from "@rollup/plugin-replace";
import cleanup from "rollup-plugin-cleanup";
import dynamicRemove from "@microsoft/dynamicproto-js/tools/rollup/node/removedynamic";
import { es3Poly, es3Check, importCheck } from "@microsoft/applicationinsights-rollup-es3";
import { updateDistEsmFiles } from "../../tools/updateDistEsm/updateDistEsm";
const version = require("./package.json").version;
const workerName = "example-shared-worker";
const workerModule = "worker";
const worker2Module = "worker2";
const banner = [
"/*!",
` * Application Insights JavaScript SDK Example - Shared Worker, ${version}`,
" * Copyright (c) Microsoft and contributors. All rights reserved.",
" */"
].join("\n");
const replaceValues = {
"// Copyright (c) Microsoft Corporation. All rights reserved.": "",
"// Licensed under the MIT License.": ""
};
function doCleanup() {
return cleanup({
comments: [
'some',
/^.\s*@DynamicProtoStub/i,
/^\*\*\s*@class\s*$/
]
})
}
const browserRollupConfigFactory = (name, isProduction, format = "umd", extension = "") => {
const browserRollupConfig = {
input: `dist-esm/${name}.js`,
output: {
file: `browser/${name}${extension ? "." +extension : ""}.js`,
banner: banner,
format: format,
name: "Microsoft.ApplicationInsights.Example",
extend: true,
freeze: false,
sourcemap: true
},
treeshake: {
propertyReadSideEffects: false,
moduleSideEffects: false,
tryCatchDeoptimization: false,
correctVarValueBeforeDeclaration: false
},
plugins: [
dynamicRemove(),
replace({
preventAssignment: true,
delimiters: ["", ""],
values: replaceValues
}),
// This just makes sure we are importing the example dependencies correctly
importCheck({ exclude: [ "applicationinsights-example-shared-worker" ] }),
nodeResolve({
module: true,
browser: true,
preferBuiltins: false
}),
doCleanup(),
es3Poly(),
es3Check()
]
};
if (isProduction) {
browserRollupConfig.output.file = `browser/${name}${extension ? "." +extension : ""}.min.js`;
browserRollupConfig.plugins.push(
uglify({
ie8: false,
ie: true,
compress: {
ie: true,
passes:3,
unsafe: true,
},
output: {
ie: true,
preamble: banner,
webkit:true
}
})
);
}
return browserRollupConfig;
};
updateDistEsmFiles(replaceValues, banner);
export default [
browserRollupConfigFactory(workerName, false, "iife", "gbl"),
browserRollupConfigFactory(workerModule, false, "esm"),
browserRollupConfigFactory(worker2Module, false, "esm")
];

Просмотреть файл

@ -0,0 +1,208 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { getDocument } from "@nevware21/ts-utils";
import { ExampleMessageType, IExampleRequest } from "./interfaces/IExampleMessage";
let _logContainers = {
log: "",
log2: ""
};
let _worker: SharedWorker;
let _worker2: SharedWorker;
//-------------------------------------------------------------------------------------
// Main Page Helper functions
//-------------------------------------------------------------------------------------
/**
* Log details to the named HTML Text Area
* @param message
* @param dest
*/
function logMessage(message: string, dest: keyof typeof _logContainers) {
var dateTime = new Date().toLocaleString();
var target = "_logContainer-" + dest || "log";
var elm = document.getElementById(target);
_logContainers[target] = dateTime + ": " + message + "\n" + (_logContainers[target] ||"");
if (_logContainers[target].length > 4096) {
_logContainers[target] = _logContainers[target].substring(0, 4090) + "...\n";
}
if (elm) {
elm.innerHTML = _logContainers[target];
}
console.log(message);
}
/**
* Clear the log and the named HTML Text Area
* @param dest
*/
export function clearLog(dest: keyof typeof _logContainers) {
var target = "_logContainer-" + dest || "log";
var elm = document.getElementById(target);
_logContainers[target] = "";
if (elm) {
elm.innerHTML = _logContainers[target];
}
}
//-------------------------------------------------------------------------------------
// Worker 1 functions for main page
//-------------------------------------------------------------------------------------
/**
* Cause Worker 1 to be loaded and started or return the previous loaded / started reference
* @returns
*/
export function loadSharedWorker() {
if (!_worker) {
_worker = new SharedWorker("./browser/worker.js");
_worker.port.onmessage = (evt) => {
let resp = evt.data;
if (resp) {
logMessage(JSON.stringify(resp), "log");
}
}
}
return _worker;
}
/**
* Send a message to Worker 1, this will initialize the worker if has not already been started
* @param message
*/
export function sendWorkerMessage(message: IExampleRequest) {
let worker = loadSharedWorker();
worker.port.postMessage(message);
}
/**
* Ask Worker 1 to initialize the SDK
* @param connectionStringId
*/
export function loadSdk(connectionStringId: string) {
let doc = getDocument();
let elm = doc.getElementById(connectionStringId) as HTMLInputElement;
let connectionString: string;
if (elm) {
connectionString = elm.value;
}
sendWorkerMessage({
type: ExampleMessageType.Load,
connectionString: connectionString
});
}
/**
* Ask Worker 1 to unload the SDK
*/
export function unloadSdk() {
sendWorkerMessage({
type: ExampleMessageType.Unload
});
}
/**
* Ask Worker 1 to fetch the provided URL (this will cause the worker fetch to trigger a Dependency Request)
* @param urlId
*/
export function fetchUrl(urlId: string) {
let doc = getDocument();
let elm = doc.getElementById(urlId) as HTMLInputElement;
let theUrl: string;
if (elm) {
theUrl = elm.value;
}
sendWorkerMessage({
type: ExampleMessageType.Fetch,
url: theUrl
});
}
/**
* Ask Worker 1 to perform a track Page view
*/
export function trackPageView() {
sendWorkerMessage({
type: ExampleMessageType.TrackPageView
});
}
/**
* Send an invalid request to Worker 1
*/
export function sendInvalidRequest() {
sendWorkerMessage({
type: 9999
});
}
//-------------------------------------------------------------------------------------
// Worker 2 functions for main page
//-------------------------------------------------------------------------------------
/**
* Cause Worker 2 to be loaded and started or return the previous loaded / started reference
* @returns
*/
export function loadSharedWorker2() {
if (!_worker2) {
_worker2 = new SharedWorker("./browser/worker2.js");
_worker2.port.onmessage = (evt) => {
let resp = evt.data;
if (resp) {
logMessage(JSON.stringify(resp), "log2");
}
}
}
return _worker2;
}
/**
* Send a message to Worker 2, this will initialize the worker if has not already been started
* @param message
*/
export function sendWorker2Message(message: IExampleRequest) {
let worker = loadSharedWorker2();
worker.port.postMessage(message);
}
/**
* Ask Worker 2 to fetch the provided URL (this will cause the worker fetch to trigger a Dependency Request)
* @param urlId
*/
export function fetch2Url(urlId: string) {
let doc = getDocument();
let elm = doc.getElementById(urlId) as HTMLInputElement;
let theUrl: string;
if (elm) {
theUrl = elm.value;
}
sendWorker2Message({
type: ExampleMessageType.Fetch,
url: theUrl
});
}
/**
* Send an invalid request to Worker 2
*/
export function sendInvalidRequest2() {
sendWorker2Message({
type: 9999
});
}

Просмотреть файл

@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/**
* Enum to identify the examples support messages
*/
export const enum ExampleMessageType {
Invalid = 0,
Load = 1,
Unload = 2,
Fetch = 3,
TrackPageView = 4
}
/**
* The format of a request to the example workers
*/
export interface IExampleRequest {
type: ExampleMessageType;
connectionString?: string;
url?: string;
}
/**
* The format of the response returned from the workers
*/
export interface IExampleResponse {
success: boolean;
message?: string;
resp?: string;
}

Просмотреть файл

@ -0,0 +1,65 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { ApplicationInsights, IConfiguration } from "@microsoft/applicationinsights-web"
// Cache the previously initialized instance to avoid creating multiple instances
let _appInsights: ApplicationInsights;
/**
* Initialize (or return the previously initialized) SDK instance for the worker
* @param config
* @returns
*/
export function initApplicationInsights(config: IConfiguration, onInitCallback: (appInsights: ApplicationInsights, port: MessagePort) => void, port: MessagePort) {
if (!_appInsights) {
// Make sure we have a configuration object
config = config || {};
if (!config.instrumentationKey || !config.connectionString) {
config.connectionString = "InstrumentationKey=YOUR_INSTRUMENTATION_KEY_GOES_HERE";
}
_appInsights = new ApplicationInsights({
config: config
});
_appInsights.loadAppInsights();
if (_appInsights.core.isInitialized()) {
// Call the callback before the trackPageView
onInitCallback(_appInsights, port);
_appInsights.trackPageView(); // Manually call trackPageView to establish the current user/session/pageview
}
return _appInsights;
}
return _appInsights;
}
/**
* Unload the SDK if it has been initialized
* @returns
*/
export function unloadApplicationInsights() {
if (_appInsights) {
_appInsights.unload();
_appInsights = null;
return true;
}
return false;
}
/**
* Request a page view request if the SDK has been initialized
* @returns
*/
export function trackPageView() {
if (_appInsights) {
_appInsights.trackPageView();
return true;
}
return false;
}

Просмотреть файл

@ -0,0 +1,206 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { initApplicationInsights, trackPageView, unloadApplicationInsights } from "./worker-npm-init";
import { ExampleMessageType, IExampleRequest, IExampleResponse } from "./interfaces/IExampleMessage";
import { ApplicationInsights, IConfiguration, INotificationListener } from "@microsoft/applicationinsights-web";
import { dumpObj, objAssign } from "@nevware21/ts-utils";
/**
* Default base configuration, add your defaults here.
* Or simply specify your entire configuration and don't have the main page pass
* the connection string.
*/
const defaultApplicationInsightsConfig: IConfiguration = {
/**
* Telemtry logging level to instrumentation key. All logs with a severity
* level higher than the configured level will sent as telemetry data to
* the configured instrumentation key.
*
* 0: ALL iKey logging off
* 1: logs to iKey: severity >= CRITICAL
* 2: logs to iKey: severity >= WARNING
*/
loggingLevelTelemetry: 2
};
/**
* Simple lookup table which matches the request type to the function that will process the request
*/
const EventHandlers: { [key: number]: (request: IExampleRequest, port: MessagePort) => IExampleResponse } = {
[ExampleMessageType.Invalid]: workerInvalid,
[ExampleMessageType.Load]: workerLoadSdk,
[ExampleMessageType.Unload]: workerUnloadSdk,
[ExampleMessageType.Fetch]: workerFetch,
[ExampleMessageType.TrackPageView]: workerTrackPageView
};
/**
* The main shared worker entry point
*/
addEventListener("connect", (evt: MessageEvent) => {
const port = evt.ports[0];
// Add the message listener
port.addEventListener("message", (evt: MessageEvent<IExampleRequest>) => {
const request = evt.data;
if (!request || !request.type) {
// doesn't look correct
port.postMessage(workerInvalid(request));
return;
}
console.log(`Worker: Received message [${request.type}] from main script`);
let handler: (request: IExampleRequest, port: MessagePort) => IExampleResponse = EventHandlers[request.type];
if (!handler) {
handler = workerInvalid;
}
try {
let response = handler(request, port);
if (response) {
port.postMessage(response);
}
} catch (e) {
port.postMessage({
success: false,
message: dumpObj(e)
});
}
});
port.start();
});
/**
* Handle "Invalid" (Unknown) request
* @param request
* @returns
*/
function workerInvalid(request: IExampleRequest) {
return {
success: false,
message: `Unsupported command - ${request ? request.type : "Invalid Request"}`
}
}
/**
* Internal hook to listen to the events send notification from the Application Insights Sender
* @param port
* @returns
*/
function notificationListener(port: MessagePort): INotificationListener {
return {
eventsSendRequest: function () {
port.postMessage({
success: true,
message: `Events Sent: ${dumpObj(arguments)}`
});
}
};
}
/**
* We only want to add any notification listener or telemetry initializer once
* otherwise they WILL get called multiple times during processing.
* @param appInsights
* @param port
*/
function onInitAddInitializers(appInsights: ApplicationInsights, port: MessagePort) {
// This callback is only called once, otherwise we would keep adding listeners and initializers
appInsights.core.getNotifyMgr().addNotificationListener(notificationListener(port));
// This is not normally needed, but this provides a view from the worker to the
// main page about errors that the worker is having / seeing
appInsights.addTelemetryInitializer((theEvent) => {
if (theEvent && theEvent.name && theEvent.name["startsWith"]("InternalMessageId") && theEvent.baseData) {
port.postMessage({
success: true,
message: "Internal Message: " + (theEvent.baseData?.message || "--")
});
// Drop ALL internal message from being sent to Azure Monitor portal
return false;
}
});
}
/**
* Initialize the SDK using the passed connection string from the request (if supplied)
* @param request
* @param port
* @returns
*/
function workerLoadSdk(request: IExampleRequest, port: MessagePort) {
let theConfig = objAssign({}, defaultApplicationInsightsConfig);
theConfig.connectionString = request.connectionString;
let appInsights = initApplicationInsights(theConfig, onInitAddInitializers, port);
if (appInsights && appInsights.core.isInitialized()) {
return {
success: true,
message: `SDK Loaded and Initialized with - ${appInsights.config.connectionString}`
};
}
return {
success: true,
message: "SDK Failed to initialize"
};
}
/**
* Unload the SDK instance
* @param request
* @returns
*/
function workerUnloadSdk(request: IExampleRequest) {
if (unloadApplicationInsights()) {
return {
success: true,
message: "SDK Unloading"
};
}
return {
success: true,
message: "SDK Already unloaded"
};
}
/**
* Perform a "fetch" request for the provided URL
* @param request
* @param port
* @returns
*/
function workerFetch(request: IExampleRequest, port: MessagePort) {
function fetchFailed(reason: any) {
port.postMessage({ success: false, message: dumpObj(reason) });
}
fetch(request.url).then((value) => {
value.text().then((theResponse) => {
port.postMessage({ success: true, resp: theResponse });
}, fetchFailed);
}, fetchFailed);
// Will return message asynchronously
return {
success: true,
message: "Fetch request received"
};
}
/**
* Attempt to send a PageView event (if the SDK is initialized)
* @param request
* @param port
* @returns
*/
function workerTrackPageView(request: IExampleRequest, port: MessagePort) {
return {
success: trackPageView(),
message: "TrackPageView requested"
};
}

Просмотреть файл

@ -0,0 +1,83 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { ExampleMessageType, IExampleRequest, IExampleResponse } from "./interfaces/IExampleMessage";
import { dumpObj } from "@nevware21/ts-utils";
const EventHandlers: { [key: number]: (request: IExampleRequest, port: MessagePort) => IExampleResponse } = {
[ExampleMessageType.Invalid]: workerInvalid,
[ExampleMessageType.Fetch]: workerFetch
};
/**
* The main shared worker entry point
*/
addEventListener("connect", (evt: MessageEvent) => {
const port = evt.ports[0];
// Add the message listener
port.addEventListener("message", (evt: MessageEvent<IExampleRequest>) => {
const request = evt.data;
if (!request || !request.type) {
// doesn't look correct
console.log("Worker2: Invalid message received -- ignoring!");
return;
}
console.log(`Worker2: Received message [${request.type}] from main script`);
let handler: (request: IExampleRequest, port: MessagePort) => IExampleResponse = EventHandlers[request.type];
if (!handler) {
handler = workerInvalid;
}
try {
let response = handler(request, port);
if (response) {
port.postMessage(response);
}
} catch (e) {
port.postMessage({
success: false,
message: dumpObj(e)
});
}
});
port.start();
});
/**
* Handle "Invalid" (Unknown) request
* @param request
* @returns
*/
function workerInvalid(request: IExampleRequest) {
return {
success: false,
message: `Unsupported commend - ${request.type}`
}
}
/**
* Perform a "fetch" request for the provided URL
* @param request
* @param port
* @returns
*/
function workerFetch(request: IExampleRequest, port: MessagePort) {
function fetchFailed(reason: any) {
port.postMessage({ success: false, message: dumpObj(reason) });
}
fetch(request.url).then((value) => {
value.text().then((theResponse) => {
port.postMessage({ success: true, resp: theResponse });
}, fetchFailed);
}, fetchFailed);
// Will return message asynchronously
return {
success: true,
message: "Worker2: Fetch request received"
};
}

Просмотреть файл

@ -0,0 +1,26 @@
{
"compilerOptions": {
"sourceMap": true,
"inlineSources": true,
"noImplicitAny": true,
"module": "es6",
"moduleResolution": "node",
"target": "es5",
"forceConsistentCasingInFileNames": true,
"importHelpers": true,
"noEmitHelpers": true,
"skipLibCheck": false,
"alwaysStrict": true,
"skipDefaultLibCheck": true,
"declaration": true,
"declarationDir": "./types",
"outDir": "./dist-esm",
"rootDir": "./src",
"suppressImplicitAnyIndexErrors": true,
"allowSyntheticDefaultImports": true
},
"include": [
"src/**/*"
],
"exclude": ["node_modules/"]
}

Просмотреть файл

@ -11,6 +11,23 @@ import {
} from "@microsoft/applicationinsights-core-js";
import { PageViewPerformanceManager } from "./PageViewPerformanceManager";
declare let WorkerGlobalScope: any;
declare let self: any;
let _isWebWorker: boolean = null;
function isWebWorker() {
if (_isWebWorker == null) {
try {
_isWebWorker = !!(self && self instanceof WorkerGlobalScope);
} catch(e) {
_isWebWorker = false;
}
}
return _isWebWorker;
}
/**
* Internal interface to pass appInsights object to subcomponents without coupling
*/
@ -99,11 +116,13 @@ export class PageViewManager {
);
_flushChannels(true);
// no navigation timing (IE 8, iOS Safari 8.4, Opera Mini 8 - see http://caniuse.com/#feat=nav-timing)
_throwInternal(_logger,
eLoggingSeverity.WARNING,
_eInternalMessageId.NavigationTimingNotSupported,
"trackPageView: navigation timing API used for calculation of page duration is not supported in this browser. This page view will be collected without duration and timing info.");
if (!isWebWorker()) {
// no navigation timing (IE 8, iOS Safari 8.4, Opera Mini 8 - see http://caniuse.com/#feat=nav-timing)
_throwInternal(_logger,
eLoggingSeverity.WARNING,
_eInternalMessageId.NavigationTimingNotSupported,
"trackPageView: navigation timing API used for calculation of page duration is not supported in this browser. This page view will be collected without duration and timing info.");
}
return;
}

Просмотреть файл

@ -20,6 +20,9 @@ import {
} from "./DependencyListener";
import { IAjaxRecordResponse, ajaxRecord } from "./ajaxRecord";
declare let WorkerGlobalScope: any;
declare let self: any;
const AJAX_MONITOR_PREFIX = "ai.ajxmn.";
const strDiagLog = "diagLog";
const strAjaxData = "ajaxData";
@ -54,6 +57,20 @@ function _supportsFetch(): (input: RequestInfo, init?: RequestInit) => Promise<R
return _global[STR_FETCH];
}
let _isWebWorker: boolean = null;
function isWebWorker() {
if (_isWebWorker == null) {
try {
_isWebWorker = !!(self && self instanceof WorkerGlobalScope);
} catch(e) {
_isWebWorker = false;
}
}
return _isWebWorker;
}
/**
* Determines whether ajax monitoring can be enabled on this document
* @returns True if Ajax monitoring is supported on this page, otherwise false
@ -617,7 +634,7 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
// Create an error callback to report any hook errors
hkErr: _createErrorCallbackFunc(_self, _eInternalMessageId.FailedMonitorAjaxOpen,
"Failed to monitor Window.fetch" + ERROR_POSTFIX)
}));
}, true, isWebWorker()));
_fetchInitialized = true;
} else if (isPolyfill) {

Просмотреть файл

@ -438,7 +438,12 @@ module.exports = function (grunt) {
path: "./extensions/applicationinsights-properties-js",
unitTestName: "prop.tests.js"
},
// Examples
"example-shared-worker": {
autoMinify: false,
path: "./examples/shared-worker",
testHttp: false
},
// Tools
"rollupuglify": {
autoMinify: false,
@ -750,6 +755,9 @@ module.exports = function (grunt) {
grunt.registerTask("clickanalyticstests", tsTestActions("clickanalytics"));
grunt.registerTask("clickanalytics-mintests", tsTestActions("clickanalytics", true));
grunt.registerTask("example-shared-worker", tsBuildActions("example-shared-worker"));
grunt.registerTask("example-shared-worker-test", tsTestActions("example-shared-worker"));
grunt.registerTask("tst-framework", tsBuildActions("tst-framework"));
grunt.registerTask("serve", ["connect:server:keepalive"]);
} catch (e) {

Просмотреть файл

@ -98,6 +98,11 @@
"packageName": "applicationinsights-web-config",
"projectFolder": "tools/config",
"shouldPublish": false
},
{
"packageName": "@microsoft/applicationinsights-example-shared-worker",
"projectFolder": "examples/shared-worker",
"shouldPublish": false
}
]
}

Просмотреть файл

@ -2,7 +2,8 @@
# Microsoft Application Insights JavaScript SDK - Core
[![Build Status](https://travis-ci.org/microsoft/applicationinsights-core-js.svg?branch=master)](https://travis-ci.org/microsoft/applicationinsights-core-js) [![Build status](https://dev.azure.com/mseng/AppInsights/_apis/build/status/AppInsights%20-%20DevTools/1DS%20JavaScript%20SDK%20-%20Core)](https://dev.azure.com/mseng/AppInsights/_build/latest?definitionId=7605)
![GitHub Workflow Status (main)](https://img.shields.io/github/actions/workflow/status/microsoft/ApplicationInsights-JS/ci.yml?branch=master)
[![npm version](https://badge.fury.io/js/%40microsoft%2Fapplicationinsights-core-js.svg)](https://badge.fury.io/js/%40microsoft%2Fapplicationinsights-core-js)
Core SDK layer for next version of application insights javascript SDK.

Просмотреть файл

@ -131,13 +131,13 @@ function _createFunctionHook(aiHook:IInstrumentHooks) {
/** @ignore */
function _getOwner(target:any, name:string, checkPrototype: boolean): any {
function _getOwner(target:any, name:string, checkPrototype: boolean, checkParentProto: boolean): any {
let owner = null;
if (target) {
if (hasOwnProperty(target, name)) {
owner = target;
} else if (checkPrototype) {
owner = _getOwner(_getObjProto(target), name, false);
owner = _getOwner(_getObjProto(target), name, checkParentProto, false);
}
}
@ -219,10 +219,11 @@ function _createInstrumentHook(owner: any, funcName: string, fn: any, callbacks:
* @param funcName - The function name
* @param callbacks - The callbacks to configure and call whenever the function is called
* @param checkPrototype - If the function doesn't exist on the target should it attempt to hook the prototype function
* @param checkParentProto - If the function doesn't exist on the target or it's prototype should it attempt to hook the parent's prototype
*/
export function InstrumentFunc(target:any, funcName:string, callbacks: IInstrumentHooksCallbacks, checkPrototype:boolean = true): IInstrumentHook {
export function InstrumentFunc(target:any, funcName:string, callbacks: IInstrumentHooksCallbacks, checkPrototype: boolean = true, checkParentProto?: boolean): IInstrumentHook {
if (target && funcName && callbacks) {
let owner = _getOwner(target, funcName, checkPrototype);
let owner = _getOwner(target, funcName, checkPrototype, checkParentProto);
if (owner) {
let fn = owner[funcName]
if (typeof fn === strShimFunction) {
@ -240,11 +241,12 @@ export function InstrumentFunc(target:any, funcName:string, callbacks: IInstrume
* @param funcNames - The function names to intercept and call
* @param callbacks - The callbacks to configure and call whenever the function is called
* @param checkPrototype - If the function doesn't exist on the target should it attempt to hook the prototype function
* @param checkParentProto - If the function doesn't exist on the target or it's prototype should it attempt to hook the parent's prototype
*/
export function InstrumentFuncs(target:any, funcNames:string[], callbacks: IInstrumentHooksCallbacks, checkPrototype:boolean = true): IInstrumentHook[] {
export function InstrumentFuncs(target:any, funcNames:string[], callbacks: IInstrumentHooksCallbacks, checkPrototype:boolean = true, checkParentProto?: boolean): IInstrumentHook[] {
let hooks: IInstrumentHook[] = null;
_arrLoop(funcNames, (funcName) => {
let hook = InstrumentFunc(target, funcName, callbacks, checkPrototype);
let hook = InstrumentFunc(target, funcName, callbacks, checkPrototype, checkParentProto);
if (hook) {
if (!hooks) {
hooks = [];
@ -264,10 +266,11 @@ export function InstrumentFuncs(target:any, funcNames:string[], callbacks: IInst
* @param evtName - The name of the event
* @param callbacks - The callbacks to configure and call whenever the function is called
* @param checkPrototype - If the function doesn't exist on the target should it attempt to hook the prototype function
* @param checkParentProto - If the function doesn't exist on the target or it's prototype should it attempt to hook the parent's prototype
*/
export function InstrumentEvent(target: any, evtName: string, callbacks: IInstrumentHooksCallbacks, checkPrototype?: boolean): IInstrumentHook {
export function InstrumentEvent(target: any, evtName: string, callbacks: IInstrumentHooksCallbacks, checkPrototype?: boolean, checkParentProto?: boolean): IInstrumentHook {
if (target && evtName && callbacks) {
let owner = _getOwner(target, evtName, checkPrototype) || target;
let owner = _getOwner(target, evtName, checkPrototype, checkParentProto) || target;
if (owner) {
return _createInstrumentHook(owner, evtName, owner[evtName], callbacks);
}

Просмотреть файл

@ -365,6 +365,10 @@ function shouldProcess(name) {
return updateDefPkgs;
}
if (name.indexOf("examples/") !== -1) {
return updateDefPkgs;
}
if (name.indexOf("extensions/") !== -1) {
return updateDefPkgs;
}