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

[Monitoring] APM Monitoring UI #22975

Merged
merged 30 commits into from
Sep 24, 2018
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8b510a2
Merge in boilerplate branch
chrisronline Sep 12, 2018
004ba9e
Manually copy over the specific metrics and UIs
chrisronline Sep 12, 2018
bbc0f9b
Add api integration tests
chrisronline Aug 31, 2018
5408598
Fix tests
chrisronline Sep 12, 2018
39783b0
Remove unused metrics
chrisronline Sep 12, 2018
807037f
Update snapshot
chrisronline Sep 13, 2018
6b50192
Fix tests
chrisronline Sep 13, 2018
bb65e55
Merge remote-tracking branch 'elastic/master' into monitoring_apm_ui
chrisronline Sep 19, 2018
b1d744d
Remove types agg
chrisronline Sep 19, 2018
512a8f7
Use ApmClusterMetric
chrisronline Sep 19, 2018
488829d
provide description for apm-server monitoring metrics (#23331)
graphaelli Sep 19, 2018
0e9329d
Vis LESS to SASS (cont.) (#23199)
cchaos Sep 19, 2018
75d8472
Tweak migrations integraiton tests to have a stable sort (#23265)
chrisdavies Sep 19, 2018
434c0bd
Fix: plugin api route with security enabled (#23334)
w33ble Sep 19, 2018
ab91dda
[migrations/tests] sort results before assertion (#23347)
Sep 20, 2018
91871c1
[ML] Moves custom URL editor Add button and form to top of flyout (#2…
peteharverson Sep 20, 2018
65797d8
Graph LESS to SASS (#23348)
cchaos Sep 20, 2018
210eacb
Developer documentation for integrating with the telemetry service (#…
tsullivan Sep 20, 2018
ab2062c
Fix a bug where ES sends a string and migrations expect a boolean (#2…
chrisdavies Sep 20, 2018
c90443f
chore: use cheerio in i18n.html.getDirectiveMessages (#23342)
w33ble Sep 20, 2018
0cc2b61
[core/utils] add shareWeakReplay() operator (#23333)
Sep 20, 2018
54ba953
Chore: fix canvas test runner (#23336)
w33ble Sep 20, 2018
6fdf6ad
Convert Discover open top nav to EUI flyout (#22971)
nreese Sep 20, 2018
236c0e9
Migrate save top nav in Discover and Visualize to EUI (#23190)
nreese Sep 20, 2018
6829db6
Moves styleSheetPath to uiExports (#23007)
tylersmalley Sep 21, 2018
0de2a64
Timelion less to sass (#23339)
cchaos Sep 21, 2018
2c7d140
Consistent casing
chrisronline Sep 21, 2018
699629c
Merge remote-tracking branch 'elastic/master' into monitoring_apm_ui
chrisronline Sep 21, 2018
4ee344e
Fix snapshot
chrisronline Sep 24, 2018
6a7ce25
Update tests
chrisronline Sep 24, 2018
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
22 changes: 0 additions & 22 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -185,25 +185,3 @@ 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.

---
This product uses "radioactive button" styles that were published on
https://zurb.com/playground/radioactive-buttons under an "MIT" License.

Copyright (c) ZURB
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.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,6 @@
"jest-cli": "^23.5.0",
"jest-raw-loader": "^1.0.1",
"jimp": "0.2.28",
"jsdom": "9.9.1",
"json5": "^1.0.1",
"karma": "1.7.0",
"karma-chrome-launcher": "2.1.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/kbn-plugin-generator/sao_template/template/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ export default function (kibana) {
title: '<%= startCase(name) %>',
description: '<%= description %>',
main: 'plugins/<%= snakeCase(name) %>/app',
<%_ if (generateScss) { -%>
styleSheetPath: require('path').resolve(__dirname, 'public/app.scss'),
<%_ } -%>
},
<%_ } -%>
<%_ if (generateHack) { -%>
hacks: [
'plugins/<%= snakeCase(name) %>/hack'
]
<%_ } -%>
<%_ if (generateScss) { -%>
styleSheetPaths: require('path').resolve(__dirname, 'public/app.scss'),
<%_ } -%>
},

config(Joi) {
Expand Down
1 change: 1 addition & 0 deletions src/core/public/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
*/

export { modifyUrl } from './modify_url';
export { shareWeakReplay } from './share_weak_replay';
243 changes: 243 additions & 0 deletions src/core/public/utils/share_weak_replay.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
/*
* 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 * as Rx from 'rxjs';
import { map, materialize, take, toArray } from 'rxjs/operators';

import { shareWeakReplay } from './share_weak_replay';

let completedCounts = 0;

function counter({ async = true }: { async?: boolean } = {}) {
let subCounter = 0;

function sendCount(subscriber: Rx.Subscriber<string>) {
let notifCounter = 0;
const sub = ++subCounter;

while (!subscriber.closed) {
subscriber.next(`${sub}:${++notifCounter}`);
}

completedCounts += 1;
}

return new Rx.Observable<string>(subscriber => {
if (!async) {
sendCount(subscriber);
return;
}

const id = setTimeout(() => sendCount(subscriber));
return () => clearTimeout(id);
});
}

async function record<T>(observable: Rx.Observable<T>) {
return observable
.pipe(
materialize(),
map(n => (n.kind === 'N' ? `N:${n.value}` : n.kind === 'E' ? `E:${n.error.message}` : 'C')),
toArray()
)
.toPromise();
}

afterEach(() => {
completedCounts = 0;
});

it('multicasts an observable to multiple children, unsubs once all children do, and resubscribes on next subscription', async () => {
const shared = counter().pipe(shareWeakReplay(1));

await expect(Promise.all([record(shared.pipe(take(1))), record(shared.pipe(take(2)))])).resolves
.toMatchInlineSnapshot(`
Array [
Array [
"N:1:1",
"C",
],
Array [
"N:1:1",
"N:1:2",
"C",
],
]
`);

await expect(Promise.all([record(shared.pipe(take(3))), record(shared.pipe(take(4)))])).resolves
.toMatchInlineSnapshot(`
Array [
Array [
"N:2:1",
"N:2:2",
"N:2:3",
"C",
],
Array [
"N:2:1",
"N:2:2",
"N:2:3",
"N:2:4",
"C",
],
]
`);

expect(completedCounts).toBe(2);
});

it('resubscribes if parent errors', async () => {
let errorCounter = 0;
const shared = counter().pipe(
map((v, i) => {
if (i === 3) {
throw new Error(`error ${++errorCounter}`);
}
return v;
}),
shareWeakReplay(2)
);

await expect(Promise.all([record(shared), record(shared)])).resolves.toMatchInlineSnapshot(`
Array [
Array [
"N:1:1",
"N:1:2",
"N:1:3",
"E:error 1",
],
Array [
"N:1:1",
"N:1:2",
"N:1:3",
"E:error 1",
],
]
`);

await expect(Promise.all([record(shared), record(shared)])).resolves.toMatchInlineSnapshot(`
Array [
Array [
"N:2:1",
"N:2:2",
"N:2:3",
"E:error 2",
],
Array [
"N:2:1",
"N:2:2",
"N:2:3",
"E:error 2",
],
]
`);

expect(completedCounts).toBe(2);
});

it('resubscribes if parent completes', async () => {
const shared = counter().pipe(
take(4),
shareWeakReplay(4)
);

await expect(Promise.all([record(shared.pipe(take(1))), record(shared)])).resolves
.toMatchInlineSnapshot(`
Array [
Array [
"N:1:1",
"C",
],
Array [
"N:1:1",
"N:1:2",
"N:1:3",
"N:1:4",
"C",
],
]
`);

await expect(Promise.all([record(shared.pipe(take(2))), record(shared)])).resolves
.toMatchInlineSnapshot(`
Array [
Array [
"N:2:1",
"N:2:2",
"C",
],
Array [
"N:2:1",
"N:2:2",
"N:2:3",
"N:2:4",
"C",
],
]
`);

expect(completedCounts).toBe(2);
});

it('supports parents that complete synchronously', async () => {
const next = jest.fn();
const complete = jest.fn();
const shared = counter({ async: false }).pipe(
take(3),
shareWeakReplay(1)
);

shared.subscribe({ next, complete });
expect(next.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"1:1",
],
Array [
"1:2",
],
Array [
"1:3",
],
]
`);
expect(complete).toHaveBeenCalledTimes(1);

next.mockClear();
complete.mockClear();

shared.subscribe({ next, complete });
expect(next.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"2:1",
],
Array [
"2:2",
],
Array [
"2:3",
],
]
`);
expect(complete).toHaveBeenCalledTimes(1);

expect(completedCounts).toBe(2);
});
66 changes: 66 additions & 0 deletions src/core/public/utils/share_weak_replay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* 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 * as Rx from 'rxjs';
import { takeUntil } from 'rxjs/operators';

/**
* Just like the [`shareReplay()`](https://rxjs-dev.firebaseapp.com/api/operators/shareReplay) operator from
* RxJS except for a few key differences:
*
* - If all downstream subscribers unsubscribe the source subscription will be unsubscribed.
*
* - Replay-ability is only maintained while the source is active, if it completes or errors
* then complete/error is sent to the current subscribers and the replay buffer is cleared.
*
* - Any subscription after the the source completes or errors will create a new subscription
* to the source observable.
*
* @param bufferSize Optional, default is `Number.POSITIVE_INFINITY`
*/
export function shareWeakReplay<T>(bufferSize?: number): Rx.MonoTypeOperatorFunction<T> {
return (source: Rx.Observable<T>) => {
let subject: Rx.ReplaySubject<T> | undefined;
const stop$ = new Rx.Subject();

return new Rx.Observable(observer => {
if (!subject) {
subject = new Rx.ReplaySubject<T>(bufferSize);
}

subject.subscribe(observer).add(() => {
if (!subject) {
return;
}

if (subject.observers.length === 0) {
stop$.next();
}

if (subject.closed || subject.isStopped) {
subject = undefined;
}
});

if (subject && subject.observers.length === 1) {
source.pipe(takeUntil(stop$)).subscribe(subject);
}
});
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@

<div id="gaugeOptionsRanges" ng-show="showColorRange" class="kuiSideBarCollapsibleSection">
<div class="kuiSideBarSection">
<table class="vis-editor-agg-editor-ranges form-group" ng-show="editorState.params.gauge.colorsRange.length">
<table class="visEditorAgg__rangesTable form-group" ng-show="editorState.params.gauge.colorsRange.length">
<tr>
<th scope="col">
<label id="gaugeOptionsCustomRangeFrom">From</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
<div class="kuiSideBarSection">
<table
data-test-subj="heatmapCustomRangesTable"
class="vis-editor-agg-editor-ranges form-group"
class="visEditorAgg__rangesTable form-group"
ng-show="editorState.params.colorsRange.length">
<tr>
<th scope="col">
Expand Down
Empty file.
3 changes: 1 addition & 2 deletions src/core_plugins/kibana/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,8 @@ export default function (kibana) {
listed: false,
description: 'the kibana you know and love',
main: 'plugins/kibana/kibana',
styleSheetPath: `${__dirname}/public/index.scss`,
},

styleSheetPaths: `${__dirname}/public/index.scss`,
links: [
{
id: 'kibana:discover',
Expand Down
Loading