Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/common_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ export type RunOptions = BaseArgs & {
playwrightOptions?: PlaywrightOptions;
networkConditions?: NetworkConditions;
reporter?: BuiltInReporterName | ReporterInstance;
apm?: ApmOptions;
};

export type PushOptions = ProjectSettings & {
Expand All @@ -254,12 +255,17 @@ export type ProjectSettings = {
space: string;
};

export type ApmOptions = {
origins: Array<string | RegExp>;
};

export type PlaywrightOptions = LaunchOptions & BrowserContextOptions;
export type SyntheticsConfig = {
params?: Params;
playwrightOptions?: PlaywrightOptions;
monitor?: MonitorConfig;
project?: ProjectSettings;
apm?: ApmOptions;
};

/** Runner Payload types */
Expand Down
3 changes: 2 additions & 1 deletion src/core/gatherer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,13 @@ export class Gatherer {
*/
static async beginRecording(driver: Driver, options: RunOptions) {
log('Gatherer: started recording');
const { network, metrics } = options;
const { network, metrics, apm } = options;
const pluginManager = new PluginManager(driver);
pluginManager.registerAll(options);
const plugins = [await pluginManager.start('browserconsole')];
network && plugins.push(await pluginManager.start('network'));
metrics && plugins.push(await pluginManager.start('performance'));
apm && plugins.push(await pluginManager.start('apm'));
await Promise.all(plugins);
return pluginManager;
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*
*/

import { randomBytes } from 'crypto';
import { join } from 'path';
import { mkdir, rm, writeFile } from 'fs/promises';
import { Journey } from '../dsl/journey';
Expand Down Expand Up @@ -50,6 +51,7 @@ import { PerformanceManager } from '../plugins';
import { Gatherer } from './gatherer';
import { log } from './logger';
import { Monitor, MonitorConfig } from '../dsl/monitor';
import { Request, Route } from 'playwright-core';

type HookType = 'beforeAll' | 'afterAll';
export type SuiteHooks = Record<HookType, Array<HooksCallback>>;
Expand Down
2 changes: 2 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ export function normalizeOptions(cliArgs: CliArgs): RunOptions {
options.privateLocations =
cliArgs.privateLocations ?? monitor?.privateLocations;

options.apm = config.apm;

return options;
}

Expand Down
58 changes: 58 additions & 0 deletions src/plugins/apm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* MIT License
*
* Copyright (c) 2020-present, Elastic NV
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

import { randomBytes } from 'crypto';
import { Request, Route } from 'playwright-core';
import { ApmOptions, Driver } from '../common_types';

export class Apm {
constructor(private driver: Driver, private options: ApmOptions) {}

async traceHandler(route: Route, request: Request) {
const traceId = randomBytes(16).toString('hex');
// We dont want to track Synthetics, so sending a dummy id
const parentId = '0'.repeat(16);
const traceparent = `00-${traceId}-${parentId}-01`;
const headers = {
...(await request.allHeaders()),
traceparent,
};
route.continue({
headers,
});
}

async start() {
for (const origin of this.options.origins) {
await this.driver.context.route(origin, this.traceHandler.bind(this));
}
}

async stop() {
for (const origin of this.options.origins) {
await this.driver.context.unroute(origin, this.traceHandler.bind(this));
}
}
}
1 change: 1 addition & 0 deletions src/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ export * from './network';
export * from './performance';
export * from './tracing';
export * from './browser-console';
export * from './apm';
25 changes: 21 additions & 4 deletions src/plugins/plugin-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
*
*/

import { PluginOutput, Driver } from '../common_types';
import { PluginOutput, Driver, ApmOptions } from '../common_types';
import {
Apm,
BrowserConsole,
NetworkManager,
PerformanceManager,
Expand All @@ -33,9 +34,21 @@ import {
} from './';
import { Step } from '../dsl';

type PluginType = 'network' | 'trace' | 'performance' | 'browserconsole';
type Plugin = NetworkManager | Tracing | PerformanceManager | BrowserConsole;
type PluginOptions = TraceOptions;
type PluginType =
| 'network'
| 'trace'
| 'performance'
| 'browserconsole'
| 'apm';
type Plugin =
| NetworkManager
| Tracing
| PerformanceManager
| BrowserConsole
| Apm;
type PluginOptions = TraceOptions & {
apm?: ApmOptions;
};

export class PluginManager {
protected plugins = new Map<PluginType, Plugin>();
Expand All @@ -44,6 +57,7 @@ export class PluginManager {
'trace',
'performance',
'browserconsole',
'apm',
];
constructor(private driver: Driver) {}

Expand All @@ -62,6 +76,9 @@ export class PluginManager {
case 'browserconsole':
instance = new BrowserConsole(this.driver);
break;
case 'apm':
instance = new Apm(this.driver, options.apm);
break;
}
instance && this.plugins.set(type, instance);
return instance;
Expand Down