@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
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { type ApplicationInsights } from "@microsoft/applicationinsights-web";
|
|
6
|
-
import { type
|
|
6
|
+
import { type ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { type TelemetryEventCategory } from "@fluidframework/telemetry-utils";
|
|
8
8
|
/**
|
|
9
|
-
* The configuration object for the {@link
|
|
10
|
-
*
|
|
11
|
-
* @public
|
|
9
|
+
* The configuration object for creating the logger via {@link createLogger}.
|
|
10
|
+
* @beta
|
|
12
11
|
*/
|
|
13
12
|
export interface FluidAppInsightsLoggerConfig {
|
|
14
13
|
/**
|
|
@@ -40,8 +39,7 @@ export interface FluidAppInsightsLoggerConfig {
|
|
|
40
39
|
}
|
|
41
40
|
/**
|
|
42
41
|
* A filter used to match against the category of a telemetry event
|
|
43
|
-
*
|
|
44
|
-
* @public
|
|
42
|
+
* @beta
|
|
45
43
|
*/
|
|
46
44
|
export interface CategoryFilter {
|
|
47
45
|
/**
|
|
@@ -51,8 +49,7 @@ export interface CategoryFilter {
|
|
|
51
49
|
}
|
|
52
50
|
/**
|
|
53
51
|
* A filter used to match against the namespaces of a telemetry event
|
|
54
|
-
*
|
|
55
|
-
* @public
|
|
52
|
+
* @beta
|
|
56
53
|
*/
|
|
57
54
|
export interface NamespaceFilter {
|
|
58
55
|
/**
|
|
@@ -88,9 +85,6 @@ export interface NamespaceFilter {
|
|
|
88
85
|
* 3. If only `categories` or a `namespace` is provided, the event should just match the with whatever was defined.
|
|
89
86
|
*
|
|
90
87
|
* 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.
|
|
91
|
-
*
|
|
92
|
-
* @public
|
|
93
|
-
*
|
|
94
88
|
* @example
|
|
95
89
|
* 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
|
|
96
90
|
* ```
|
|
@@ -110,55 +104,17 @@ export interface NamespaceFilter {
|
|
|
110
104
|
* },
|
|
111
105
|
* });
|
|
112
106
|
* ```
|
|
107
|
+
* @beta
|
|
113
108
|
*/
|
|
114
109
|
export type TelemetryFilter = CategoryFilter | NamespaceFilter | (CategoryFilter & NamespaceFilter);
|
|
115
110
|
/**
|
|
116
|
-
*
|
|
111
|
+
* Creates an {@link @fluidframework/core-interfaces#ITelemetryBaseLogger | ITelemetryBaseLogger}
|
|
117
112
|
* that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.
|
|
118
|
-
*
|
|
113
|
+
*
|
|
114
|
+
* The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights(),
|
|
119
115
|
* or else logging will not occur.
|
|
120
116
|
*
|
|
121
|
-
* @
|
|
122
|
-
* @public
|
|
117
|
+
* @beta
|
|
123
118
|
*/
|
|
124
|
-
export declare
|
|
125
|
-
|
|
126
|
-
* The Azure ApplicationInsights client utilized by this logger.
|
|
127
|
-
* The ApplicationInsights instance MUST be initialized with client.loadAppInsights()
|
|
128
|
-
* or else logging will not occur.
|
|
129
|
-
*/
|
|
130
|
-
private readonly baseLoggingClient;
|
|
131
|
-
private readonly config;
|
|
132
|
-
constructor(client: ApplicationInsights, config?: FluidAppInsightsLoggerConfig);
|
|
133
|
-
/**
|
|
134
|
-
* Routes Fluid telemetry events to the trackEvent App Insights API.
|
|
135
|
-
* This method also uses the provided {@link FluidAppInsightsLoggerConfig} to
|
|
136
|
-
* determine whether an event should be sent or not.
|
|
137
|
-
*/
|
|
138
|
-
send(event: ITelemetryBaseEvent): void;
|
|
139
|
-
private shouldSendEvent;
|
|
140
|
-
/**
|
|
141
|
-
* Checks if a given telemetry event conforms to any of the provided {@link TelemetryFilter} rules.
|
|
142
|
-
*
|
|
143
|
-
* 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.
|
|
144
|
-
* The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.
|
|
145
|
-
*
|
|
146
|
-
* 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.
|
|
147
|
-
*
|
|
148
|
-
* 3. If only `categories` or a `namespace` is provided, the event should match either one of them.
|
|
149
|
-
*
|
|
150
|
-
* 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.
|
|
151
|
-
*
|
|
152
|
-
* @param event - The telemetry event to check against the filters.
|
|
153
|
-
*
|
|
154
|
-
* @returns `true` if the event matches any filter, otherwise `false`.
|
|
155
|
-
*/
|
|
156
|
-
private doesEventMatchFilter;
|
|
157
|
-
/**
|
|
158
|
-
* Checks an array of telemetry filters for any issues, merges redundant filters, and returns a fully validated array.
|
|
159
|
-
*
|
|
160
|
-
* @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.
|
|
161
|
-
*/
|
|
162
|
-
private validateFilters;
|
|
163
|
-
}
|
|
164
|
-
//# sourceMappingURL=fluidAppInsightsLogger.d.ts.map
|
|
119
|
+
export declare function createLogger(client: ApplicationInsights, config?: FluidAppInsightsLoggerConfig): ITelemetryBaseLogger;
|
|
120
|
+
//# sourceMappingURL=fluidAppInsightsLogger.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fluidAppInsightsLogger.d.mts","sourceRoot":"","sources":["../src/fluidAppInsightsLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAEI,EAAE,KAAK,mBAAmB,EAAE,MAAM,oCAAoC;OACtE,EAEN,KAAK,oBAAoB,EACzB,MAAM,iCAAiC;OACjC,EAAE,KAAK,sBAAsB,EAAE,MAAM,iCAAiC;AAE7E;;;GAGG;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;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,UAAU,EAAE,sBAAsB,EAAE,CAAC;CACrC;AAED;;;GAGG;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,eAAe,GAAG,CAAC,cAAc,GAAG,eAAe,CAAC,CAAC;AA6LpG;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC3B,MAAM,EAAE,mBAAmB,EAC3B,MAAM,CAAC,EAAE,4BAA4B,GACnC,oBAAoB,CAEtB"}
|
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
* or else logging will not occur.
|
|
10
10
|
*
|
|
11
11
|
* @sealed
|
|
12
|
-
* @public
|
|
13
12
|
*/
|
|
14
|
-
|
|
13
|
+
class FluidAppInsightsLogger {
|
|
15
14
|
constructor(client, config) {
|
|
16
15
|
this.baseLoggingClient = client;
|
|
17
16
|
// Deep copy config to prevent issues if user mutates the object they passed in
|
|
@@ -165,4 +164,16 @@ export class FluidAppInsightsLogger {
|
|
|
165
164
|
}
|
|
166
165
|
}
|
|
167
166
|
}
|
|
168
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Creates an {@link @fluidframework/core-interfaces#ITelemetryBaseLogger | ITelemetryBaseLogger}
|
|
169
|
+
* that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.
|
|
170
|
+
*
|
|
171
|
+
* The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights(),
|
|
172
|
+
* or else logging will not occur.
|
|
173
|
+
*
|
|
174
|
+
* @beta
|
|
175
|
+
*/
|
|
176
|
+
export function createLogger(client, config) {
|
|
177
|
+
return new FluidAppInsightsLogger(client, config);
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=fluidAppInsightsLogger.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fluidAppInsightsLogger.mjs","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 creating the logger via {@link createLogger}.\n * @beta\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 * @beta\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 * @beta\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 * @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 * @beta\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 */\nclass 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\n/**\n * Creates an {@link @fluidframework/core-interfaces#ITelemetryBaseLogger | ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n *\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights(),\n * or else logging will not occur.\n *\n * @beta\n */\nexport function createLogger(\n\tclient: ApplicationInsights,\n\tconfig?: FluidAppInsightsLoggerConfig,\n): ITelemetryBaseLogger {\n\treturn new FluidAppInsightsLogger(client, config);\n}\n"]}
|
package/lib/index.d.mts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
export { type FluidAppInsightsLoggerConfig, type TelemetryFilter, type CategoryFilter, type NamespaceFilter, createLogger, } from "./fluidAppInsightsLogger.mjs";
|
|
6
|
+
export type { TelemetryEventCategory } from "@fluidframework/telemetry-utils";
|
|
7
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAQI,EACN,KAAK,4BAA4B,EACjC,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,YAAY,GACZ;YAEW,EAAE,sBAAsB,EAAE,MAAM,iCAAiC"}
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
export {
|
|
6
|
-
//# sourceMappingURL=index.
|
|
5
|
+
export { createLogger, } from "./fluidAppInsightsLogger.mjs";
|
|
6
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAQI,EAKN,YAAY,GACZ","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 {\n\ttype FluidAppInsightsLoggerConfig,\n\ttype TelemetryFilter,\n\ttype CategoryFilter,\n\ttype NamespaceFilter,\n\tcreateLogger,\n} from \"./fluidAppInsightsLogger\";\n\nexport type { TelemetryEventCategory } from \"@fluidframework/telemetry-utils\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fluidAppInsightsLogger.spec.d.mts","sourceRoot":"","sources":["../../src/test/fluidAppInsightsLogger.spec.ts"],"names":[],"mappings":""}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
1
|
import { strict as assert } from "node:assert";
|
|
6
2
|
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
|
|
7
3
|
import { assert as sinonAssert, spy } from "sinon";
|
|
8
|
-
import {
|
|
4
|
+
import { createLogger, } from "../fluidAppInsightsLogger.mjs";
|
|
9
5
|
describe("FluidAppInsightsLogger", () => {
|
|
10
6
|
let appInsightsClient;
|
|
11
7
|
let trackEventSpy;
|
|
@@ -20,7 +16,7 @@ describe("FluidAppInsightsLogger", () => {
|
|
|
20
16
|
trackEventSpy = spy(appInsightsClient, "trackEvent");
|
|
21
17
|
});
|
|
22
18
|
it("send() routes telemetry events to ApplicationInsights.trackEvent", () => {
|
|
23
|
-
const logger =
|
|
19
|
+
const logger = createLogger(appInsightsClient);
|
|
24
20
|
const mockTelemetryEvent = {
|
|
25
21
|
category: "mockEvent",
|
|
26
22
|
eventName: "mockEventName",
|
|
@@ -47,7 +43,7 @@ describe("FluidAppInsightsLogger", () => {
|
|
|
47
43
|
],
|
|
48
44
|
},
|
|
49
45
|
};
|
|
50
|
-
assert.throws(() =>
|
|
46
|
+
assert.throws(() => createLogger(appInsightsClient, invalidConfig), new Error("Cannot have duplicate namespace pattern filters"));
|
|
51
47
|
});
|
|
52
48
|
it("constructor() throws error when filter config with namespace pattern exception that is not part of the parent pattern is provided", () => {
|
|
53
49
|
const invalidConfig = {
|
|
@@ -61,7 +57,7 @@ describe("FluidAppInsightsLogger", () => {
|
|
|
61
57
|
],
|
|
62
58
|
},
|
|
63
59
|
};
|
|
64
|
-
assert.throws(() =>
|
|
60
|
+
assert.throws(() => createLogger(appInsightsClient, invalidConfig), new Error("Cannot have a namespace pattern exception that is not a child of the parent namespace"));
|
|
65
61
|
});
|
|
66
62
|
it("constructor() throws error when multiple filters that only define categories are provided", () => {
|
|
67
63
|
const invalidConfig = {
|
|
@@ -77,7 +73,7 @@ describe("FluidAppInsightsLogger", () => {
|
|
|
77
73
|
],
|
|
78
74
|
},
|
|
79
75
|
};
|
|
80
|
-
assert.throws(() =>
|
|
76
|
+
assert.throws(() => createLogger(appInsightsClient, invalidConfig), new Error("Cannot have multiple filters that only define categories"));
|
|
81
77
|
});
|
|
82
78
|
});
|
|
83
79
|
describe("Telemetry Filter - filter mode", () => {
|
|
@@ -94,7 +90,7 @@ describe("Telemetry Filter - filter mode", () => {
|
|
|
94
90
|
trackEventSpy = spy(appInsightsClient, "trackEvent");
|
|
95
91
|
});
|
|
96
92
|
it("exclusive filter mode sends all events when no filters are defined", () => {
|
|
97
|
-
const logger =
|
|
93
|
+
const logger = createLogger(appInsightsClient, {
|
|
98
94
|
filtering: {
|
|
99
95
|
mode: "exclusive",
|
|
100
96
|
},
|
|
@@ -108,7 +104,7 @@ describe("Telemetry Filter - filter mode", () => {
|
|
|
108
104
|
sinonAssert.callCount(trackEventSpy, 1);
|
|
109
105
|
});
|
|
110
106
|
it("inclusive filter mode sends no events when no filters are defined", () => {
|
|
111
|
-
const logger =
|
|
107
|
+
const logger = createLogger(appInsightsClient, {
|
|
112
108
|
filtering: {
|
|
113
109
|
mode: "inclusive",
|
|
114
110
|
},
|
|
@@ -153,7 +149,7 @@ describe("Telemetry Filter - Category Filtering", () => {
|
|
|
153
149
|
trackEventSpy = spy(appInsightsClient, "trackEvent");
|
|
154
150
|
});
|
|
155
151
|
it("exclusive filtering mode DOES NOT SEND events that DO MATCH with atleast one category within a single filter containing multiple categories", () => {
|
|
156
|
-
const logger =
|
|
152
|
+
const logger = createLogger(appInsightsClient, {
|
|
157
153
|
filtering: {
|
|
158
154
|
mode: "exclusive",
|
|
159
155
|
filters: [
|
|
@@ -178,7 +174,7 @@ describe("Telemetry Filter - Category Filtering", () => {
|
|
|
178
174
|
sinonAssert.callCount(trackEventSpy, 0);
|
|
179
175
|
});
|
|
180
176
|
it("exclusive filter mode DOES NOT SEND events that DO MATCH with one of multiple category filters", () => {
|
|
181
|
-
const logger =
|
|
177
|
+
const logger = createLogger(appInsightsClient, exclusiveLoggerFilterConfig);
|
|
182
178
|
// should be excluded - match with category in filter
|
|
183
179
|
const event1 = {
|
|
184
180
|
category: "performance",
|
|
@@ -194,7 +190,7 @@ describe("Telemetry Filter - Category Filtering", () => {
|
|
|
194
190
|
sinonAssert.callCount(trackEventSpy, 0);
|
|
195
191
|
});
|
|
196
192
|
it("exclusive filter mode DOES SEND events that DO NOT MATCH with one of multiple category filters", () => {
|
|
197
|
-
const logger =
|
|
193
|
+
const logger = createLogger(appInsightsClient, exclusiveLoggerFilterConfig);
|
|
198
194
|
// should be included - does not match any category filter
|
|
199
195
|
const event = {
|
|
200
196
|
category: "error",
|
|
@@ -214,7 +210,7 @@ describe("Telemetry Filter - Category Filtering", () => {
|
|
|
214
210
|
});
|
|
215
211
|
// ------------------------------------------------------------------------------------
|
|
216
212
|
it("inclusive filtering mode DOES SEND events that DO MATCH with atleast one category within a single filter containing multiple categories", () => {
|
|
217
|
-
const logger =
|
|
213
|
+
const logger = createLogger(appInsightsClient, {
|
|
218
214
|
filtering: {
|
|
219
215
|
mode: "inclusive",
|
|
220
216
|
filters: [
|
|
@@ -239,7 +235,7 @@ describe("Telemetry Filter - Category Filtering", () => {
|
|
|
239
235
|
sinonAssert.callCount(trackEventSpy, 2);
|
|
240
236
|
});
|
|
241
237
|
it("inclusive filter mode DOES SEND events that DO MATCH with one of multiple category filters", () => {
|
|
242
|
-
const logger =
|
|
238
|
+
const logger = createLogger(appInsightsClient, inclusiveLoggerFilterConfig);
|
|
243
239
|
// should be included - match with category filter
|
|
244
240
|
const event1 = {
|
|
245
241
|
category: "performance",
|
|
@@ -255,7 +251,7 @@ describe("Telemetry Filter - Category Filtering", () => {
|
|
|
255
251
|
sinonAssert.callCount(trackEventSpy, 2);
|
|
256
252
|
});
|
|
257
253
|
it("inclusive filter mode DOES NOT SEND events that DO NOT MATCH with one of multiple category filters", () => {
|
|
258
|
-
const logger =
|
|
254
|
+
const logger = createLogger(appInsightsClient, inclusiveLoggerFilterConfig);
|
|
259
255
|
// should be excluded - does not match any category filter
|
|
260
256
|
const event = {
|
|
261
257
|
category: "error",
|
|
@@ -305,7 +301,7 @@ describe("Telemetry Filter - Namespace Filtering", () => {
|
|
|
305
301
|
trackEventSpy = spy(appInsightsClient, "trackEvent");
|
|
306
302
|
});
|
|
307
303
|
it("exclusive filter mode DOES NOT SEND events that MATCH with one of multiple namespace filters", () => {
|
|
308
|
-
const logger =
|
|
304
|
+
const logger = createLogger(appInsightsClient, exclusiveLoggerFilterConfig);
|
|
309
305
|
// should be excluded - partial match with namespace filter
|
|
310
306
|
const event1 = {
|
|
311
307
|
category: "performance",
|
|
@@ -333,7 +329,7 @@ describe("Telemetry Filter - Namespace Filtering", () => {
|
|
|
333
329
|
sinonAssert.callCount(trackEventSpy, 0);
|
|
334
330
|
});
|
|
335
331
|
it("exclusive filter mode DOES SEND events that DO NOT MATCH with one of multiple namespace filters", () => {
|
|
336
|
-
const logger =
|
|
332
|
+
const logger = createLogger(appInsightsClient, exclusiveLoggerFilterConfig);
|
|
337
333
|
// should be included - does not match any namespace filter
|
|
338
334
|
const event = {
|
|
339
335
|
category: "performance",
|
|
@@ -352,7 +348,7 @@ describe("Telemetry Filter - Namespace Filtering", () => {
|
|
|
352
348
|
}
|
|
353
349
|
});
|
|
354
350
|
it("exclusive filter mode DOES SEND events that MATCH with one of multiple namespace filters if they also partially match with a namespace exception", () => {
|
|
355
|
-
const logger =
|
|
351
|
+
const logger = createLogger(appInsightsClient, exclusiveLoggerFilterConfig);
|
|
356
352
|
// should be included - partial match with namespace filter but also partially matches namespace pattern exception
|
|
357
353
|
const event1 = {
|
|
358
354
|
category: "performance",
|
|
@@ -381,7 +377,7 @@ describe("Telemetry Filter - Namespace Filtering", () => {
|
|
|
381
377
|
});
|
|
382
378
|
// ------------------------------------------------------------------------------------
|
|
383
379
|
it("inclusive filter mode DOES SEND events that MATCH with one of multiple namespace filters", () => {
|
|
384
|
-
const logger =
|
|
380
|
+
const logger = createLogger(appInsightsClient, inclusiveLoggerFilterConfig);
|
|
385
381
|
// should be included - partial match with namespace filter
|
|
386
382
|
const event1 = {
|
|
387
383
|
category: "performance",
|
|
@@ -409,7 +405,7 @@ describe("Telemetry Filter - Namespace Filtering", () => {
|
|
|
409
405
|
sinonAssert.callCount(trackEventSpy, 4);
|
|
410
406
|
});
|
|
411
407
|
it("inclusive filter mode DOES NOT SEND events that DO NOT MATCH with one of multiple namespace filters", () => {
|
|
412
|
-
const logger =
|
|
408
|
+
const logger = createLogger(appInsightsClient, inclusiveLoggerFilterConfig);
|
|
413
409
|
// should be excluded - does not match any namespace filter
|
|
414
410
|
const event = {
|
|
415
411
|
category: "performance",
|
|
@@ -419,7 +415,7 @@ describe("Telemetry Filter - Namespace Filtering", () => {
|
|
|
419
415
|
sinonAssert.callCount(trackEventSpy, 0);
|
|
420
416
|
});
|
|
421
417
|
it("inclusive filter mode DOES NOT SEND events that MATCH with one of multiple namespace filters if they also partially match with a namespace exception", () => {
|
|
422
|
-
const logger =
|
|
418
|
+
const logger = createLogger(appInsightsClient, inclusiveLoggerFilterConfig);
|
|
423
419
|
// should be excluded - partial match with namespace filter but also partially matches namespace pattern exception
|
|
424
420
|
const event1 = {
|
|
425
421
|
category: "performance",
|
|
@@ -447,7 +443,7 @@ describe("Telemetry Filter - Namespace Filtering", () => {
|
|
|
447
443
|
sinonAssert.callCount(trackEventSpy, 0);
|
|
448
444
|
});
|
|
449
445
|
it("inclusive filter mode DOES NOT SEND events that DO NOT MATCH the most specific filter despite matching more generic ones. ", () => {
|
|
450
|
-
const logger =
|
|
446
|
+
const logger = createLogger(appInsightsClient, {
|
|
451
447
|
filtering: {
|
|
452
448
|
mode: "inclusive",
|
|
453
449
|
filters: [
|
|
@@ -519,7 +515,7 @@ describe("Telemetry Filter - Category & Namespace Combination Filtering", () =>
|
|
|
519
515
|
trackEventSpy = spy(appInsightsClient, "trackEvent");
|
|
520
516
|
});
|
|
521
517
|
it("exclusive filter mode DOES NOT SEND events that match combination category and namespace filters unless they match a namespace exception", () => {
|
|
522
|
-
const logger =
|
|
518
|
+
const logger = createLogger(appInsightsClient, exclusiveLoggerFilterConfig);
|
|
523
519
|
// should be included - does not match any filter
|
|
524
520
|
const event1 = {
|
|
525
521
|
category: "error",
|
|
@@ -574,7 +570,7 @@ describe("Telemetry Filter - Category & Namespace Combination Filtering", () =>
|
|
|
574
570
|
assert.strictEqual(actualSentEvent3.length, 1);
|
|
575
571
|
});
|
|
576
572
|
it("inclusive filter mode DOES SEND events that match combination category and namespace filters unless they match a namespace exception", () => {
|
|
577
|
-
const logger =
|
|
573
|
+
const logger = createLogger(appInsightsClient, inclusiveLoggerFilterConfig);
|
|
578
574
|
// should be excluded - does not match any filter
|
|
579
575
|
const event1 = {
|
|
580
576
|
category: "error",
|
|
@@ -622,4 +618,4 @@ describe("Telemetry Filter - Category & Namespace Combination Filtering", () =>
|
|
|
622
618
|
assert.strictEqual(actualSentEvent5.length, 1);
|
|
623
619
|
});
|
|
624
620
|
});
|
|
625
|
-
//# sourceMappingURL=fluidAppInsightsLogger.spec.
|
|
621
|
+
//# sourceMappingURL=fluidAppInsightsLogger.spec.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fluidAppInsightsLogger.spec.mjs","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\tcreateLogger,\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 = createLogger(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() => createLogger(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() => createLogger(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() => createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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 = createLogger(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"]}
|