Skip to content

Commit

Permalink
[Monitoring] Introducing Logs UI (elastic#31275)
Browse files Browse the repository at this point in the history
* Initial implementation

* More logs UI work

* Remove unnecessary code

* Add support to build a logs url based on the cluster and/or node uuid

* Deep link directly

* Update link

* Use CCS to access remote filebeat data

* Fix existing tests

* Add log specific api integration tests

* Localization

* Adding more localization

* Adding unit tests for logs ui

* Client side unit tests, configuration for log fetch count, adding visual callout for why we can't detect logs

* Remove debug

* Fix localization issue

* Update tests

* PR feedback

* Update import

* Format the count to avoid a huge string of numbers

* Use @timestamp instead

* Handle scenario where the time period is not right but the type exists

* Update jest tests

* Update api tests

* Text changes

* Add periods

* Update tests
  • Loading branch information
chrisronline committed Apr 15, 2019
1 parent 0ffe5e4 commit 5f5dd32
Show file tree
Hide file tree
Showing 46 changed files with 6,470 additions and 40 deletions.
2 changes: 2 additions & 0 deletions x-pack/plugins/monitoring/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,5 @@ export const INDEX_PATTERN_LOGSTASH = '.monitoring-logstash-6-*,.monitoring-logs
export const INDEX_PATTERN_BEATS = '.monitoring-beats-6-*,.monitoring-beats-7-*';
export const INDEX_ALERTS = '.monitoring-alerts-6,.monitoring-alerts-7';
export const INDEX_PATTERN_ELASTICSEARCH = '.monitoring-es-6-*,.monitoring-es-7-*';

export const INDEX_PATTERN_FILEBEAT = 'filebeat-*';
3 changes: 2 additions & 1 deletion x-pack/plugins/monitoring/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export const config = (Joi) => {
keyPassphrase: Joi.string(),
alwaysPresentCertificate: Joi.boolean().default(false),
}).default(),
apiVersion: Joi.string().default('master')
apiVersion: Joi.string().default('master'),
logFetchCount: Joi.number().default(10)
}).default(),
tests: Joi.object({
cloud_detector: Joi.object({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { get } from 'lodash';
import React, { Fragment } from 'react';
import { get, capitalize } from 'lodash';
import { formatNumber } from 'plugins/monitoring/lib/format_number';
import { ClusterItemContainer, HealthStatusIndicator, BytesUsage, BytesPercentageUsage } from './helpers';
import {
Expand All @@ -18,9 +18,14 @@ import {
EuiDescriptionListTitle,
EuiDescriptionListDescription,
EuiHorizontalRule,
EuiBadge,
EuiToolTip,
EuiFlexGroup,
} from '@elastic/eui';
import { LicenseText } from './license_text';
import { i18n } from '@kbn/i18n';
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
import { Reason } from '../../logs/reason';

const calculateShards = shards => {
const total = get(shards, 'total', 0);
Expand All @@ -40,8 +45,97 @@ const calculateShards = shards => {
};
};

function ElasticsearchPanelUi(props) {
function getBadgeColorFromLogLevel(level) {
switch (level) {
case 'warn':
return 'warning';
case 'debug':
return 'hollow';
case 'info':
return 'default';
case 'error':
return 'danger';
}
}

function renderLogs(props) {
if (!props.logs.enabled) {
return (
<EuiDescriptionList>
<Reason reason={props.logs.reason}/>
</EuiDescriptionList>
);
}

return (
<EuiDescriptionList type="column">
{props.logs.types.map((log, index) => (
<Fragment key={index}>
<EuiDescriptionListTitle>
<FormattedMessage
id="xpack.monitoring.cluster.overview.logsPanel.logTypeTitle"
defaultMessage="{type}"
values={{
type: capitalize(log.type),
}}
/>
</EuiDescriptionListTitle>
<EuiDescriptionListDescription>
{renderLog(log)}
</EuiDescriptionListDescription>
</Fragment>
))}
{props.logs.types.length === 0
? (
<FormattedMessage
id="xpack.monitoring.cluster.overview.logsPanel.noLogsFound"
defaultMessage="No logs found."
/>
)
: null
}
</EuiDescriptionList>
);
}

const logLevelText = {
info: i18n.translate('xpack.monitoring.cluster.overview.esPanel.infoLogsTooltipText', {
defaultMessage: 'The number of information logs'
}),
warn: i18n.translate('xpack.monitoring.cluster.overview.esPanel.warnLogsTooltipText', {
defaultMessage: 'The number of warning logs'
}),
debug: i18n.translate('xpack.monitoring.cluster.overview.esPanel.debugLogsTooltipText', {
defaultMessage: 'The number of debug logs'
}),
error: i18n.translate('xpack.monitoring.cluster.overview.esPanel.errorLogsTooltipText', {
defaultMessage: 'The number of error logs'
}),
fatal: i18n.translate('xpack.monitoring.cluster.overview.esPanel.fatalLogsTooltipText', {
defaultMessage: 'The number of fatal logs'
}),
};

function renderLog(log) {
return (
<EuiFlexGroup wrap responsive={false} gutterSize="xs">
{log.levels.map((level, index) => (
<EuiFlexItem grow={false} key={index}>
<EuiToolTip
position="top"
content={logLevelText[level.level]}
>
<EuiBadge color={getBadgeColorFromLogLevel(level.level)}>
{formatNumber(level.count, 'int_commas')}
</EuiBadge>
</EuiToolTip>
</EuiFlexItem>
))}
</EuiFlexGroup>
);
}

function ElasticsearchPanelUi(props) {
const clusterStats = props.cluster_stats || {};
const nodes = clusterStats.nodes;
const indices = clusterStats.indices;
Expand Down Expand Up @@ -239,6 +333,28 @@ function ElasticsearchPanelUi(props) {
</EuiPanel>
</EuiFlexItem>

<EuiFlexItem>
<EuiPanel paddingSize="m">
<EuiTitle size="s">
<h3>
<EuiLink
onClick={goToElasticsearch}
aria-label={props.intl.formatMessage({
id: 'xpack.monitoring.cluster.overview.esPanel.logsLinkAriaLabel', defaultMessage: 'Elasticsearch Logs' })}
data-test-subj="esLogs"
>
<FormattedMessage
id="xpack.monitoring.cluster.overview.esPanel.logsLinkLabel"
defaultMessage="Logs"
/>
</EuiLink>
</h3>
</EuiTitle>
<EuiHorizontalRule margin="m" />
{renderLogs(props)}
</EuiPanel>
</EuiFlexItem>

</EuiFlexGrid>
</ClusterItemContainer>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ import {
import { IndexDetailStatus } from '../index_detail_status';
import { MonitoringTimeseriesContainer } from '../../chart';
import { ShardAllocation } from '../shard_allocation/shard_allocation';
import { Logs } from '../../logs';

export const Index = ({
scope,
indexSummary,
metrics,
clusterUuid,
indexUuid,
logs,
kbnUrl,
...props
}) => {
Expand Down Expand Up @@ -54,6 +58,10 @@ export const Index = ({
))}
</EuiFlexGrid>
<EuiSpacer size="m"/>
<EuiPanel>
<Logs logs={logs} indexUuid={indexUuid} clusterUuid={clusterUuid} />
</EuiPanel>
<EuiSpacer size="m"/>
<ShardAllocation scope={scope} kbnUrl={kbnUrl} type="index" />
</EuiPageContent>
</EuiPageBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ import {
EuiPanel,
} from '@elastic/eui';
import { NodeDetailStatus } from '../node_detail_status';
import { Logs } from '../../logs/';
import { MonitoringTimeseriesContainer } from '../../chart';
import { ShardAllocation } from '../shard_allocation/shard_allocation';

export const Node = ({
nodeSummary,
metrics,
logs,
nodeId,
clusterUuid,
scope,
kbnUrl,
...props
Expand Down Expand Up @@ -53,9 +57,15 @@ export const Node = ({
</EuiFlexItem>
))}
</EuiFlexGrid>
<EuiSpacer size="m"/>
<ShardAllocation scope={scope} kbnUrl={kbnUrl}/>
</EuiPageContent>
<EuiSpacer size="m"/>
<EuiPanel>
<Logs logs={logs} nodeId={nodeId} clusterUuid={clusterUuid} />
</EuiPanel>
<EuiSpacer size="m"/>
<EuiPanel>
<ShardAllocation scope={scope} kbnUrl={kbnUrl}/>
</EuiPanel>
</EuiPageBody>
</EuiPage>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ import { ClusterStatus } from '../cluster_status';
import { ShardActivity } from '../shard_activity';
import { MonitoringTimeseriesContainer } from '../../chart';
import { EuiPage, EuiFlexGrid, EuiFlexItem, EuiPanel, EuiSpacer, EuiPageBody, EuiPageContent } from '@elastic/eui';
import { Logs } from '../../logs/logs';

export function ElasticsearchOverview({
clusterStatus,
metrics,
logs,
cluster,
shardActivity,
...props
}) {
Expand Down Expand Up @@ -42,8 +45,15 @@ export function ElasticsearchOverview({
</EuiFlexItem>
))}
</EuiFlexGrid>
<ShardActivity data={shardActivity} {...props} />
</EuiPageContent>
<EuiSpacer size="m" />
<EuiPanel>
<Logs logs={logs} clusterUuid={cluster.cluster_uuid}/>
</EuiPanel>
<EuiSpacer size="m" />
<EuiPanel>
<ShardActivity data={shardActivity} {...props} />
</EuiPanel>
</EuiPageBody>
</EuiPage>
);
Expand Down
Loading

0 comments on commit 5f5dd32

Please sign in to comment.