Path: blob/main/extensions/copilot/src/platform/log/common/logExecTime.ts
13401 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { isCancellationError } from '../../../util/vs/base/common/errors';6import { StopWatch } from '../../../util/vs/base/common/stopwatch';7import { ILogService } from './logService';89type MeasureCallBack<R> = (time: number, status: 'success' | 'failed' | 'cancelled', result: R | undefined) => void;1011/**12* Helper that collects how long a block of code takes to execute.13*/1415export async function measureExecTime<R>(fn: () => PromiseLike<R>, cb: MeasureCallBack<R>): Promise<R> {16const sw = new StopWatch();17try {18const result = await fn();19cb(sw.elapsed(), 'success', result);20return result;21} catch (error) {22cb(sw.elapsed(), isCancellationError(error) ? 'cancelled' : 'failed', undefined);23throw error;24}25}2627/**28* Helper that logs how long a block of code takes to execute.29*/30export async function logExecTime<R>(logService: ILogService, name: string, fn: () => PromiseLike<R>, measureCb?: MeasureCallBack<R>): Promise<R> {31return measureExecTime(() => {32logService.trace(`${name} started`);33return fn();34}, (time, status, result) => {35logService.trace(`${name} ${status}. Elapsed ${time}`);36measureCb?.(time, status, result);37});38}3940/**41* Decorator that adds logging for how long the method takes to execute.42*/43export function LogExecTime<T>(44getLogService: (self: T) => ILogService,45logName: string,46measureCb?: (this: T, time: number, status: 'success' | 'failed' | 'cancelled') => void,47) {48return function (target: T, propertyKey: string, descriptor: PropertyDescriptor) {49const originalMethod = descriptor.value;50let idPool = 0;51descriptor.value = async function (this: T, ...args: any[]) {52const id = idPool++;53const logService = getLogService(this);54return logExecTime(logService, `${logName}#${id}`, () => originalMethod.apply(this, args), measureCb?.bind(this));55};5657return descriptor;58};59}606162/**63* Decorator that adds a callback about how long an async method takes to execute.64*/65export function MeasureExecTime<T>(cb: (this: T, time: number, status: 'success' | 'failed' | 'cancelled') => void) {66return function (target: T, propertyKey: string, descriptor: PropertyDescriptor) {67const originalMethod = descriptor.value;68descriptor.value = function (this: T, ...args: any[]) {69return measureExecTime(() => originalMethod.apply(this, args), cb.bind(this));70};71return descriptor;72};73}747576