[Uptime] ICMP not displayed in Overview page or as a filter option (#32083)

* Add definition for type filter in addition to scheme.

* Remove scheme from filter bar.

* Update ES queries to return ICMP counts.

* Update API tests for new histogram size. Add tests for ICMP data.

* Improve code quality for server function.

* Remove unneeded ICMP-specific code.

* Remove unneeded ICMP code from error list query.

* Add correct curve to monitor chart.

* Update ICMP docs and fix broken API tests.

* Add filter bar icmp functional test.

* Update filter bar UI test to ensure that ICMP monitors are supported.
This commit is contained in:
Justin Kambic 2019-03-07 12:09:59 -05:00 committed by GitHub
parent 0a5b524ffd
commit 4c1264dd51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 1064 additions and 183 deletions

View file

@ -410,7 +410,7 @@
"name": "millisFromNow",
"description": "Milliseconds from the timestamp to the current time",
"args": [],
"type": { "kind": "SCALAR", "name": "Int", "ofType": null },
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
"isDeprecated": false,
"deprecationReason": null
},
@ -1812,7 +1812,7 @@
"deprecationReason": null
},
{
"name": "scheme",
"name": "status",
"description": "",
"args": [],
"type": {
@ -1828,7 +1828,7 @@
"deprecationReason": null
},
{
"name": "status",
"name": "type",
"description": "",
"args": [],
"type": {
@ -1882,6 +1882,14 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "monitorType",
"description": "",
"args": [],
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "count",
"description": "",

View file

@ -43,7 +43,7 @@ export interface Ping {
/** The timestamp of the ping's creation */
timestamp: string;
/** Milliseconds from the timestamp to the current time */
millisFromNow?: number | null;
millisFromNow?: string | null;
/** The agent that recorded the ping */
beat?: Beat | null;
@ -355,9 +355,9 @@ export interface FilterBar {
port?: number[] | null;
scheme?: string[] | null;
status?: string[] | null;
type?: string[] | null;
}
export interface ErrorListItem {
@ -367,6 +367,8 @@ export interface ErrorListItem {
type: string;
monitorType?: string | null;
count?: number | null;
statusCode?: string | null;

View file

@ -0,0 +1,164 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FilterBar component renders without errors 1`] = `
<EuiFlexGroup
alignItems="stretch"
component="div"
direction="row"
gutterSize="l"
justifyContent="flexStart"
responsive={true}
wrap={false}
>
<EuiFlexItem
component="div"
grow={true}
>
<EuiSearchBar
filters={
Array [
Object {
"field": "monitor.status",
"items": Array [
Object {
"name": "Up",
"value": "up",
},
Object {
"name": "Down",
"value": "down",
},
],
"type": "field_value_toggle_group",
},
Object {
"field": "monitor.id",
"multiSelect": false,
"name": "Host",
"options": Array [
Object {
"value": "http@http://localhost:12349/",
"view": "http@http://localhost:12349/",
},
Object {
"value": "http@http://localhost:9200",
"view": "http@http://localhost:9200",
},
Object {
"value": "http@http://www.example.com",
"view": "http@http://www.example.com",
},
Object {
"value": "http@http://www.google.com/",
"view": "http@http://www.google.com/",
},
Object {
"value": "http@https://news.google.com/",
"view": "http@https://news.google.com/",
},
Object {
"value": "http@https://www.elastic.co",
"view": "http@https://www.elastic.co",
},
Object {
"value": "http@https://www.github.com/",
"view": "http@https://www.github.com/",
},
Object {
"value": "http@https://www.google.com/",
"view": "http@https://www.google.com/",
},
Object {
"value": "http@https://www.wikipedia.org/",
"view": "http@https://www.wikipedia.org/",
},
Object {
"value": "icmp-icmptest-ip@8.8.8.8",
"view": "icmp-icmptest-ip@8.8.8.8",
},
Object {
"value": "tcp-tcp@localhost:9200",
"view": "tcp-tcp@localhost:9200",
},
],
"searchThreshold": 2,
"type": "field_value_selection",
},
Object {
"field": "tcp.port",
"multiSelect": false,
"name": "Port",
"options": Array [
Object {
"value": 80,
"view": 80,
},
Object {
"value": 443,
"view": 443,
},
Object {
"value": 9200,
"view": 9200,
},
Object {
"value": 12349,
"view": 12349,
},
],
"searchThreshold": 2,
"type": "field_value_selection",
},
Object {
"field": "monitor.type",
"multiSelect": false,
"name": "Type",
"options": Array [
Object {
"value": "http",
"view": "http",
},
Object {
"value": "icmp",
"view": "icmp",
},
Object {
"value": "tcp",
"view": "tcp",
},
],
"searchThreshold": 2,
"type": "field_value_selection",
},
]
}
onChange={[Function]}
schema={
Object {
"fields": Object {
"monitor.host": Object {
"type": "string",
},
"monitor.id": Object {
"type": "string",
},
"monitor.ip": Object {
"type": "string",
},
"monitor.scheme": Object {
"type": "string",
},
"monitor.status": Object {
"type": "string",
},
"tcp.port": Object {
"type": "number",
},
},
"strict": true,
}
}
/>
</EuiFlexItem>
</EuiFlexGroup>
`;

View file

@ -0,0 +1,36 @@
/*
* 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 from 'react';
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
import { FilterBar as FBType } from '../../../../common/graphql/types';
import { FilterBar } from '../filter_bar';
describe('FilterBar component', () => {
const filterBar: FBType = {
status: ['up', 'down'],
port: [80, 443, 9200, 12349],
id: [
'http@http://localhost:12349/',
'http@http://localhost:9200',
'http@http://www.example.com',
'http@http://www.google.com/',
'http@https://news.google.com/',
'http@https://www.elastic.co',
'http@https://www.github.com/',
'http@https://www.google.com/',
'http@https://www.wikipedia.org/',
'icmp-icmptest-ip@8.8.8.8',
'tcp-tcp@localhost:9200',
],
type: ['http', 'icmp', 'tcp'],
};
it('renders without errors', () => {
const component = shallowWithIntl(<FilterBar filterBar={filterBar} updateQuery={jest.fn()} />);
expect(component).toMatchSnapshot();
});
});

View file

@ -20,7 +20,7 @@ interface FilterBarProps {
const MAX_SELECTION_LENGTH = 20;
const SEARCH_THRESHOLD = 2;
export const FilterBar = ({ filterBar: { id, port, scheme }, updateQuery }: FilterBarProps) => {
export const FilterBar = ({ filterBar: { id, port, type }, updateQuery }: FilterBarProps) => {
const showFilterDisclaimer =
(id && id.length && id.length > MAX_SELECTION_LENGTH) ||
(port && port.length && port.length > MAX_SELECTION_LENGTH);
@ -74,13 +74,12 @@ export const FilterBar = ({ filterBar: { id, port, scheme }, updateQuery }: Filt
},
{
type: 'field_value_selection',
field: 'monitor.scheme',
field: 'monitor.type',
name: i18n.translate('xpack.uptime.filterBar.options.typeLabel', {
defaultMessage: 'Type',
}),
multiSelect: false,
options:
scheme && scheme.map((schemeValue: string) => ({ value: schemeValue, view: schemeValue })),
options: type && type.map((typeValue: string) => ({ value: typeValue, view: typeValue })),
searchThreshold: SEARCH_THRESHOLD,
},
];

View file

@ -82,7 +82,7 @@ export const MonitorList = ({ dangerColor, loading, monitors, primaryColor }: Mo
defaultMessage: 'Host',
}),
render: (host: string, monitor: any) => (
<Link to={`/monitor/${monitor.key.id}`}>{host}</Link>
<Link to={`/monitor/${monitor.key.id}`}>{host || monitor.key.id}</Link>
),
},
{

View file

@ -16,6 +16,7 @@ query ErrorList($dateRangeStart: String!, $dateRangeEnd: String!, $filters: Stri
latestMessage
monitorId
type
monitorType
count
statusCode
timestamp

View file

@ -12,7 +12,7 @@ query FilterBar($dateRangeStart: String!, $dateRangeEnd: String!) {
status
port
id
scheme
type
}
}
`;

View file

@ -184,6 +184,7 @@ export class MonitorChartsQuery extends React.Component<Props, MonitorChartsStat
}
)}
data={downSeries}
curve="curveBasis"
color={danger}
/>
</EuiSeriesChart>

View file

@ -10,8 +10,8 @@ export const monitorsSchema = gql`
type FilterBar {
id: [String!]
port: [Int!]
scheme: [String!]
status: [String!]
type: [String!]
}
type HistogramDataPoint {
@ -79,6 +79,7 @@ export const monitorsSchema = gql`
latestMessage: String
monitorId: String
type: String!
monitorType: String
count: Int
statusCode: String
timestamp: String

View file

@ -234,6 +234,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
const params = {
index: INDEX_NAMES.HEARTBEAT,
body: {
size: 0,
query,
aggs: {
hosts: {
@ -250,6 +251,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
port: {
terms: {
field: 'tcp.port',
missing_bucket: true,
},
},
},
@ -270,7 +272,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
histogram: {
auto_date_histogram: {
field: '@timestamp',
buckets: 50,
buckets: 25,
},
aggs: {
status: {
@ -286,11 +288,15 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
},
},
};
const res = await this.database.search(request, params);
const aggBuckets: any[] = get(res, 'aggregations.hosts.buckets', []);
const result = aggBuckets
.map(({ key, histogram: { buckets }, latest: { hits: { hits } } }) => {
if (statusFilter && hits[0]._source.monitor.status !== statusFilter) {
const httpTcpResult = await this.database.search(request, params);
const result = get(httpTcpResult, 'aggregations.hosts.buckets', [])
.map((resultBucket: any) => {
const key = get(resultBucket, 'key');
const buckets: any[] = get(resultBucket, 'histogram.buckets', []);
const hits: any[] = get(resultBucket, 'latest.hits.hits', []);
const latestStatus: string | undefined = get(hits, '[0]._source.monitor.status', undefined);
if (statusFilter && latestStatus !== statusFilter) {
return undefined;
}
const upSeries: any[] = [];
@ -317,7 +323,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
downSeries,
};
})
.filter(f => f !== undefined);
.filter((f: any) => f !== undefined);
return result;
}
@ -328,11 +334,11 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
): Promise<any> {
const MONITOR_SOURCE_ID_KEY = 'monitor.id';
const MONITOR_SOURCE_TCP_KEY = 'tcp.port';
const MONITOR_SOURCE_SCHEME_KEY = 'monitor.scheme';
const MONITOR_SOURCE_TYPE_KEY = 'monitor.type';
const params = {
index: INDEX_NAMES.HEARTBEAT,
body: {
_source: [MONITOR_SOURCE_ID_KEY, MONITOR_SOURCE_TCP_KEY, MONITOR_SOURCE_SCHEME_KEY],
_source: [MONITOR_SOURCE_ID_KEY, MONITOR_SOURCE_TCP_KEY, MONITOR_SOURCE_TYPE_KEY],
size: 1000,
query: {
range: {
@ -353,7 +359,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
const result = await this.database.search(request, params);
const ids: string[] = [];
const ports = new Set<number>();
const schemes = new Set<string>();
const types = new Set<string>();
const hits = get(result, 'hits.hits', []);
hits.forEach((hit: any) => {
@ -363,9 +369,9 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
`_source.${MONITOR_SOURCE_TCP_KEY}`,
undefined
);
const schemeValue: string | undefined = get(
const typeValue: string | undefined = get(
hit,
`_source.${MONITOR_SOURCE_SCHEME_KEY}`,
`_source.${MONITOR_SOURCE_TYPE_KEY}`,
undefined
);
@ -375,13 +381,13 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
if (portValue) {
ports.add(portValue);
}
if (schemeValue) {
schemes.add(schemeValue);
if (typeValue) {
types.add(typeValue);
}
});
return {
scheme: Array.from(schemes).sort(),
type: Array.from(types).sort(),
port: Array.from(ports).sort((a: number, b: number) => a - b),
id: ids.sort(),
status: ['up', 'down'],
@ -436,14 +442,10 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
},
},
};
const {
aggregations: {
error_type: { buckets },
},
} = await this.database.search(request, params);
const queryResult = await this.database.search(request, params);
const errorsList: ErrorListItem[] = [];
buckets.forEach(
get(queryResult, 'aggregations.error_type.buckets', []).forEach(
({
key: errorType,
by_id: { buckets: monitorBuckets },
@ -458,10 +460,12 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
const errorMessage = get(source, 'error.message', null);
const statusCode = get(source, 'http.response.status_code', null);
const timestamp = get(source, '@timestamp', null);
const monitorType = get(source, 'monitor.type', null);
errorsList.push({
latestMessage: errorMessage,
monitorId,
type: errorType,
monitorType,
count,
statusCode,
timestamp,

View file

@ -145,6 +145,7 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
rest_total_hits_as_int: true,
body: {
query,
size: 0,
aggs: {
timeseries: {
auto_date_histogram: {

View file

@ -16,8 +16,8 @@ export default function ({ getService }) {
describe('get_all_pings', () => {
const archive = 'uptime/pings';
before(() => esArchiver.load(archive));
after(() => esArchiver.unload(archive));
before(async () => await esArchiver.load(archive));
after(async () => await esArchiver.unload(archive));
it('should get all pings stored in index', async () => {
const { body: apiResponse } = await supertest

View file

@ -3,6 +3,7 @@
{
"latestMessage": "received status code 301 expecting 200",
"monitorId": "http@http://www.example.com",
"monitorType": "http",
"type": "validate",
"count": 482,
"statusCode": "301",
@ -11,6 +12,7 @@
{
"latestMessage": "Get http://localhost:12349/: dial tcp 127.0.0.1:12349: connect: connection refused",
"monitorId": "http@http://localhost:12349/",
"monitorType": "http",
"type": "io",
"count": 6,
"statusCode": null,
@ -19,6 +21,7 @@
{
"latestMessage": "Get https://example.com/: http: request timed out while waiting for response (Client.Timeout exceeded while awaiting headers)",
"monitorId": "http@http://www.example.com",
"monitorType": "http",
"type": "io",
"count": 1,
"statusCode": null,
@ -27,6 +30,7 @@
{
"latestMessage": "Get http://www.google.com/: dial tcp 172.217.11.36:80: connect: network is down",
"monitorId": "http@http://www.google.com/",
"monitorType": "http",
"type": "io",
"count": 1,
"statusCode": null,
@ -35,6 +39,7 @@
{
"latestMessage": "Get https://www.google.com/: dial tcp 172.217.11.36:443: connect: network is down",
"monitorId": "http@https://www.google.com/",
"monitorType": "http",
"type": "io",
"count": 1,
"statusCode": null,

View file

@ -3,6 +3,7 @@
{
"latestMessage": "Get http://localhost:12349/: dial tcp 127.0.0.1:12349: connect: connection refused",
"monitorId": "http@http://localhost:12349/",
"monitorType": "http",
"type": "io",
"count": 6,
"statusCode": null,

View file

@ -3,6 +3,7 @@
{
"latestMessage": "received status code 301 expecting 200",
"monitorId": "http@http://www.example.com",
"monitorType": "http",
"type": "validate",
"count": 482,
"statusCode": "301",
@ -11,6 +12,7 @@
{
"latestMessage": "Get https://example.com/: http: request timed out while waiting for response (Client.Timeout exceeded while awaiting headers)",
"monitorId": "http@http://www.example.com",
"monitorType": "http",
"type": "io",
"count": 1,
"statusCode": null,
@ -19,6 +21,7 @@
{
"latestMessage": "Get http://www.google.com/: dial tcp 172.217.11.36:80: connect: network is down",
"monitorId": "http@http://www.google.com/",
"monitorType": "http",
"type": "io",
"count": 1,
"statusCode": null,

View file

@ -3,6 +3,7 @@
{
"latestMessage": "received status code 301 expecting 200",
"monitorId": "http@http://www.example.com",
"monitorType": "http",
"type": "validate",
"count": 482,
"statusCode": "301",
@ -11,6 +12,7 @@
{
"latestMessage": "Get https://example.com/: http: request timed out while waiting for response (Client.Timeout exceeded while awaiting headers)",
"monitorId": "http@http://www.example.com",
"monitorType": "http",
"type": "io",
"count": 1,
"statusCode": null,
@ -19,6 +21,7 @@
{
"latestMessage": "Get http://www.google.com/: dial tcp 172.217.11.36:80: connect: network is down",
"monitorId": "http@http://www.google.com/",
"monitorType": "http",
"type": "io",
"count": 1,
"statusCode": null,

View file

@ -13,6 +13,6 @@
"http@https://www.wikipedia.org/",
"tcp-tcp@localhost:9200"
],
"scheme": ["http", "https", "tcp"]
"type": ["http", "tcp"]
}
}

View file

@ -0,0 +1,20 @@
{
"filterBar": {
"status": ["up", "down"],
"port": [80, 443, 9200, 12349],
"id": [
"http@http://localhost:12349/",
"http@http://localhost:9200",
"http@http://www.example.com",
"http@http://www.google.com/",
"http@https://news.google.com/",
"http@https://www.elastic.co",
"http@https://www.github.com/",
"http@https://www.google.com/",
"http@https://www.wikipedia.org/",
"icmp-icmptest-ip@8.8.8.8",
"tcp-tcp@localhost:9200"
],
"type": ["http", "icmp", "tcp"]
}
}

View file

@ -0,0 +1,105 @@
{
"monitorStatus": {
"monitors": [
{
"key": { "id": "http@http://localhost:9200", "port": 9200 },
"ping": {
"timestamp": "2019-03-05T18:05:32.540Z",
"monitor": {
"status": "up",
"type": "http",
"host": "localhost",
"ip": "127.0.0.1",
"duration": { "us": 2569 }
}
},
"upSeries": [
{ "x": 1551807000000, "y": 26 },
{ "x": 1551807300000, "y": 30 },
{ "x": 1551807600000, "y": 30 },
{ "x": 1551807900000, "y": 30 },
{ "x": 1551808200000, "y": 30 },
{ "x": 1551808500000, "y": 30 },
{ "x": 1551808800000, "y": 20 },
{ "x": 1551809100000, "y": 4 }
],
"downSeries": [
{ "x": 1551807000000, "y": 3 },
{ "x": 1551807300000, "y": null },
{ "x": 1551807600000, "y": null },
{ "x": 1551807900000, "y": null },
{ "x": 1551808200000, "y": null },
{ "x": 1551808500000, "y": null },
{ "x": 1551808800000, "y": null },
{ "x": 1551809100000, "y": null }
]
},
{
"key": { "id": "icmp-icmptest-ip@8.8.8.8", "port": null },
"ping": {
"timestamp": "2019-03-05T18:05:30.000Z",
"monitor": {
"status": "up",
"type": "icmp",
"host": null,
"ip": "8.8.8.8",
"duration": { "us": 18897 }
}
},
"upSeries": [
{ "x": 1551807000000, "y": 58 },
{ "x": 1551807300000, "y": 54 },
{ "x": 1551807600000, "y": 60 },
{ "x": 1551807900000, "y": 60 },
{ "x": 1551808200000, "y": 60 },
{ "x": 1551808500000, "y": 60 },
{ "x": 1551808800000, "y": 35 },
{ "x": 1551809100000, "y": 7 }
],
"downSeries": [
{ "x": 1551807000000, "y": 1 },
{ "x": 1551807300000, "y": 1 },
{ "x": 1551807600000, "y": null },
{ "x": 1551807900000, "y": null },
{ "x": 1551808200000, "y": null },
{ "x": 1551808500000, "y": null },
{ "x": 1551808800000, "y": null },
{ "x": 1551809100000, "y": null }
]
},
{
"key": { "id": "tcp-tcp@localhost:9200", "port": 9200 },
"ping": {
"timestamp": "2019-03-05T18:05:32.540Z",
"monitor": {
"status": "up",
"type": "tcp",
"host": "localhost",
"ip": "127.0.0.1",
"duration": { "us": 1914 }
}
},
"upSeries": [
{ "x": 1551807000000, "y": 52 },
{ "x": 1551807300000, "y": 60 },
{ "x": 1551807600000, "y": 60 },
{ "x": 1551807900000, "y": 60 },
{ "x": 1551808200000, "y": 60 },
{ "x": 1551808500000, "y": 60 },
{ "x": 1551808800000, "y": 35 },
{ "x": 1551809100000, "y": 7 }
],
"downSeries": [
{ "x": 1551807000000, "y": 7 },
{ "x": 1551807300000, "y": null },
{ "x": 1551807600000, "y": null },
{ "x": 1551807900000, "y": null },
{ "x": 1551808200000, "y": null },
{ "x": 1551808500000, "y": null },
{ "x": 1551808800000, "y": null },
{ "x": 1551809100000, "y": null }
]
}
]
}
}

View file

@ -0,0 +1,39 @@
{
"monitorStatus": {
"monitors": [
{
"key": { "id": "icmp-icmptest-ip@8.8.8.8", "port": null },
"ping": {
"timestamp": "2019-03-05T18:05:30.000Z",
"monitor": {
"status": "up",
"type": "icmp",
"host": null,
"ip": "8.8.8.8",
"duration": { "us": 18897 }
}
},
"upSeries": [
{ "x": 1551807000000, "y": 58 },
{ "x": 1551807300000, "y": 54 },
{ "x": 1551807600000, "y": 60 },
{ "x": 1551807900000, "y": 60 },
{ "x": 1551808200000, "y": 60 },
{ "x": 1551808500000, "y": 60 },
{ "x": 1551808800000, "y": 35 },
{ "x": 1551809100000, "y": 7 }
],
"downSeries": [
{ "x": 1551807000000, "y": 1 },
{ "x": 1551807300000, "y": 1 },
{ "x": 1551807600000, "y": null },
{ "x": 1551807900000, "y": null },
{ "x": 1551808200000, "y": null },
{ "x": 1551808500000, "y": null },
{ "x": 1551808800000, "y": null },
{ "x": 1551809100000, "y": null }
]
}
]
}
}

View file

@ -184,89 +184,25 @@
}
},
"upSeries": [
{ "x": 1547848920000, "y": 10 },
{ "x": 1547848980000, "y": 20 },
{ "x": 1547849040000, "y": 20 },
{ "x": 1547849100000, "y": 20 },
{ "x": 1547849160000, "y": 20 },
{ "x": 1547849220000, "y": 20 },
{ "x": 1547849280000, "y": 20 },
{ "x": 1547849340000, "y": 20 },
{ "x": 1547849400000, "y": 20 },
{ "x": 1547849460000, "y": 20 },
{ "x": 1547849520000, "y": 20 },
{ "x": 1547849580000, "y": 20 },
{ "x": 1547849640000, "y": 20 },
{ "x": 1547849700000, "y": 20 },
{ "x": 1547849760000, "y": 20 },
{ "x": 1547849820000, "y": 20 },
{ "x": 1547849880000, "y": 20 },
{ "x": 1547849940000, "y": 20 },
{ "x": 1547850000000, "y": 20 },
{ "x": 1547850060000, "y": 20 },
{ "x": 1547850120000, "y": 20 },
{ "x": 1547850180000, "y": 20 },
{ "x": 1547850240000, "y": 20 },
{ "x": 1547850300000, "y": 20 },
{ "x": 1547850360000, "y": 20 },
{ "x": 1547850420000, "y": 20 },
{ "x": 1547850480000, "y": 20 },
{ "x": 1547850540000, "y": 20 },
{ "x": 1547850600000, "y": 20 },
{ "x": 1547850660000, "y": 20 },
{ "x": 1547850720000, "y": 20 },
{ "x": 1547850780000, "y": 20 },
{ "x": 1547850840000, "y": 20 },
{ "x": 1547850900000, "y": 20 },
{ "x": 1547850960000, "y": 20 },
{ "x": 1547851020000, "y": 20 },
{ "x": 1547851080000, "y": 20 },
{ "x": 1547851140000, "y": 20 },
{ "x": 1547851200000, "y": 20 },
{ "x": 1547851260000, "y": 20 },
{ "x": 1547848920000, "y": 90 },
{ "x": 1547849220000, "y": 100 },
{ "x": 1547849520000, "y": 100 },
{ "x": 1547849820000, "y": 100 },
{ "x": 1547850120000, "y": 100 },
{ "x": 1547850420000, "y": 100 },
{ "x": 1547850720000, "y": 100 },
{ "x": 1547851020000, "y": 100 },
{ "x": 1547851320000, "y": 8 }
],
"downSeries": [
{ "x": 1547848920000, "y": null },
{ "x": 1547848980000, "y": null },
{ "x": 1547849040000, "y": null },
{ "x": 1547849100000, "y": null },
{ "x": 1547849160000, "y": null },
{ "x": 1547849220000, "y": null },
{ "x": 1547849280000, "y": null },
{ "x": 1547849340000, "y": null },
{ "x": 1547849400000, "y": null },
{ "x": 1547849460000, "y": null },
{ "x": 1547849520000, "y": null },
{ "x": 1547849580000, "y": null },
{ "x": 1547849640000, "y": null },
{ "x": 1547849700000, "y": null },
{ "x": 1547849760000, "y": null },
{ "x": 1547849820000, "y": null },
{ "x": 1547849880000, "y": null },
{ "x": 1547849940000, "y": null },
{ "x": 1547850000000, "y": null },
{ "x": 1547850060000, "y": null },
{ "x": 1547850120000, "y": null },
{ "x": 1547850180000, "y": null },
{ "x": 1547850240000, "y": null },
{ "x": 1547850300000, "y": null },
{ "x": 1547850360000, "y": null },
{ "x": 1547850420000, "y": null },
{ "x": 1547850480000, "y": null },
{ "x": 1547850540000, "y": null },
{ "x": 1547850600000, "y": null },
{ "x": 1547850660000, "y": null },
{ "x": 1547850720000, "y": null },
{ "x": 1547850780000, "y": null },
{ "x": 1547850840000, "y": null },
{ "x": 1547850900000, "y": null },
{ "x": 1547850960000, "y": null },
{ "x": 1547851020000, "y": null },
{ "x": 1547851080000, "y": null },
{ "x": 1547851140000, "y": null },
{ "x": 1547851200000, "y": null },
{ "x": 1547851260000, "y": null },
{ "x": 1547851320000, "y": null }
]
},

View file

@ -141,89 +141,25 @@
}
},
"upSeries": [
{ "x": 1547848920000, "y": 10 },
{ "x": 1547848980000, "y": 20 },
{ "x": 1547849040000, "y": 20 },
{ "x": 1547849100000, "y": 20 },
{ "x": 1547849160000, "y": 20 },
{ "x": 1547849220000, "y": 20 },
{ "x": 1547849280000, "y": 20 },
{ "x": 1547849340000, "y": 20 },
{ "x": 1547849400000, "y": 20 },
{ "x": 1547849460000, "y": 20 },
{ "x": 1547849520000, "y": 20 },
{ "x": 1547849580000, "y": 20 },
{ "x": 1547849640000, "y": 20 },
{ "x": 1547849700000, "y": 20 },
{ "x": 1547849760000, "y": 20 },
{ "x": 1547849820000, "y": 20 },
{ "x": 1547849880000, "y": 20 },
{ "x": 1547849940000, "y": 20 },
{ "x": 1547850000000, "y": 20 },
{ "x": 1547850060000, "y": 20 },
{ "x": 1547850120000, "y": 20 },
{ "x": 1547850180000, "y": 20 },
{ "x": 1547850240000, "y": 20 },
{ "x": 1547850300000, "y": 20 },
{ "x": 1547850360000, "y": 20 },
{ "x": 1547850420000, "y": 20 },
{ "x": 1547850480000, "y": 20 },
{ "x": 1547850540000, "y": 20 },
{ "x": 1547850600000, "y": 20 },
{ "x": 1547850660000, "y": 20 },
{ "x": 1547850720000, "y": 20 },
{ "x": 1547850780000, "y": 20 },
{ "x": 1547850840000, "y": 20 },
{ "x": 1547850900000, "y": 20 },
{ "x": 1547850960000, "y": 20 },
{ "x": 1547851020000, "y": 20 },
{ "x": 1547851080000, "y": 20 },
{ "x": 1547851140000, "y": 20 },
{ "x": 1547851200000, "y": 20 },
{ "x": 1547851260000, "y": 20 },
{ "x": 1547848920000, "y": 90 },
{ "x": 1547849220000, "y": 100 },
{ "x": 1547849520000, "y": 100 },
{ "x": 1547849820000, "y": 100 },
{ "x": 1547850120000, "y": 100 },
{ "x": 1547850420000, "y": 100 },
{ "x": 1547850720000, "y": 100 },
{ "x": 1547851020000, "y": 100 },
{ "x": 1547851320000, "y": 8 }
],
"downSeries": [
{ "x": 1547848920000, "y": null },
{ "x": 1547848980000, "y": null },
{ "x": 1547849040000, "y": null },
{ "x": 1547849100000, "y": null },
{ "x": 1547849160000, "y": null },
{ "x": 1547849220000, "y": null },
{ "x": 1547849280000, "y": null },
{ "x": 1547849340000, "y": null },
{ "x": 1547849400000, "y": null },
{ "x": 1547849460000, "y": null },
{ "x": 1547849520000, "y": null },
{ "x": 1547849580000, "y": null },
{ "x": 1547849640000, "y": null },
{ "x": 1547849700000, "y": null },
{ "x": 1547849760000, "y": null },
{ "x": 1547849820000, "y": null },
{ "x": 1547849880000, "y": null },
{ "x": 1547849940000, "y": null },
{ "x": 1547850000000, "y": null },
{ "x": 1547850060000, "y": null },
{ "x": 1547850120000, "y": null },
{ "x": 1547850180000, "y": null },
{ "x": 1547850240000, "y": null },
{ "x": 1547850300000, "y": null },
{ "x": 1547850360000, "y": null },
{ "x": 1547850420000, "y": null },
{ "x": 1547850480000, "y": null },
{ "x": 1547850540000, "y": null },
{ "x": 1547850600000, "y": null },
{ "x": 1547850660000, "y": null },
{ "x": 1547850720000, "y": null },
{ "x": 1547850780000, "y": null },
{ "x": 1547850840000, "y": null },
{ "x": 1547850900000, "y": null },
{ "x": 1547850960000, "y": null },
{ "x": 1547851020000, "y": null },
{ "x": 1547851080000, "y": null },
{ "x": 1547851140000, "y": null },
{ "x": 1547851200000, "y": null },
{ "x": 1547851260000, "y": null },
{ "x": 1547851320000, "y": null }
]
},

View file

@ -0,0 +1,80 @@
/*
* 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 expect from 'expect.js';
import monitorList from './fixtures/icmp_monitor_list';
import monitorListFiltered from './fixtures/icmp_monitor_list_filtered';
import icmpFilterList from './fixtures/icmp_filter_list';
import { getFilterBarQueryString } from '../../../../../plugins/uptime/public/components/queries/filter_bar/get_filter_bar';
import { getMonitorListQueryString } from '../../../../../plugins/uptime/public/components/queries/monitor_list/get_monitor_list';
export default function ({ getService }) {
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
const icmpArchive = 'uptime/icmp_docs';
describe('uptime API with ICMP documents', () => {
before('unload non-icmp index', async () => {
await esArchiver.load(icmpArchive);
});
after('re-load non-icmp index', async () => {
await esArchiver.unload(icmpArchive);
});
it('will return a list of monitors including icmp-type', async () => {
const getMonitorListQuery = {
operationName: 'MonitorList',
query: getMonitorListQueryString,
variables: {
dateRangeStart: 1551763670000,
dateRangeEnd: 1551821270000,
},
};
const {
body: { data },
} = await supertest
.post('/api/uptime/graphql')
.set('kbn-xsrf', 'foo')
.send({ ...getMonitorListQuery });
expect(data).to.eql(monitorList);
});
it('will return a list of only icmp-type monitors', async () => {
const getMonitorListQuery = {
operationName: 'MonitorList',
query: getMonitorListQueryString,
variables: {
dateRangeStart: 1551763670000,
dateRangeEnd: 1551821270000,
filters: `{"bool":{"must":[{"match":{"monitor.type":{"query":"icmp","operator":"and"}}}]}}`,
},
};
const {
body: { data },
} = await supertest
.post('/api/uptime/graphql')
.set('kbn-xsrf', 'foo')
.send({ ...getMonitorListQuery });
expect(data).to.eql(monitorListFiltered);
});
it('will return a list of all available filter options for monitor type', async () => {
const getFilterBarQuery = {
operationName: 'FilterBar',
query: getFilterBarQueryString,
variables: { dateRangeStart: 1541821270000, dateRangeEnd: 1551821270000 },
};
const {
body: { data },
} = await supertest
.post('/api/uptime/graphql')
.set('kbn-xsrf', 'foo')
.send({ ...getFilterBarQuery });
expect(data).to.eql(icmpFilterList);
});
});
}

View file

@ -9,8 +9,8 @@ export default function ({ getService, loadTestFile }) {
const archive = 'uptime/full_heartbeat';
describe('graphql queries', () => {
before('load heartbeat data', () => esArchiver.load(archive));
after('unload heartbeat index', () => esArchiver.unload(archive));
before('load heartbeat data', async () => await esArchiver.load(archive));
after('unload heartbeat index', async () => await esArchiver.unload(archive));
// each of these test files imports a GQL query from
// the uptime app and runs it against the live HTTP server,
// verifying the pre-loaded documents are returned in a way that
@ -22,5 +22,6 @@ export default function ({ getService, loadTestFile }) {
loadTestFile(require.resolve('./monitor_status_bar'));
loadTestFile(require.resolve('./ping_list'));
loadTestFile(require.resolve('./snapshot'));
loadTestFile(require.resolve('./icmp_queries'));
});
}

View file

@ -0,0 +1,535 @@
{
"type": "index",
"value": {
"index": "heartbeat-6.7.0.icmp",
"settings": {
"index": {
"number_of_shards": "1",
"analysis": {
"analyzer": {
"url": {
"type": "standard",
"max_token_length": "1000",
"tokenizer": "uax_url_email"
}
}
},
"number_of_replicas": "0"
}
},
"mappings": {
"doc": {
"_meta": {
"version": "6.7.0"
},
"dynamic_templates": [
{
"fields": {
"path_match": "fields.*",
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
},
{
"docker.container.labels": {
"path_match": "docker.container.labels.*",
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
},
{
"strings_as_keyword": {
"match_mapping_type": "string",
"mapping": {
"ignore_above": 1024,
"type": "keyword"
}
}
}
],
"date_detection": false,
"properties": {
"@timestamp": {
"type": "date"
},
"beat": {
"properties": {
"hostname": {
"type": "keyword",
"ignore_above": 1024
},
"name": {
"type": "keyword",
"ignore_above": 1024
},
"timezone": {
"type": "keyword",
"ignore_above": 1024
},
"version": {
"type": "keyword",
"ignore_above": 1024
}
}
},
"cloud": {
"properties": {
"availability_zone": {
"type": "alias",
"path": "meta.cloud.availability_zone"
},
"instance": {
"properties": {
"id": {
"type": "alias",
"path": "meta.cloud.instance_id"
},
"name": {
"type": "alias",
"path": "meta.cloud.instance_name"
}
}
},
"machine": {
"properties": {
"type": {
"type": "alias",
"path": "meta.cloud.machine_type"
}
}
},
"project": {
"properties": {
"id": {
"type": "alias",
"path": "meta.cloud.project_id"
}
}
},
"provider": {
"type": "alias",
"path": "meta.cloud.provider"
},
"region": {
"type": "alias",
"path": "meta.cloud.region"
}
}
},
"container": {
"properties": {
"id": {
"type": "alias",
"path": "docker.container.id"
},
"image": {
"properties": {
"name": {
"type": "alias",
"path": "docker.container.image"
}
}
},
"name": {
"type": "alias",
"path": "docker.container.name"
}
}
},
"docker": {
"properties": {
"container": {
"properties": {
"id": {
"type": "keyword",
"ignore_above": 1024
},
"image": {
"type": "keyword",
"ignore_above": 1024
},
"labels": {
"type": "object"
},
"name": {
"type": "keyword",
"ignore_above": 1024
}
}
}
}
},
"error": {
"properties": {
"code": {
"type": "long"
},
"message": {
"type": "text",
"norms": false
},
"type": {
"type": "keyword",
"ignore_above": 1024
}
}
},
"event": {
"properties": {
"dataset": {
"type": "keyword",
"ignore_above": 1024
},
"timezone": {
"type": "alias",
"path": "beat.timezone"
}
}
},
"fields": {
"type": "object"
},
"host": {
"properties": {
"architecture": {
"type": "keyword",
"ignore_above": 1024
},
"hostname": {
"type": "alias",
"path": "beat.hostname"
},
"id": {
"type": "keyword",
"ignore_above": 1024
},
"ip": {
"type": "ip"
},
"mac": {
"type": "keyword",
"ignore_above": 1024
},
"name": {
"type": "keyword",
"ignore_above": 1024
},
"os": {
"properties": {
"build": {
"type": "keyword",
"ignore_above": 1024
},
"family": {
"type": "keyword",
"ignore_above": 1024
},
"name": {
"type": "keyword",
"ignore_above": 1024
},
"platform": {
"type": "keyword",
"ignore_above": 1024
},
"version": {
"type": "keyword",
"ignore_above": 1024
}
}
}
}
},
"http": {
"properties": {
"response": {
"properties": {
"status_code": {
"type": "long"
}
}
},
"rtt": {
"properties": {
"content": {
"properties": {
"us": {
"type": "long"
}
}
},
"response_header": {
"properties": {
"us": {
"type": "long"
}
}
},
"total": {
"properties": {
"us": {
"type": "long"
}
}
},
"validate": {
"properties": {
"us": {
"type": "long"
}
}
},
"validate_body": {
"properties": {
"us": {
"type": "long"
}
}
},
"write_request": {
"properties": {
"us": {
"type": "long"
}
}
}
}
},
"url": {
"type": "text",
"norms": false,
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 1024
}
}
}
}
},
"icmp": {
"properties": {
"requests": {
"type": "long"
},
"rtt": {
"properties": {
"us": {
"type": "long"
}
}
}
}
},
"kubernetes": {
"properties": {
"annotations": {
"type": "object"
},
"container": {
"properties": {
"image": {
"type": "keyword",
"ignore_above": 1024
},
"name": {
"type": "keyword",
"ignore_above": 1024
}
}
},
"labels": {
"type": "object"
},
"namespace": {
"type": "keyword",
"ignore_above": 1024
},
"node": {
"properties": {
"name": {
"type": "keyword",
"ignore_above": 1024
}
}
},
"pod": {
"properties": {
"name": {
"type": "keyword",
"ignore_above": 1024
},
"uid": {
"type": "keyword",
"ignore_above": 1024
}
}
}
}
},
"meta": {
"properties": {
"cloud": {
"properties": {
"availability_zone": {
"type": "keyword",
"ignore_above": 1024
},
"instance_id": {
"type": "keyword",
"ignore_above": 1024
},
"instance_name": {
"type": "keyword",
"ignore_above": 1024
},
"machine_type": {
"type": "keyword",
"ignore_above": 1024
},
"project_id": {
"type": "keyword",
"ignore_above": 1024
},
"provider": {
"type": "keyword",
"ignore_above": 1024
},
"region": {
"type": "keyword",
"ignore_above": 1024
}
}
}
}
},
"monitor": {
"properties": {
"duration": {
"properties": {
"us": {
"type": "long"
}
}
},
"host": {
"type": "keyword",
"ignore_above": 1024
},
"id": {
"type": "keyword",
"ignore_above": 1024
},
"ip": {
"type": "ip"
},
"name": {
"type": "keyword",
"ignore_above": 1024
},
"scheme": {
"type": "keyword",
"ignore_above": 1024
},
"status": {
"type": "keyword",
"ignore_above": 1024
},
"type": {
"type": "keyword",
"ignore_above": 1024
}
}
},
"resolve": {
"properties": {
"host": {
"type": "keyword",
"ignore_above": 1024
},
"ip": {
"type": "ip"
},
"rtt": {
"properties": {
"us": {
"type": "long"
}
}
}
}
},
"socks5": {
"properties": {
"rtt": {
"properties": {
"connect": {
"properties": {
"us": {
"type": "long"
}
}
}
}
}
}
},
"tags": {
"type": "keyword",
"ignore_above": 1024
},
"tcp": {
"properties": {
"port": {
"type": "long"
},
"rtt": {
"properties": {
"connect": {
"properties": {
"us": {
"type": "long"
}
}
},
"validate": {
"properties": {
"us": {
"type": "long"
}
}
}
}
}
}
},
"tls": {
"properties": {
"certificate_not_valid_after": {
"type": "date"
},
"certificate_not_valid_before": {
"type": "date"
},
"rtt": {
"properties": {
"handshake": {
"properties": {
"us": {
"type": "long"
}
}
}
}
}
}
}
}
}
}
}
}