@fluidframework/app-insights-logger 2.0.0-dev.7.3.0.210328 → 2.0.0-rc.1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +1 -1
- package/api-extractor-esm.json +18 -0
- package/api-extractor-lint.json +4 -0
- package/api-extractor.json +1 -2
- package/api-report/app-insights-logger.api.md +6 -10
- package/dist/app-insights-logger-alpha.d.ts +130 -0
- package/dist/app-insights-logger-beta.d.ts +130 -0
- package/dist/app-insights-logger-public.d.ts +22 -0
- package/dist/app-insights-logger-untrimmed.d.ts +130 -0
- package/dist/fluidAppInsightsLogger.d.ts +11 -55
- package/dist/fluidAppInsightsLogger.d.ts.map +1 -1
- package/dist/fluidAppInsightsLogger.js +14 -3
- package/dist/fluidAppInsightsLogger.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/app-insights-logger-alpha.d.mts +124 -0
- package/lib/app-insights-logger-beta.d.mts +124 -0
- package/lib/app-insights-logger-public.d.mts +16 -0
- package/lib/app-insights-logger-untrimmed.d.mts +124 -0
- package/lib/{fluidAppInsightsLogger.d.ts → fluidAppInsightsLogger.d.mts} +12 -56
- package/lib/fluidAppInsightsLogger.d.mts.map +1 -0
- package/lib/{fluidAppInsightsLogger.js → fluidAppInsightsLogger.mjs} +14 -3
- package/lib/fluidAppInsightsLogger.mjs.map +1 -0
- package/lib/index.d.mts +7 -0
- package/lib/index.d.mts.map +1 -0
- package/lib/{index.js → index.mjs} +2 -2
- package/lib/index.mjs.map +1 -0
- package/lib/test/fluidAppInsightsLogger.spec.d.mts +2 -0
- package/lib/test/fluidAppInsightsLogger.spec.d.mts.map +1 -0
- package/lib/test/{fluidAppInsightsLogger.spec.js → fluidAppInsightsLogger.spec.mjs} +23 -27
- package/lib/test/fluidAppInsightsLogger.spec.mjs.map +1 -0
- package/package.json +87 -15
- package/src/fluidAppInsightsLogger.ts +22 -12
- package/src/index.ts +6 -7
- package/tsconfig.json +5 -3
- package/lib/fluidAppInsightsLogger.d.ts.map +0 -1
- package/lib/fluidAppInsightsLogger.js.map +0 -1
- package/lib/index.d.ts +0 -13
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/test/fluidAppInsightsLogger.spec.d.ts +0 -2
- package/lib/test/fluidAppInsightsLogger.spec.d.ts.map +0 -1
- package/lib/test/fluidAppInsightsLogger.spec.js.map +0 -1
- package/tsconfig.esnext.json +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/app-insights-logger",
|
|
3
|
-
"version": "2.0.0-
|
|
3
|
+
"version": "2.0.0-rc.1.0.0",
|
|
4
4
|
"description": "Contains a Fluid logging client that sends telemetry events to Azure App Insights",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -11,22 +11,76 @@
|
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"author": "Microsoft and contributors",
|
|
13
13
|
"sideEffects": false,
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": {
|
|
17
|
+
"types": "./lib/index.d.mts",
|
|
18
|
+
"default": "./lib/index.mjs"
|
|
19
|
+
},
|
|
20
|
+
"require": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"default": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"./alpha": {
|
|
26
|
+
"import": {
|
|
27
|
+
"types": "./lib/app-insights-logger-alpha.d.mts",
|
|
28
|
+
"default": "./lib/index.mjs"
|
|
29
|
+
},
|
|
30
|
+
"require": {
|
|
31
|
+
"types": "./dist/app-insights-logger-alpha.d.ts",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"./beta": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./lib/app-insights-logger-beta.d.mts",
|
|
38
|
+
"default": "./lib/index.mjs"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/app-insights-logger-beta.d.ts",
|
|
42
|
+
"default": "./dist/index.js"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./internal": {
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./lib/index.d.mts",
|
|
48
|
+
"default": "./lib/index.mjs"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/index.d.ts",
|
|
52
|
+
"default": "./dist/index.js"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"./public": {
|
|
56
|
+
"import": {
|
|
57
|
+
"types": "./lib/app-insights-logger-public.d.mts",
|
|
58
|
+
"default": "./lib/index.mjs"
|
|
59
|
+
},
|
|
60
|
+
"require": {
|
|
61
|
+
"types": "./dist/app-insights-logger-public.d.ts",
|
|
62
|
+
"default": "./dist/index.js"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
14
66
|
"main": "dist/index.js",
|
|
15
|
-
"module": "lib/index.
|
|
67
|
+
"module": "lib/index.mjs",
|
|
16
68
|
"types": "dist/index.d.ts",
|
|
17
69
|
"dependencies": {
|
|
18
|
-
"@fluidframework/core-interfaces": "2.0.0-
|
|
19
|
-
"@fluidframework/telemetry-utils": "2.0.0-
|
|
70
|
+
"@fluidframework/core-interfaces": ">=2.0.0-rc.1.0.0 <2.0.0-rc.1.1.0",
|
|
71
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-rc.1.0.0 <2.0.0-rc.1.1.0",
|
|
20
72
|
"@microsoft/applicationinsights-web": "^2.8.11"
|
|
21
73
|
},
|
|
22
74
|
"devDependencies": {
|
|
75
|
+
"@arethetypeswrong/cli": "^0.13.3",
|
|
23
76
|
"@fluidframework/build-common": "^2.0.3",
|
|
24
|
-
"@fluidframework/build-tools": "^0.
|
|
25
|
-
"@fluidframework/mocha-test-setup": "2.0.0-
|
|
26
|
-
"@microsoft/api-extractor": "^7.
|
|
77
|
+
"@fluidframework/build-tools": "^0.29.0",
|
|
78
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-rc.1.0.0 <2.0.0-rc.1.1.0",
|
|
79
|
+
"@microsoft/api-extractor": "^7.38.3",
|
|
27
80
|
"@types/mocha": "^9.1.1",
|
|
28
|
-
"@types/node": "^
|
|
81
|
+
"@types/node": "^18.19.0",
|
|
29
82
|
"@types/sinon": "^7.0.13",
|
|
83
|
+
"copyfiles": "^2.4.1",
|
|
30
84
|
"cross-env": "^7.0.3",
|
|
31
85
|
"eslint": "~8.50.0",
|
|
32
86
|
"eslint-config-prettier": "~9.0.0",
|
|
@@ -37,6 +91,7 @@
|
|
|
37
91
|
"prettier": "~3.0.3",
|
|
38
92
|
"rimraf": "^4.4.0",
|
|
39
93
|
"sinon": "^7.4.2",
|
|
94
|
+
"tsc-multi": "^1.1.0",
|
|
40
95
|
"tslib": "^1.10.0",
|
|
41
96
|
"typescript": "~5.1.6"
|
|
42
97
|
},
|
|
@@ -50,29 +105,46 @@
|
|
|
50
105
|
}
|
|
51
106
|
}
|
|
52
107
|
},
|
|
108
|
+
"fluidBuild": {
|
|
109
|
+
"tasks": {
|
|
110
|
+
"build:docs": {
|
|
111
|
+
"dependsOn": [
|
|
112
|
+
"...",
|
|
113
|
+
"api-extractor:commonjs",
|
|
114
|
+
"api-extractor:esnext"
|
|
115
|
+
],
|
|
116
|
+
"script": false
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
53
120
|
"typeValidation": {
|
|
54
121
|
"disabled": true,
|
|
55
122
|
"broken": {}
|
|
56
123
|
},
|
|
57
124
|
"scripts": {
|
|
125
|
+
"api": "fluid-build . --task api",
|
|
126
|
+
"api-extractor:commonjs": "api-extractor run --local",
|
|
127
|
+
"api-extractor:esnext": "api-extractor run --config ./api-extractor-esm.json",
|
|
58
128
|
"build": "fluid-build . --task build",
|
|
59
129
|
"build:commonjs": "fluid-build . --task commonjs",
|
|
60
130
|
"build:compile": "fluid-build . --task compile",
|
|
61
|
-
"build:docs": "
|
|
62
|
-
"build:esnext": "tsc --
|
|
131
|
+
"build:docs": "fluid-build . --task api",
|
|
132
|
+
"build:esnext": "tsc-multi --config ../../../../common/build/build-common/tsc-multi.esm.json",
|
|
133
|
+
"check:are-the-types-wrong": "attw --pack . --entrypoints .",
|
|
134
|
+
"check:release-tags": "api-extractor run --local --config ./api-extractor-lint.json",
|
|
63
135
|
"ci:build:docs": "api-extractor run",
|
|
64
|
-
"clean": "rimraf --glob _api-extractor-temp coverage dist lib nyc \"
|
|
136
|
+
"clean": "rimraf --glob _api-extractor-temp coverage dist lib nyc \"**/*.tsbuildinfo\" \"**/*.build.log\"",
|
|
65
137
|
"eslint": "eslint src",
|
|
66
138
|
"eslint:fix": "eslint src --fix",
|
|
67
139
|
"format": "npm run prettier:fix",
|
|
68
140
|
"format-and-build": "npm run format && npm run build",
|
|
69
141
|
"format-and-compile": "npm run format && npm run build:compile",
|
|
70
|
-
"lint": "npm run prettier && npm run eslint",
|
|
142
|
+
"lint": "npm run prettier && npm run check:release-tags && npm run eslint",
|
|
71
143
|
"lint:fix": "npm run prettier:fix && npm run eslint:fix",
|
|
72
|
-
"prettier": "prettier --check . --ignore-path ../../../../.prettierignore",
|
|
73
|
-
"prettier:fix": "prettier --write . --ignore-path ../../../../.prettierignore",
|
|
144
|
+
"prettier": "prettier --check . --cache --ignore-path ../../../../.prettierignore",
|
|
145
|
+
"prettier:fix": "prettier --write . --cache --ignore-path ../../../../.prettierignore",
|
|
74
146
|
"test": "npm run test:mocha",
|
|
75
|
-
"test:mocha": "mocha --recursive \"dist/test/**/*.spec
|
|
147
|
+
"test:mocha": "mocha --recursive \"dist/test/**/*.spec.*js\" -r node_modules/@fluidframework/mocha-test-setup",
|
|
76
148
|
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
77
149
|
"tsc": "tsc"
|
|
78
150
|
}
|
|
@@ -11,9 +11,8 @@ import {
|
|
|
11
11
|
import { type TelemetryEventCategory } from "@fluidframework/telemetry-utils";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* The configuration object for the {@link
|
|
15
|
-
*
|
|
16
|
-
* @public
|
|
14
|
+
* The configuration object for creating the logger via {@link createLogger}.
|
|
15
|
+
* @beta
|
|
17
16
|
*/
|
|
18
17
|
export interface FluidAppInsightsLoggerConfig {
|
|
19
18
|
/**
|
|
@@ -46,8 +45,7 @@ export interface FluidAppInsightsLoggerConfig {
|
|
|
46
45
|
|
|
47
46
|
/**
|
|
48
47
|
* A filter used to match against the category of a telemetry event
|
|
49
|
-
*
|
|
50
|
-
* @public
|
|
48
|
+
* @beta
|
|
51
49
|
*/
|
|
52
50
|
export interface CategoryFilter {
|
|
53
51
|
/**
|
|
@@ -58,8 +56,7 @@ export interface CategoryFilter {
|
|
|
58
56
|
|
|
59
57
|
/**
|
|
60
58
|
* A filter used to match against the namespaces of a telemetry event
|
|
61
|
-
*
|
|
62
|
-
* @public
|
|
59
|
+
* @beta
|
|
63
60
|
*/
|
|
64
61
|
export interface NamespaceFilter {
|
|
65
62
|
/**
|
|
@@ -96,9 +93,6 @@ export interface NamespaceFilter {
|
|
|
96
93
|
* 3. If only `categories` or a `namespace` is provided, the event should just match the with whatever was defined.
|
|
97
94
|
*
|
|
98
95
|
* 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.
|
|
99
|
-
*
|
|
100
|
-
* @public
|
|
101
|
-
*
|
|
102
96
|
* @example
|
|
103
97
|
* With the following configuration, an event `{ namespace: "A.B.C", categories: ["generic"] }` will not be sent despite matching the first, less specific filter because it did not match the second filter which was the most relevant and specific
|
|
104
98
|
* ```
|
|
@@ -118,6 +112,7 @@ export interface NamespaceFilter {
|
|
|
118
112
|
* },
|
|
119
113
|
* });
|
|
120
114
|
* ```
|
|
115
|
+
* @beta
|
|
121
116
|
*/
|
|
122
117
|
export type TelemetryFilter = CategoryFilter | NamespaceFilter | (CategoryFilter & NamespaceFilter);
|
|
123
118
|
|
|
@@ -128,9 +123,8 @@ export type TelemetryFilter = CategoryFilter | NamespaceFilter | (CategoryFilter
|
|
|
128
123
|
* or else logging will not occur.
|
|
129
124
|
*
|
|
130
125
|
* @sealed
|
|
131
|
-
* @public
|
|
132
126
|
*/
|
|
133
|
-
|
|
127
|
+
class FluidAppInsightsLogger implements ITelemetryBaseLogger {
|
|
134
128
|
/**
|
|
135
129
|
* The Azure ApplicationInsights client utilized by this logger.
|
|
136
130
|
* The ApplicationInsights instance MUST be initialized with client.loadAppInsights()
|
|
@@ -308,3 +302,19 @@ export class FluidAppInsightsLogger implements ITelemetryBaseLogger {
|
|
|
308
302
|
}
|
|
309
303
|
}
|
|
310
304
|
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Creates an {@link @fluidframework/core-interfaces#ITelemetryBaseLogger | ITelemetryBaseLogger}
|
|
308
|
+
* that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.
|
|
309
|
+
*
|
|
310
|
+
* The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights(),
|
|
311
|
+
* or else logging will not occur.
|
|
312
|
+
*
|
|
313
|
+
* @beta
|
|
314
|
+
*/
|
|
315
|
+
export function createLogger(
|
|
316
|
+
client: ApplicationInsights,
|
|
317
|
+
config?: FluidAppInsightsLoggerConfig,
|
|
318
|
+
): ITelemetryBaseLogger {
|
|
319
|
+
return new FluidAppInsightsLogger(client, config);
|
|
320
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -9,13 +9,12 @@
|
|
|
9
9
|
* @packageDocumentation
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
export
|
|
13
|
-
FluidAppInsightsLoggerConfig,
|
|
14
|
-
TelemetryFilter,
|
|
15
|
-
CategoryFilter,
|
|
16
|
-
NamespaceFilter,
|
|
12
|
+
export {
|
|
13
|
+
type FluidAppInsightsLoggerConfig,
|
|
14
|
+
type TelemetryFilter,
|
|
15
|
+
type CategoryFilter,
|
|
16
|
+
type NamespaceFilter,
|
|
17
|
+
createLogger,
|
|
17
18
|
} from "./fluidAppInsightsLogger";
|
|
18
19
|
|
|
19
|
-
export { FluidAppInsightsLogger } from "./fluidAppInsightsLogger";
|
|
20
|
-
|
|
21
20
|
export type { TelemetryEventCategory } from "@fluidframework/telemetry-utils";
|
package/tsconfig.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends":
|
|
2
|
+
"extends": [
|
|
3
|
+
"../../../../common/build/build-common/tsconfig.base.json",
|
|
4
|
+
"../../../../common/build/build-common/tsconfig.cjs.json",
|
|
5
|
+
],
|
|
6
|
+
"include": ["src/**/*"],
|
|
3
7
|
"compilerOptions": {
|
|
4
8
|
"rootDir": "src",
|
|
5
9
|
"outDir": "dist",
|
|
6
|
-
"composite": true,
|
|
7
10
|
"types": ["mocha", "node"],
|
|
8
11
|
},
|
|
9
|
-
"include": ["src/**/*"],
|
|
10
12
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fluidAppInsightsLogger.d.ts","sourceRoot":"","sources":["../src/fluidAppInsightsLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAE9E;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC5C;;;OAGG;IACH,SAAS,EAAE;QACV;;;;;;WAMG;QACH,IAAI,EAAE,WAAW,GAAG,WAAW,CAAC;QAChC;;;;;;;;;;WAUG;QACH,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;KAC5B,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,UAAU,EAAE,sBAAsB,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC/B;;;;;;OAMG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,0BAA0B,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,eAAe,GAAG,CAAC,cAAc,GAAG,eAAe,CAAC,CAAC;AAEpG;;;;;;;;GAQG;AACH,qBAAa,sBAAuB,YAAW,oBAAoB;IAClE;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAsB;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;gBACnC,MAAM,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,4BAA4B;IA6BrF;;;;OAIG;IACI,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAS7C,OAAO,CAAC,eAAe;IAYvB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,oBAAoB;IA+D5B;;;;OAIG;IACH,OAAO,CAAC,eAAe;CA8BvB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fluidAppInsightsLogger.js","sourceRoot":"","sources":["../src/fluidAppInsightsLogger.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ApplicationInsights } from \"@microsoft/applicationinsights-web\";\nimport {\n\ttype ITelemetryBaseEvent,\n\ttype ITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces\";\nimport { type TelemetryEventCategory } from \"@fluidframework/telemetry-utils\";\n\n/**\n * The configuration object for the {@link FluidAppInsightsLogger}\n *\n * @public\n */\nexport interface FluidAppInsightsLoggerConfig {\n\t/**\n\t * This Configuration defines how filtering will be applied to Fluid telemetry events flowing through the logger.\n\t * This determines which events will be sent to Azure App Insights.\n\t */\n\tfiltering: {\n\t\t/**\n\t\t * Determines whether all telemetry events are sent or not sent by default and whether filters will exclude matching telemetry events or include them.\n\t\t *\n\t\t * \"inclusive\" mode means all logs are NOT SENT by default and only the events that match at least one or more specified filters WILL be sent (included).\n\t\t *\n\t\t * \"exclusive\" mode means all logs ARE SENT by default and only the events that match at least one or more specified filters WILL NOT be sent (excluded).\n\t\t */\n\t\tmode: \"inclusive\" | \"exclusive\";\n\t\t/**\n\t\t * Controls the filtering of log events.\n\t\t *\n\t\t * @remarks Leaving this undefined will be treated as an empty array.\n\t\t *\n\t\t * In order for the filters to be valid they must meet the following conditions:\n\t\t *\n\t\t * 1. There must not be any two filters with the same `namespacePattern`.\n\t\t *\n\t\t * 2. All {@link NamespaceFilter} must not have any defined `namespacePatternException` that is not a child of the parent `namespacePattern`\n\t\t */\n\t\tfilters?: TelemetryFilter[];\n\t};\n}\n\n/**\n * A filter used to match against the category of a telemetry event\n *\n * @public\n */\nexport interface CategoryFilter {\n\t/**\n\t * The categories of telemetry events that this filter applies to\n\t */\n\tcategories: TelemetryEventCategory[];\n}\n\n/**\n * A filter used to match against the namespaces of a telemetry event\n *\n * @public\n */\nexport interface NamespaceFilter {\n\t/**\n\t * The namespace pattern to filter telemetry events.\n\t *\n\t * @remarks This will match namespaces that start with the given string. It is not a Regex pattern.\n\t * @example\n\t * \"perf:latency\" will match any namespace starting with \"perf:latency\"\n\t */\n\tnamespacePattern: string;\n\t/**\n\t * A list of namespace patterns to explicitly exclude from the filter.\n\t *\n\t * @example\n\t * If you have a namespacePattern of \"perf:latency\" but want to exclude\n\t * events from \"perf:latency:ops\", you would add \"perf:latency:ops\" to this list.\n\t */\n\tnamespacePatternExceptions?: Set<string>;\n}\n\n/**\n * Object used with an {@link FluidAppInsightsLoggerConfig}\n * to define a filter with logic for matching it to telemetry events.\n * Filters can include either a category, namespace or both types of filters; a valid filter must have at least one defined.\n * Not definining the `categories` filter array is the same as providing an array with all possible categories.\n *\n * Events must satisify the following rules for a telemetry filter:\n *\n * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n *\n * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n *\n * 3. If only `categories` or a `namespace` is provided, the event should just match the with whatever was defined.\n *\n * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n *\n * @public\n *\n * @example\n * With the following configuration, an event `{ namespace: \"A.B.C\", categories: [\"generic\"] }` will not be sent despite matching the first, less specific filter because it did not match the second filter which was the most relevant and specific\n * ```\n * const logger = new FluidAppInsightsLogger(appInsightsClient, {\n *\t\t\tfiltering: {\n *\t\t\t\tmode: \"inclusive\",\n *\t\t\t\tfilters: [\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B\",\n *\t\t\t\t\t\tcategories: [\"generic\", \"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B:C\",\n *\t\t\t\t\t\tcategories: [\"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t],\n *\t\t\t},\n *\t\t});\n * ```\n */\nexport type TelemetryFilter = CategoryFilter | NamespaceFilter | (CategoryFilter & NamespaceFilter);\n\n/**\n * An implementation of {@link @fluidframework/core-interfaces#ITelemetryBaseLogger | ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n * or else logging will not occur.\n *\n * @sealed\n * @public\n */\nexport class FluidAppInsightsLogger implements ITelemetryBaseLogger {\n\t/**\n\t * The Azure ApplicationInsights client utilized by this logger.\n\t * The ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n\t * or else logging will not occur.\n\t */\n\tprivate readonly baseLoggingClient: ApplicationInsights;\n\tprivate readonly config: FluidAppInsightsLoggerConfig;\n\tpublic constructor(client: ApplicationInsights, config?: FluidAppInsightsLoggerConfig) {\n\t\tthis.baseLoggingClient = client;\n\t\t// Deep copy config to prevent issues if user mutates the object they passed in\n\t\tthis.config = config\n\t\t\t? structuredClone(config)\n\t\t\t: {\n\t\t\t\t\tfiltering: {\n\t\t\t\t\t\tmode: \"exclusive\",\n\t\t\t\t\t\tfilters: [],\n\t\t\t\t\t},\n\t\t\t };\n\n\t\tif (this.config.filtering.filters) {\n\t\t\tthis.validateFilters(this.config.filtering.filters);\n\t\t\t// Sort filters by longest namespace first.\n\t\t\tthis.config.filtering.filters.sort((a, b) => {\n\t\t\t\tconst namespaceALength =\n\t\t\t\t\t\"namespacePattern\" in a && a.namespacePattern !== undefined\n\t\t\t\t\t\t? a.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\tconst namespaceBLength =\n\t\t\t\t\t\"namespacePattern\" in b && b.namespacePattern !== undefined\n\t\t\t\t\t\t? b.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\treturn namespaceBLength - namespaceALength;\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Routes Fluid telemetry events to the trackEvent App Insights API.\n\t * This method also uses the provided {@link FluidAppInsightsLoggerConfig} to\n\t * determine whether an event should be sent or not.\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\tif (this.shouldSendEvent(event)) {\n\t\t\tthis.baseLoggingClient.trackEvent({\n\t\t\t\tname: event.eventName,\n\t\t\t\tproperties: event,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate shouldSendEvent(event: ITelemetryBaseEvent): boolean {\n\t\t// No events should be sent by default in \"inclusive\" mode, and all events should be\n\t\t// sent by default in \"exclusive\" mode.\n\t\tlet shouldSendEvent = this.config.filtering.mode === \"inclusive\" ? false : true;\n\t\tif (this.doesEventMatchFilter(event)) {\n\t\t\t// If the event does match a filter, in \"inclusive\" filter mode that means it should\n\t\t\t// be sent (included). In \"exclusive\" mode the opposite is true.\n\t\t\tshouldSendEvent = this.config.filtering.mode === \"inclusive\" ? true : false;\n\t\t}\n\t\treturn shouldSendEvent;\n\t}\n\n\t/**\n\t * Checks if a given telemetry event conforms to any of the provided {@link TelemetryFilter} rules.\n\t *\n\t * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n\t * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n\t *\n\t * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n\t *\n\t * 3. If only `categories` or a `namespace` is provided, the event should match either one of them.\n\t *\n\t * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n\t *\n\t * @param event - The telemetry event to check against the filters.\n\t *\n\t * @returns `true` if the event matches any filter, otherwise `false`.\n\t */\n\tprivate doesEventMatchFilter(event: ITelemetryBaseEvent): boolean {\n\t\tfor (const filter of this.config.filtering.filters ?? []) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (event.eventName.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t// Found matching namespace pattern, since filters are ordered in most specific first,\n\t\t\t\t\t// this is the most specific, relevant matching filter for the event.\n\n\t\t\t\t\t// By default, if no categories are defined then any category is a valid match.\n\t\t\t\t\tlet doesFilterCategoriesMatch = true;\n\t\t\t\t\tif (\n\t\t\t\t\t\t\"categories\" in filter &&\n\t\t\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\t\t\tfilter.categories.length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tdoesFilterCategoriesMatch = false;\n\t\t\t\t\t\tconst matchingCategory = filter.categories.find(\n\t\t\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdoesFilterCategoriesMatch = matchingCategory ? true : false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\t\t// The most specific, relevant filter matches so no need to attempt to evaluate against other filters\n\t\t\t\t\t\t// as long as the events namespace does not match any defined namespace exception.\n\t\t\t\t\t\tif (filter.namespacePatternExceptions !== undefined) {\n\t\t\t\t\t\t\tfor (const patternException of filter.namespacePatternExceptions) {\n\t\t\t\t\t\t\t\tif (event.eventName.startsWith(patternException)) {\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Filter only has categories defined\n\t\t\telse if (\n\t\t\t\t\"categories\" in filter &&\n\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\tfilter.categories.length > 0\n\t\t\t) {\n\t\t\t\tconst doesFilterCategoriesMatch = filter.categories.find(\n\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t);\n\n\t\t\t\t// This filter specified no namespaces but it has a category match.\n\t\t\t\t// Since filters are ordered by most specific first, we know that no previous\n\t\t\t\t// filters with namespaces matched so we can return true.\n\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Checks an array of telemetry filters for any issues, merges redundant filters, and returns a fully validated array.\n\t *\n\t * @throws An Error if there are two filters with duplicate namespace patterns or a filter with a pattern exception that is not a child of the parent pattern.\n\t */\n\tprivate validateFilters(filters: TelemetryFilter[]): void {\n\t\tconst uniqueFilterNamespaces = new Set<string>();\n\n\t\tfor (const filter of filters) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (uniqueFilterNamespaces.has(filter.namespacePattern)) {\n\t\t\t\t\tthrow new Error(\"Cannot have duplicate namespace pattern filters\");\n\t\t\t\t} else {\n\t\t\t\t\tuniqueFilterNamespaces.add(filter.namespacePattern);\n\t\t\t\t}\n\n\t\t\t\tfor (const patternException of filter.namespacePatternExceptions ?? []) {\n\t\t\t\t\tif (!patternException.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Cannot have a namespace pattern exception that is not a child of the parent namespace\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\"categories\" in filter && filter.categories !== undefined) {\n\t\t\t\t// These are filters that only contain \"categories\". For the purpose of this validation logic, we are treating filters\n\t\t\t\t// that does not contain a defined namespace as the the same as a blank \"\" namespace pattern (which will match any event).\n\t\t\t\tif (uniqueFilterNamespaces.has(\"\")) {\n\t\t\t\t\tthrow new Error(\"Cannot have multiple filters that only define categories\");\n\t\t\t\t}\n\t\t\t\tuniqueFilterNamespaces.add(\"\");\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid filter does not have either a namespace or a category.\");\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
package/lib/index.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* This package provides a telemetry logger that will route typical Fluid telemetry to Azure App Insights.
|
|
7
|
-
* {@link https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview?tabs=net|Azure App Insights}
|
|
8
|
-
* @packageDocumentation
|
|
9
|
-
*/
|
|
10
|
-
export type { FluidAppInsightsLoggerConfig, TelemetryFilter, CategoryFilter, NamespaceFilter, } from "./fluidAppInsightsLogger";
|
|
11
|
-
export { FluidAppInsightsLogger } from "./fluidAppInsightsLogger";
|
|
12
|
-
export type { TelemetryEventCategory } from "@fluidframework/telemetry-utils";
|
|
13
|
-
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH,YAAY,EACX,4BAA4B,EAC5B,eAAe,EACf,cAAc,EACd,eAAe,GACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,YAAY,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC"}
|
package/lib/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * This package provides a telemetry logger that will route typical Fluid telemetry to Azure App Insights.\n * {@link https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview?tabs=net|Azure App Insights}\n * @packageDocumentation\n */\n\nexport type {\n\tFluidAppInsightsLoggerConfig,\n\tTelemetryFilter,\n\tCategoryFilter,\n\tNamespaceFilter,\n} from \"./fluidAppInsightsLogger\";\n\nexport { FluidAppInsightsLogger } from \"./fluidAppInsightsLogger\";\n\nexport type { TelemetryEventCategory } from \"@fluidframework/telemetry-utils\";\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fluidAppInsightsLogger.spec.d.ts","sourceRoot":"","sources":["../../src/test/fluidAppInsightsLogger.spec.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fluidAppInsightsLogger.spec.js","sourceRoot":"","sources":["../../src/test/fluidAppInsightsLogger.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { strict as assert } from \"node:assert\";\n\nimport { ApplicationInsights, type IEventTelemetry } from \"@microsoft/applicationinsights-web\";\nimport type Sinon from \"sinon\";\nimport { assert as sinonAssert, spy } from \"sinon\";\nimport {\n\tFluidAppInsightsLogger,\n\ttype TelemetryFilter,\n\ttype FluidAppInsightsLoggerConfig,\n} from \"../fluidAppInsightsLogger\";\n\ndescribe(\"FluidAppInsightsLogger\", () => {\n\tlet appInsightsClient: ApplicationInsights;\n\tlet trackEventSpy: Sinon.SinonSpy;\n\n\tbeforeEach(() => {\n\t\tappInsightsClient = new ApplicationInsights({\n\t\t\tconfig: {\n\t\t\t\tconnectionString:\n\t\t\t\t\t// (this is an example string)\n\t\t\t\t\t\"InstrumentationKey=abcdefgh-ijkl-mnop-qrst-uvwxyz6ffd9c;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/\",\n\t\t\t},\n\t\t});\n\t\ttrackEventSpy = spy(appInsightsClient, \"trackEvent\");\n\t});\n\n\tit(\"send() routes telemetry events to ApplicationInsights.trackEvent\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient);\n\n\t\tconst mockTelemetryEvent = {\n\t\t\tcategory: \"mockEvent\",\n\t\t\teventName: \"mockEventName\",\n\t\t};\n\t\tlogger.send(mockTelemetryEvent);\n\t\tsinonAssert.calledOnce(trackEventSpy);\n\n\t\tconst expectedAppInsightsEvent = {\n\t\t\tname: mockTelemetryEvent.eventName,\n\t\t\tproperties: mockTelemetryEvent,\n\t\t};\n\n\t\tsinonAssert.calledWith(trackEventSpy, expectedAppInsightsEvent);\n\t});\n\n\tit(\"constructor() throws error when filter config with duplicate namespaces is provided\", () => {\n\t\tconst invalidConfig: FluidAppInsightsLoggerConfig = {\n\t\t\tfiltering: {\n\t\t\t\tmode: \"inclusive\",\n\t\t\t\tfilters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tnamespacePattern: \"A:B:C\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tnamespacePattern: \"A:B:C\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t};\n\t\tassert.throws(\n\t\t\t() => new FluidAppInsightsLogger(appInsightsClient, invalidConfig),\n\t\t\tnew Error(\"Cannot have duplicate namespace pattern filters\"),\n\t\t);\n\t});\n\n\tit(\"constructor() throws error when filter config with namespace pattern exception that is not part of the parent pattern is provided\", () => {\n\t\tconst invalidConfig: FluidAppInsightsLoggerConfig = {\n\t\t\tfiltering: {\n\t\t\t\tmode: \"inclusive\",\n\t\t\t\tfilters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tnamespacePattern: \"A:B:C\",\n\t\t\t\t\t\tnamespacePatternExceptions: new Set([\"D:C:A\"]),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t};\n\t\tassert.throws(\n\t\t\t() => new FluidAppInsightsLogger(appInsightsClient, invalidConfig),\n\t\t\tnew Error(\n\t\t\t\t\"Cannot have a namespace pattern exception that is not a child of the parent namespace\",\n\t\t\t),\n\t\t);\n\t});\n\n\tit(\"constructor() throws error when multiple filters that only define categories are provided\", () => {\n\t\tconst invalidConfig: FluidAppInsightsLoggerConfig = {\n\t\t\tfiltering: {\n\t\t\t\tmode: \"inclusive\",\n\t\t\t\tfilters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcategories: [\"error\"],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tcategories: [\"generic\", \"performance\"],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t};\n\t\tassert.throws(\n\t\t\t() => new FluidAppInsightsLogger(appInsightsClient, invalidConfig),\n\t\t\tnew Error(\"Cannot have multiple filters that only define categories\"),\n\t\t);\n\t});\n});\n\ndescribe(\"Telemetry Filter - filter mode\", () => {\n\tlet appInsightsClient: ApplicationInsights;\n\tlet trackEventSpy: Sinon.SinonSpy;\n\n\tbeforeEach(() => {\n\t\tappInsightsClient = new ApplicationInsights({\n\t\t\tconfig: {\n\t\t\t\tconnectionString:\n\t\t\t\t\t// (this is an example string)\n\t\t\t\t\t\"InstrumentationKey=abcdefgh-ijkl-mnop-qrst-uvwxyz6ffd9c;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/\",\n\t\t\t},\n\t\t});\n\t\ttrackEventSpy = spy(appInsightsClient, \"trackEvent\");\n\t});\n\n\tit(\"exclusive filter mode sends all events when no filters are defined\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, {\n\t\t\tfiltering: {\n\t\t\t\tmode: \"exclusive\",\n\t\t\t},\n\t\t});\n\n\t\tconst perfCategoryEvent = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perfCategoryEventName\",\n\t\t};\n\n\t\tlogger.send(perfCategoryEvent);\n\n\t\t// Expect all events to be sent in exclusive mode\n\t\tsinonAssert.callCount(trackEventSpy, 1);\n\t});\n\n\tit(\"inclusive filter mode sends no events when no filters are defined\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, {\n\t\t\tfiltering: {\n\t\t\t\tmode: \"inclusive\",\n\t\t\t},\n\t\t});\n\n\t\tconst perfCategoryEvent = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perfCategoryEventName\",\n\t\t};\n\n\t\tlogger.send(perfCategoryEvent);\n\n\t\t// Expect no events to be sent\n\t\tsinonAssert.callCount(trackEventSpy, 0);\n\t});\n});\n\ndescribe(\"Telemetry Filter - Category Filtering\", () => {\n\tlet appInsightsClient: ApplicationInsights;\n\tlet trackEventSpy: Sinon.SinonSpy;\n\tconst configFilters: TelemetryFilter[] = [\n\t\t{\n\t\t\tcategories: [\"performance\", \"generic\"],\n\t\t},\n\t];\n\tconst exclusiveLoggerFilterConfig: FluidAppInsightsLoggerConfig = {\n\t\tfiltering: {\n\t\t\tmode: \"exclusive\",\n\t\t\tfilters: configFilters,\n\t\t},\n\t};\n\tconst inclusiveLoggerFilterConfig: FluidAppInsightsLoggerConfig = {\n\t\tfiltering: {\n\t\t\tmode: \"inclusive\",\n\t\t\tfilters: configFilters,\n\t\t},\n\t};\n\n\tbeforeEach(() => {\n\t\tappInsightsClient = new ApplicationInsights({\n\t\t\tconfig: {\n\t\t\t\tconnectionString:\n\t\t\t\t\t// (this is an example string)\n\t\t\t\t\t\"InstrumentationKey=abcdefgh-ijkl-mnop-qrst-uvwxyz6ffd9c;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/\",\n\t\t\t},\n\t\t});\n\t\ttrackEventSpy = spy(appInsightsClient, \"trackEvent\");\n\t});\n\n\tit(\"exclusive filtering mode DOES NOT SEND events that DO MATCH with atleast one category within a single filter containing multiple categories\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, {\n\t\t\tfiltering: {\n\t\t\t\tmode: \"exclusive\",\n\t\t\t\tfilters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcategories: [\"performance\", \"generic\"],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t});\n\n\t\t// should be excluded - matches category filter\n\t\tconst event = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\t\t// should be excluded - matches category filter\n\t\tconst event2 = {\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\t\tlogger.send(event);\n\t\tlogger.send(event2);\n\t\tsinonAssert.callCount(trackEventSpy, 0);\n\t});\n\n\tit(\"exclusive filter mode DOES NOT SEND events that DO MATCH with one of multiple category filters\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, exclusiveLoggerFilterConfig);\n\t\t// should be excluded - match with category in filter\n\t\tconst event1 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:latency:ops\",\n\t\t};\n\t\t// should be excluded - match with category in filter\n\t\tconst event2 = {\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"perf:memory:container\",\n\t\t};\n\t\tlogger.send(event1);\n\t\tlogger.send(event2);\n\t\tsinonAssert.callCount(trackEventSpy, 0);\n\t});\n\n\tit(\"exclusive filter mode DOES SEND events that DO NOT MATCH with one of multiple category filters\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, exclusiveLoggerFilterConfig);\n\t\t// should be included - does not match any category filter\n\t\tconst event = {\n\t\t\tcategory: \"error\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\n\t\tlogger.send(event);\n\n\t\tconst expectedAppInsightsSentEvent: IEventTelemetry = {\n\t\t\tname: event.eventName,\n\t\t\tproperties: {\n\t\t\t\t...event,\n\t\t\t},\n\t\t};\n\t\tsinonAssert.callCount(trackEventSpy, 1);\n\t\tfor (const call of trackEventSpy.getCalls()) {\n\t\t\tsinonAssert.calledWithExactly(call, expectedAppInsightsSentEvent);\n\t\t}\n\t});\n\n\t// ------------------------------------------------------------------------------------\n\n\tit(\"inclusive filtering mode DOES SEND events that DO MATCH with atleast one category within a single filter containing multiple categories\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, {\n\t\t\tfiltering: {\n\t\t\t\tmode: \"inclusive\",\n\t\t\t\tfilters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcategories: [\"performance\", \"generic\"],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t});\n\n\t\t// should be included - matches category filter\n\t\tconst event = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\t\t// should be included - matches category filter\n\t\tconst event2 = {\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\t\tlogger.send(event);\n\t\tlogger.send(event2);\n\t\tsinonAssert.callCount(trackEventSpy, 2);\n\t});\n\n\tit(\"inclusive filter mode DOES SEND events that DO MATCH with one of multiple category filters\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, inclusiveLoggerFilterConfig);\n\t\t// should be included - match with category filter\n\t\tconst event1 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:latency:ops\",\n\t\t};\n\t\t// should be included - match with category filter\n\t\tconst event2 = {\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"perf:memory:container\",\n\t\t};\n\t\tlogger.send(event1);\n\t\tlogger.send(event2);\n\t\tsinonAssert.callCount(trackEventSpy, 2);\n\t});\n\n\tit(\"inclusive filter mode DOES NOT SEND events that DO NOT MATCH with one of multiple category filters\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, inclusiveLoggerFilterConfig);\n\t\t// should be excluded - does not match any category filter\n\t\tconst event = {\n\t\t\tcategory: \"error\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\n\t\tlogger.send(event);\n\t\tsinonAssert.callCount(trackEventSpy, 0);\n\t});\n});\n\ndescribe(\"Telemetry Filter - Namespace Filtering\", () => {\n\tlet appInsightsClient: ApplicationInsights;\n\tlet trackEventSpy: Sinon.SinonSpy;\n\tconst namespaceFilterPattern1 = \"perf:latency\";\n\tconst namespaceFilterPattern2 = \"perf:memory\";\n\tconst namespaceFilterPattern1Exception = `${namespaceFilterPattern1}:ops`;\n\tconst namespaceFilterPattern2Exception = `${namespaceFilterPattern2}:container`;\n\tconst configFilters: TelemetryFilter[] = [\n\t\t{\n\t\t\tnamespacePattern: namespaceFilterPattern1,\n\t\t\tnamespacePatternExceptions: new Set([namespaceFilterPattern1Exception]),\n\t\t},\n\t\t{\n\t\t\tnamespacePattern: namespaceFilterPattern2,\n\t\t\tnamespacePatternExceptions: new Set([namespaceFilterPattern2Exception]),\n\t\t},\n\t];\n\tconst exclusiveLoggerFilterConfig: FluidAppInsightsLoggerConfig = {\n\t\tfiltering: {\n\t\t\tmode: \"exclusive\",\n\t\t\tfilters: configFilters,\n\t\t},\n\t};\n\tconst inclusiveLoggerFilterConfig: FluidAppInsightsLoggerConfig = {\n\t\tfiltering: {\n\t\t\tmode: \"inclusive\",\n\t\t\tfilters: configFilters,\n\t\t},\n\t};\n\n\tbeforeEach(() => {\n\t\tappInsightsClient = new ApplicationInsights({\n\t\t\tconfig: {\n\t\t\t\tconnectionString:\n\t\t\t\t\t// (this is an example string)\n\t\t\t\t\t\"InstrumentationKey=abcdefgh-ijkl-mnop-qrst-uvwxyz6ffd9c;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/\",\n\t\t\t},\n\t\t});\n\t\ttrackEventSpy = spy(appInsightsClient, \"trackEvent\");\n\t});\n\n\tit(\"exclusive filter mode DOES NOT SEND events that MATCH with one of multiple namespace filters\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, exclusiveLoggerFilterConfig);\n\t\t// should be excluded - partial match with namespace filter\n\t\tconst event1 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: `${namespaceFilterPattern1}:signals`,\n\t\t};\n\t\t// should be excluded - partial match with second namespace filter\n\t\tconst event2 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: `${namespaceFilterPattern2}:ops:summary`,\n\t\t};\n\t\t// should be excluded - perfect match with namespace filter\n\t\tconst event3 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: namespaceFilterPattern1,\n\t\t};\n\t\t// should be excluded - perfect match with second namespace filter\n\t\tconst event4 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: namespaceFilterPattern2,\n\t\t};\n\t\tlogger.send(event1);\n\t\tlogger.send(event2);\n\t\tlogger.send(event3);\n\t\tlogger.send(event4);\n\t\tsinonAssert.callCount(trackEventSpy, 0);\n\t});\n\n\tit(\"exclusive filter mode DOES SEND events that DO NOT MATCH with one of multiple namespace filters\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, exclusiveLoggerFilterConfig);\n\t\t// should be included - does not match any namespace filter\n\t\tconst event = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\n\t\tlogger.send(event);\n\n\t\tconst expectedAppInsightsSentEvent: IEventTelemetry = {\n\t\t\tname: event.eventName,\n\t\t\tproperties: {\n\t\t\t\t...event,\n\t\t\t},\n\t\t};\n\t\tsinonAssert.callCount(trackEventSpy, 1);\n\t\tfor (const call of trackEventSpy.getCalls()) {\n\t\t\tsinonAssert.calledWithExactly(call, expectedAppInsightsSentEvent);\n\t\t}\n\t});\n\n\tit(\"exclusive filter mode DOES SEND events that MATCH with one of multiple namespace filters if they also partially match with a namespace exception\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, exclusiveLoggerFilterConfig);\n\t\t// should be included - partial match with namespace filter but also partially matches namespace pattern exception\n\t\tconst event1 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: `${namespaceFilterPattern1Exception}:roundTripTime`,\n\t\t};\n\t\t// should be included - partial match with second namespace filter but also partially matches namespace pattern exception\n\t\tconst event2 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: `${namespaceFilterPattern2Exception}:summary`,\n\t\t};\n\t\t// should be included - partial match with namespace filter but also perfectly matches namespace pattern exception\n\t\tconst event3 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: namespaceFilterPattern1Exception,\n\t\t};\n\t\t// should be included - partial match with second namespace filter but also perfectly matches namespace pattern exception\n\t\tconst event4 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: namespaceFilterPattern2Exception,\n\t\t};\n\t\tlogger.send(event1);\n\t\tlogger.send(event2);\n\t\tlogger.send(event3);\n\t\tlogger.send(event4);\n\t\tsinonAssert.callCount(trackEventSpy, 4);\n\t});\n\n\t// ------------------------------------------------------------------------------------\n\n\tit(\"inclusive filter mode DOES SEND events that MATCH with one of multiple namespace filters\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, inclusiveLoggerFilterConfig);\n\t\t// should be included - partial match with namespace filter\n\t\tconst event1 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: `${namespaceFilterPattern1}:signals`,\n\t\t};\n\t\t// should be included - partial match with second namespace filter\n\t\tconst event2 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: `${namespaceFilterPattern2}:ops:summary`,\n\t\t};\n\t\t// should be included - perfect match with namespace filter\n\t\tconst event3 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: namespaceFilterPattern1,\n\t\t};\n\t\t// should be included - perfect match with second namespace filter\n\t\tconst event4 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: namespaceFilterPattern2,\n\t\t};\n\t\tlogger.send(event1);\n\t\tlogger.send(event2);\n\t\tlogger.send(event3);\n\t\tlogger.send(event4);\n\t\tsinonAssert.callCount(trackEventSpy, 4);\n\t});\n\n\tit(\"inclusive filter mode DOES NOT SEND events that DO NOT MATCH with one of multiple namespace filters\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, inclusiveLoggerFilterConfig);\n\t\t// should be excluded - does not match any namespace filter\n\t\tconst event = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\n\t\tlogger.send(event);\n\t\tsinonAssert.callCount(trackEventSpy, 0);\n\t});\n\n\tit(\"inclusive filter mode DOES NOT SEND events that MATCH with one of multiple namespace filters if they also partially match with a namespace exception\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, inclusiveLoggerFilterConfig);\n\t\t// should be excluded - partial match with namespace filter but also partially matches namespace pattern exception\n\t\tconst event1 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: `${namespaceFilterPattern1}:ops:roundTripTime`,\n\t\t};\n\t\t// should be excluded - partial match with second namespace filter but also partially matches namespace pattern exception\n\t\tconst event2 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: `${namespaceFilterPattern2}:container:summary`,\n\t\t};\n\t\t// should be excluded - partial match with namespace filter but also perfectly matches namespace pattern exception\n\t\tconst event3 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: namespaceFilterPattern1Exception,\n\t\t};\n\t\t// should be excluded - partial match with second namespace filter but also perfectly matches namespace pattern exception\n\t\tconst event4 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: namespaceFilterPattern2Exception,\n\t\t};\n\t\tlogger.send(event1);\n\t\tlogger.send(event2);\n\t\tlogger.send(event3);\n\t\tlogger.send(event4);\n\t\tsinonAssert.callCount(trackEventSpy, 0);\n\t});\n\n\tit(\"inclusive filter mode DOES NOT SEND events that DO NOT MATCH the most specific filter despite matching more generic ones. \", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, {\n\t\t\tfiltering: {\n\t\t\t\tmode: \"inclusive\",\n\t\t\t\tfilters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tnamespacePattern: \"A:B\",\n\t\t\t\t\t\tcategories: [\"generic\", \"error\"],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tnamespacePattern: \"A:B:C\",\n\t\t\t\t\t\tcategories: [\"error\"],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t});\n\n\t\t// should be excluded because the event matches the \"A:B\" filter but the \"A:B:C\" filter is more specific\n\t\t// so it should be evaluated first and it only allows \"errors\".\n\t\tconst event1 = {\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"A:B:C\",\n\t\t};\n\n\t\t// should be included because it matches the \"A:B:C\" filter that should be getting applied to it\n\t\tconst event2 = {\n\t\t\tcategory: \"error\",\n\t\t\teventName: \"A:B:C\",\n\t\t};\n\n\t\tlogger.send(event1);\n\t\tlogger.send(event2);\n\t\tsinonAssert.callCount(trackEventSpy, 1);\n\t\tfor (const call of trackEventSpy.getCalls()) {\n\t\t\tsinonAssert.calledWithExactly(call, {\n\t\t\t\tname: event2.eventName,\n\t\t\t\tproperties: {\n\t\t\t\t\t...event2,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t});\n});\n\ndescribe(\"Telemetry Filter - Category & Namespace Combination Filtering\", () => {\n\tlet appInsightsClient: ApplicationInsights;\n\tlet trackEventSpy: Sinon.SinonSpy;\n\tconst configFilters: TelemetryFilter[] = [\n\t\t{\n\t\t\tcategories: [\"performance\"],\n\t\t\tnamespacePattern: \"perf:latency\",\n\t\t\tnamespacePatternExceptions: new Set([\"perf:latency:ops\"]),\n\t\t},\n\t];\n\tconst exclusiveLoggerFilterConfig: FluidAppInsightsLoggerConfig = {\n\t\tfiltering: {\n\t\t\tmode: \"exclusive\",\n\t\t\tfilters: configFilters,\n\t\t},\n\t};\n\tconst inclusiveLoggerFilterConfig: FluidAppInsightsLoggerConfig = {\n\t\tfiltering: {\n\t\t\tmode: \"inclusive\",\n\t\t\tfilters: configFilters,\n\t\t},\n\t};\n\n\tbeforeEach(() => {\n\t\tappInsightsClient = new ApplicationInsights({\n\t\t\tconfig: {\n\t\t\t\tconnectionString:\n\t\t\t\t\t// (this is an example string)\n\t\t\t\t\t\"InstrumentationKey=abcdefgh-ijkl-mnop-qrst-uvwxyz6ffd9c;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/\",\n\t\t\t},\n\t\t});\n\t\ttrackEventSpy = spy(appInsightsClient, \"trackEvent\");\n\t});\n\n\tit(\"exclusive filter mode DOES NOT SEND events that match combination category and namespace filters unless they match a namespace exception\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, exclusiveLoggerFilterConfig);\n\n\t\t// should be included - does not match any filter\n\t\tconst event1 = {\n\t\t\tcategory: \"error\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\n\t\t// should be included - only partial matches namespace filter but not category\n\t\tconst event2 = {\n\t\t\tcategory: \"error\",\n\t\t\teventName: \"perf:latency:ops:delta\",\n\t\t};\n\n\t\t// should be included - partial namespace match and category match but also matches exception.\n\t\tconst event3 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:latency:ops:delta\",\n\t\t};\n\n\t\t// should be excluded - perfect namespace and category match.\n\t\tconst event4 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:latency\",\n\t\t};\n\n\t\t// should be excluded - partial namespace match and category match.\n\t\tconst event5 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:latency:container:syncTime\",\n\t\t};\n\n\t\tlogger.send(event1);\n\t\tlogger.send(event2);\n\t\tlogger.send(event3);\n\t\tlogger.send(event4);\n\t\tlogger.send(event5);\n\n\t\tconst actualSentEvent1 = trackEventSpy.getCalls().filter((call) =>\n\t\t\tcall.calledWithExactly({\n\t\t\t\tname: event1.eventName,\n\t\t\t\tproperties: {\n\t\t\t\t\t...event1,\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t\tconst actualSentEvent2 = trackEventSpy.getCalls().filter((call) =>\n\t\t\tcall.calledWithExactly({\n\t\t\t\tname: event2.eventName,\n\t\t\t\tproperties: {\n\t\t\t\t\t...event2,\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t\tconst actualSentEvent3 = trackEventSpy.getCalls().filter((call) =>\n\t\t\tcall.calledWithExactly({\n\t\t\t\tname: event3.eventName,\n\t\t\t\tproperties: {\n\t\t\t\t\t...event3,\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\n\t\tsinonAssert.callCount(trackEventSpy, 3);\n\t\tassert.strictEqual(actualSentEvent1.length, 1);\n\t\tassert.strictEqual(actualSentEvent2.length, 1);\n\t\tassert.strictEqual(actualSentEvent3.length, 1);\n\t});\n\n\tit(\"inclusive filter mode DOES SEND events that match combination category and namespace filters unless they match a namespace exception\", () => {\n\t\tconst logger = new FluidAppInsightsLogger(appInsightsClient, inclusiveLoggerFilterConfig);\n\n\t\t// should be excluded - does not match any filter\n\t\tconst event1 = {\n\t\t\tcategory: \"error\",\n\t\t\teventName: \"perf:runtime:container\",\n\t\t};\n\n\t\t// should be excluded - only partial matches namespace filter but not category\n\t\tconst event2 = {\n\t\t\tcategory: \"error\",\n\t\t\teventName: \"perf:latency:ops:delta\",\n\t\t};\n\n\t\t// should be excluded - partial namespace match and category match but also matches exception.\n\t\tconst event3 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:latency:ops:delta\",\n\t\t};\n\n\t\t// should be included - perfect namespace and category match.\n\t\tconst event4 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:latency\",\n\t\t};\n\n\t\t// should be included - partial namespace match and category match.\n\t\tconst event5 = {\n\t\t\tcategory: \"performance\",\n\t\t\teventName: \"perf:latency:container:syncTime\",\n\t\t};\n\n\t\tlogger.send(event1);\n\t\tlogger.send(event2);\n\t\tlogger.send(event3);\n\t\tlogger.send(event4);\n\t\tlogger.send(event5);\n\n\t\tconst actualSentEvent4 = trackEventSpy.getCalls().filter((call) =>\n\t\t\tcall.calledWithExactly({\n\t\t\t\tname: event4.eventName,\n\t\t\t\tproperties: {\n\t\t\t\t\t...event4,\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t\tconst actualSentEvent5 = trackEventSpy.getCalls().filter((call) =>\n\t\t\tcall.calledWithExactly({\n\t\t\t\tname: event4.eventName,\n\t\t\t\tproperties: {\n\t\t\t\t\t...event4,\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\n\t\tsinonAssert.callCount(trackEventSpy, 2);\n\t\tassert.strictEqual(actualSentEvent4.length, 1);\n\t\tassert.strictEqual(actualSentEvent5.length, 1);\n\t});\n});\n"]}
|