Add config to exclude a specific request auto tracking (#1582)

* Add config to exclude a specific request auto tracking

* add iconfig

* update the config to pass in regex array or string array to exclude specific routes

* update to support older browser

* update logic

* update md files
This commit is contained in:
Xiao Li 2021-06-16 16:26:57 -07:00 коммит произвёл GitHub
Родитель c7cf90f4d1
Коммит 2612a3cc28
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 118 добавлений и 0 удалений

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

@ -275,6 +275,7 @@ Most configuration fields are named such that they can be defaulted to falsey. A
| autoTrackPageVisitTime | boolean | false | If true, on a pageview, the _previous_ instrumented page's view time is tracked and sent as telemetry and a new timer is started for the current pageview. It is sent as a custom metric named `PageVisitTime` in `milliseconds` and is calculated via the Date [now()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now) function (if available) and falls back to (new Date()).[getTime()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime) if now() is unavailable (IE8 or less). Default is false. |
| disableAjaxTracking | boolean | false | If true, Ajax calls are not autocollected. Default is false. |
| disableFetchTracking | boolean | true | If true, Fetch requests are not autocollected. Default is true |
| excludeRequestFromAutoTrackingPatterns | string[] \| RegExp[] | undefined | Provide a way to exclude specific route from automatic tracking for XMLHttpRequest or Fetch request. If defined, for an ajax / fetch request that the request url matches with the regex patterns, auto tracking is turned off. Default is undefined. |
| overridePageViewDuration | boolean | false | If true, default behavior of trackPageView is changed to record end of page view duration interval when trackPageView is called. If false and no custom duration is provided to trackPageView, the page view performance is calculated using the navigation timing API. Default is false. |
| maxAjaxCallsPerView | numeric | 500 | Default 500 - controls how many ajax calls will be monitored per page view. Set to -1 to monitor all (unlimited) ajax calls on the page. |
| disableDataLossAnalysis | boolean | true | If false, internal telemetry sender buffers will be checked at startup for items not yet sent. |

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

@ -209,6 +209,36 @@ export class AjaxTests extends TestClass {
}
});
this.testCase({
name: "Ajax: xhr without disabled flag but with exclude string configured are not tracked",
test: () => {
this._ajax = new AjaxMonitor();
let appInsightsCore = new AppInsightsCore();
const ExcludeRequestRegex = ["microsoft"];
let coreConfig: IConfiguration & IConfig = { instrumentationKey: "", disableAjaxTracking: true, excludeRequestFromAutoTrackingPatterns: ExcludeRequestRegex };
appInsightsCore.initialize(coreConfig, [this._ajax, new TestChannelPlugin()]);
// act
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://microsoft.com");
// assert
Assert.equal(undefined, (<any>xhr).ajaxData, "RequestUrl is collected correctly");
xhr = new XMLHttpRequest();
xhr.open("GET", "http://microsoft.com");
// assert
Assert.equal(undefined, (<any>xhr).ajaxData, "Follow up GET Request was not instrumented");
xhr = new XMLHttpRequest();
xhr.open("POST", "http://microsoft.com");
// assert
Assert.equal(undefined, (<any>xhr).ajaxData, "Follow up POST Request was not instrumented");
}
});
this.testCase({
name: "Ajax: xhr request header is tracked as part C data when enableRequestHeaderTracking flag is true",
test: () => {
@ -403,6 +433,57 @@ export class AjaxTests extends TestClass {
}]
});
this.testCaseAsync({
name: "Fetch: fetch with disabled flag false and with exclude request regex pattern isn't tracked and any followup request to the same URL event without the disabled flag are also not tracked",
stepDelay: 10,
autoComplete: false,
timeOut: 10000,
steps: [ (done) => {
hookFetch((resolve) => {
TestClass.orgSetTimeout(function() {
resolve({
headers: new Headers(),
ok: true,
body: null,
bodyUsed: false,
redirected: false,
status: 200,
statusText: "Hello",
trailer: null,
type: "basic",
url: "https://httpbin.org/status/200"
});
}, 0);
});
this._ajax = new AjaxMonitor();
let appInsightsCore = new AppInsightsCore();
const ExcludeRequestRegex = ["bin"];
let coreConfig = { instrumentationKey: "", disableFetchTracking: false, excludeRequestFromAutoTrackingPatterns: ExcludeRequestRegex };
appInsightsCore.initialize(coreConfig, [this._ajax, new TestChannelPlugin()]);
let fetchSpy = this.sandbox.spy(appInsightsCore, "track")
// Act
Assert.ok(fetchSpy.notCalled, "No fetch called yet");
fetch("https://httpbin.org/status/200", {method: "post"}).then(() => {
// Assert
Assert.ok(fetchSpy.notCalled, "The initial request was not tracked");
fetch("https://httpbin.org/status/200", {method: "post" }).then(() => {
// Assert
Assert.ok(fetchSpy.notCalled, "The follow up request should also not have been tracked");
done();
}, () => {
Assert.ok(false, "fetch failed!");
done();
});
}, () => {
Assert.ok(false, "fetch failed!");
done();
});
}]
});
this.testCaseAsync({
name: "Fetch: fetch gets instrumented",
stepDelay: 10,

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

@ -155,6 +155,7 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
maxAjaxCallsPerView: 500,
disableAjaxTracking: false,
disableFetchTracking: true,
excludeRequestFromAutoTrackingPatterns: undefined,
disableCorrelationHeaders: false,
distributedTracingMode: DistributedTracingModes.AI_AND_W3C,
correlationHeaderExcludedDomains: [
@ -212,6 +213,7 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
let _enableResponseHeaderTracking:boolean = false;
let _hooks:IInstrumentHook[] = [];
let _disabledUrls:any = {};
let _excludeRequestFromAutoTrackingPatterns: string[] | RegExp[];
dynamicProto(AjaxMonitor, this, (_self, base) => {
_self.initialize = (config: IConfiguration & IConfig, core: IAppInsightsCore, extensions: IPlugin[], pluginChain?:ITelemetryPluginChain) => {
@ -228,6 +230,7 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
_enableAjaxPerfTracking = _config.enableAjaxPerfTracking;
_maxAjaxCallsPerView = _config.maxAjaxCallsPerView;
_enableResponseHeaderTracking = _config.enableResponseHeaderTracking;
_excludeRequestFromAutoTrackingPatterns = _config.excludeRequestFromAutoTrackingPatterns;
_isUsingAIHeaders = distributedTracingMode === DistributedTracingModes.AI || distributedTracingMode === DistributedTracingModes.AI_AND_W3C;
_isUsingW3CHeaders = distributedTracingMode === DistributedTracingModes.AI_AND_W3C || distributedTracingMode === DistributedTracingModes.W3C;
@ -548,6 +551,24 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
function _isDisabledRequest(xhr?: XMLHttpRequestInstrumented, request?: Request | string, init?: RequestInit) {
let isDisabled = false;
let theUrl:string = ((!isString(request) ? ((request ||{}) as Request).url || "" : request as string) ||"").toLowerCase();
// check excludeRequestFromAutoTrackingPatterns before stripping off any query string
arrForEach(_excludeRequestFromAutoTrackingPatterns, (regex: string | RegExp) => {
let theRegex = regex;
if (isString(regex)) {
theRegex = new RegExp(regex);
}
if (!isDisabled) {
isDisabled = (theRegex as RegExp).test(theUrl);
}
});
// if request url matches with exclude regex pattern, return true and no need to check for headers
if (isDisabled) {
return isDisabled;
}
let idx = _indexOf(theUrl, "?");
let idx2 = _indexOf(theUrl, "#");
if (idx === -1 || (idx2 !== -1 && idx2 < idx)) {

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

@ -118,6 +118,14 @@ export interface IConfig {
*/
disableFetchTracking?: boolean;
/**
* @description Provide a way to exclude specific route from automatic tracking for XMLHttpRequest or Fetch request. For an ajax / fetch request that the request url matches with the regex patterns, auto tracking is turned off.
* @type {string[] | RegExp[]}
* @memberof IConfig
* @defaultValue undefined.
*/
excludeRequestFromAutoTrackingPatterns?: string[] | RegExp[];
/**
* @description If true, default behavior of trackPageView is changed to record end of page view duration interval when trackPageView is called. If false and no custom duration is provided to trackPageView, the page view performance is calculated using the navigation timing API. Default is false
* @type {boolean}

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

@ -45,4 +45,11 @@ export interface ICorrelationConfig {
* Response and request headers to be excluded from ajax tracking data.
*/
ignoreHeaders?: string[];
/**
* Provide a way to exclude specific route from automatic tracking for XMLHttpRequest or Fetch request.
* For an ajax / fetch request that the request url matches with the regex patterns, auto tracking is turned off.
* Default is undefined.
*/
excludeRequestFromAutoTrackingPatterns?: string[] | RegExp[];
}