Skip to content

Commit aca9581

Browse files
authored
[Uptime] Remove Scripted Metric Query (#69229) (#71242)
Resolves #68096 , removing unnecessary scripted metric query from overview page and unifying the Check and Ping types. This simplifies the types in a number of ways, and reduces the total quantity of code to execute the queries for the overview page. It also fixes the Tls and related types which were inconsistent and presented a problem here since they are used by this JS. There are now three stages where before there were four: Find potential matches: where we determine which monitor IDs are eligible for the overview page Refine potential matches: where we determine which ones actually match and return the summary documents for each location to build the MonitorSummary object Get monitor histograms: where we calculate the histograms for each monitor. In the future we might make this a separate API call. This improves the overall code structure, and leaves the test coverage about the same depending on how you look at it. I think we can do more to improve the quality of code / tests here, but this seemed like a good initial place to draw the line for now. In perfunctory testing on our internal observability clusters I saw perf improve from 2.5s to 1.1s on the Uptime homepage with no filters. So, it looks like there are potentially perf improvements (no real benchmarking was done). Previously, this returned all pings from the latest check group. This was not actually used anywhere, only the summary pings are required for the current UI, so we now only return those from the list API as this saves a query.
1 parent ebfd803 commit aca9581

49 files changed

Lines changed: 1683 additions & 1947 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

x-pack/plugins/uptime/common/runtime_types/monitor/state.ts

Lines changed: 27 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,68 +5,9 @@
55
*/
66

77
import * as t from 'io-ts';
8-
9-
export const CheckMonitorType = t.intersection([
10-
t.partial({
11-
name: t.string,
12-
ip: t.union([t.array(t.union([t.string, t.null])), t.string, t.null]),
13-
}),
14-
t.type({
15-
status: t.string,
16-
}),
17-
]);
18-
19-
export const CheckType = t.intersection([
20-
t.partial({
21-
agent: t.partial({
22-
id: t.string,
23-
}),
24-
container: t.type({
25-
id: t.string,
26-
}),
27-
kubernetes: t.type({
28-
pod: t.type({
29-
uid: t.string,
30-
}),
31-
}),
32-
observer: t.type({
33-
geo: t.partial({
34-
name: t.string,
35-
location: t.partial({
36-
lat: t.number,
37-
lon: t.number,
38-
}),
39-
}),
40-
}),
41-
}),
42-
t.type({
43-
monitor: CheckMonitorType,
44-
timestamp: t.number,
45-
}),
46-
]);
47-
48-
export type Check = t.TypeOf<typeof CheckType>;
8+
import { PingType } from '../ping/ping';
499

5010
export const StateType = t.intersection([
51-
t.partial({
52-
checks: t.array(CheckType),
53-
observer: t.partial({
54-
geo: t.partial({
55-
name: t.array(t.string),
56-
}),
57-
}),
58-
summary: t.partial({
59-
up: t.number,
60-
down: t.number,
61-
geo: t.partial({
62-
name: t.string,
63-
location: t.partial({
64-
lat: t.number,
65-
lon: t.number,
66-
}),
67-
}),
68-
}),
69-
}),
7011
t.type({
7112
timestamp: t.string,
7213
url: t.partial({
@@ -76,9 +17,31 @@ export const StateType = t.intersection([
7617
port: t.number,
7718
scheme: t.string,
7819
}),
20+
summaryPings: t.array(PingType),
21+
summary: t.partial({
22+
status: t.string,
23+
up: t.number,
24+
down: t.number,
25+
}),
26+
monitor: t.partial({
27+
name: t.string,
28+
}),
29+
}),
30+
t.partial({
31+
tls: t.partial({
32+
not_after: t.union([t.string, t.null]),
33+
not_before: t.union([t.string, t.null]),
34+
}),
35+
observer: t.type({
36+
geo: t.type({
37+
name: t.array(t.string),
38+
}),
39+
}),
7940
}),
8041
]);
8142

43+
export type MonitorSummaryState = t.TypeOf<typeof StateType>;
44+
8245
export const HistogramPointType = t.type({
8346
timestamp: t.number,
8447
up: t.union([t.number, t.undefined]),
@@ -105,18 +68,18 @@ export const MonitorSummaryType = t.intersection([
10568

10669
export type MonitorSummary = t.TypeOf<typeof MonitorSummaryType>;
10770

108-
export const MonitorSummaryResultType = t.intersection([
71+
export const MonitorSummariesResultType = t.intersection([
10972
t.partial({
110-
summaries: t.array(MonitorSummaryType),
73+
totalSummaryCount: t.number,
11174
}),
11275
t.type({
76+
summaries: t.array(MonitorSummaryType),
11377
prevPagePagination: t.union([t.string, t.null]),
11478
nextPagePagination: t.union([t.string, t.null]),
115-
totalSummaryCount: t.number,
11679
}),
11780
]);
11881

119-
export type MonitorSummaryResult = t.TypeOf<typeof MonitorSummaryResultType>;
82+
export type MonitorSummariesResult = t.TypeOf<typeof MonitorSummariesResultType>;
12083

12184
export const FetchMonitorStatesQueryArgsType = t.intersection([
12285
t.partial({

x-pack/plugins/uptime/common/runtime_types/ping/ping.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,51 @@ export const HttpResponseBodyType = t.partial({
1616

1717
export type HttpResponseBody = t.TypeOf<typeof HttpResponseBodyType>;
1818

19-
export const TlsType = t.partial({
19+
const ECSDistinguishedName = t.type({
20+
common_name: t.string,
21+
distinguished_name: t.string,
22+
});
23+
24+
export const X509ExpiryType = t.type({
2025
not_after: t.string,
2126
not_before: t.string,
2227
});
2328

29+
export type X509Expiry = t.TypeOf<typeof X509ExpiryType>;
30+
31+
export const X509Type = t.intersection([
32+
t.type({
33+
issuer: ECSDistinguishedName,
34+
subject: ECSDistinguishedName,
35+
serial_number: t.string,
36+
public_key_algorithm: t.string,
37+
signature_algorithm: t.string,
38+
}),
39+
X509ExpiryType,
40+
t.partial({
41+
public_key_curve: t.string,
42+
public_key_exponent: t.number,
43+
public_key_size: t.number,
44+
}),
45+
]);
46+
47+
export type X509 = t.TypeOf<typeof X509Type>;
48+
49+
export const TlsType = t.partial({
50+
// deprecated in favor of server.x509.not_after/not_before
51+
certificate_not_valid_after: t.string,
52+
certificate_not_valid_before: t.string,
53+
cipher: t.string,
54+
established: t.boolean,
55+
server: t.partial({
56+
hash: t.type({
57+
sha256: t.string,
58+
sha1: t.string,
59+
}),
60+
x509: X509Type,
61+
}),
62+
});
63+
2464
export type Tls = t.TypeOf<typeof TlsType>;
2565

2666
export const MonitorType = t.intersection([
@@ -123,6 +163,11 @@ export const PingType = t.intersection([
123163
observer: t.partial({
124164
geo: t.partial({
125165
name: t.string,
166+
location: t.union([
167+
t.string,
168+
t.partial({ lat: t.number, lon: t.number }),
169+
t.partial({ lat: t.string, lon: t.string }),
170+
]),
126171
}),
127172
}),
128173
resolve: t.partial({
@@ -156,6 +201,30 @@ export const PingType = t.intersection([
156201

157202
export type Ping = t.TypeOf<typeof PingType>;
158203

204+
// Convenience function for tests etc that makes an empty ping
205+
// object with the minimum of fields.
206+
export const makePing = (f: {
207+
docId?: string;
208+
type?: string;
209+
id?: string;
210+
timestamp?: string;
211+
ip?: string;
212+
status?: string;
213+
duration?: number;
214+
}): Ping => {
215+
return {
216+
docId: f.docId || 'myDocId',
217+
timestamp: f.timestamp || '2020-07-07T01:14:08Z',
218+
monitor: {
219+
id: f.id || 'myId',
220+
type: f.type || 'myType',
221+
ip: f.ip || '127.0.0.1',
222+
status: f.status || 'up',
223+
duration: { us: f.duration || 100000 },
224+
},
225+
};
226+
};
227+
159228
export const PingsResponseType = t.type({
160229
total: t.number,
161230
locations: t.array(t.string),

x-pack/plugins/uptime/public/components/monitor/status_details/__test__/__snapshots__/ssl_certificate.test.tsx.snap

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugins/uptime/public/components/monitor/status_details/__test__/ssl_certificate.test.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../common/constants';
1515

1616
describe('SSL Certificate component', () => {
1717
let monitorTls: Tls;
18+
const dateInTwoMonths = moment().add(2, 'month').toString();
19+
const yesterday = moment().subtract(1, 'day').toString();
1820

1921
beforeEach(() => {
20-
const dateInTwoMonths = moment().add(2, 'month').toString();
21-
2222
monitorTls = {
23-
not_after: dateInTwoMonths,
23+
certificate_not_valid_after: dateInTwoMonths,
24+
certificate_not_valid_before: yesterday,
2425
};
2526

2627
const useDispatchSpy = jest.spyOn(redux, 'useDispatch');
@@ -32,7 +33,8 @@ describe('SSL Certificate component', () => {
3233

3334
it('shallow renders', () => {
3435
const monitorTls1 = {
35-
not_after: '2020-04-24T11:41:38.200Z',
36+
certificate_not_valid_after: '2020-04-24T11:41:38.200Z',
37+
certificate_not_valid_before: '2019-04-24T11:41:38.200Z',
3638
};
3739
const component = shallowWithRouter(<MonitorSSLCertificate tls={monitorTls1} />);
3840
expect(component).toMatchSnapshot();
@@ -45,7 +47,8 @@ describe('SSL Certificate component', () => {
4547

4648
it('renders null if invalid date', () => {
4749
monitorTls = {
48-
not_after: 'i am so invalid date',
50+
certificate_not_valid_after: 'i am so invalid date',
51+
certificate_not_valid_before: 'i am so invalid date',
4952
};
5053
const component = renderWithRouter(<MonitorSSLCertificate tls={monitorTls} />);
5154
expect(component).toMatchSnapshot();
@@ -54,7 +57,8 @@ describe('SSL Certificate component', () => {
5457
it('renders expiration date with a warning state if ssl expiry date is less than 5 days', () => {
5558
const dateIn5Days = moment().add(5, 'day').toString();
5659
monitorTls = {
57-
not_after: dateIn5Days,
60+
certificate_not_valid_after: dateIn5Days,
61+
certificate_not_valid_before: yesterday,
5862
};
5963
const component = mountWithRouter(<MonitorSSLCertificate tls={monitorTls} />);
6064

@@ -69,7 +73,8 @@ describe('SSL Certificate component', () => {
6973
it('does not render the expiration date with a warning state if expiry date is greater than a month', () => {
7074
const dateIn40Days = moment().add(40, 'day').toString();
7175
monitorTls = {
72-
not_after: dateIn40Days,
76+
certificate_not_valid_after: dateIn40Days,
77+
certificate_not_valid_before: yesterday,
7378
};
7479
const component = mountWithRouter(<MonitorSSLCertificate tls={monitorTls} />);
7580

x-pack/plugins/uptime/public/components/monitor/status_details/status_bar/ssl_certificate.tsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import React from 'react';
88
import { Link } from 'react-router-dom';
99
import { EuiSpacer } from '@elastic/eui';
1010
import { FormattedMessage } from '@kbn/i18n/react';
11-
import { Tls } from '../../../../../common/runtime_types';
11+
import { Tls, X509Expiry } from '../../../../../common/runtime_types';
1212
import { CERTIFICATES_ROUTE } from '../../../../../common/constants';
1313
import { MonListDescription, MonListTitle } from './status_bar';
1414
import { CertStatusColumn } from '../../../overview/monitor_list/cert_status_column';
@@ -21,7 +21,21 @@ interface Props {
2121
}
2222

2323
export const MonitorSSLCertificate = ({ tls }: Props) => {
24-
return tls?.not_after ? (
24+
let expiry: X509Expiry | null = null;
25+
if (tls?.server?.x509) {
26+
expiry = tls.server.x509;
27+
} else if (tls?.certificate_not_valid_after && tls?.certificate_not_valid_before) {
28+
expiry = {
29+
not_after: tls.certificate_not_valid_after,
30+
not_before: tls.certificate_not_valid_before,
31+
};
32+
}
33+
34+
if (!expiry) {
35+
return null;
36+
}
37+
38+
return (
2539
<>
2640
<MonListTitle>
2741
<FormattedMessage
@@ -33,9 +47,9 @@ export const MonitorSSLCertificate = ({ tls }: Props) => {
3347
<EuiSpacer size="s" />
3448
<MonListDescription>
3549
<Link to={CERTIFICATES_ROUTE} className="eui-displayInline">
36-
<CertStatusColumn cert={tls} boldStyle={true} />
50+
<CertStatusColumn expiry={expiry} boldStyle={true} />
3751
</Link>
3852
</MonListDescription>
3953
</>
40-
) : null;
54+
);
4155
};

0 commit comments

Comments
 (0)