[Uptime] Expanded list update most recent error timestamp (#51935)

* update most recent error timestamo

* update snaps

* update snap
This commit is contained in:
Shahzad 2019-12-05 14:14:27 +01:00 committed by GitHub
parent c40a3b0e17
commit a096254eb7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 25 deletions

View file

@ -6,17 +6,18 @@
import * as t from 'io-ts';
// IO type for validation
export const ErrorType = t.partial({
export const MonitorErrorType = t.partial({
code: t.number,
message: t.string,
type: t.string,
});
// Typescript type for type checking
export type Error = t.TypeOf<typeof ErrorType>;
export type MonitorError = t.TypeOf<typeof MonitorErrorType>;
export const MonitorDetailsType = t.intersection([
t.type({ monitorId: t.string }),
t.partial({ error: ErrorType }),
t.partial({ error: MonitorErrorType }),
t.partial({ timestamp: t.string }),
]);
export type MonitorDetails = t.TypeOf<typeof MonitorDetailsType>;

View file

@ -6,7 +6,7 @@ Array [
class="euiText euiText--extraSmall"
>
<h3>
Most recent error
Most recent error (5 days ago)
</h3>
</div>,
<button
@ -54,6 +54,7 @@ exports[`MostRecentError component validates props with shallow render 1`] = `
}
}
monitorId="bad-ssl"
timestamp="2019-11-30T01:57:37.792Z"
/>
</Router>
`;

View file

@ -8,25 +8,32 @@ import { shallowWithIntl, renderWithIntl } from 'test_utils/enzyme_helpers';
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { MostRecentError } from '../most_recent_error';
import { MonitorDetails, MonitorError } from '../../../../../../common/runtime_types';
describe('MostRecentError component', () => {
let monitorDetails: any;
let monitorDetails: MonitorDetails;
let monitorError: MonitorError;
beforeEach(() => {
monitorError = {
type: 'io',
message: 'Get https://expired.badssl.com: x509: certificate has expired or is not yet valid',
};
monitorDetails = {
monitorId: 'bad-ssl',
error: {
type: 'io',
message:
'Get https://expired.badssl.com: x509: certificate has expired or is not yet valid',
},
timestamp: '2019-11-30T01:57:37.792Z',
error: monitorError,
};
});
it('validates props with shallow render', () => {
const component = shallowWithIntl(
<Router>
<MostRecentError monitorId={monitorDetails.monitorId} error={monitorDetails.error} />
<MostRecentError
monitorId={monitorDetails.monitorId}
error={monitorDetails.error}
timestamp={monitorDetails.timestamp}
/>
</Router>
);
expect(component).toMatchSnapshot();
@ -35,7 +42,11 @@ describe('MostRecentError component', () => {
it('renders properly with empty data', () => {
const component = renderWithIntl(
<Router>
<MostRecentError monitorId={monitorDetails.monitorId} error={monitorDetails.error} />
<MostRecentError
monitorId={monitorDetails.monitorId}
error={monitorDetails.error}
timestamp={monitorDetails.timestamp}
/>
</Router>
);
expect(component).toMatchSnapshot();

View file

@ -15,6 +15,7 @@ import { fetchMonitorDetails } from '../../../../state/actions/monitor';
import { MostRecentError } from './most_recent_error';
import { getMonitorDetails } from '../../../../state/selectors';
import { MonitorStatusList } from './monitor_status_list';
import { MonitorDetails } from '../../../../../common/runtime_types';
const ContainerDiv = styled.div`
padding: 10px;
@ -30,7 +31,7 @@ interface MonitorListDrawerProps {
/**
* Monitor details to be fetched from rest api using monitorId
*/
monitorDetails: any;
monitorDetails: MonitorDetails;
/**
* Redux action to trigger , loading monitor details
@ -69,7 +70,11 @@ export function MonitorListDrawerComponent({
<EuiSpacer size="s" />
<MonitorStatusList checks={summary.state.checks} />
{monitorDetails && monitorDetails.error && (
<MostRecentError error={monitorDetails.error} monitorId={summary.monitor_id} />
<MostRecentError
error={monitorDetails.error}
monitorId={summary.monitor_id}
timestamp={monitorDetails.timestamp}
/>
)}
</ContainerDiv>
);

View file

@ -5,46 +5,51 @@
*/
import React from 'react';
import { EuiText } from '@elastic/eui';
import moment from 'moment';
import { i18n } from '@kbn/i18n';
import { MonitorPageLink } from '../monitor_page_link';
import { useUrlParams } from '../../../../hooks';
import { stringifyUrlParams } from '../../../../lib/helper/stringify_url_params';
interface RecentError {
message: string;
type: string;
}
import { MonitorError } from '../../../../../common/runtime_types';
interface MostRecentErrorProps {
/**
* error returned from API for monitor details
*/
error: RecentError;
error: MonitorError | undefined;
/**
* monitorId to be used for link to detail page
*/
monitorId: string;
/**
* Timestamp of error for the monitor
*/
timestamp: string | undefined;
}
export const MostRecentError = ({ error, monitorId }: MostRecentErrorProps) => {
export const MostRecentError = ({ error, monitorId, timestamp }: MostRecentErrorProps) => {
const [getUrlParams] = useUrlParams();
const { absoluteDateRangeStart, absoluteDateRangeEnd, ...params } = getUrlParams();
params.selectedPingStatus = 'down';
const linkParameters = stringifyUrlParams(params);
const timestampStr = timestamp ? moment(new Date(timestamp).valueOf()).fromNow() : '';
return (
<>
<EuiText size="xs">
<h3>
{i18n.translate('xpack.uptime.monitorList.mostRecentError.title', {
defaultMessage: 'Most recent error',
defaultMessage: 'Most recent error ({timestamp})',
values: { timestamp: timestampStr },
description: 'Most Recent Error title in Monitor List Expanded row',
})}
</h3>
</EuiText>
<MonitorPageLink monitorId={monitorId} linkParameters={linkParameters}>
{error.message}
{error?.message}
</MonitorPageLink>
</>
);

View file

@ -16,7 +16,7 @@ import {
import { getHistogramIntervalFormatted } from '../../helper';
import { DatabaseAdapter } from '../database';
import { UMMonitorsAdapter } from './adapter_types';
import { MonitorDetails, Error } from '../../../../common/runtime_types';
import { MonitorDetails, MonitorError } from '../../../../common/runtime_types';
const formatStatusBuckets = (time: any, buckets: any, docCount: any) => {
let up = null;
@ -278,6 +278,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
index: INDEX_NAMES.HEARTBEAT,
body: {
size: 1,
_source: ['error', '@timestamp'],
query: {
bool: {
must: [
@ -308,11 +309,15 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
const result = await this.database.search(request, params);
const monitorError: Error | undefined = get(result, 'hits.hits[0]._source.error', undefined);
const data = result.hits.hits[0]?._source;
const monitorError: MonitorError | undefined = data?.error;
const errorTimeStamp: string | undefined = data?.['@timestamp'];
return {
monitorId,
error: monitorError,
timestamp: errorTimeStamp,
};
}
}