UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

1 lines 30 kB
{"version":3,"sources":["../../../packages/core/performance/performance-profile.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAKjC,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAqB5E;;GAEG;AACH,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,MAAM,CAAC,WAAW,CAAwB;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqB;IAE5C,OAAO,CAAC,QAAQ,CAAoC;IACpD,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,8BAA8B,CAAiC;IACvE,OAAO,CAAC,8BAA8B,CAAiC;IACvE,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAAmC;IAC3D,OAAO,CAAC,oCAAoC,CAAuC;IAEnF;;OAEG;IACH,WAAkB,OAAO,IAAI,kBAAkB,CAO9C;IAED,WAAkB,QAAQ,IAAI,0BAA0B,CAEvD;IAED;;OAEG;WACW,kBAAkB,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI;IAYhC;;OAEG;WACW,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAW3C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAoBpC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAoB7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAoB/B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAmB1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAiBrC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAiB9B,OAAO,CAAC,MAAM,CAAC,aAAa;IA0B5B,OAAO,CAAC,MAAM,CAAC,MAAM;IAcrB,OAAO,CAAC,MAAM,CAAC,QAAQ;IA2EvB,OAAO,CAAC,MAAM,CAAC,UAAU;IAelB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAKtB,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAK9B,OAAO,CAAC,uBAAuB;IAiBxB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IA4C3B,cAAc,IAAI,IAAI;IA0B7B,OAAO,CAAC,GAAG;IAwBX,OAAO,CAAC,SAAS;IAiBjB,OAAO,CAAC,YAAY;IAmEpB,OAAO,CAAC,wBAAwB;IAwChC,OAAO,CAAC,iBAAiB;IA+CzB,OAAO,CAAC,yBAAyB;CAgBpC","file":"performance-profile.d.ts","sourcesContent":["import { of, Subscription, throwError } from 'rxjs';\r\nimport { AjaxError, AjaxRequest, AjaxResponse } from 'rxjs/ajax';\r\nimport { filter, map, take } from 'rxjs/operators';\r\nimport { CimResultFormat, CimStream, CimStreamMonitorSetContext, CimStreamOptions, CimStreamRequestData } from '../data/cim-stream';\r\nimport { Http } from '../data/http';\r\nimport { Net } from '../data/net';\r\nimport { PowerShellCommand } from '../data/powershell';\r\nimport { PowerShellStream, PowerShellStreamMonitorSetContext, PowerShellStreamOptions } from '../data/powershell-stream';\r\nimport { WebsocketStreamDataRequestState } from '../data/websocket-stream';\r\nimport { Logging } from '../diagnostics/logging';\r\nimport { RpcObservablePerformanceClient } from '../rpc/performance/rpc-observable-performance-client';\r\nimport { RpcObservablePerformanceConfigClient } from '../rpc/performance/rpc-observable-performance-config-client';\r\nimport { RpcObservablePerformanceServer } from '../rpc/performance/rpc-observable-performance-server';\r\nimport { Rpc } from '../rpc/rpc';\r\nimport {\r\n PerformanceProfileData, PerformanceProfileDataCim, PerformanceProfileDataPowerShell, PerformanceProfileXhrFetch\r\n} from './performance-profile-data';\r\nimport { PerformanceProfileDataType } from './performance-profile-data-type';\r\nimport { PerformanceProfileDatabase } from './performance-profile-database';\r\nimport { PerformanceProfileRecord } from './performance-profile-record';\r\n\r\ninterface PowerShellStreamContext {\r\n id: number;\r\n start: number;\r\n progressStart: number;\r\n progressEnd?: number;\r\n count: number;\r\n itemCount: number;\r\n}\r\n\r\ninterface CimStreamContext {\r\n id: number;\r\n start: number;\r\n progressStart: number;\r\n progressEnd?: number;\r\n count: number;\r\n itemCount: number;\r\n}\r\n\r\n/**\r\n * Performance measurement class.\r\n */\r\nexport class PerformanceProfile {\r\n private static monitorName = 'PerformanceProfile';\r\n private static instance: PerformanceProfile;\r\n\r\n private database: PerformanceProfileDatabase = null;\r\n private rpc: Rpc;\r\n private rpcObservablePerformanceClient: RpcObservablePerformanceClient;\r\n private rpcObservablePerformanceServer: RpcObservablePerformanceServer;\r\n private subscription: Subscription;\r\n private moduleVersionMap: { [index: string]: string } = {};\r\n private rpcObservablePerformanceConfigClient: RpcObservablePerformanceConfigClient;\r\n\r\n /**\r\n * Gets the current PerformanceProfile instance.\r\n */\r\n public static get current(): PerformanceProfile {\r\n if (PerformanceProfile.instance) {\r\n return PerformanceProfile.instance;\r\n }\r\n\r\n PerformanceProfile.instance = new PerformanceProfile();\r\n return PerformanceProfile.instance;\r\n }\r\n\r\n public static get database(): PerformanceProfileDatabase {\r\n return PerformanceProfile.current.database;\r\n }\r\n\r\n /**\r\n * Record Route navigation performance measurement.\r\n */\r\n public static logRouteNavigation(\r\n source: string,\r\n start: number,\r\n end: number,\r\n url: string,\r\n target?: string,\r\n errorMessage?: string): void {\r\n const data: PerformanceProfileData = {\r\n source,\r\n start,\r\n end,\r\n errorMessage,\r\n type: PerformanceProfileDataType.RouteNavigation,\r\n routeNavigation: { url, target }\r\n };\r\n PerformanceProfile.current.log(data);\r\n }\r\n\r\n /**\r\n * Record Null packet.\r\n */\r\n public static logNull(source: string): void {\r\n const data: PerformanceProfileData = {\r\n source,\r\n start: 0,\r\n end: 0,\r\n errorMessage: null,\r\n type: PerformanceProfileDataType.Null\r\n };\r\n PerformanceProfile.current.logAnyway(data);\r\n }\r\n\r\n /**\r\n * Record XHR or Fetch performance measurement for PowerShell.\r\n */\r\n private static logXhrFetchPowerShell(\r\n source: string,\r\n start: number,\r\n end: number,\r\n url: string,\r\n method: string,\r\n status: number,\r\n powershell: PerformanceProfileDataPowerShell,\r\n errorMessage?: string): void {\r\n const data: PerformanceProfileData = {\r\n source,\r\n start,\r\n end,\r\n errorMessage,\r\n type: PerformanceProfileDataType.XhrFetch,\r\n xhrFetch: { url, method, status, powershell }\r\n };\r\n PerformanceProfile.current.log(data);\r\n }\r\n\r\n /**\r\n * Record XHR or Fetch performance measurement for CIM.\r\n */\r\n private static logXhrFetchCim(\r\n source: string,\r\n start: number,\r\n end: number,\r\n url: string,\r\n method: string,\r\n status: number,\r\n cim: PerformanceProfileDataCim,\r\n errorMessage?: string): void {\r\n const data: PerformanceProfileData = {\r\n source,\r\n start,\r\n end,\r\n errorMessage,\r\n type: PerformanceProfileDataType.XhrFetch,\r\n xhrFetch: { url, method, status, cim }\r\n };\r\n PerformanceProfile.current.log(data);\r\n }\r\n\r\n /**\r\n * Record XHR or Fetch performance measurement for Batch.\r\n */\r\n private static logXhrFetchBatch(\r\n source: string,\r\n start: number,\r\n end: number,\r\n url: string,\r\n method: string,\r\n status: number,\r\n batch: PerformanceProfileXhrFetch[],\r\n errorMessage?: string): void {\r\n const data: PerformanceProfileData = {\r\n source,\r\n start,\r\n end,\r\n errorMessage,\r\n type: PerformanceProfileDataType.XhrFetch,\r\n xhrFetch: { url, method, status, batch }\r\n };\r\n PerformanceProfile.current.log(data);\r\n }\r\n\r\n /**\r\n * Record XHR or Fetch performance measurement for general.\r\n */\r\n private static logXhrFetch(\r\n source: string,\r\n start: number,\r\n end: number,\r\n url: string,\r\n method: string,\r\n status: number,\r\n errorMessage?: string): void {\r\n const data: PerformanceProfileData = {\r\n source,\r\n start,\r\n end,\r\n errorMessage,\r\n type: PerformanceProfileDataType.XhrFetch,\r\n xhrFetch: { url, method, status }\r\n };\r\n PerformanceProfile.current.log(data);\r\n }\r\n\r\n /**\r\n * Record WebSocket performance measurement.\r\n */\r\n private static logWebSocketPowerShell(\r\n source: string,\r\n nodeName: string,\r\n command: string,\r\n context: PowerShellStreamContext,\r\n errorMessage?: string): void {\r\n const data: PerformanceProfileData = {\r\n source,\r\n start: context.progressStart,\r\n end: context.progressEnd,\r\n errorMessage,\r\n type: PerformanceProfileDataType.WebSocket,\r\n webSocket: { nodeName, id: context.id, count: context.count, itemCount: context.itemCount, powershell: { command } }\r\n };\r\n PerformanceProfile.current.log(data);\r\n }\r\n\r\n /**\r\n * Record WebSocket performance measurement.\r\n */\r\n private static logWebSocketCim(\r\n source: string,\r\n nodeName: string,\r\n cim: CimStreamRequestData,\r\n context: CimStreamContext,\r\n errorMessage?: string): void {\r\n const data: PerformanceProfileData = {\r\n source,\r\n start: context.progressStart,\r\n end: context.progressEnd,\r\n errorMessage,\r\n type: PerformanceProfileDataType.WebSocket,\r\n webSocket: { nodeName, id: context.id, count: context.count, itemCount: context.itemCount, cim }\r\n };\r\n PerformanceProfile.current.log(data);\r\n }\r\n\r\n private static powershellApi(\r\n url: string,\r\n body: string,\r\n response: { completed?: string, sessionId?: string; properties?: { completed: string; sessionId: string; }; }): PerformanceProfileDataPowerShell {\r\n const powershell: { command?: string; sessionId?: string; completed?: string } = {};\r\n if (body && body.indexOf('\\\"properties\\\"') > 0) {\r\n powershell.command = PerformanceProfile.getBetween(body, ',\\\"command\\\":\\\"', '\\\",\\\"')\r\n || PerformanceProfile.getBetween(body, '\\\"script\\\":\\\"##', '##:');\r\n }\r\n\r\n powershell.completed = response && response.completed;\r\n if (!powershell.completed) {\r\n powershell.completed = response && response.properties && response.properties.completed;\r\n }\r\n\r\n powershell.sessionId = response && response.sessionId;\r\n if (!powershell.sessionId) {\r\n powershell.sessionId = response && response.properties && response.properties.sessionId;\r\n if (!powershell.sessionId) {\r\n powershell.sessionId = PerformanceProfile.getBetween(url, '/pssessions/', '?');\r\n }\r\n }\r\n\r\n return powershell;\r\n }\r\n\r\n private static cimApi(url: string, body: string): PerformanceProfileDataCim {\r\n if (url.indexOf('/features/cim/query') > 0 || url.indexOf('/services/WinREST/CIM/query') > 0) {\r\n try {\r\n return JSON.parse(body);\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n const namespaceName = PerformanceProfile.getBetween(url, '/namespaces/', '/classes/');\r\n const className = PerformanceProfile.getBetween(url, '/classes/', '/instances');\r\n return { namespace: namespaceName, className: className };\r\n }\r\n\r\n private static batchApi(body: string, response: string): PerformanceProfileXhrFetch[] {\r\n const delimiter = '\\x0d\\x0a';\r\n const batch: PerformanceProfileXhrFetch[] = [];\r\n let last = body.indexOf(delimiter);\r\n let separator = body.substring(0, last + 2);\r\n const bodySegments = body.split(separator);\r\n last = response.indexOf(delimiter);\r\n separator = response.substring(0, last + 2);\r\n const responseSegments = response.split(separator);\r\n if (bodySegments.length === responseSegments.length && bodySegments.length > 1) {\r\n let batchMethod: string;\r\n let batchUrl: string;\r\n let batchBody: string;\r\n let batchStatus: number;\r\n let batchResponse: any;\r\n for (let i = 1; i < bodySegments.length; i++) {\r\n const bodySegment = bodySegments[i];\r\n const responseSegment = responseSegments[i];\r\n const bodySegmentLines = bodySegment.split(delimiter);\r\n let emptyLines = 0;\r\n for (let j = 0; j < bodySegmentLines.length; j++) {\r\n const line = bodySegmentLines[j];\r\n if (line.length > 0) {\r\n if (emptyLines === 1 && !batchUrl) {\r\n // reached header segment.\r\n const query = line.split(' ');\r\n batchMethod = query[0];\r\n batchUrl = query[1];\r\n } else if (emptyLines >= 2 && !batchBody) {\r\n batchBody = line;\r\n }\r\n } else {\r\n emptyLines++;\r\n }\r\n }\r\n\r\n emptyLines = 0;\r\n const responseSegmentLines = responseSegment.split(delimiter);\r\n for (let j = 0; j < responseSegmentLines.length; j++) {\r\n const line = responseSegmentLines[j];\r\n if (line.length > 0) {\r\n if (emptyLines === 1 && !batchStatus) {\r\n // reached header segment.\r\n const query = line.split(' ');\r\n batchStatus = Number(query[1]);\r\n } else if (emptyLines >= 2 && !batchResponse) {\r\n try {\r\n batchResponse = JSON.parse(line);\r\n } catch {\r\n batchResponse = {};\r\n }\r\n }\r\n } else {\r\n emptyLines++;\r\n }\r\n }\r\n\r\n const batchItem: PerformanceProfileXhrFetch = {\r\n url: batchUrl,\r\n status: batchStatus,\r\n method: batchMethod\r\n };\r\n if (batchUrl.indexOf('/features/powershellApi/') > 0 || batchUrl.indexOf('/services/WinREST/PowerShell/') > 0) {\r\n batchItem.powershell = PerformanceProfile.powershellApi(batchUrl, batchBody, batchResponse);\r\n } else if (batchUrl.includes('/features/cim/query') || batchUrl.includes('/services/WinREST/CIM/')) {\r\n batchItem.cim = PerformanceProfile.cimApi(batchUrl, batchBody);\r\n }\r\n\r\n batch.push(batchItem);\r\n }\r\n }\r\n\r\n return batch;\r\n }\r\n\r\n private static getBetween(source: string, begin: string, end: string): string {\r\n let index0 = source.indexOf(begin);\r\n if (index0 < 0) {\r\n return null;\r\n }\r\n\r\n index0 += begin.length;\r\n const index1 = source.indexOf(end, index0);\r\n if (index1 < 0) {\r\n return null;\r\n }\r\n\r\n return source.substring(index0, index1);\r\n }\r\n\r\n public enable(rpc: Rpc): void {\r\n MsftSme.setPerformanceProfile(true);\r\n this.registerRpc(rpc);\r\n }\r\n\r\n public disable(rpc: Rpc): void {\r\n MsftSme.setPerformanceProfile(false);\r\n this.registerRpc(rpc);\r\n }\r\n\r\n private checkPerformanceProfile(): boolean {\r\n if (!MsftSme.getPerformanceProfile()) {\r\n if (this.database) {\r\n this.database.close();\r\n this.database = null;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n if (!this.database) {\r\n this.database = new PerformanceProfileDatabase();\r\n }\r\n\r\n return true;\r\n }\r\n\r\n public registerRpc(rpc: Rpc): void {\r\n if (!this.rpc) {\r\n this.rpc = rpc;\r\n if (MsftSme.isShell()) {\r\n this.subscription = rpc.stateChanged\r\n .pipe(\r\n filter(active => active),\r\n take(1))\r\n .subscribe(() => {\r\n this.rpcObservablePerformanceConfigClient = new RpcObservablePerformanceConfigClient(this.rpc);\r\n this.rpcObservablePerformanceServer = new RpcObservablePerformanceServer(rpc);\r\n this.rpcObservablePerformanceServer.register(\r\n request => {\r\n if (request.type === PerformanceProfileDataType.Null) {\r\n // The packet is null packet and retain only the version data.\r\n if (request.sourceVersion === '0.2.0') {\r\n // this version can support config command when on/off switch was used.\r\n this.moduleVersionMap[request.sourceName] = request.sourceVersion;\r\n }\r\n\r\n return of(null);\r\n }\r\n\r\n if (!this.checkPerformanceProfile()) {\r\n return of(null);\r\n }\r\n\r\n return this.database.write(request).pipe(map(() => null));\r\n });\r\n });\r\n } else {\r\n this.subscription = rpc.stateChanged\r\n .pipe(\r\n filter(active => active),\r\n take(1))\r\n .subscribe(() => {\r\n this.rpcObservablePerformanceClient = new RpcObservablePerformanceClient(rpc);\r\n });\r\n }\r\n }\r\n\r\n this.updateMonitors();\r\n }\r\n\r\n public updateMonitors(): void {\r\n const enabled = this.checkPerformanceProfile();\r\n if (this.rpcObservablePerformanceConfigClient) {\r\n // enable/disable the performance profile data collection to current modules.\r\n // but these must be version 0.2.0.\r\n const items = this.rpc.rpcManager.getCurrentRpcOutbound();\r\n if (items) {\r\n for (const item of items) {\r\n if (this.moduleVersionMap[item.name]) {\r\n this.rpcObservablePerformanceConfigClient.config({ enabled }, item).subscribe();\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (enabled) {\r\n this.registerHttp();\r\n this.registerPowerShellStream();\r\n this.registerCimStream();\r\n } else {\r\n Http.unregisterMonitors(PerformanceProfile.monitorName);\r\n PowerShellStream.unregisterMonitors(PerformanceProfile.monitorName);\r\n CimStream.unregisterMonitors(PerformanceProfile.monitorName);\r\n }\r\n }\r\n\r\n private log(message: PerformanceProfileData): void {\r\n if (!this.checkPerformanceProfile()) {\r\n return;\r\n }\r\n\r\n const self = MsftSme.self();\r\n const record: PerformanceProfileRecord = {\r\n ...message,\r\n ...{ sessionId: self.Init.sessionId, timestamp: Date.now(), moduleName: self.Init.moduleName }\r\n };\r\n\r\n if (!record.errorMessage) {\r\n delete record['errorMessage'];\r\n }\r\n\r\n if (this.rpc && this.rpc.stateActive && this.rpcObservablePerformanceClient) {\r\n // send to shell.\r\n this.rpcObservablePerformanceClient.log(record).subscribe();\r\n } else {\r\n // write to database.\r\n this.database.write(record).subscribe();\r\n }\r\n }\r\n\r\n private logAnyway(message: PerformanceProfileData): void {\r\n const self = MsftSme.self();\r\n const record: PerformanceProfileRecord = {\r\n ...message,\r\n ...{ sessionId: self.Init.sessionId, timestamp: Date.now(), moduleName: self.Init.moduleName }\r\n };\r\n\r\n if (!record.errorMessage) {\r\n delete record['errorMessage'];\r\n }\r\n\r\n if (this.rpc && this.rpc.stateActive && this.rpcObservablePerformanceClient) {\r\n // send to shell.\r\n this.rpcObservablePerformanceClient.log(record).subscribe();\r\n }\r\n }\r\n\r\n private registerHttp(): void {\r\n const startPropertyName = '_start_';\r\n\r\n Http.registerMonitorSet({\r\n name: PerformanceProfile.monitorName,\r\n preMonitor: (request: AjaxRequest) => {\r\n if (!request) {\r\n Logging.logWarning('Http', 'Http performance profile measurement error to access the AjaxRequest object.');\r\n return of(request);\r\n }\r\n\r\n request[startPropertyName] = Date.now();\r\n return of(request);\r\n },\r\n successMonitor: (response: AjaxResponse<any>) => {\r\n if (!response || !response.request || !response.request.url) {\r\n Logging.logWarning('Http', 'Http performance profile measurement error to access the AjaxResponse object.');\r\n return of(response);\r\n }\r\n\r\n const request = response.request;\r\n const url = request.url;\r\n const method = request.method;\r\n const end = Date.now();\r\n const start = request[startPropertyName];\r\n if (url.indexOf('/features/powershellApi/') > 0 || url.indexOf('/services/WinREST/PowerShell/') > 0){\r\n const powershell = PerformanceProfile.powershellApi(url, request.body, response.response);\r\n PerformanceProfile.logXhrFetchPowerShell('Http', start, end, url, method, response.status, powershell);\r\n } else if (url.includes('/features/cim/') || url.includes('/services/WinREST/CIM')) {\r\n const cim = PerformanceProfile.cimApi(url, request.body);\r\n PerformanceProfile.logXhrFetchCim('Http', start, end, url, method, response.status, cim);\r\n } else if (url.indexOf('/api/batch') > 0) {\r\n const batch = PerformanceProfile.batchApi(request.body, response.response);\r\n PerformanceProfile.logXhrFetchBatch('Http', start, end, url, method, response.status, batch);\r\n } else {\r\n PerformanceProfile.logXhrFetch('Http', start, end, url, method, response.status);\r\n }\r\n\r\n return of(response);\r\n },\r\n errorMonitor: (error: AjaxError) => {\r\n if (!error || !error.response || !error.request || !error.request.url) {\r\n Logging.logWarning('Http', 'Http performance profile measurement error to access the AjaxError object.');\r\n return throwError(() => error);\r\n }\r\n\r\n const request = error.request;\r\n const url = request.url;\r\n const method = request.method;\r\n const end = Date.now();\r\n const start = request[startPropertyName];\r\n const message = Net.getErrorMessage(error);\r\n if (url.indexOf('features/powershellApi') > 0 || url.indexOf('/services/WinREST/PowerShell/') > 0) {\r\n const powershell = PerformanceProfile.powershellApi(url, request.body, error.response);\r\n PerformanceProfile.logXhrFetchPowerShell('Http', start, end, url, method, error.status, powershell, message);\r\n } else if (url.includes('/features/cim/') || url.includes('/services/WinREST/CIM/')) {\r\n const cim = PerformanceProfile.cimApi(url, request.body);\r\n PerformanceProfile.logXhrFetchCim('Http', start, end, url, method, error.status, cim, message);\r\n } else {\r\n PerformanceProfile.logXhrFetch('Http', start, end, url, method, error.status, message);\r\n }\r\n\r\n return throwError(() => error);\r\n }\r\n });\r\n }\r\n\r\n private registerPowerShellStream(): void {\r\n let masterId = 1;\r\n PowerShellStream.registerMonitorSet({\r\n name: PerformanceProfile.monitorName,\r\n preMonitor: (nodeName: string, command: PowerShellCommand, options?: PowerShellStreamOptions) => {\r\n const start = Date.now();\r\n const id = masterId++;\r\n const context: PowerShellStreamMonitorSetContext<PowerShellStreamContext> = {\r\n nodeName,\r\n command,\r\n options,\r\n data: { id, start, progressStart: start, count: 0, itemCount: 0 }\r\n };\r\n return of(context);\r\n },\r\n successMonitor: (response: any, context: PowerShellStreamMonitorSetContext<PowerShellStreamContext>) => {\r\n context.data.progressEnd = Date.now();\r\n context.data.count++;\r\n context.data.itemCount += (response && response.results && response.results.length || 1);\r\n PerformanceProfile.logWebSocketPowerShell(\r\n 'PowerShellStream',\r\n context.nodeName,\r\n context.command.command,\r\n context.data);\r\n context.data.progressStart = Date.now();\r\n return of(response);\r\n },\r\n errorMonitor: (error: any, context: PowerShellStreamMonitorSetContext<PowerShellStreamContext>) => {\r\n context.data.progressEnd = Date.now();\r\n PerformanceProfile.logWebSocketPowerShell(\r\n 'PowerShellStream',\r\n context.nodeName,\r\n context.command.command,\r\n context.data,\r\n Net.getErrorMessage(error));\r\n return throwError(() => error);\r\n }\r\n });\r\n }\r\n\r\n private registerCimStream(): void {\r\n let masterId = 1;\r\n CimStream.registerMonitorSet({\r\n name: PerformanceProfile.monitorName,\r\n preMonitor: (\r\n nodeName: string,\r\n requestState: WebsocketStreamDataRequestState,\r\n request: CimStreamRequestData,\r\n format: CimResultFormat,\r\n options?: CimStreamOptions) => {\r\n const start = Date.now();\r\n const id = masterId++;\r\n const context: CimStreamMonitorSetContext<CimStreamContext> = {\r\n nodeName,\r\n requestState,\r\n request,\r\n format,\r\n options,\r\n data: { id, start, progressStart: start, count: 0, itemCount: 0 }\r\n };\r\n return of(context);\r\n },\r\n successMonitor: (response: any, context: CimStreamMonitorSetContext<CimStreamContext>) => {\r\n context.data.progressEnd = Date.now();\r\n context.data.count++;\r\n context.data.itemCount += (response && response.results && response.results.length || 1);\r\n PerformanceProfile.logWebSocketCim(\r\n 'CimStream',\r\n context.nodeName,\r\n this.removeCimStreamDetailData(context.request),\r\n context.data);\r\n context.data.progressStart = Date.now();\r\n return of(response);\r\n },\r\n errorMonitor: (error: any, context: CimStreamMonitorSetContext<CimStreamContext>) => {\r\n context.data.progressEnd = Date.now();\r\n PerformanceProfile.logWebSocketCim(\r\n 'CimStream',\r\n context.nodeName,\r\n this.removeCimStreamDetailData(context.request),\r\n context.data,\r\n Net.getErrorMessage(error));\r\n return throwError(() => error);\r\n }\r\n });\r\n }\r\n\r\n private removeCimStreamDetailData(request: CimStreamRequestData): CimStreamRequestData {\r\n const skipKeys = ['data', 'keyProperties'];\r\n const requestRaw: any = request;\r\n const keys = Object.keys(requestRaw);\r\n const trimmedKeys = keys.filter(key => skipKeys.indexOf(key) < 0);\r\n if (keys.length !== trimmedKeys.length) {\r\n const copy: any = {};\r\n for (const key of trimmedKeys) {\r\n copy[key] = requestRaw[key];\r\n }\r\n\r\n return copy;\r\n }\r\n\r\n return request;\r\n }\r\n}\r\n"]}