-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add start-up timing logs in frontend and backend
Added some finer-grained logging of timing measurements in backend start-up tasks. Includes a refactoring of similar patterns used throughout frontend and backend code, using different performance tracing APIs, into a common injected Stopwatch service providing Measurements. Also publishes the backend Stopwatch to frontends via a new BackendStopwatch RPC service, letting frontends log messages in the timeframe of the backend application. Contributed on behalf of STMicroelectronics. Signed-off-by: Christian W. Damus <[email protected]>
- Loading branch information
Showing
19 changed files
with
643 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
packages/core/src/browser/performance/frontend-stopwatch.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2019, 2021 TypeFox, STMicroelectronics and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
*******************************************************************************/ | ||
|
||
import { injectable } from 'inversify'; | ||
import { Measurement, MeasurementOptions, Stopwatch } from '../../common'; | ||
|
||
@injectable() | ||
export class FrontendStopwatch extends Stopwatch { | ||
|
||
constructor() { | ||
super({ | ||
owner: 'frontend', | ||
now: () => performance.now(), | ||
}); | ||
} | ||
|
||
start(name: string, options?: MeasurementOptions): Measurement { | ||
const startMarker = `${name}-start`; | ||
const endMarker = `${name}-end`; | ||
performance.clearMeasures(name); | ||
performance.clearMarks(startMarker); | ||
performance.clearMarks(endMarker); | ||
|
||
performance.mark(startMarker); | ||
|
||
return this.createMeasurement(name, () => { | ||
performance.mark(endMarker); | ||
|
||
let duration: number; | ||
|
||
try { | ||
performance.measure(name, startMarker, endMarker); | ||
|
||
const entries = performance.getEntriesByName(name); | ||
// If no entries, then performance measurement was disabled or failed, so | ||
// signal that with a `NaN` result | ||
duration = entries.length > 0 ? entries[0].duration : Number.NaN; | ||
} catch (e) { | ||
console.warn(e); | ||
duration = Number.NaN; | ||
} | ||
|
||
performance.clearMeasures(name); | ||
performance.clearMarks(startMarker); | ||
performance.clearMarks(endMarker); | ||
return duration; | ||
}, options); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2021 STMicroelectronics and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
export * from './frontend-stopwatch'; | ||
export * from './measurement-frontend-bindings'; |
31 changes: 31 additions & 0 deletions
31
packages/core/src/browser/performance/measurement-frontend-bindings.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2021 STMicroelectronics and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
*******************************************************************************/ | ||
|
||
import { interfaces } from 'inversify'; | ||
import { BackendStopwatch, Stopwatch, stopwatchPath } from '../../common'; | ||
import { WebSocketConnectionProvider } from '../messaging'; | ||
import { FrontendStopwatch } from './frontend-stopwatch'; | ||
|
||
export function bindFrontendStopwatch(bind: interfaces.Bind): interfaces.BindingWhenOnSyntax<Stopwatch> { | ||
return bind(Stopwatch).to(FrontendStopwatch).inSingletonScope(); | ||
} | ||
|
||
export function bindBackendStopwatch(bind: interfaces.Bind): interfaces.BindingWhenOnSyntax<unknown> { | ||
return bind(BackendStopwatch).toDynamicValue(ctx => { | ||
const connection = ctx.container.get(WebSocketConnectionProvider); | ||
return connection.createProxy<BackendStopwatch>(stopwatchPath); | ||
}).inSingletonScope(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2021 STMicroelectronics and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
export * from './measurement'; | ||
export * from './stopwatch'; | ||
export * from './measurement-protocol'; |
87 changes: 87 additions & 0 deletions
87
packages/core/src/common/performance/measurement-protocol.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2021 STMicroelectronics and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
*******************************************************************************/ | ||
|
||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
|
||
import { inject, injectable, LazyServiceIdentifer } from 'inversify'; | ||
import { Measurement, MeasurementOptions } from './measurement'; | ||
import { Stopwatch } from './stopwatch'; | ||
import { JsonRpcServer } from '../messaging'; | ||
|
||
export const BackendStopwatch = Symbol('BackendStopwatch'); | ||
|
||
/** API path of the stopwatch service that exposes the back-end stopwatch to clients. */ | ||
export const stopwatchPath = '/services/stopwatch'; | ||
|
||
/** Token representing a remote measurement in the {@link BackendStopwatch} protocol. */ | ||
export type RemoteMeasurement = number; | ||
|
||
/** | ||
* A service that exposes the back-end's {@link Stopwatch} to clients | ||
* via the remote API. | ||
*/ | ||
export interface BackendStopwatch extends JsonRpcServer<unknown> { | ||
|
||
/** | ||
* Create a {@link Measurement} that will compute the time that elapsed on the back-end when logged. | ||
* | ||
* @param name the {@link Measurement.name measurement name} | ||
* @param options optional configuration of the new measurement | ||
* @returns a token identifying an unique self-timing measurement relative to the back-end's timeline | ||
*/ | ||
start(name: string, options?: MeasurementOptions): Promise<RemoteMeasurement>; | ||
|
||
/** | ||
* Stop a measurement previously {@link start started} and log in the back-end a measurement of | ||
* its duration relative to the back-end's timeline. | ||
* | ||
* @param measurement token identifying a measurement previously {@link start started} | ||
* @param message a message to log | ||
* @param messageArgs optional arguments to the `message` | ||
*/ | ||
stop(measurement: RemoteMeasurement, message: string, messageArgs: any[]): Promise<void>; | ||
|
||
} | ||
|
||
/** | ||
* Default implementation of the (remote) back-end stopwatch service. | ||
*/ | ||
@injectable() | ||
export class DefaultBackendStopwatch { | ||
|
||
readonly measurements = new Map<number, Measurement>(); | ||
|
||
protected idSequence: number = 0; | ||
|
||
constructor(@inject(new LazyServiceIdentifer(() => Stopwatch)) protected readonly stopwatch: Stopwatch) { | ||
// Nothing else to initialize | ||
} | ||
|
||
start(name: string, options?: MeasurementOptions): RemoteMeasurement { | ||
const result = ++this.idSequence; | ||
this.measurements.set(result, this.stopwatch.start(name, options)); | ||
return result; | ||
} | ||
|
||
stop(measurementToken: RemoteMeasurement, message: string, messageArgs: any[]): void { | ||
const measurement = this.measurements.get(measurementToken); | ||
if (measurement) { | ||
this.measurements.delete(measurementToken); | ||
measurement.log(message, ...messageArgs); | ||
} | ||
} | ||
|
||
}; |
Oops, something went wrong.