Skip to content

Commit

Permalink
[AI][Task]17099792: Add sample and doc to dependency plugin (#1989)
Browse files Browse the repository at this point in the history
* add sample and doc to dependency plugin

* update dependency doc

* update

* add aisku sample

* update

* update examples

* update

* update example links
  • Loading branch information
Karlie-777 committed Mar 1, 2023
1 parent 67f7ab1 commit 044384b
Show file tree
Hide file tree
Showing 24 changed files with 1,749 additions and 121 deletions.
313 changes: 199 additions & 114 deletions common/config/rush/npm-shrinkwrap.json

Large diffs are not rendered by default.

93 changes: 93 additions & 0 deletions docs/Dependency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Microsoft Application Insights JavaScript SDK - Dependencies Plugin

Dependencies Plugin for the Application Insights Javascript SDK

## Configuration

[`ICorrelationConfig`](../../shared/AppInsightsCommon/src/Interfaces/ICorrelationConfig.ts)

## Functions

### Dependency Listeners

`addDependencyListener(dependencyListener: DependencyListenerFunction): IDependencyListenerHandler`

A [dependency listener](../API-reference.md#adddependencylistener) is a callback function that **allows you to perform additional manipulation of the request details before the request is performed**.

This includes :-

- Complete access to either the XMLHttpRequest instance or the fetch API `input` and `init` arguments.
- Ability to get/set the properties used to generate the W3C `traceparent` header (`traceId`, `spanId,`traceFlags)
- Set values in the object context container for other listeners called after the current one, as well as this context object is also made available to all dependency initializers.

```javascript
public addDependencyListener(dependencyListener: (dependencyDetails: IDependencyListenerDetails) => void): IDependencyListenerHandler;

// Example Usage
let handler = appInsights.addDependencyListener((details) => {
// You have complete access to the xhr instance
// details.xhr: XMLHttpRequest;

// Or if a fetch request you have complete access to the input and init objects
// details.input: Request | string;
// details.init: RequestInit;

// Access or change the W3C traceId that will be added to the outbound request
details.traceId = "";

// Access or change the W3C spanId that will be added to the outbound request
details.spanId = "";

// Access or change the W3C traceflags that will be added to the outbound request
details.traceFlags = 1;

// Add additional context values (any) that can be used by other listeners and is
// also passed to any dependency initializers
details.context.someValue = 1234;
});

// [Optional] Remove the dependency initializer
handler.remove();
```

### Dependency Initializers

`addDependencyInitializer(dependencyInitializer: DependencyInitializerFunction): IDependencyInitializerHandler`

A [Dependency Initializer](../API-reference.md#adddependencyinitializer) is very similar to a [Telemetry Initializer](https://github.com/Microsoft/ApplicationInsights-JS#telemetry-initializers) in that it **allows you modify the contents of collected telemetry before being sent from the user's browser**. And you can also returning `false` to cause the event to not be emitted.

The differences between a telemetry initializer and a dependency initializer are :-

- A Dependency Initializer is called "before" the event is processed by the pipeline, as such it will NOT (yet) contain the automatically populated properties that are applied later;
- When a dependency initializer returns `false` to drop the event the event does NOT count against the `maxAjaxCallsPerView` as this blocks the event call from being tracked, and while returning `false` from a [Telemetry Initializer](https://github.com/Microsoft/ApplicationInsights-JS#telemetry-initializers) will also stop the event from being reported because this is further down the processing pipeline the dependency event IS counted against the `maxAjaxCallsPerView` limit.
- It has access to an optional "context" `{ [key: string]: any }` object that is also available to the Dependency Listeners. This allows a listener to add additional details to the context (before the XHR/fetch request is sent), and the initializer will be called after the request has completed.

```javascript
public addDependencyInitializer(dependencyInitializer: (item: IDependencyInitializerDetails) => boolean | void): IDependencyInitializerHandler

// Example Usage
let handler = appInsights.addDependencyInitializer((details) => {
details.item.xxxx = ""; // item is the telemetry event "before" it's been processed

// [Optional] To stop any event from being reported you can
// return false;
});


// [Optional] Remove the dependency initializer
handler.remove();
```

### Track Dependency

`trackDependencyData(dependency:` `IDependencyTelemetry``, properties?: { [key: string]: any }): void`

[TrackDependencyData](../API-reference.md#trackdependencydata) function allows you to manually log a dependency call.

```javascript
appInsights.trackDependencyData({absoluteUrl: 'some url', responseCode: 200, method: 'GET', id: 'some id'});
```

## Sample

A [sample](./../examples/dependency/README.md) is provided to show how to filter, modify, block and disable dependency data.
44 changes: 44 additions & 0 deletions examples/AISKU/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Application Insights JavaScript SDK

## AISKU Sample

This Sample shows how to track [`pageview`](../../API-reference.md#trackpageview), [`event`](../../API-reference.md#trackevent), [`trace`](../../API-reference.md#tracktrace), [`metric`](../../API-reference.md#trackmetric), [`exception`](../../API-reference.md#trackexception), get cookies details by using `cookieMgr` and record event duration manually by using `startTrackEvent` and `stopTrackEvent`.

## Sample Build

- Build the repository before running this example.
- Run `npm run serve` under root folder.
- Open `http://localhost:9001/examples/AISKU/`.

## Description

- button `Change Config` will change config dynamically.
- button `Create Pageview` will trigger a pageview telemetry.
- button `Create Event` will trigger an event telemetry.
- button `Create Trace` will trigger a trace telemetry.
- button `Create Metric` will trigger a metric telemetry.
- button `Create Exception` will trigger an exception telemetry.
- button `Start Tracking event` will start timing an event with given name `manual_record_event`
- button `Stop Tracking event` will stop timing the previous event with given name `manual_record_event`.

## 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. For more information see the Code of Conduct FAQ or contact 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 Microsoft’s privacy statement. Our privacy statement is located at [here](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 Microsoft’s Trademark & Brand Guidelines. 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-party’s policies.

## License

MIT
30 changes: 30 additions & 0 deletions examples/AISKU/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<html lang="en">
<head>
<meta charset="utf-8">
<title>AISKU Sample</title>
<link rel="stylesheet" href="style/style.css"/>

<!-- use this section for snippet Initialization -->
<!-- <script type="text/javascript">!function(T,l,y){var S=T.location,k="script",D="instrumentationKey",C="ingestionendpoint",I="disableExceptionTracking",E="ai.device.",b="toLowerCase",w="crossOrigin",N="POST",e="appInsightsSDK",t=y.name||"appInsights";(y.name||T[e])&&(T[e]=t);var n=T[t]||function(d){var g=!1,f=!1,m={initialize:!0,queue:[],sv:"5",version:2,config:d};function v(e,t){var n={},a="Browser";return n[E+"id"]=a[b](),n[E+"type"]=a,n["ai.operation.name"]=S&&S.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(m.sv||m.version),{time:function(){var e=new Date;function t(e){var t=""+e;return 1===t.length&&(t="0"+t),t}return e.getUTCFullYear()+"-"+t(1+e.getUTCMonth())+"-"+t(e.getUTCDate())+"T"+t(e.getUTCHours())+":"+t(e.getUTCMinutes())+":"+t(e.getUTCSeconds())+"."+((e.getUTCMilliseconds()/1e3).toFixed(3)+"").slice(2,5)+"Z"}(),iKey:e,name:"Microsoft.ApplicationInsights."+e.replace(/-/g,"")+"."+t,sampleRate:100,tags:n,data:{baseData:{ver:2}}}}var h=d.url||y.src;if(h){function a(e){var t,n,a,i,r,o,s,c,u,p,l;g=!0,m.queue=[],f||(f=!0,t=h,s=function(){var e={},t=d.connectionString;if(t)for(var n=t.split(";"),a=0;a<n.length;a++){var i=n[a].split("=");2===i.length&&(e[i[0][b]()]=i[1])}if(!e[C]){var r=e.endpointsuffix,o=r?e.location:null;e[C]="https://"+(o?o+".":"")+"dc."+(r||"services.visualstudio.com")}return e}(),c=s[D]||d[D]||"",u=s[C],p=u?u+"/v2/track":d.endpointUrl,(l=[]).push((n="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",a=t,i=p,(o=(r=v(c,"Exception")).data).baseType="ExceptionData",o.baseData.exceptions=[{typeName:"SDKLoadFailed",message:n.replace(/\./g,"-"),hasFullStack:!1,stack:n+"\nSnippet failed to load ["+a+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(S&&S.pathname||"_unknown_")+"\nEndpoint: "+i,parsedStack:[]}],r)),l.push(function(e,t,n,a){var i=v(c,"Message"),r=i.data;r.baseType="MessageData";var o=r.baseData;return o.message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+n+")").replace(/\"/g,"")+'"',o.properties={endpoint:a},i}(0,0,t,p)),function(e,t){if(JSON){var n=T.fetch;if(n&&!y.useXhr)n(t,{method:N,body:JSON.stringify(e),mode:"cors"});else if(XMLHttpRequest){var a=new XMLHttpRequest;a.open(N,t),a.setRequestHeader("Content-type","application/json"),a.send(JSON.stringify(e))}}}(l,p))}function i(e,t){f||setTimeout(function(){!t&&m.core||a()},500)}var e=function(){var n=l.createElement(k);n.src=h;var e=y[w];return!e&&""!==e||"undefined"==n[w]||(n[w]=e),n.onload=i,n.onerror=a,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||i(0,t)},n}();y.ld<0?l.getElementsByTagName("head")[0].appendChild(e):setTimeout(function(){l.getElementsByTagName(k)[0].parentNode.appendChild(e)},y.ld||0)}try{m.cookie=l.cookie}catch(p){}function t(e){for(;e.length;)!function(t){m[t]=function(){var e=arguments;g||m.queue.push(function(){m[t].apply(m,e)})}}(e.pop())}var n="track",r="TrackPage",o="TrackEvent";t([n+"Event",n+"PageView",n+"Exception",n+"Trace",n+"DependencyData",n+"Metric",n+"PageViewPerformance","start"+r,"stop"+r,"start"+o,"stop"+o,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),m.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4};var s=(d.extensionConfig||{}).ApplicationInsightsAnalytics||{};if(!0!==d[I]&&!0!==s[I]){var c="onerror";t(["_"+c]);var u=T[c];T[c]=function(e,t,n,a,i){var r=u&&u(e,t,n,a,i);return!0!==r&&m["_"+c]({message:e,url:t,lineNumber:n,columnNumber:a,error:i}),r},d.autoExceptionInstrumented=!0}return m}(y.cfg);function a(){y.onInit&&y.onInit(n)}(T[t]=n).queue&&0===n.queue.length?(n.queue.push(a),n.trackPageView({})):a()}(window,document,{
src: "https://js.monitor.azure.com/scripts/b/ai.2.min.js", // The SDK URL Source for the CDN
crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
cfg: { // Application Insights Configuration
connectionString: "InstrumentationKey=YOUR_INSTRUMENTATION_KEY_GOES_HERE"
}});
</script> -->

</head>
<body>
<h1>Microsoft Application Insights JavaScript SDK - AISKU</h1>
<!-- this script is only used for local build testing -->
<!-- <script src="../../AISKU/dist/applicationinsights-web.js"></script>
<script>
let appInsights = new Microsoft.ApplicationInsights.ApplicationInsights({ config: {connectionString: "InstrumentationKey=key123", disableInstrumentationKeyValidation: true}});
appInsights.loadAppInsights();
window.appInsights = appInsights;
</script> -->
<script src="./browser/aisku-example-index.gbl.js"></script>
</body>
</html>
57 changes: 57 additions & 0 deletions examples/AISKU/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "@microsoft/applicationinsights-example-aisku",
"author": "Microsoft Application Insights Team",
"version": "2.8.10",
"description": "Microsoft Application Insights AISKU Example",
"homepage": "https://github.com/microsoft/ApplicationInsights-JS#readme",
"keywords": [
"azure",
"cloud",
"script errors",
"microsoft",
"application insights",
"browser performance monitoring",
"web analytics",
"example"
],
"scripts": {
"clean": "grunt clean",
"build": "npm run build:esm && npm run build:browser",
"build:esm": "grunt example-aisku",
"build:browser": "rollup -c rollup.config.js",
"rebuild": "npm run build",
"test": "",
"mintest": "",
"perftest": "",
"lint": "tslint -p tsconfig.json",
"ai-min": "",
"ai-restore": ""
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/ApplicationInsights-JS/tree/master/shared/AppInsightsCore"
},
"license": "MIT",
"sideEffects": false,
"devDependencies": {
"@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",
"@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"
},
"peerDependencies": {
"tslib": "*"
},
"dependencies": {
"@microsoft/applicationinsights-shims": "2.0.2",
"@microsoft/dynamicproto-js": "^1.1.7",
"@microsoft/applicationinsights-web": "2.8.10",
"@microsoft/applicationinsights-core-js": "2.8.10"
}
}
100 changes: 100 additions & 0 deletions examples/AISKU/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
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 = "aisku-example-index";

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: [ "aisku-example-index" ] }),
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")
];
Loading

0 comments on commit 044384b

Please sign in to comment.