Skip to content

Commit

Permalink
[Monitoring] CCR UI (elastic#23013)
Browse files Browse the repository at this point in the history
* Initial version of CCR monitoring UI

* Adding missing files

* Use icons

* Use new column header text

* Update tests

* Basic of shard detail page

* Do these in parallel

* Disable time picker on ccr page

* Remove summary for now

* Remove unnecessary code here

* Fix a few things on the shard page

* Only send down what we need

* update snapshot

* Handle no ccr_stats documents

* Ensure we fetch the latest

* Updates

* Format the time

* Add api integration tests

* Adding pagination and sorting

* Updated query logic

* Change this back

* Add specific information about the follower and leader lag ops

* Update tests

* UI updates

* Address PR issues

* Fix tests

* Update shapshots

* Add timestamp

* Update tests

* Add a few snapshot tests

* Use timezone formatter

* Fix tests

* Fix aligment of shard table

* PR feedback

* Update snapshots

* Update snapshot
  • Loading branch information
chrisronline committed Oct 5, 2018
1 parent 3c7646e commit 89e18a1
Show file tree
Hide file tree
Showing 34 changed files with 2,856 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Ccr that it renders normally 1`] = `
<EuiPage
restrictWidth={false}
>
<EuiPageBody
restrictWidth={false}
>
<EuiPageContent
panelPaddingSize="l"
>
<EuiPageContentBody>
<EuiInMemoryTable
className="monitoringElasticsearchCcrListingTable"
columns={
Array [
Object {
"field": "index",
"name": "Index",
"render": [Function],
"sortable": true,
},
Object {
"field": "follows",
"name": "Follows",
"sortable": true,
},
Object {
"field": "opsSynced",
"name": "Ops synced",
"sortable": true,
},
Object {
"field": "syncLagTime",
"name": "Last fetch time",
"render": [Function],
"sortable": true,
},
Object {
"field": "syncLagOps",
"name": "Sync Lag (ops)",
"sortable": true,
},
Object {
"field": "error",
"name": "Error",
"render": [Function],
"sortable": true,
},
]
}
itemId="id"
itemIdToExpandedRowMap={Object {}}
items={
Array [
Object {
"follows": "leader",
"id": "follower",
"index": "follower",
"opsSynced": 400,
"shards": Array [
Object {
"opsSynced": 200,
"shardId": 0,
"syncLagOps": 2,
"syncLagOpsFollower": 1,
"syncLagOpsLeader": 1,
"syncLagTime": 45000,
},
Object {
"opsSynced": 200,
"shardId": 1,
"syncLagOps": 1,
"syncLagOpsFollower": 0,
"syncLagOpsLeader": 1,
"syncLagTime": 60000,
},
],
"syncLagOps": 5,
"syncLagTime": 60000,
},
Object {
"error": "not_working_properly",
"follows": "leader2",
"id": "follower2",
"index": "follower2",
"opsSynced": 50,
"shards": Array [
Object {
"opsSynced": 20,
"shardId": 1,
"syncLagOps": 0,
"syncLagOpsFollower": 0,
"syncLagOpsLeader": 0,
"syncLagTime": 11000,
},
Object {
"error": "not_working_properly",
"opsSynced": 30,
"shardId": 2,
"syncLagOps": 5,
"syncLagOpsFollower": 5,
"syncLagOpsLeader": 0,
"syncLagTime": 1000,
},
],
"syncLagOps": 1,
"syncLagTime": 12000,
},
]
}
pagination={false}
responsive={true}
sorting={
Object {
"sort": Object {
"direction": "asc",
"field": "index",
},
}
}
/>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</EuiPage>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* [1] - We want the collapsed table (that shows the shard data) to be inline
* with the columns from the main table so we need to remove the padding
*/
.monitoringElasticsearchCcrListingTable .euiTableRow-isExpandedRow > .euiTableRowCell > .euiTableCellContent {
padding: 0; /* [1] */
}
211 changes: 211 additions & 0 deletions x-pack/plugins/monitoring/public/components/elasticsearch/ccr/ccr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React, { Fragment, Component } from 'react';
import {
EuiInMemoryTable,
EuiLink,
EuiPage,
EuiPageBody,
EuiPageContent,
EuiPageContentBody,
EuiIcon,
EuiIconTip,
EuiTextColor
} from '@elastic/eui';

import './ccr.css';

function toSeconds(ms) {
return Math.floor(ms / 1000) + 's';
}

export class Ccr extends Component {
constructor(props) {
super(props);
this.state = {
itemIdToExpandedRowMap: {},
};
}

toggleShards(index, shards) {
const itemIdToExpandedRowMap = {
...this.state.itemIdToExpandedRowMap
};

if (itemIdToExpandedRowMap[index]) {
delete itemIdToExpandedRowMap[index];
} else {
let pagination = {
initialPageSize: 5,
pageSizeOptions: [5, 10, 20]
};

if (shards.length <= pagination.initialPageSize) {
pagination = false;
}

itemIdToExpandedRowMap[index] = (
<EuiInMemoryTable
items={shards}
columns={[
{
field: 'shardId',
name: 'Shard',
render: shardId => {
return (
<EuiLink href={`#/elasticsearch/ccr/${index}/shard/${shardId}`}>
{shardId}
</EuiLink>
);
}
},
{
render: () => null
},
{
field: 'opsSynced',
name: 'Ops synced'
},
{
field: 'syncLagTime',
name: 'Last fetch time',
render: syncLagTime => <span>{toSeconds(syncLagTime)}</span>
},
{
field: 'syncLagOps',
name: 'Sync Lag (ops)',
render: (syncLagOps, data) => (
<span>
{syncLagOps}
&nbsp;&nbsp;
<EuiIconTip
size="m"
type="iInCircle"
content={(
<Fragment>
<span>Leader lag: {data.syncLagOpsLeader}</span>
<br/>
<span>Follower lag: {data.syncLagOpsFollower}</span>
</Fragment>
)}
position="right"
/>
</span>
)
},
{
field: 'error',
name: 'Error',
render: error => (
<EuiTextColor color="danger">
{error}
</EuiTextColor>
)
}
]}
sorting={true}
pagination={pagination}
/>
);
}
this.setState({ itemIdToExpandedRowMap });
}

renderTable() {
const { data } = this.props;
const items = data;

let pagination = {
initialPageSize: 5,
pageSizeOptions: [5, 10, 20]
};

if (items.length <= pagination.initialPageSize) {
pagination = false;
}

const sorting = {
sort: {
field: 'index',
direction: 'asc',
},
};

return (
<EuiInMemoryTable
className="monitoringElasticsearchCcrListingTable"
columns={[
{
field: 'index',
name: 'Index',
sortable: true,
render: (index, { shards }) => {
const expanded = !!this.state.itemIdToExpandedRowMap[index];
return (
<EuiLink onClick={() => this.toggleShards(index, shards)}>
{index}
&nbsp;
{ expanded ? <EuiIcon type="arrowUp" /> : <EuiIcon type="arrowDown" /> }
</EuiLink>
);
}
},
{
field: 'follows',
sortable: true,
name: 'Follows'
},
{
field: 'opsSynced',
sortable: true,
name: 'Ops synced'
},
{
field: 'syncLagTime',
sortable: true,
name: 'Last fetch time',
render: syncLagTime => <span>{toSeconds(syncLagTime)}</span>
},
{
field: 'syncLagOps',
sortable: true,
name: 'Sync Lag (ops)',
},
{
field: 'error',
sortable: true,
name: 'Error',
render: error => (
<EuiTextColor color="danger">
{error}
</EuiTextColor>
)
}
]}
items={items}
pagination={pagination}
sorting={sorting}
itemId="id"
itemIdToExpandedRowMap={this.state.itemIdToExpandedRowMap}
/>
);
}

render() {
return (
<EuiPage>
<EuiPageBody>
<EuiPageContent>
<EuiPageContentBody>
{this.renderTable()}
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</EuiPage>
);
}
}
Loading

0 comments on commit 89e18a1

Please sign in to comment.