Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0b8d10f
Base service with receiving_telemetry check
epixa Dec 7, 2019
f896263
Shell of a pulse client in core
epixa Dec 8, 2019
cac89e5
Start of readme
epixa Dec 10, 2019
2899489
Basic client polling
epixa Dec 11, 2019
a2da5c3
fix service readme
epixa Dec 11, 2019
0027f51
remove incomplete client readme
epixa Dec 11, 2019
7013658
client: disallow channels mutation
epixa Dec 13, 2019
d4b9f09
create instructions observable from constructor arg
epixa Dec 13, 2019
d2078ac
client: using instructions provided by service
epixa Dec 13, 2019
3fb38ee
log pulse service startup
epixa Dec 13, 2019
99b265b
service: accept channel-based telemetry intake
epixa Dec 13, 2019
6b1ecd7
client: hardcoded telemetry collection
epixa Dec 13, 2019
451da7c
client: send telemetry
epixa Dec 13, 2019
3bd969b
client: expose pulse to plugins
epixa Dec 16, 2019
cb82e2d
client: channel names based on file system
epixa Dec 16, 2019
788c749
readme: document how to work on this POC
epixa Dec 16, 2019
362d071
readme: fix path links
epixa Dec 16, 2019
63cd7b9
Adds basic framework for the errors channel
TinaHeiligers Dec 17, 2019
af42ed3
Adds instructions to create index patterns
TinaHeiligers Dec 17, 2019
4152499
Reverts changes in plugin.ts
TinaHeiligers Dec 17, 2019
3586021
Merge branch 'pulse_poc' into pulse_poc_errors_channel
TinaHeiligers Dec 20, 2019
b8eaaa0
Removes content added to the README
TinaHeiligers Dec 20, 2019
b17b9d6
Removes dummy return content from errors channel getRecords
TinaHeiligers Dec 20, 2019
7066c8d
Merge branch 'pulse_poc' into pulse_poc_errors_channel
TinaHeiligers Jan 9, 2020
40e6a41
Done with adding changes from UI Notifications PR in x-pack/plugins/p…
TinaHeiligers Jan 10, 2020
de11350
Adds notifications collector to client
TinaHeiligers Jan 10, 2020
7833324
Updates changes from UI Notifications in errors collectors
TinaHeiligers Jan 11, 2020
bb031d6
Implements changes from UI notifications default collector and channe…
TinaHeiligers Jan 11, 2020
36778b9
Implements changes to src/core/server/pulse/index.ts from UI Notifica…
TinaHeiligers Jan 11, 2020
f90851b
Implements minor changes in server.ts from UI Notifications
TinaHeiligers Jan 11, 2020
a0acb4a
Implements more changes
TinaHeiligers Jan 11, 2020
f030b59
Implements changes in src/core/public from UI Notifications. Kibana n…
TinaHeiligers Jan 11, 2020
2cbbd19
Merge branch 'pulse_fixed_versions' into pulse_poc_errors_channel_wit…
TinaHeiligers Jan 11, 2020
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
7 changes: 7 additions & 0 deletions src/core/public/core_system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { ChromeService } from './chrome';
import { FatalErrorsService, FatalErrorsSetup } from './fatal_errors';
import { HttpService } from './http';
import { I18nService } from './i18n';
import { PulseService } from './pulse';
import {
InjectedMetadataParams,
InjectedMetadataService,
Expand Down Expand Up @@ -100,6 +101,7 @@ export class CoreSystem {
private readonly rendering: RenderingService;
private readonly context: ContextService;
private readonly integrations: IntegrationsService;
private readonly pulse: PulseService;

private readonly rootDomElement: HTMLElement;
private readonly coreContext: CoreContext;
Expand Down Expand Up @@ -137,6 +139,7 @@ export class CoreSystem {
this.rendering = new RenderingService();
this.application = new ApplicationService();
this.integrations = new IntegrationsService();
this.pulse = new PulseService();

this.coreContext = { coreId: Symbol('core'), env: injectedMetadata.env };

Expand All @@ -162,6 +165,7 @@ export class CoreSystem {
const http = this.http.setup({ injectedMetadata, fatalErrors: this.fatalErrorsSetup });
const uiSettings = this.uiSettings.setup({ http, injectedMetadata });
const notifications = this.notifications.setup({ uiSettings });
const pulse = await this.pulse.setup();

const pluginDependencies = this.plugins.getOpaqueIds();
const context = this.context.setup({
Expand All @@ -184,6 +188,7 @@ export class CoreSystem {
injectedMetadata,
notifications,
uiSettings,
pulse,
};

// Services that do not expose contracts at setup
Expand Down Expand Up @@ -216,6 +221,7 @@ export class CoreSystem {
const i18n = await this.i18n.start();
const application = await this.application.start({ http, injectedMetadata });
await this.integrations.start({ uiSettings });
const pulse = await this.pulse.start();

const coreUiTargetDomElement = document.createElement('div');
coreUiTargetDomElement.id = 'kibana-body';
Expand Down Expand Up @@ -271,6 +277,7 @@ export class CoreSystem {
notifications,
overlays,
uiSettings,
pulse,
};

const plugins = await this.plugins.start(core);
Expand Down
5 changes: 5 additions & 0 deletions src/core/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import { UiSettingsState, IUiSettingsClient } from './ui_settings';
import { ApplicationSetup, Capabilities, ApplicationStart } from './application';
import { DocLinksStart } from './doc_links';
import { SavedObjectsStart } from './saved_objects';
import { PulseServiceSetup, PulseServiceStart } from './pulse';
export { PackageInfo, EnvironmentMode } from '../server/types';
import {
IContextContainer,
Expand Down Expand Up @@ -177,6 +178,7 @@ export interface CoreSetup<TPluginsStart extends object = object> {
notifications: NotificationsSetup;
/** {@link IUiSettingsClient} */
uiSettings: IUiSettingsClient;
pulse: PulseServiceSetup;
/**
* exposed temporarily until https://github.com/elastic/kibana/issues/41990 done
* use *only* to retrieve config values. There is no way to set injected values
Expand Down Expand Up @@ -219,6 +221,7 @@ export interface CoreStart {
i18n: I18nStart;
/** {@link NotificationsStart} */
notifications: NotificationsStart;
pulse: PulseServiceStart;
/** {@link OverlayStart} */
overlays: OverlayStart;
/** {@link IUiSettingsClient} */
Expand Down Expand Up @@ -306,4 +309,6 @@ export {
PluginOpaqueId,
IUiSettingsClient,
UiSettingsState,
PulseServiceSetup,
PulseServiceStart,
};
2 changes: 2 additions & 0 deletions src/core/public/plugins/plugin_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export function createPluginSetupContext<
http: deps.http,
notifications: deps.notifications,
uiSettings: deps.uiSettings,
pulse: deps.pulse,
injectedMetadata: {
getInjectedVar: deps.injectedMetadata.getInjectedVar,
},
Expand Down Expand Up @@ -147,6 +148,7 @@ export function createPluginStartContext<
overlays: deps.overlays,
uiSettings: deps.uiSettings,
savedObjects: deps.savedObjects,
pulse: deps.pulse,
injectedMetadata: {
getInjectedVar: deps.injectedMetadata.getInjectedVar,
},
Expand Down
21 changes: 21 additions & 0 deletions src/core/public/pulse/channel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// eslint-disable-next-line @kbn/eslint/no-restricted-paths
export { PulseInstruction, PulseChannel } from '../../server/pulse/channel';
22 changes: 22 additions & 0 deletions src/core/public/pulse/collectors/default.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

export async function getRecords() {
return [{}];
}
22 changes: 22 additions & 0 deletions src/core/public/pulse/collectors/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

export async function getRecords() {
return [{}];
}
22 changes: 22 additions & 0 deletions src/core/public/pulse/collectors/notifications.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

export async function getRecords() {
return [{}];
}
153 changes: 153 additions & 0 deletions src/core/public/pulse/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { Subject } from 'rxjs';

// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { InstructionsResponse } from '../../server/pulse';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { PulseChannel, PulseInstruction } from './channel';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { Fetcher, sendPulse } from '../../server/pulse/send_pulse';

export interface PulseServiceSetup {
getChannel: (id: string) => PulseChannel;
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface PulseServiceStart {}

const channelNames = ['default', 'notifications', 'errors'];

export class PulseService {
private retriableErrors = 0;
private readonly channels: Map<string, PulseChannel>;
private readonly instructions: Map<string, Subject<any>> = new Map();

constructor() {
this.channels = new Map(
channelNames.map((id): [string, PulseChannel] => {
const instructions$ = new Subject<PulseInstruction>();
this.instructions.set(id, instructions$);
const channel = new PulseChannel({ id, instructions$ });
return [channel.id, channel];
})
);
}

public async setup(): Promise<PulseServiceSetup> {
// poll for instructions every second for this deployment
setInterval(() => {
// eslint-disable-next-line no-console
this.loadInstructions().catch(err => console.error(err.stack));
}, 10000);

// eslint-disable-next-line no-console
console.log('Will attempt first telemetry collection in 5 seconds...');
setTimeout(() => {
setInterval(() => {
// eslint-disable-next-line no-console
this.sendTelemetry().catch(err => console.error(err.stack));
}, 5000);
}, 5000);

return {
getChannel: (id: string) => {
const channel = this.channels.get(id);
if (!channel) {
throw new Error(`Unknown channel: ${id}`);
}
return channel;
},
};
}

private async sendTelemetry() {
const fetcher: Fetcher<Response> = async (url, channels) => {
return await fetch(url, {
method: 'post',

headers: {
'content-type': 'application/json',
'kbn-xsrf': 'true',
},
body: JSON.stringify({
channels,
}),
});
};

return await sendPulse(this.channels, fetcher);
}

private async loadInstructions() {
const url = 'http://localhost:5601/api/pulse_poc/instructions/123';
let response: any;
try {
response = await fetch(url);
} catch (err) {
if (!err.message.includes('ECONNREFUSED')) {
throw err;
}
this.handleRetriableError();
return;
}
if (response.status === 503) {
this.handleRetriableError();
return;
}

if (response.status !== 200) {
const responseBody = await response.text();
throw new Error(`${response.status}: ${responseBody}`);
}

const responseBody: InstructionsResponse = await response.json();

responseBody.channels.forEach(channel => {
const instructions$ = this.instructions.get(channel.id);
if (!instructions$) {
throw new Error(
`Channel (${channel.id}) from service has no corresponding channel handler in client`
);
}

channel.instructions.forEach(instruction => instructions$.next(instruction));
});
}

private handleRetriableError() {
this.retriableErrors++;
if (this.retriableErrors === 1) {
// eslint-disable-next-line no-console
console.warn(
'Kibana is not yet available at http://localhost:5601/api, will continue to check for the next 120 seconds...'
);
} else if (this.retriableErrors > 120) {
this.retriableErrors = 0;
}
}

async start(): Promise<PulseServiceStart> {
return {};
}
public stop() {
// nothing to do here currently
}
}
3 changes: 3 additions & 0 deletions src/core/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { IUiSettingsClient, UiSettingsServiceSetup, UiSettingsServiceStart } fro
import { SavedObjectsClientContract } from './saved_objects/types';
import { SavedObjectsServiceSetup, SavedObjectsServiceStart } from './saved_objects';
import { CapabilitiesSetup, CapabilitiesStart } from './capabilities';
import { PulseServiceSetup } from './pulse';
import { UuidServiceSetup } from './uuid';

export { bootstrap } from './bootstrap';
Expand Down Expand Up @@ -274,6 +275,7 @@ export interface CoreSetup {
/** {@link UiSettingsServiceSetup} */
uiSettings: UiSettingsServiceSetup;
/** {@link UuidServiceSetup} */
pulse: PulseServiceSetup;
uuid: UuidServiceSetup;
}

Expand All @@ -298,5 +300,6 @@ export {
PluginsServiceSetup,
PluginsServiceStart,
PluginOpaqueId,
PulseServiceSetup,
UuidServiceSetup,
};
1 change: 1 addition & 0 deletions src/core/server/legacy/legacy_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ export class LegacyService implements CoreService {
dataClient$: setupDeps.core.elasticsearch.dataClient$,
createClient: setupDeps.core.elasticsearch.createClient,
},
pulse: setupDeps.core.pulse,
http: {
createCookieSessionStorageFactory: setupDeps.core.http.createCookieSessionStorageFactory,
registerRouteHandlerContext: setupDeps.core.http.registerRouteHandlerContext.bind(
Expand Down
1 change: 1 addition & 0 deletions src/core/server/plugins/plugin_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
plugin: PluginWrapper<TPlugin, TPluginDependencies>
): CoreSetup {
return {
pulse: deps.pulse,
capabilities: {
registerProvider: deps.capabilities.registerProvider,
registerSwitcher: deps.capabilities.registerSwitcher,
Expand Down
Loading