Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: move progress log into the metadata #5411

Merged
merged 1 commit into from
Feb 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/dispatchers/dispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ import { EventEmitter } from 'events';
import * as channels from '../protocol/channels';
import { serializeError } from '../protocol/serializers';
import { createScheme, Validator, ValidationError } from '../protocol/validator';
import { assert, createGuid, debugAssert, isUnderTest } from '../utils/utils';
import { assert, createGuid, debugAssert, isUnderTest, monotonicTime } from '../utils/utils';
import { tOptional } from '../protocol/validatorPrimitives';
import { kBrowserOrContextClosedError } from '../utils/errors';
import { CallMetadata } from '../server/instrumentation';
import { StackFrame } from '../common/types';

export const dispatcherSymbol = Symbol('dispatcher');

Expand Down Expand Up @@ -124,7 +125,7 @@ export class DispatcherConnection {
private _rootDispatcher: Root;
onmessage = (message: object) => {};
private _validateParams: (type: string, method: string, params: any) => any;
private _validateMetadata: (metadata: any) => any;
private _validateMetadata: (metadata: any) => { stack?: StackFrame[] };

sendMessageToClient(guid: string, method: string, params: any) {
this.onmessage({ guid, method, params: this._replaceDispatchersWithGuids(params) });
Expand Down Expand Up @@ -180,9 +181,12 @@ export class DispatcherConnection {
throw new Error(`Mismatching dispatcher: "${dispatcher._type}" does not implement "${method}"`);
const callMetadata: CallMetadata = {
...this._validateMetadata(metadata),
startTime: monotonicTime(),
endTime: 0,
type: dispatcher._type,
method,
params,
log: [],
};
const result = await (dispatcher as any)[method](validated, callMetadata);
this.onmessage({ id, result: this._replaceDispatchersWithGuids(result) });
Expand Down
20 changes: 11 additions & 9 deletions src/server/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ export type Attribution = {
};

export type CallMetadata = {
startTime: number;
endTime: number;
type: string;
method: string;
params: any;
stack?: StackFrame[];
log: string[];
error?: Error;
};

export class SdkObject extends EventEmitter {
Expand All @@ -49,27 +53,22 @@ export class SdkObject extends EventEmitter {
}
}

export type ActionResult = {
logs: string[],
startTime: number,
endTime: number,
error?: Error,
};

export interface Instrumentation {
onContextCreated(context: BrowserContext): Promise<void>;
onContextWillDestroy(context: BrowserContext): Promise<void>;
onContextDidDestroy(context: BrowserContext): Promise<void>;
onActionCheckpoint(name: string, sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
onAfterAction(result: ActionResult, sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
onAfterAction(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
onLog(logName: string, message: string, sdkObject: SdkObject, metadata: CallMetadata): void;
}

export interface InstrumentationListener {
onContextCreated?(context: BrowserContext): Promise<void>;
onContextWillDestroy?(context: BrowserContext): Promise<void>;
onContextDidDestroy?(context: BrowserContext): Promise<void>;
onActionCheckpoint?(name: string, sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
onAfterAction?(result: ActionResult, sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
onAfterAction?(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
onLog?(logName: string, message: string, sdkObject: SdkObject, metadata: CallMetadata): void;
}

export function multiplexInstrumentation(listeners: InstrumentationListener[]): Instrumentation {
Expand All @@ -87,8 +86,11 @@ export function multiplexInstrumentation(listeners: InstrumentationListener[]):

export function internalCallMetadata(): CallMetadata {
return {
startTime: 0,
endTime: 0,
type: 'Internal',
method: '',
params: {},
log: [],
};
}
33 changes: 12 additions & 21 deletions src/server/progress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { TimeoutError } from '../utils/errors';
import { assert, monotonicTime } from '../utils/utils';
import { rewriteErrorMessage } from '../utils/stackTrace';
import { debugLogger, LogName } from '../utils/debugLogger';
import { LogName } from '../utils/debugLogger';
import { CallMetadata, Instrumentation, SdkObject } from './instrumentation';

export interface Progress {
Expand All @@ -38,11 +38,10 @@ export class ProgressController {
// Cleanups to be run only in the case of abort.
private _cleanups: (() => any)[] = [];

private _logName: LogName = 'api';
private _logName = 'api';
private _state: 'before' | 'running' | 'aborted' | 'finished' = 'before';
private _deadline: number = 0;
private _timeout: number = 0;
private _logRecording: string[] = [];
readonly metadata: CallMetadata;
readonly instrumentation: Instrumentation;
readonly sdkObject: SdkObject;
Expand Down Expand Up @@ -70,9 +69,10 @@ export class ProgressController {

const progress: Progress = {
log: message => {
if (this._state === 'running')
this._logRecording.push(message);
debugLogger.log(this._logName, message);
if (this._state === 'running') {
this.metadata.log.push(message);
this.instrumentation.onLog(this._logName, message, this.sdkObject, this.metadata);
}
},
timeUntilDeadline: () => this._deadline ? this._deadline - monotonicTime() : 2147483647, // 2^31-1 safe setTimeout in Node.
isRunning: () => this._state === 'running',
Expand All @@ -93,34 +93,25 @@ export class ProgressController {

const timeoutError = new TimeoutError(`Timeout ${this._timeout}ms exceeded.`);
const timer = setTimeout(() => this._forceAbort(timeoutError), progress.timeUntilDeadline());
const startTime = monotonicTime();
try {
const promise = task(progress);
const result = await Promise.race([promise, this._forceAbortPromise]);
clearTimeout(timer);
this._state = 'finished';
await this.instrumentation.onAfterAction({
startTime,
endTime: monotonicTime(),
logs: this._logRecording,
}, this.sdkObject, this.metadata);
this._logRecording = [];
this.metadata.endTime = monotonicTime();
await this.instrumentation.onAfterAction(this.sdkObject, this.metadata);
return result;
} catch (e) {
clearTimeout(timer);
this._state = 'aborted';
await Promise.all(this._cleanups.splice(0).map(cleanup => runCleanup(cleanup)));
await this.instrumentation.onAfterAction({
startTime,
endTime: monotonicTime(),
logs: this._logRecording,
error: e,
}, this.sdkObject, this.metadata);
this.metadata.endTime = monotonicTime();
this.metadata.error = e;
await this.instrumentation.onAfterAction(this.sdkObject, this.metadata);
rewriteErrorMessage(e,
e.message +
formatLogRecording(this._logRecording) +
formatLogRecording(this.metadata.log) +
kLoggingNote);
this._logRecording = [];
throw e;
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/server/supplements/inspectorController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { BrowserContext } from '../browserContext';
import { isDebugMode } from '../../utils/utils';
import { RecorderSupplement } from './recorderSupplement';
import { InstrumentationListener } from '../instrumentation';
import { debugLogger } from '../../utils/debugLogger';

export class InspectorController implements InstrumentationListener {
async onContextCreated(context: BrowserContext): Promise<void> {
Expand All @@ -28,4 +29,8 @@ export class InspectorController implements InstrumentationListener {
});
}
}

onLog(logName: string, message: string): void {
debugLogger.log(logName as any, message);
}
}
16 changes: 8 additions & 8 deletions src/trace/tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { helper, RegisteredListener } from '../server/helper';
import { Dialog } from '../server/dialog';
import { Frame, NavigationEvent } from '../server/frames';
import { snapshotScript } from './snapshotterInjected';
import { ActionResult, CallMetadata, InstrumentationListener, SdkObject } from '../server/instrumentation';
import { CallMetadata, InstrumentationListener, SdkObject } from '../server/instrumentation';

const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs));
const fsAppendFileAsync = util.promisify(fs.appendFile.bind(fs));
Expand Down Expand Up @@ -59,8 +59,8 @@ export class Tracer implements InstrumentationListener {
this._contextTracers.get(sdkObject.attribution.context!)?.onActionCheckpoint(name, sdkObject, metadata);
}

async onAfterAction(result: ActionResult, sdkObject: SdkObject, metadata: CallMetadata): Promise<void> {
this._contextTracers.get(sdkObject.attribution.context!)?.onAfterAction(result, sdkObject, metadata);
async onAfterAction(sdkObject: SdkObject, metadata: CallMetadata): Promise<void> {
this._contextTracers.get(sdkObject.attribution.context!)?.onAfterAction(sdkObject, metadata);
}
}

Expand Down Expand Up @@ -160,7 +160,7 @@ class ContextTracer implements SnapshotterDelegate {
await this._snapshotter.forceSnapshot(sdkObject.attribution.page, snapshotId);
}

async onAfterAction(result: ActionResult, sdkObject: SdkObject, metadata: CallMetadata): Promise<void> {
async onAfterAction(sdkObject: SdkObject, metadata: CallMetadata): Promise<void> {
if (!sdkObject.attribution.page)
return;
const event: trace.ActionTraceEvent = {
Expand All @@ -173,10 +173,10 @@ class ContextTracer implements SnapshotterDelegate {
// FIXME: filter out evaluation snippets, binary
params: metadata.params,
stack: metadata.stack,
startTime: result.startTime,
endTime: result.endTime,
logs: result.logs.slice(),
error: result.error ? result.error.stack : undefined,
startTime: metadata.startTime,
endTime: metadata.endTime,
logs: metadata.log.slice(),
error: metadata.error ? metadata.error.stack : undefined,
snapshots: snapshotsForMetadata(metadata),
};
this._appendTraceEvent(event);
Expand Down
2 changes: 1 addition & 1 deletion utils/check_deps.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ DEPS['src/install/'] = ['src/utils/'];
// Client depends on chromium protocol for types.
DEPS['src/client/'] = ['src/common/', 'src/utils/', 'src/protocol/', 'src/server/chromium/protocol.ts'];

DEPS['src/dispatchers/'] = ['src/utils/', 'src/protocol/', 'src/server/**'];
DEPS['src/dispatchers/'] = ['src/common/', 'src/utils/', 'src/protocol/', 'src/server/**'];

// Generic dependencies for server-side code.
DEPS['src/server/'] = [
Expand Down