[scout] custom logger + clients as singleton (#208435)

## Summary

Adding custom `ScoutLogger` class to use across its services so that we
can better read logs related only to test framework runner.
We can also later migrate from `ToolingLog` to something better
integrated with Playwright to unify logs from different levels
https://github.com/elastic/kibana/issues/203591

To make sure we use the same instance, I converted few core services
(logger, kbnClient, esClient, esArchiver) to singletons.


Log output example:

```
Running 1 test using 1 worker

› should allow removing the dashboard panel after the underlying saved search has been deleted @svlSecurity @svlOblt @svlSearch @ess
 debg [scout] [service] logger
 info [scout] [config] Reading test servers confiuration from file: /Users/dmle/github/kibana/.scout/servers/local.json
 debg [scout] [service] config
 debg [scout] [service] esClient
 debg [scout] [service] kbnClient
 debg [scout] [service] esArchiver
 debg [scout] [service] uiSettings
 debg [scout] Requesting url (redacted): [http://localhost:5620/api/status]
 info [scout] [x-pack/test/functional/es_archives/logstash_functional] Loading "mappings.json"
 info [scout] [x-pack/test/functional/es_archives/logstash_functional] Loading "data.json.gz"
 info [scout] [x-pack/test/functional/es_archives/logstash_functional] Skipped restore for existing index "logstash-2015.09.22"
 info [scout] [x-pack/test/functional/es_archives/logstash_functional] Skipped restore for existing index "logstash-2015.09.20"
 info [scout] [x-pack/test/functional/es_archives/logstash_functional] Skipped restore for existing index "logstash-2015.09.21"
```
This commit is contained in:
Dzmitry Lemechko 2025-01-29 16:20:43 +01:00 committed by GitHub
parent 6a39afdede
commit 38fc6344c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 155 additions and 126 deletions

View file

@ -28,4 +28,11 @@ export type {
ScoutParallelWorkerFixtures,
} from './src/playwright';
export type { Client, KbnClient, KibanaUrl, SamlSessionManager, ToolingLog } from './src/types';
export type {
EsClient,
KbnClient,
KibanaUrl,
ScoutLogger,
ScoutServerConfig,
ScoutTestConfig,
} from './src/types';

View file

@ -7,17 +7,16 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { KbnClient, createEsClientForTesting } from '@kbn/test';
import type { ToolingLog } from '@kbn/tooling-log';
import { ScoutTestConfig } from '../../types';
import { serviceLoadedMsg } from '../../playwright/utils';
import { createEsClientForTesting, KbnClient } from '@kbn/test';
import { ScoutLogger } from './logger';
import { ScoutTestConfig, EsClient } from '../../types';
interface ClientOptions {
serviceName: string;
url: string;
username: string;
password: string;
log: ToolingLog;
log: ScoutLogger;
}
function createClientUrlWithAuth({ serviceName, url, username, password, log }: ClientOptions) {
@ -25,34 +24,45 @@ function createClientUrlWithAuth({ serviceName, url, username, password, log }:
clientUrl.username = username;
clientUrl.password = password;
log.debug(serviceLoadedMsg(`${serviceName}client`));
log.serviceLoaded(`${serviceName}Client`);
return clientUrl.toString();
}
export function createEsClient(config: ScoutTestConfig, log: ToolingLog) {
const { username, password } = config.auth;
const elasticsearchUrl = createClientUrlWithAuth({
serviceName: 'Es',
url: config.hosts.elasticsearch,
username,
password,
log,
});
let esClientInstance: EsClient | null = null;
let kbnClientInstance: KbnClient | null = null;
return createEsClientForTesting({
esUrl: elasticsearchUrl,
authOverride: { username, password },
});
export function getEsClient(config: ScoutTestConfig, log: ScoutLogger) {
if (!esClientInstance) {
const { username, password } = config.auth;
const elasticsearchUrl = createClientUrlWithAuth({
serviceName: 'es',
url: config.hosts.elasticsearch,
username,
password,
log,
});
esClientInstance = createEsClientForTesting({
esUrl: elasticsearchUrl,
authOverride: { username, password },
});
}
return esClientInstance;
}
export function createKbnClient(config: ScoutTestConfig, log: ToolingLog) {
const kibanaUrl = createClientUrlWithAuth({
serviceName: 'Kbn',
url: config.hosts.kibana,
username: config.auth.username,
password: config.auth.password,
log,
});
export function getKbnClient(config: ScoutTestConfig, log: ScoutLogger) {
if (!kbnClientInstance) {
const kibanaUrl = createClientUrlWithAuth({
serviceName: 'kbn',
url: config.hosts.kibana,
username: config.auth.username,
password: config.auth.password,
log,
});
return new KbnClient({ log, url: kibanaUrl });
kbnClientInstance = new KbnClient({ log, url: kibanaUrl });
}
return kbnClientInstance;
}

View file

@ -9,21 +9,23 @@
import path from 'path';
import fs from 'fs';
import { ToolingLog } from '@kbn/tooling-log';
import { ScoutTestConfig } from '../../types';
import { serviceLoadedMsg } from '../../playwright/utils';
import { ScoutLogger, ScoutTestConfig } from '../../types';
export function createScoutConfig(configDir: string, configName: string, log: ToolingLog) {
export function createScoutConfig(
configDir: string,
configName: string,
log: ScoutLogger
): ScoutTestConfig {
if (!configDir || !fs.existsSync(configDir)) {
throw new Error(`Directory with servers configuration is missing`);
}
const configPath = path.join(configDir, `${configName}.json`);
log.info(`Reading test servers confiuration from file: ${configPath}`);
log.info(`[config] Reading test servers confiuration from file: ${configPath}`);
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as ScoutTestConfig;
log.debug(serviceLoadedMsg('config'));
log.serviceLoaded('config');
return config;
}

View file

@ -7,22 +7,24 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { Client } from '@elastic/elasticsearch';
import { EsArchiver } from '@kbn/es-archiver';
import { REPO_ROOT } from '@kbn/repo-info';
import type { KbnClient } from '@kbn/test';
import type { ToolingLog } from '@kbn/tooling-log';
import { serviceLoadedMsg } from '../../playwright/utils';
import { ScoutLogger } from './logger';
import { EsClient, KbnClient } from '../../types';
export function createEsArchiver(esClient: Client, kbnClient: KbnClient, log: ToolingLog) {
const esArchiver = new EsArchiver({
log,
client: esClient,
kbnClient,
baseDir: REPO_ROOT,
});
let esArchiverInstance: EsArchiver | undefined;
log.debug(serviceLoadedMsg('esArchiver'));
export function getEsArchiver(esClient: EsClient, kbnClient: KbnClient, log: ScoutLogger) {
if (!esArchiverInstance) {
esArchiverInstance = new EsArchiver({
log,
client: esClient,
kbnClient,
baseDir: REPO_ROOT,
});
return esArchiver;
log.serviceLoaded('esArchiver');
}
return esArchiverInstance;
}

View file

@ -7,11 +7,15 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
export { createEsClient, createKbnClient } from './clients';
export { getEsClient, getKbnClient } from './clients';
export { createScoutConfig } from './config';
export { createEsArchiver } from './es_archiver';
export { getEsArchiver } from './es_archiver';
export { createKbnUrl } from './kibana_url';
export { createSamlSessionManager } from './saml_auth';
export { createLogger } from './logger';
export { getLogger } from './logger';
export type { KibanaUrl } from './kibana_url';
export type { SamlSessionManager } from '@kbn/test';
export type { ScoutLogger } from './logger';
export type { KbnClient } from '@kbn/test';
export type { Client as EsClient } from '@elastic/elasticsearch';

View file

@ -7,9 +7,8 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import type { ToolingLog } from '@kbn/tooling-log';
import { ScoutTestConfig } from '../../types';
import { serviceLoadedMsg } from '../../playwright/utils';
import { ScoutLogger } from './logger';
export interface PathOptions {
/**
@ -65,10 +64,10 @@ export class KibanaUrl {
}
}
export function createKbnUrl(scoutConfig: ScoutTestConfig, log: ToolingLog) {
export function createKbnUrl(scoutConfig: ScoutTestConfig, log: ScoutLogger) {
const kbnUrl = new KibanaUrl(new URL(scoutConfig.hosts.kibana));
log.debug(serviceLoadedMsg('kbnUrl'));
log.serviceLoaded('kbnUrl');
return kbnUrl;
}

View file

@ -8,12 +8,32 @@
*/
import { ToolingLog } from '@kbn/tooling-log';
import { serviceLoadedMsg } from '../../playwright/utils';
export function createLogger() {
const log = new ToolingLog({ level: 'verbose', writeTo: process.stdout });
export class ScoutLogger extends ToolingLog {
constructor() {
super({ level: 'verbose', writeTo: process.stdout }, { context: 'scout' });
this.serviceLoaded('logger');
}
log.debug(serviceLoadedMsg('logger'));
return log;
/**
* Used to log when a service/fixture is loaded
* @param name unique name of the service
*/
public serviceLoaded(name: string) {
this.debug(`[service] ${name}`);
}
}
let loggerInstance: ScoutLogger | null = null;
/**
* Singleton logger instance to share across the Scout components
* @returns {ScoutLogger}
*/
export function getLogger(): ScoutLogger {
if (!loggerInstance) {
loggerInstance = new ScoutLogger();
}
return loggerInstance;
}

View file

@ -16,10 +16,9 @@ import {
} from '@kbn/es';
import { REPO_ROOT } from '@kbn/repo-info';
import { HostOptions, SamlSessionManager } from '@kbn/test';
import { ToolingLog } from '@kbn/tooling-log';
import { ScoutTestConfig } from '../../types';
import { Protocol } from '../../playwright/types';
import { serviceLoadedMsg } from '../../playwright/utils';
import { ScoutLogger } from './logger';
const getResourceDirPath = (config: ScoutTestConfig) => {
return config.serverless
@ -43,7 +42,7 @@ const createKibanaHostOptions = (config: ScoutTestConfig): HostOptions => {
export const createSamlSessionManager = (
config: ScoutTestConfig,
log: ToolingLog
log: ScoutLogger
): SamlSessionManager => {
const resourceDirPath = getResourceDirPath(config);
const rolesDefinitionPath = path.resolve(resourceDirPath, 'roles.yml');
@ -65,7 +64,7 @@ export const createSamlSessionManager = (
cloudUsersFilePath: config.cloudUsersFilePath,
});
log.debug(serviceLoadedMsg('samlAuth'));
log.serviceLoaded('samlAuth');
return sessionManager;
};

View file

@ -13,9 +13,9 @@ import type {
EsClient,
KbnClient,
KibanaUrl,
ScoutLogger,
ScoutSpaceParallelFixture,
ScoutTestConfig,
ToolingLog,
} from './worker';
import {
scoutPageParallelFixture,
@ -43,7 +43,7 @@ export interface ScoutParallelTestFixtures {
}
export interface ScoutParallelWorkerFixtures {
log: ToolingLog;
log: ScoutLogger;
config: ScoutTestConfig;
kbnUrl: KibanaUrl;
kbnClient: KbnClient;

View file

@ -14,8 +14,8 @@ import type {
EsClient,
KbnClient,
KibanaUrl,
ScoutLogger,
ScoutTestConfig,
ToolingLog,
UiSettingsFixture,
} from './worker';
import {
@ -48,7 +48,7 @@ export interface ScoutTestFixtures {
}
export interface ScoutWorkerFixtures {
log: ToolingLog;
log: ScoutLogger;
config: ScoutTestConfig;
kbnUrl: KibanaUrl;
kbnClient: KbnClient;

View file

@ -9,7 +9,6 @@
import { BrowserAuthFixture, LoginFunction } from '.';
import { PROJECT_DEFAULT_ROLES } from '../../../../common';
import { serviceLoadedMsg } from '../../../utils';
import { coreWorkerFixtures } from '../../worker';
import { ScoutSpaceParallelFixture } from '../../worker/scout_space';
@ -50,7 +49,7 @@ export const browserAuthParallelFixture = coreWorkerFixtures.extend<
return loginAs(roleName);
};
log.debug(serviceLoadedMsg(`browserAuth:${scoutSpace.id}`));
log.serviceLoaded(`browserAuth:${scoutSpace.id}`);
await use({ loginAsAdmin, loginAsViewer, loginAsPrivilegedUser });
},
});

View file

@ -8,7 +8,6 @@
*/
import { PROJECT_DEFAULT_ROLES } from '../../../../common';
import { serviceLoadedMsg } from '../../../utils';
import { coreWorkerFixtures } from '../../worker';
import { BrowserAuthFixture, LoginFunction } from '.';
@ -45,7 +44,7 @@ export const browserAuthFixture = coreWorkerFixtures.extend<{ browserAuth: Brows
return loginAs(roleName);
};
log.debug(serviceLoadedMsg('browserAuth'));
log.serviceLoaded('browserAuth');
await use({ loginAsAdmin, loginAsViewer, loginAsPrivilegedUser });
},
});

View file

@ -8,7 +8,6 @@
*/
import { PageObjects, createCorePageObjects } from '../../../page_objects';
import { serviceLoadedMsg } from '../../../utils';
import { ScoutSpaceParallelFixture } from '../../worker';
import { scoutPageParallelFixture } from '../scout_page';
@ -28,7 +27,7 @@ export const pageObjectsParallelFixture = scoutPageParallelFixture.extend<
>({
pageObjects: async ({ page, log, scoutSpace }, use) => {
const corePageObjects = createCorePageObjects(page);
log.debug(serviceLoadedMsg(`pageObjects:${scoutSpace.id}`));
log.serviceLoaded(`pageObjects:${scoutSpace.id}`);
await use(corePageObjects);
},
});

View file

@ -8,7 +8,6 @@
*/
import { PageObjects, createCorePageObjects } from '../../../page_objects';
import { serviceLoadedMsg } from '../../../utils';
import { scoutPageFixture } from '../scout_page';
/**
@ -24,7 +23,7 @@ export const pageObjectsFixture = scoutPageFixture.extend<{
}>({
pageObjects: async ({ page, log }, use) => {
const corePageObjects = createCorePageObjects(page);
log.debug(serviceLoadedMsg(`pageObjects`));
log.serviceLoaded('pageObjects');
await use(corePageObjects);
},
});

View file

@ -9,14 +9,13 @@
import { Page, test as base } from '@playwright/test';
import { ScoutPage } from '.';
import { KibanaUrl, ToolingLog } from '../../worker';
import { KibanaUrl, ScoutLogger } from '../../worker';
import { ScoutSpaceParallelFixture } from '../../worker/scout_space';
import { extendPlaywrightPage } from './single_thread';
import { serviceLoadedMsg } from '../../../utils';
export const scoutPageParallelFixture = base.extend<
{ page: ScoutPage },
{ log: ToolingLog; kbnUrl: KibanaUrl; scoutSpace: ScoutSpaceParallelFixture }
{ log: ScoutLogger; kbnUrl: KibanaUrl; scoutSpace: ScoutSpaceParallelFixture }
>({
page: async (
{
@ -24,7 +23,7 @@ export const scoutPageParallelFixture = base.extend<
page,
kbnUrl,
scoutSpace,
}: { log: ToolingLog; page: Page; kbnUrl: KibanaUrl; scoutSpace: ScoutSpaceParallelFixture },
}: { log: ScoutLogger; page: Page; kbnUrl: KibanaUrl; scoutSpace: ScoutSpaceParallelFixture },
use: (extendedPage: ScoutPage) => Promise<void>
) => {
const extendedPage = extendPlaywrightPage({ page, kbnUrl });
@ -33,7 +32,7 @@ export const scoutPageParallelFixture = base.extend<
extendedPage.gotoApp = (appName: string) =>
page.goto(kbnUrl.app(appName, { space: scoutSpace.id }));
log.debug(serviceLoadedMsg(`scoutPage:${scoutSpace.id}`));
log.serviceLoaded(`scoutPage:${scoutSpace.id}`);
await use(extendedPage);
},
});

View file

@ -9,9 +9,8 @@
import { Page } from '@playwright/test';
import { subj } from '@kbn/test-subj-selector';
import { KibanaUrl, ToolingLog, coreWorkerFixtures } from '../../worker';
import { KibanaUrl, ScoutLogger, coreWorkerFixtures } from '../../worker';
import { ScoutPage } from '.';
import { serviceLoadedMsg } from '../../../utils';
/**
* Instead of defining each method individually, we use a list of method names and loop through them, creating methods dynamically.
@ -118,16 +117,16 @@ export function extendPlaywrightPage({
* ```
*/
export const scoutPageFixture = coreWorkerFixtures.extend<
{ page: ScoutPage; log: ToolingLog },
{ page: ScoutPage; log: ScoutLogger },
{ kbnUrl: KibanaUrl }
>({
page: async (
{ page, kbnUrl, log }: { page: Page; kbnUrl: KibanaUrl; log: ToolingLog },
{ page, kbnUrl, log }: { page: Page; kbnUrl: KibanaUrl; log: ScoutLogger },
use: (extendedPage: ScoutPage) => Promise<void>
) => {
const extendedPage = extendPlaywrightPage({ page, kbnUrl });
log.debug(serviceLoadedMsg(`scoutPage`));
log.serviceLoaded('scoutPage');
await use(extendedPage);
},
});

View file

@ -8,26 +8,24 @@
*/
import { test as base } from '@playwright/test';
import type { ToolingLog } from '@kbn/tooling-log';
import { KbnClient, SamlSessionManager } from '@kbn/test';
import { Client } from '@elastic/elasticsearch';
import {
createKbnUrl,
createEsClient,
createKbnClient,
createLogger,
getEsClient,
getKbnClient,
getLogger,
createSamlSessionManager,
createScoutConfig,
KibanaUrl,
} from '../../../common/services';
import { ScoutTestOptions } from '../../types';
import { ScoutTestConfig } from '.';
import { ScoutLogger } from '../../../common';
// re-export to import types from '@kbn-scout'
export type { KbnClient, SamlSessionManager } from '@kbn/test';
export type { ToolingLog } from '@kbn/tooling-log';
export type { ScoutLogger } from '../../../common';
export type { Client as EsClient } from '@elastic/elasticsearch';
export type { KibanaUrl } from '../../../common/services/kibana_url';
export type { ScoutTestConfig } from '../../../types';
@ -42,7 +40,7 @@ export type { ScoutTestConfig } from '../../../types';
export const coreWorkerFixtures = base.extend<
{},
{
log: ToolingLog;
log: ScoutLogger;
config: ScoutTestConfig;
kbnUrl: KibanaUrl;
esClient: Client;
@ -54,7 +52,7 @@ export const coreWorkerFixtures = base.extend<
// all other fixtures within the worker scope.
log: [
({}, use) => {
use(createLogger());
use(getLogger());
},
{ scope: 'worker' },
],
@ -92,7 +90,7 @@ export const coreWorkerFixtures = base.extend<
*/
esClient: [
({ config, log }, use) => {
use(createEsClient(config, log));
use(getEsClient(config, log));
},
{ scope: 'worker' },
],
@ -102,7 +100,7 @@ export const coreWorkerFixtures = base.extend<
*/
kbnClient: [
({ log, config }, use) => {
use(createKbnClient(config, log));
use(getKbnClient(config, log));
},
{ scope: 'worker' },
],

View file

@ -10,7 +10,7 @@
import { LoadActionPerfOptions } from '@kbn/es-archiver';
import { IndexStats } from '@kbn/es-archiver/src/lib/stats';
import { coreWorkerFixtures } from './core_fixtures';
import { createEsArchiver } from '../../../common/services';
import { getEsArchiver } from '../../../common/services';
export interface EsArchiverFixture {
/**
@ -37,7 +37,7 @@ export const esArchiverFixture = coreWorkerFixtures.extend<{}, { esArchiver: EsA
*/
esArchiver: [
({ log, esClient, kbnClient }, use) => {
const esArchiverInstance = createEsArchiver(esClient, kbnClient, log);
const esArchiverInstance = getEsArchiver(esClient, kbnClient, log);
const loadIfNeeded = async (name: string, performance?: LoadActionPerfOptions | undefined) =>
esArchiverInstance!.loadIfNeeded(name, performance);

View file

@ -9,7 +9,7 @@
export { coreWorkerFixtures } from './core_fixtures';
export type {
ToolingLog,
ScoutLogger,
ScoutTestConfig,
KibanaUrl,
EsClient,

View file

@ -8,7 +8,7 @@
*/
import { UiSettingValues } from '@kbn/test/src/kbn_client/kbn_client_ui_settings';
import { formatTime, isValidUTCDate, measurePerformance, serviceLoadedMsg } from '../../../utils';
import { formatTime, isValidUTCDate, measurePerformance } from '../../../utils';
import { coreWorkerFixtures } from '..';
import { ImportSavedObjects, ScoutSpaceParallelFixture } from '.';
@ -121,7 +121,7 @@ export const scoutSpaceParallelFixture = coreWorkerFixtures.extend<
setDefaultTime,
};
log.debug(serviceLoadedMsg(`scoutSpace:${spaceId}`));
log.serviceLoaded(`scoutSpace:${spaceId}`);
await use({ savedObjects, uiSettings, id: spaceId });
// Cleanup space after tests via API call

View file

@ -8,7 +8,7 @@
*/
import { UiSettingValues } from '@kbn/test/src/kbn_client/kbn_client_ui_settings';
import { isValidUTCDate, formatTime, serviceLoadedMsg } from '../../../utils';
import { isValidUTCDate, formatTime } from '../../../utils';
import { coreWorkerFixtures } from '../core_fixtures';
import { UiSettingsFixture } from '.';
@ -35,7 +35,7 @@ export const uiSettingsFixture = coreWorkerFixtures.extend<{}, { uiSettings: UiS
},
};
log.debug(serviceLoadedMsg(`uiSettings`));
log.serviceLoaded('uiSettings');
await use(kbnClientUiSettings);
},
{ scope: 'worker' },

View file

@ -9,35 +9,34 @@
import { FullConfig } from 'playwright/test';
import {
createEsArchiver,
createEsClient,
createKbnClient,
createLogger,
getLogger,
getEsArchiver,
createScoutConfig,
getEsClient,
getKbnClient,
} from '../../common';
import { ScoutTestOptions } from '../types';
import { measurePerformance } from '../utils';
export async function ingestTestDataHook(config: FullConfig, archives: string[]) {
const log = createLogger();
const log = getLogger();
if (archives.length === 0) {
log.info('[scout setup] no test data to ingest');
log.debug('[setup] no test data to ingest');
return;
}
return measurePerformance(log, '[scout setup]: ingestTestDataHook', async () => {
return measurePerformance(log, '[setup]: ingestTestDataHook', async () => {
// TODO: This should be configurable local vs cloud
const configName = 'local';
const projectUse = config.projects[0].use as ScoutTestOptions;
const serversConfigDir = projectUse.serversConfigDir;
const scoutConfig = createScoutConfig(serversConfigDir, configName, log);
const esClient = getEsClient(scoutConfig, log);
const kbnClient = getKbnClient(scoutConfig, log);
const esArchiver = getEsArchiver(esClient, kbnClient, log);
const esClient = createEsClient(scoutConfig, log);
const kbnCLient = createKbnClient(scoutConfig, log);
const esArchiver = createEsArchiver(esClient, kbnCLient, log);
log.info('[scout setup] loading test data (only if indexes do not exist)...');
log.debug('[setup] loading test data (only if indexes do not exist)...');
for (const archive of archives) {
await esArchiver.loadIfNeeded(archive);
}

View file

@ -7,5 +7,5 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
export { serviceLoadedMsg, isValidUTCDate, formatTime, getPlaywrightGrepTag } from './runner_utils';
export { isValidUTCDate, formatTime, getPlaywrightGrepTag } from './runner_utils';
export { measurePerformance } from './performance';

View file

@ -7,10 +7,10 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { ToolingLog } from '../../types';
import { ScoutLogger } from '../fixtures/worker';
export const measurePerformance = async <T>(
log: ToolingLog,
log: ScoutLogger,
label: string,
fn: () => Promise<T>
): Promise<T> => {

View file

@ -11,8 +11,6 @@ import moment from 'moment';
import { Config } from '../../config';
import { tagsByMode } from '../tags';
export const serviceLoadedMsg = (name: string) => `[scout service] ${name}`;
export const isValidUTCDate = (date: string): boolean => {
return !isNaN(Date.parse(date)) && new Date(date).toISOString() === date;
};

View file

@ -7,7 +7,4 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
export type { KbnClient, SamlSessionManager } from '@kbn/test';
export type { Client } from '@elastic/elasticsearch';
export type { KibanaUrl } from '../common/services';
export type { ToolingLog } from '@kbn/tooling-log';
export type { EsClient, KbnClient, KibanaUrl, SamlSessionManager, ScoutLogger } from '../common';