mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Uptime] Summary based monitors Page (#39751)
This implements the overview page changes described in elastic/uptime#41 and https://docs.google.com/document/d/1jlyOam08gC3oq0W8dim0BF-5QYEOXFqSg48nMwbirmg/edit One change that was necessary was omitting the swimlane visualization. After speaking to the ML team it was discovered that incorporating this component isn't possible yet, as it requires cross-plugin code sharing. In its stead we have re-used the monitor checks over time graph. We may want to keep this, as the graph used here is superior for multiple IP use cases.
This commit is contained in:
parent
53273ecff4
commit
9949107a79
46 changed files with 1244 additions and 1282 deletions
|
@ -154,6 +154,59 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "getSnapshotHistogram",
|
||||
"description": "",
|
||||
"args": [
|
||||
{
|
||||
"name": "dateRangeStart",
|
||||
"description": "",
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "dateRangeEnd",
|
||||
"description": "",
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "filters",
|
||||
"description": "",
|
||||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "monitorId",
|
||||
"description": "",
|
||||
"type": { "kind": "SCALAR", "name": "String", "ofType": null },
|
||||
"defaultValue": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "OBJECT", "name": "HistogramDataPoint", "ofType": null }
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "getMonitorChartsData",
|
||||
"description": "",
|
||||
|
@ -376,7 +429,7 @@
|
|||
"fields": [
|
||||
{
|
||||
"name": "total",
|
||||
"description": "",
|
||||
"description": "Total number of matching pings",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
|
@ -386,9 +439,29 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "locations",
|
||||
"description": "Unique list of all locations the query matched",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "pings",
|
||||
"description": "",
|
||||
"description": "List of pings ",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
|
@ -1915,26 +1988,6 @@
|
|||
"type": { "kind": "SCALAR", "name": "Int", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "histogram",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "OBJECT", "name": "HistogramDataPoint", "ofType": null }
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
|
@ -1999,27 +2052,7 @@
|
|||
"description": "The data used to populate the monitor charts.",
|
||||
"fields": [
|
||||
{
|
||||
"name": "durationArea",
|
||||
"description": "The max and min values for the monitor duration.",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "OBJECT", "name": "MonitorDurationAreaPoint", "ofType": null }
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "durationLine",
|
||||
"name": "locationDurationLines",
|
||||
"description": "The average values for the monitor duration.",
|
||||
"args": [],
|
||||
"type": {
|
||||
|
@ -2031,11 +2064,7 @@
|
|||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "MonitorDurationAveragePoint",
|
||||
"ofType": null
|
||||
}
|
||||
"ofType": { "kind": "OBJECT", "name": "LocationDurationLine", "ofType": null }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2094,34 +2123,42 @@
|
|||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "MonitorDurationAreaPoint",
|
||||
"description": "Represents a monitor's duration performance in microseconds at a point in time.",
|
||||
"name": "LocationDurationLine",
|
||||
"description": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "x",
|
||||
"description": "The timeseries value for this point in time.",
|
||||
"name": "name",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
|
||||
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "yMin",
|
||||
"description": "The min duration value in microseconds at this time.",
|
||||
"name": "line",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "Float", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "yMax",
|
||||
"description": "The max duration value in microseconds at this point.",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "Float", "ofType": null },
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "MonitorDurationAveragePoint",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
|
@ -2131,16 +2168,6 @@
|
|||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "SCALAR",
|
||||
"name": "Float",
|
||||
"description": "The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). ",
|
||||
"fields": null,
|
||||
"inputFields": null,
|
||||
"interfaces": null,
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "MonitorDurationAveragePoint",
|
||||
|
@ -2172,6 +2199,16 @@
|
|||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "SCALAR",
|
||||
"name": "Float",
|
||||
"description": "The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). ",
|
||||
"fields": null,
|
||||
"inputFields": null,
|
||||
"interfaces": null,
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "StatusData",
|
||||
|
@ -3174,6 +3211,45 @@
|
|||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "MonitorDurationAreaPoint",
|
||||
"description": "Represents a monitor's duration performance in microseconds at a point in time.",
|
||||
"fields": [
|
||||
{
|
||||
"name": "x",
|
||||
"description": "The timeseries value for this point in time.",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "SCALAR", "name": "UnsignedInteger", "ofType": null }
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "yMin",
|
||||
"description": "The min duration value in microseconds at this time.",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "Float", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "yMax",
|
||||
"description": "The max duration value in microseconds at this point.",
|
||||
"args": [],
|
||||
"type": { "kind": "SCALAR", "name": "Float", "ofType": null },
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
|
|
|
@ -29,6 +29,8 @@ export interface Query {
|
|||
|
||||
getSnapshot?: Snapshot | null;
|
||||
|
||||
getSnapshotHistogram: HistogramDataPoint[];
|
||||
|
||||
getMonitorChartsData?: MonitorChart | null;
|
||||
/** Fetch the most recent event data for a monitor ID, date range, location. */
|
||||
getLatestMonitors: Ping[];
|
||||
|
@ -41,8 +43,11 @@ export interface Query {
|
|||
}
|
||||
|
||||
export interface PingResults {
|
||||
/** Total number of matching pings */
|
||||
total: UnsignedInteger;
|
||||
|
||||
/** Unique list of all locations the query matched */
|
||||
locations: string[];
|
||||
/** List of pings */
|
||||
pings: Ping[];
|
||||
}
|
||||
/** A request sent from a monitor to a host */
|
||||
|
@ -386,8 +391,6 @@ export interface Snapshot {
|
|||
down?: number | null;
|
||||
|
||||
total?: number | null;
|
||||
|
||||
histogram: HistogramDataPoint[];
|
||||
}
|
||||
|
||||
export interface HistogramDataPoint {
|
||||
|
@ -403,10 +406,8 @@ export interface HistogramDataPoint {
|
|||
}
|
||||
/** The data used to populate the monitor charts. */
|
||||
export interface MonitorChart {
|
||||
/** The max and min values for the monitor duration. */
|
||||
durationArea: MonitorDurationAreaPoint[];
|
||||
/** The average values for the monitor duration. */
|
||||
durationLine: MonitorDurationAveragePoint[];
|
||||
locationDurationLines: LocationDurationLine[];
|
||||
/** The counts of up/down checks for the monitor. */
|
||||
status: StatusData[];
|
||||
/** The maximum status doc count in this chart. */
|
||||
|
@ -414,14 +415,11 @@ export interface MonitorChart {
|
|||
/** The maximum duration value in this chart. */
|
||||
durationMaxValue: number;
|
||||
}
|
||||
/** Represents a monitor's duration performance in microseconds at a point in time. */
|
||||
export interface MonitorDurationAreaPoint {
|
||||
/** The timeseries value for this point in time. */
|
||||
x: UnsignedInteger;
|
||||
/** The min duration value in microseconds at this time. */
|
||||
yMin?: number | null;
|
||||
/** The max duration value in microseconds at this point. */
|
||||
yMax?: number | null;
|
||||
|
||||
export interface LocationDurationLine {
|
||||
name: string;
|
||||
|
||||
line: MonitorDurationAveragePoint[];
|
||||
}
|
||||
/** Represents the average monitor duration ms at a point in time. */
|
||||
export interface MonitorDurationAveragePoint {
|
||||
|
@ -489,6 +487,15 @@ export interface DataPoint {
|
|||
|
||||
y?: number | null;
|
||||
}
|
||||
/** Represents a monitor's duration performance in microseconds at a point in time. */
|
||||
export interface MonitorDurationAreaPoint {
|
||||
/** The timeseries value for this point in time. */
|
||||
x: UnsignedInteger;
|
||||
/** The min duration value in microseconds at this time. */
|
||||
yMin?: number | null;
|
||||
/** The max duration value in microseconds at this point. */
|
||||
yMax?: number | null;
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// Arguments
|
||||
|
@ -524,6 +531,15 @@ export interface GetSnapshotQueryArgs {
|
|||
|
||||
filters?: string | null;
|
||||
}
|
||||
export interface GetSnapshotHistogramQueryArgs {
|
||||
dateRangeStart: string;
|
||||
|
||||
dateRangeEnd: string;
|
||||
|
||||
filters?: string | null;
|
||||
|
||||
monitorId?: string | null;
|
||||
}
|
||||
export interface GetMonitorChartsDataQueryArgs {
|
||||
monitorId: string;
|
||||
|
||||
|
|
|
@ -11,110 +11,56 @@ exports[`MonitorCharts component renders the component without errors 1`] = `
|
|||
}
|
||||
>
|
||||
<DurationChart
|
||||
durationArea={
|
||||
locationDurationLines={
|
||||
Array [
|
||||
Object {
|
||||
"x": 1548697620000,
|
||||
"yMax": 3120392,
|
||||
"yMin": 106421,
|
||||
},
|
||||
Object {
|
||||
"x": 1548697920000,
|
||||
"yMax": 3955186,
|
||||
"yMin": 121653,
|
||||
},
|
||||
Object {
|
||||
"x": 1548698220000,
|
||||
"yMax": 3705359,
|
||||
"yMin": 118224,
|
||||
},
|
||||
Object {
|
||||
"x": 1548698520000,
|
||||
"yMax": 6669234,
|
||||
"yMin": 123345,
|
||||
},
|
||||
Object {
|
||||
"x": 1548698820000,
|
||||
"yMax": 3955729,
|
||||
"yMin": 117268,
|
||||
},
|
||||
Object {
|
||||
"x": 1548699120000,
|
||||
"yMax": 4045216,
|
||||
"yMin": 122110,
|
||||
},
|
||||
Object {
|
||||
"x": 1548699420000,
|
||||
"yMax": 3682859,
|
||||
"yMin": 120015,
|
||||
},
|
||||
Object {
|
||||
"x": 1548699720000,
|
||||
"yMax": 3701297,
|
||||
"yMin": 114751,
|
||||
},
|
||||
Object {
|
||||
"x": 1548700020000,
|
||||
"yMax": 3632224,
|
||||
"yMin": 111949,
|
||||
},
|
||||
Object {
|
||||
"x": 1548700320000,
|
||||
"yMax": 3801401,
|
||||
"yMin": 105126,
|
||||
},
|
||||
Object {
|
||||
"x": 1548700620000,
|
||||
"yMax": 3925269,
|
||||
"yMin": 123639,
|
||||
},
|
||||
]
|
||||
}
|
||||
durationLine={
|
||||
Array [
|
||||
Object {
|
||||
"x": 1548697620000,
|
||||
"y": 743928.2027027027,
|
||||
},
|
||||
Object {
|
||||
"x": 1548697920000,
|
||||
"y": 766840.0133333333,
|
||||
},
|
||||
Object {
|
||||
"x": 1548698220000,
|
||||
"y": 786970.8266666667,
|
||||
},
|
||||
Object {
|
||||
"x": 1548698520000,
|
||||
"y": 781064.7808219178,
|
||||
},
|
||||
Object {
|
||||
"x": 1548698820000,
|
||||
"y": 741563.04,
|
||||
},
|
||||
Object {
|
||||
"x": 1548699120000,
|
||||
"y": 759354.6756756756,
|
||||
},
|
||||
Object {
|
||||
"x": 1548699420000,
|
||||
"y": 737533.3866666667,
|
||||
},
|
||||
Object {
|
||||
"x": 1548699720000,
|
||||
"y": 728669.0266666666,
|
||||
},
|
||||
Object {
|
||||
"x": 1548700020000,
|
||||
"y": 719951.64,
|
||||
},
|
||||
Object {
|
||||
"x": 1548700320000,
|
||||
"y": 769181.7866666666,
|
||||
},
|
||||
Object {
|
||||
"x": 1548700620000,
|
||||
"y": 740805.2666666667,
|
||||
"line": Array [
|
||||
Object {
|
||||
"x": 1548697620000,
|
||||
"y": 743928.2027027027,
|
||||
},
|
||||
Object {
|
||||
"x": 1548697920000,
|
||||
"y": 766840.0133333333,
|
||||
},
|
||||
Object {
|
||||
"x": 1548698220000,
|
||||
"y": 786970.8266666667,
|
||||
},
|
||||
Object {
|
||||
"x": 1548698520000,
|
||||
"y": 781064.7808219178,
|
||||
},
|
||||
Object {
|
||||
"x": 1548698820000,
|
||||
"y": 741563.04,
|
||||
},
|
||||
Object {
|
||||
"x": 1548699120000,
|
||||
"y": 759354.6756756756,
|
||||
},
|
||||
Object {
|
||||
"x": 1548699420000,
|
||||
"y": 737533.3866666667,
|
||||
},
|
||||
Object {
|
||||
"x": 1548699720000,
|
||||
"y": 728669.0266666666,
|
||||
},
|
||||
Object {
|
||||
"x": 1548700020000,
|
||||
"y": 719951.64,
|
||||
},
|
||||
Object {
|
||||
"x": 1548700320000,
|
||||
"y": 769181.7866666666,
|
||||
},
|
||||
Object {
|
||||
"x": 1548700620000,
|
||||
"y": 740805.2666666667,
|
||||
},
|
||||
],
|
||||
"name": "somewhere",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -123,79 +69,18 @@ exports[`MonitorCharts component renders the component without errors 1`] = `
|
|||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<ChecksChart
|
||||
dangerColor="dangerColor"
|
||||
status={
|
||||
Array [
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 74,
|
||||
"up": 74,
|
||||
"x": 1548697620000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 75,
|
||||
"up": 75,
|
||||
"x": 1548697920000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 75,
|
||||
"up": 75,
|
||||
"x": 1548698220000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 73,
|
||||
"up": 73,
|
||||
"x": 1548698520000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 75,
|
||||
"up": 75,
|
||||
"x": 1548698820000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 74,
|
||||
"up": 74,
|
||||
"x": 1548699120000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 75,
|
||||
"up": 75,
|
||||
"x": 1548699420000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 75,
|
||||
"up": 75,
|
||||
"x": 1548699720000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 75,
|
||||
"up": 75,
|
||||
"x": 1548700020000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 75,
|
||||
"up": 75,
|
||||
"x": 1548700320000,
|
||||
},
|
||||
Object {
|
||||
"down": null,
|
||||
"total": 75,
|
||||
"up": 75,
|
||||
"x": 1548700620000,
|
||||
},
|
||||
]
|
||||
<withApollo(Component)
|
||||
absoluteEndDate={1322903730000}
|
||||
absoluteStartDate={1322903730000}
|
||||
dangerColor="#bd271e"
|
||||
successColor="#017d73"
|
||||
variables={
|
||||
Object {
|
||||
"dateRangeEnd": "2011-12-03T10:15:30+01:00",
|
||||
"dateRangeStart": "2011-12-03T10:15:30+01:00",
|
||||
"monitorId": "something",
|
||||
}
|
||||
}
|
||||
successColor="success"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -51,42 +51,98 @@ exports[`PingList component renders sorted list without errors 1`] = `
|
|||
}
|
||||
}
|
||||
>
|
||||
<EuiComboBox
|
||||
aria-label="Status"
|
||||
compressed={false}
|
||||
fullWidth={false}
|
||||
isClearable={false}
|
||||
onChange={[Function]}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"label": "All",
|
||||
"value": "",
|
||||
},
|
||||
Object {
|
||||
"label": "Up",
|
||||
"value": "up",
|
||||
},
|
||||
Object {
|
||||
"label": "Down",
|
||||
"value": "down",
|
||||
},
|
||||
]
|
||||
}
|
||||
selectedOptions={
|
||||
Array [
|
||||
Object {
|
||||
"label": "Down",
|
||||
"value": "down",
|
||||
},
|
||||
]
|
||||
}
|
||||
singleSelection={
|
||||
Object {
|
||||
"asPlainText": true,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow
|
||||
aria-label="Status"
|
||||
describedByIds={Array []}
|
||||
fullWidth={false}
|
||||
hasEmptyLabelSpace={false}
|
||||
label="Status"
|
||||
labelType="label"
|
||||
>
|
||||
<EuiComboBox
|
||||
aria-label="Status"
|
||||
compressed={false}
|
||||
fullWidth={false}
|
||||
isClearable={false}
|
||||
onChange={[Function]}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"label": "All",
|
||||
"value": "",
|
||||
},
|
||||
Object {
|
||||
"label": "Up",
|
||||
"value": "up",
|
||||
},
|
||||
Object {
|
||||
"label": "Down",
|
||||
"value": "down",
|
||||
},
|
||||
]
|
||||
}
|
||||
selectedOptions={
|
||||
Array [
|
||||
Object {
|
||||
"label": "Down",
|
||||
"value": "down",
|
||||
},
|
||||
]
|
||||
}
|
||||
singleSelection={
|
||||
Object {
|
||||
"asPlainText": true,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow
|
||||
aria-label="Location"
|
||||
describedByIds={Array []}
|
||||
fullWidth={false}
|
||||
hasEmptyLabelSpace={false}
|
||||
label="Location"
|
||||
labelType="label"
|
||||
>
|
||||
<EuiComboBox
|
||||
aria-label="Location"
|
||||
compressed={false}
|
||||
fullWidth={false}
|
||||
isClearable={false}
|
||||
onChange={[Function]}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"label": "All",
|
||||
"value": "All",
|
||||
},
|
||||
Object {
|
||||
"label": "nyc",
|
||||
"value": "nyc",
|
||||
},
|
||||
]
|
||||
}
|
||||
selectedOptions={
|
||||
Array [
|
||||
Object {
|
||||
"label": "All",
|
||||
"value": "All",
|
||||
},
|
||||
]
|
||||
}
|
||||
singleSelection={
|
||||
Object {
|
||||
"asPlainText": true,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
|
@ -102,6 +158,12 @@ exports[`PingList component renders sorted list without errors 1`] = `
|
|||
"name": "Status",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"dataType": "number",
|
||||
"field": "observer.geo.name",
|
||||
"name": "Location",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"dataType": "number",
|
||||
"field": "monitor.ip",
|
||||
|
|
|
@ -1,184 +1,65 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Snapshot component renders without errors 1`] = `
|
||||
<EuiFlexGroup
|
||||
gutterSize="s"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={4}
|
||||
<Fragment>
|
||||
<EuiTitle
|
||||
size="xs"
|
||||
>
|
||||
<EuiTitle
|
||||
size="xs"
|
||||
>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
defaultMessage="Current status"
|
||||
id="xpack.uptime.snapshot.endpointStatusTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="s"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
direction="column"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup
|
||||
gutterSize="s"
|
||||
justifyContent="spaceEvenly"
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description="Up"
|
||||
textAlign="center"
|
||||
title={8}
|
||||
titleColor="secondary"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description="Down"
|
||||
textAlign="center"
|
||||
title={2}
|
||||
titleColor="danger"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description="Total"
|
||||
textAlign="center"
|
||||
title={10}
|
||||
titleColor="subdued"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={8}
|
||||
>
|
||||
<EuiTitle
|
||||
size="xs"
|
||||
>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
defaultMessage="Status over time"
|
||||
id="xpack.uptime.snapshot.statusOverTimeTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="s"
|
||||
style={
|
||||
Object {
|
||||
"height": 170,
|
||||
}
|
||||
}
|
||||
>
|
||||
<SnapshotHistogram
|
||||
absoluteEndDate={1548700920000}
|
||||
absoluteStartDate={1548697920000}
|
||||
dangerColor="#F050F0"
|
||||
histogram={
|
||||
Array [
|
||||
Object {
|
||||
"downCount": 3,
|
||||
"upCount": 7,
|
||||
"x": 1548697920000,
|
||||
"x0": 1548697620000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 3,
|
||||
"upCount": 7,
|
||||
"x": 1548698220000,
|
||||
"x0": 1548697920000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 3,
|
||||
"upCount": 7,
|
||||
"x": 1548698520000,
|
||||
"x0": 1548698220000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 3,
|
||||
"upCount": 7,
|
||||
"x": 1548698820000,
|
||||
"x0": 1548698520000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 2,
|
||||
"upCount": 8,
|
||||
"x": 1548699120000,
|
||||
"x0": 1548698820000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 2,
|
||||
"upCount": 8,
|
||||
"x": 1548699420000,
|
||||
"x0": 1548699120000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 2,
|
||||
"upCount": 8,
|
||||
"x": 1548699720000,
|
||||
"x0": 1548699420000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 2,
|
||||
"upCount": 8,
|
||||
"x": 1548700020000,
|
||||
"x0": 1548699720000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 2,
|
||||
"upCount": 8,
|
||||
"x": 1548700320000,
|
||||
"x0": 1548700020000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 2,
|
||||
"upCount": 8,
|
||||
"x": 1548700620000,
|
||||
"x0": 1548700320000,
|
||||
"y": 1,
|
||||
},
|
||||
Object {
|
||||
"downCount": 2,
|
||||
"upCount": 8,
|
||||
"x": 1548700920000,
|
||||
"x0": 1548700620000,
|
||||
"y": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
successColor="#000000"
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
defaultMessage="Current status"
|
||||
id="xpack.uptime.snapshot.endpointStatusTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="s"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
direction="column"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup
|
||||
gutterSize="s"
|
||||
justifyContent="spaceEvenly"
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description="Up"
|
||||
textAlign="center"
|
||||
title={8}
|
||||
titleColor="secondary"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description="Down"
|
||||
textAlign="center"
|
||||
title={2}
|
||||
titleColor="danger"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description="Total"
|
||||
textAlign="center"
|
||||
title={10}
|
||||
titleColor="subdued"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
</Fragment>
|
||||
`;
|
||||
|
|
|
@ -12,31 +12,23 @@ import { MonitorChart } from '../../../../common/graphql/types';
|
|||
describe('MonitorCharts component', () => {
|
||||
const chartResponse: { monitorChartsData: MonitorChart } = {
|
||||
monitorChartsData: {
|
||||
durationArea: [
|
||||
{ x: 1548697620000, yMin: 106421, yMax: 3120392 },
|
||||
{ x: 1548697920000, yMin: 121653, yMax: 3955186 },
|
||||
{ x: 1548698220000, yMin: 118224, yMax: 3705359 },
|
||||
{ x: 1548698520000, yMin: 123345, yMax: 6669234 },
|
||||
{ x: 1548698820000, yMin: 117268, yMax: 3955729 },
|
||||
{ x: 1548699120000, yMin: 122110, yMax: 4045216 },
|
||||
{ x: 1548699420000, yMin: 120015, yMax: 3682859 },
|
||||
{ x: 1548699720000, yMin: 114751, yMax: 3701297 },
|
||||
{ x: 1548700020000, yMin: 111949, yMax: 3632224 },
|
||||
{ x: 1548700320000, yMin: 105126, yMax: 3801401 },
|
||||
{ x: 1548700620000, yMin: 123639, yMax: 3925269 },
|
||||
],
|
||||
durationLine: [
|
||||
{ x: 1548697620000, y: 743928.2027027027 },
|
||||
{ x: 1548697920000, y: 766840.0133333333 },
|
||||
{ x: 1548698220000, y: 786970.8266666667 },
|
||||
{ x: 1548698520000, y: 781064.7808219178 },
|
||||
{ x: 1548698820000, y: 741563.04 },
|
||||
{ x: 1548699120000, y: 759354.6756756756 },
|
||||
{ x: 1548699420000, y: 737533.3866666667 },
|
||||
{ x: 1548699720000, y: 728669.0266666666 },
|
||||
{ x: 1548700020000, y: 719951.64 },
|
||||
{ x: 1548700320000, y: 769181.7866666666 },
|
||||
{ x: 1548700620000, y: 740805.2666666667 },
|
||||
locationDurationLines: [
|
||||
{
|
||||
name: 'somewhere',
|
||||
line: [
|
||||
{ x: 1548697620000, y: 743928.2027027027 },
|
||||
{ x: 1548697920000, y: 766840.0133333333 },
|
||||
{ x: 1548698220000, y: 786970.8266666667 },
|
||||
{ x: 1548698520000, y: 781064.7808219178 },
|
||||
{ x: 1548698820000, y: 741563.04 },
|
||||
{ x: 1548699120000, y: 759354.6756756756 },
|
||||
{ x: 1548699420000, y: 737533.3866666667 },
|
||||
{ x: 1548699720000, y: 728669.0266666666 },
|
||||
{ x: 1548700020000, y: 719951.64 },
|
||||
{ x: 1548700320000, y: 769181.7866666666 },
|
||||
{ x: 1548700620000, y: 740805.2666666667 },
|
||||
],
|
||||
},
|
||||
],
|
||||
status: [
|
||||
{ x: 1548697620000, up: 74, down: null, total: 74 },
|
||||
|
@ -65,6 +57,9 @@ describe('MonitorCharts component', () => {
|
|||
mean="mean"
|
||||
range="range"
|
||||
success="success"
|
||||
monitorId="something"
|
||||
dateRangeStart="2011-12-03T10:15:30+01:00"
|
||||
dateRangeEnd="2011-12-03T10:15:30+01:00"
|
||||
/>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { PingResults } from '../../../../common/graphql/types';
|
||||
import { PingListComponent } from '../ping_list';
|
||||
import { PingListComponent, BaseLocationOptions } from '../ping_list';
|
||||
import { EuiComboBoxProps } from '@elastic/eui';
|
||||
|
||||
describe('PingList component', () => {
|
||||
let pingList: { allPings: PingResults };
|
||||
|
@ -181,6 +182,7 @@ describe('PingList component', () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
locations: ['nyc'],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -194,6 +196,8 @@ describe('PingList component', () => {
|
|||
onUpdateApp={jest.fn()}
|
||||
onSelectedStatusUpdate={jest.fn()}
|
||||
selectedOption="down"
|
||||
selectedLocation={BaseLocationOptions}
|
||||
setSelectedLocation={(loc: EuiComboBoxProps[]) => {}}
|
||||
/>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
|
|
|
@ -14,19 +14,6 @@ describe('Snapshot component', () => {
|
|||
up: 8,
|
||||
down: 2,
|
||||
total: 10,
|
||||
histogram: [
|
||||
{ upCount: 7, downCount: 3, x: 1548697920000, x0: 1548697620000, y: 1 },
|
||||
{ upCount: 7, downCount: 3, x: 1548698220000, x0: 1548697920000, y: 1 },
|
||||
{ upCount: 7, downCount: 3, x: 1548698520000, x0: 1548698220000, y: 1 },
|
||||
{ upCount: 7, downCount: 3, x: 1548698820000, x0: 1548698520000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548699120000, x0: 1548698820000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548699420000, x0: 1548699120000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548699720000, x0: 1548699420000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548700020000, x0: 1548699720000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548700320000, x0: 1548700020000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548700620000, x0: 1548700320000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548700920000, x0: 1548700620000, y: 1 },
|
||||
],
|
||||
};
|
||||
|
||||
it('renders without errors', () => {
|
||||
|
|
|
@ -1,179 +1,7 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`SnapshotHistogram component renders the component without errors 1`] = `
|
||||
<Fragment>
|
||||
<Chart
|
||||
renderer="canvas"
|
||||
>
|
||||
<inject-SettingsComponent-with-chartStore
|
||||
showLegend={false}
|
||||
xDomain={
|
||||
Object {
|
||||
"max": 1548700920000,
|
||||
"min": 1548697920000,
|
||||
}
|
||||
}
|
||||
/>
|
||||
<inject-AxisSpec-with-chartStore
|
||||
id="Snapshot X Axis"
|
||||
position="bottom"
|
||||
showOverlappingTicks={false}
|
||||
tickFormat={[Function]}
|
||||
/>
|
||||
<inject-AxisSpec-with-chartStore
|
||||
id="Snapshot Y Axis"
|
||||
position="left"
|
||||
showOverlappingTicks={true}
|
||||
title="Monitors"
|
||||
/>
|
||||
<inject-BarSeriesSpecComponent-with-chartStore
|
||||
customSeriesColors={
|
||||
Map {
|
||||
Object {
|
||||
"colorValues": Array [],
|
||||
"specId": "Up",
|
||||
} => "#FEFEFE",
|
||||
}
|
||||
}
|
||||
data={
|
||||
Array [
|
||||
Array [
|
||||
1548697920000,
|
||||
7,
|
||||
],
|
||||
Array [
|
||||
1548698220000,
|
||||
7,
|
||||
],
|
||||
Array [
|
||||
1548698520000,
|
||||
7,
|
||||
],
|
||||
Array [
|
||||
1548698820000,
|
||||
7,
|
||||
],
|
||||
Array [
|
||||
1548699120000,
|
||||
8,
|
||||
],
|
||||
Array [
|
||||
1548699420000,
|
||||
8,
|
||||
],
|
||||
Array [
|
||||
1548699720000,
|
||||
8,
|
||||
],
|
||||
Array [
|
||||
1548700020000,
|
||||
8,
|
||||
],
|
||||
Array [
|
||||
1548700320000,
|
||||
8,
|
||||
],
|
||||
Array [
|
||||
1548700620000,
|
||||
8,
|
||||
],
|
||||
Array [
|
||||
1548700920000,
|
||||
8,
|
||||
],
|
||||
]
|
||||
}
|
||||
id="Up"
|
||||
name="Up"
|
||||
stackAccessors={
|
||||
Array [
|
||||
0,
|
||||
]
|
||||
}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType="time"
|
||||
yAccessors={
|
||||
Array [
|
||||
1,
|
||||
]
|
||||
}
|
||||
yScaleType="linear"
|
||||
/>
|
||||
<inject-BarSeriesSpecComponent-with-chartStore
|
||||
customSeriesColors={
|
||||
Map {
|
||||
Object {
|
||||
"colorValues": Array [],
|
||||
"specId": "Down Monitors",
|
||||
} => "#FF00FF",
|
||||
}
|
||||
}
|
||||
data={
|
||||
Array [
|
||||
Array [
|
||||
1548697920000,
|
||||
3,
|
||||
],
|
||||
Array [
|
||||
1548698220000,
|
||||
3,
|
||||
],
|
||||
Array [
|
||||
1548698520000,
|
||||
3,
|
||||
],
|
||||
Array [
|
||||
1548698820000,
|
||||
3,
|
||||
],
|
||||
Array [
|
||||
1548699120000,
|
||||
2,
|
||||
],
|
||||
Array [
|
||||
1548699420000,
|
||||
2,
|
||||
],
|
||||
Array [
|
||||
1548699720000,
|
||||
2,
|
||||
],
|
||||
Array [
|
||||
1548700020000,
|
||||
2,
|
||||
],
|
||||
Array [
|
||||
1548700320000,
|
||||
2,
|
||||
],
|
||||
Array [
|
||||
1548700620000,
|
||||
2,
|
||||
],
|
||||
Array [
|
||||
1548700920000,
|
||||
2,
|
||||
],
|
||||
]
|
||||
}
|
||||
id="Down Monitors"
|
||||
name="Down"
|
||||
stackAccessors={
|
||||
Array [
|
||||
0,
|
||||
]
|
||||
}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType="time"
|
||||
yAccessors={
|
||||
Array [
|
||||
1,
|
||||
]
|
||||
}
|
||||
yScaleType="linear"
|
||||
/>
|
||||
</Chart>
|
||||
</Fragment>
|
||||
<ApolloConsumer>
|
||||
<Component />
|
||||
</ApolloConsumer>
|
||||
`;
|
||||
|
|
|
@ -14,23 +14,10 @@ describe('SnapshotHistogram component', () => {
|
|||
absoluteEndDate: 1548700920000,
|
||||
successColor: '#FEFEFE',
|
||||
dangerColor: '#FF00FF',
|
||||
histogram: [
|
||||
{ upCount: 7, downCount: 3, x: 1548697920000, x0: 1548697620000, y: 1 },
|
||||
{ upCount: 7, downCount: 3, x: 1548698220000, x0: 1548697920000, y: 1 },
|
||||
{ upCount: 7, downCount: 3, x: 1548698520000, x0: 1548698220000, y: 1 },
|
||||
{ upCount: 7, downCount: 3, x: 1548698820000, x0: 1548698520000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548699120000, x0: 1548698820000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548699420000, x0: 1548699120000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548699720000, x0: 1548699420000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548700020000, x0: 1548699720000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548700320000, x0: 1548700020000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548700620000, x0: 1548700320000, y: 1 },
|
||||
{ upCount: 8, downCount: 2, x: 1548700920000, x0: 1548700620000, y: 1 },
|
||||
],
|
||||
};
|
||||
|
||||
it('renders the component without errors', () => {
|
||||
const component = shallowWithIntl(<SnapshotHistogram {...props} />);
|
||||
const component = shallowWithIntl(<SnapshotHistogram {...props} variables={{}} />);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
AreaSeries,
|
||||
Axis,
|
||||
Chart,
|
||||
CurveType,
|
||||
|
@ -25,24 +24,16 @@ import {
|
|||
convertMicrosecondsToMilliseconds as microsToMillis,
|
||||
getChartDateLabel,
|
||||
} from '../../../lib/helper';
|
||||
import {
|
||||
MonitorDurationAreaPoint,
|
||||
MonitorDurationAveragePoint,
|
||||
} from '../../../../common/graphql/types';
|
||||
import { LocationDurationLine } from '../../../../common/graphql/types';
|
||||
import { UptimeSettingsContext } from '../../../contexts';
|
||||
import { getColorsMap } from './get_colors_map';
|
||||
|
||||
interface DurationChartProps {
|
||||
/**
|
||||
* Timeseries data that is used to express a max/min area series
|
||||
* on the duration chart.
|
||||
*/
|
||||
durationArea: MonitorDurationAreaPoint[];
|
||||
/**
|
||||
* Timeseries data that is used to express an average line series
|
||||
* on the duration chart.
|
||||
* on the duration chart. One entry per location
|
||||
*/
|
||||
durationLine: MonitorDurationAveragePoint[];
|
||||
locationDurationLines: LocationDurationLine[];
|
||||
/**
|
||||
* The color to be used for the average duration series.
|
||||
*/
|
||||
|
@ -60,17 +51,32 @@ interface DurationChartProps {
|
|||
* @param props The props required for this component to render properly
|
||||
*/
|
||||
export const DurationChart = ({
|
||||
durationArea,
|
||||
durationLine,
|
||||
locationDurationLines,
|
||||
meanColor,
|
||||
rangeColor,
|
||||
}: DurationChartProps) => {
|
||||
const { absoluteStartDate, absoluteEndDate } = useContext(UptimeSettingsContext);
|
||||
// this id is used for the area chart representing the max/min of check durations
|
||||
const areaSpecId = getSpecId('area');
|
||||
|
||||
// this id is used for the line chart representing the average duration length
|
||||
const averageSpecId = getSpecId('average');
|
||||
const averageSpecId = getSpecId('average-');
|
||||
|
||||
const lineSeries = locationDurationLines.map(line => {
|
||||
const locationSpecId = getSpecId('loc-avg' + line.name);
|
||||
return (
|
||||
<LineSeries
|
||||
curve={CurveType.CURVE_MONOTONE_X}
|
||||
customSeriesColors={getColorsMap(meanColor, averageSpecId)}
|
||||
data={line.line.map(({ x, y }) => [x || 0, microsToMillis(y)])}
|
||||
id={locationSpecId}
|
||||
key={`locline-${line.name}`}
|
||||
name={line.name}
|
||||
xAccessor={0}
|
||||
xScaleType={ScaleType.Time}
|
||||
yAccessors={[1]}
|
||||
yScaleToDataExtent={false}
|
||||
yScaleType={ScaleType.Linear}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
|
@ -85,7 +91,11 @@ export const DurationChart = ({
|
|||
</EuiTitle>
|
||||
<EuiPanel>
|
||||
<Chart>
|
||||
<Settings xDomain={{ min: absoluteStartDate, max: absoluteEndDate }} showLegend={false} />
|
||||
<Settings
|
||||
xDomain={{ min: absoluteStartDate, max: absoluteEndDate }}
|
||||
showLegend={true}
|
||||
legendPosition={Position.Bottom}
|
||||
/>
|
||||
<Axis
|
||||
id={getAxisId('bottom')}
|
||||
position={Position.Bottom}
|
||||
|
@ -104,45 +114,7 @@ export const DurationChart = ({
|
|||
defaultMessage: 'Duration ms',
|
||||
})}
|
||||
/>
|
||||
<AreaSeries
|
||||
curve={CurveType.CURVE_MONOTONE_X}
|
||||
customSeriesColors={getColorsMap(rangeColor, areaSpecId)}
|
||||
data={durationArea.map(({ x, yMin, yMax }) => ({
|
||||
x,
|
||||
Min: microsToMillis(yMin),
|
||||
Max: microsToMillis(yMax),
|
||||
}))}
|
||||
id={areaSpecId}
|
||||
name={i18n.translate(
|
||||
'xpack.uptime.monitorCharts.monitorDuration.series.durationRangeLabel',
|
||||
{
|
||||
defaultMessage: 'Duration range',
|
||||
}
|
||||
)}
|
||||
xAccessor={'x'}
|
||||
xScaleType={ScaleType.Time}
|
||||
yAccessors={['Max']}
|
||||
yScaleType={ScaleType.Linear}
|
||||
y0Accessors={['Min']}
|
||||
yScaleToDataExtent={false}
|
||||
/>
|
||||
<LineSeries
|
||||
curve={CurveType.CURVE_MONOTONE_X}
|
||||
customSeriesColors={getColorsMap(meanColor, averageSpecId)}
|
||||
data={durationLine.map(({ x, y }) => [x || 0, microsToMillis(y)])}
|
||||
id={averageSpecId}
|
||||
name={i18n.translate(
|
||||
'xpack.uptime.monitorCharts.monitorDuration.series.meanDurationLabel',
|
||||
{
|
||||
defaultMessage: 'Mean duration',
|
||||
}
|
||||
)}
|
||||
xAccessor={0}
|
||||
xScaleType={ScaleType.Time}
|
||||
yAccessors={[1]}
|
||||
yScaleToDataExtent={false}
|
||||
yScaleType={ScaleType.Linear}
|
||||
/>
|
||||
{lineSeries}
|
||||
</Chart>
|
||||
</EuiPanel>
|
||||
</React.Fragment>
|
||||
|
|
|
@ -15,11 +15,15 @@ import {
|
|||
timeFormatter,
|
||||
Settings,
|
||||
} from '@elastic/charts';
|
||||
import { EuiEmptyPrompt, EuiTitle, EuiPanel } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { Fragment } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { HistogramDataPoint } from '../../../../common/graphql/types';
|
||||
import { getColorsMap } from './get_colors_map';
|
||||
import { getChartDateLabel } from '../../../lib/helper';
|
||||
import { withUptimeGraphQL, UptimeGraphQLQueryProps } from '../../higher_order';
|
||||
import { snapshotHistogramQuery } from '../../../queries/snapshot_histogram_query';
|
||||
|
||||
export interface SnapshotHistogramProps {
|
||||
/**
|
||||
|
@ -38,19 +42,61 @@ export interface SnapshotHistogramProps {
|
|||
* The color value that is used to represent down checks.
|
||||
*/
|
||||
dangerColor: string;
|
||||
/**
|
||||
* The data the histogram will visualize.
|
||||
*/
|
||||
histogram: HistogramDataPoint[];
|
||||
}
|
||||
|
||||
export const SnapshotHistogram = ({
|
||||
interface SnapshotHistogramQueryResult {
|
||||
histogram?: HistogramDataPoint[];
|
||||
}
|
||||
|
||||
type Props = UptimeGraphQLQueryProps<SnapshotHistogramQueryResult> & SnapshotHistogramProps;
|
||||
|
||||
export const SnapshotHistogramComponent = ({
|
||||
absoluteStartDate,
|
||||
absoluteEndDate,
|
||||
dangerColor,
|
||||
histogram,
|
||||
successColor,
|
||||
}: SnapshotHistogramProps) => {
|
||||
data,
|
||||
}: Props) => {
|
||||
if (!data || !data.histogram)
|
||||
/**
|
||||
* TODO: the Fragment, EuiTitle, and EuiPanel should be extractec to a dumb component
|
||||
* that we can reuse in the subsequent return statement at the bottom of this function.
|
||||
*/
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.statusOverTimeTitle"
|
||||
defaultMessage="Status over time"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiPanel paddingSize="s" style={{ height: 170 }}>
|
||||
<EuiEmptyPrompt
|
||||
title={
|
||||
<EuiTitle>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.noDataTitle"
|
||||
defaultMessage="No histogram data available"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
}
|
||||
body={
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.noDataDescription"
|
||||
defaultMessage="Sorry, there is no data available for the histogram"
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</Fragment>
|
||||
);
|
||||
const { histogram } = data;
|
||||
const downMonitorsName = i18n.translate('xpack.uptime.snapshotHistogram.downMonitorsId', {
|
||||
defaultMessage: 'Down Monitors',
|
||||
});
|
||||
|
@ -62,57 +108,72 @@ export const SnapshotHistogram = ({
|
|||
const upSpecId = getSpecId(upMonitorsId);
|
||||
return (
|
||||
<Fragment>
|
||||
<Chart>
|
||||
<Settings xDomain={{ min: absoluteStartDate, max: absoluteEndDate }} showLegend={false} />
|
||||
<Axis
|
||||
id={getAxisId(
|
||||
i18n.translate('xpack.uptime.snapshotHistogram.xAxisId', {
|
||||
defaultMessage: 'Snapshot X Axis',
|
||||
})
|
||||
)}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={false}
|
||||
tickFormat={timeFormatter(getChartDateLabel(absoluteStartDate, absoluteEndDate))}
|
||||
/>
|
||||
<Axis
|
||||
id={getAxisId(
|
||||
i18n.translate('xpack.uptime.snapshotHistogram.yAxisId', {
|
||||
defaultMessage: 'Snapshot Y Axis',
|
||||
})
|
||||
)}
|
||||
position={Position.Left}
|
||||
showOverlappingTicks={true}
|
||||
title={i18n.translate('xpack.uptime.snapshotHistogram.yAxis.title', {
|
||||
defaultMessage: 'Monitors',
|
||||
})}
|
||||
/>
|
||||
<BarSeries
|
||||
customSeriesColors={getColorsMap(successColor, upSpecId)}
|
||||
data={histogram.map(({ x, upCount }) => [x, upCount || 0])}
|
||||
id={upSpecId}
|
||||
name={upMonitorsId}
|
||||
stackAccessors={[0]}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType={ScaleType.Time}
|
||||
yAccessors={[1]}
|
||||
yScaleType={ScaleType.Linear}
|
||||
/>
|
||||
<BarSeries
|
||||
customSeriesColors={getColorsMap(dangerColor, downSpecId)}
|
||||
data={histogram.map(({ x, downCount }) => [x, downCount || 0])}
|
||||
id={downSpecId}
|
||||
name={i18n.translate('xpack.uptime.snapshotHistogram.series.downLabel', {
|
||||
defaultMessage: 'Down',
|
||||
})}
|
||||
stackAccessors={[0]}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType={ScaleType.Time}
|
||||
yAccessors={[1]}
|
||||
yScaleType={ScaleType.Linear}
|
||||
/>
|
||||
</Chart>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.statusOverTimeTitle"
|
||||
defaultMessage="Status over time"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiPanel paddingSize="s" style={{ height: 170 }}>
|
||||
<Chart>
|
||||
<Settings xDomain={{ min: absoluteStartDate, max: absoluteEndDate }} showLegend={false} />
|
||||
<Axis
|
||||
id={getAxisId(
|
||||
i18n.translate('xpack.uptime.snapshotHistogram.xAxisId', {
|
||||
defaultMessage: 'Snapshot X Axis',
|
||||
})
|
||||
)}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={false}
|
||||
tickFormat={timeFormatter(getChartDateLabel(absoluteStartDate, absoluteEndDate))}
|
||||
/>
|
||||
<Axis
|
||||
id={getAxisId(
|
||||
i18n.translate('xpack.uptime.snapshotHistogram.yAxisId', {
|
||||
defaultMessage: 'Snapshot Y Axis',
|
||||
})
|
||||
)}
|
||||
position={Position.Left}
|
||||
showOverlappingTicks={true}
|
||||
title={i18n.translate('xpack.uptime.snapshotHistogram.yAxis.title', {
|
||||
defaultMessage: 'Monitors',
|
||||
})}
|
||||
/>
|
||||
<BarSeries
|
||||
customSeriesColors={getColorsMap(successColor, upSpecId)}
|
||||
data={histogram.map(({ x, upCount }) => [x, upCount || 0])}
|
||||
id={upSpecId}
|
||||
name={upMonitorsId}
|
||||
stackAccessors={[0]}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType={ScaleType.Time}
|
||||
yAccessors={[1]}
|
||||
yScaleType={ScaleType.Linear}
|
||||
/>
|
||||
<BarSeries
|
||||
customSeriesColors={getColorsMap(dangerColor, downSpecId)}
|
||||
data={histogram.map(({ x, downCount }) => [x, downCount || 0])}
|
||||
id={downSpecId}
|
||||
name={i18n.translate('xpack.uptime.snapshotHistogram.series.downLabel', {
|
||||
defaultMessage: 'Down',
|
||||
})}
|
||||
stackAccessors={[0]}
|
||||
timeZone="local"
|
||||
xAccessor={0}
|
||||
xScaleType={ScaleType.Time}
|
||||
yAccessors={[1]}
|
||||
yScaleType={ScaleType.Linear}
|
||||
/>
|
||||
</Chart>
|
||||
</EuiPanel>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export const SnapshotHistogram = withUptimeGraphQL<
|
||||
SnapshotHistogramQueryResult,
|
||||
SnapshotHistogramProps
|
||||
>(SnapshotHistogramComponent, snapshotHistogramQuery);
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 { EuiIcon, EuiLink, EuiText } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
interface LocationNameProps {
|
||||
location: string | null | undefined;
|
||||
}
|
||||
export const LocationName = ({ location }: LocationNameProps) =>
|
||||
!!location ? (
|
||||
<EuiText>{location}</EuiText>
|
||||
) : (
|
||||
<EuiLink
|
||||
href="https://www.elastic.co/guide/en/beats/heartbeat/current/configuration-observer-options.html"
|
||||
target="_blank"
|
||||
>
|
||||
{i18n.translate('xpack.uptime.locationName.helpLinkAnnotation', {
|
||||
defaultMessage: 'Add location',
|
||||
description:
|
||||
'Text that instructs the user to navigate to our docs to add a geographic location to their data',
|
||||
})}
|
||||
|
||||
<EuiIcon size="s" type="popout" />
|
||||
</EuiLink>
|
||||
);
|
|
@ -6,46 +6,62 @@
|
|||
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { Fragment } from 'react';
|
||||
import React, { Fragment, useContext } from 'react';
|
||||
import DateMath from '@elastic/datemath';
|
||||
import { Moment } from 'moment';
|
||||
import { MonitorChart } from '../../../common/graphql/types';
|
||||
import { UptimeGraphQLQueryProps, withUptimeGraphQL } from '../higher_order';
|
||||
import { monitorChartsQuery } from '../../queries';
|
||||
import { DurationChart } from './charts';
|
||||
import { ChecksChart } from './charts/checks_chart';
|
||||
import { UptimeSettingsContext } from '../../contexts';
|
||||
import { SnapshotHistogram } from './charts/snapshot_histogram';
|
||||
|
||||
interface MonitorChartsQueryResult {
|
||||
monitorChartsData?: MonitorChart;
|
||||
}
|
||||
|
||||
interface MonitorChartsProps {
|
||||
monitorId: string;
|
||||
danger: string;
|
||||
mean: string;
|
||||
range: string;
|
||||
success: string;
|
||||
dateRangeStart: string;
|
||||
dateRangeEnd: string;
|
||||
}
|
||||
|
||||
type Props = MonitorChartsProps & UptimeGraphQLQueryProps<MonitorChartsQueryResult>;
|
||||
|
||||
export const MonitorChartsComponent = (props: Props) => {
|
||||
const { danger, data, mean, range, success } = props;
|
||||
const { data, mean, range, monitorId, dateRangeStart, dateRangeEnd } = props;
|
||||
if (data && data.monitorChartsData) {
|
||||
const {
|
||||
monitorChartsData: { durationArea, durationLine, status },
|
||||
monitorChartsData: { locationDurationLines },
|
||||
} = data;
|
||||
|
||||
const { colors } = useContext(UptimeSettingsContext);
|
||||
const parseDateRange = (r: string): number => {
|
||||
const parsed: Moment | undefined = DateMath.parse(r);
|
||||
return parsed ? parsed.valueOf() : 0;
|
||||
};
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem style={{ height: 400 }}>
|
||||
<DurationChart
|
||||
durationArea={durationArea}
|
||||
durationLine={durationLine}
|
||||
locationDurationLines={locationDurationLines}
|
||||
meanColor={mean}
|
||||
rangeColor={range}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<ChecksChart dangerColor={danger} status={status} successColor={success} />
|
||||
<SnapshotHistogram
|
||||
absoluteStartDate={parseDateRange(dateRangeStart)}
|
||||
absoluteEndDate={parseDateRange(dateRangeEnd)}
|
||||
successColor={colors.success}
|
||||
dangerColor={colors.danger}
|
||||
variables={{ dateRangeStart, dateRangeEnd, monitorId }}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</Fragment>
|
||||
|
|
|
@ -25,6 +25,7 @@ import { MonitorListActionsPopover } from './monitor_list_actions_popover';
|
|||
import { MonitorPageLink } from './monitor_page_link';
|
||||
import { MonitorListStatusColumn } from './monitor_list_status_column';
|
||||
import { MonitorBarSeries } from './charts';
|
||||
import { LocationName } from './location_name';
|
||||
|
||||
interface MonitorListQueryResult {
|
||||
// TODO: clean up this ugly result data shape, there should be no nesting
|
||||
|
@ -121,11 +122,7 @@ export const MonitorListComponent = ({
|
|||
defaultMessage: 'ID',
|
||||
}),
|
||||
render: (id: string, monitor: LatestMonitor) => (
|
||||
<MonitorPageLink
|
||||
id={id}
|
||||
location={get<string | undefined>(monitor, 'ping.observer.geo.name')}
|
||||
linkParameters={linkParameters}
|
||||
>
|
||||
<MonitorPageLink id={id} location={undefined} linkParameters={linkParameters}>
|
||||
{monitor.ping && monitor.ping.monitor && monitor.ping.monitor.name
|
||||
? monitor.ping.monitor.name
|
||||
: id}
|
||||
|
@ -138,23 +135,7 @@ export const MonitorListComponent = ({
|
|||
defaultMessage: 'Location',
|
||||
description: 'Users can specify a name for a location',
|
||||
}),
|
||||
render: (locationName: string | null | undefined) =>
|
||||
!!locationName ? (
|
||||
locationName
|
||||
) : (
|
||||
<EuiLink
|
||||
href="https://www.elastic.co/guide/en/beats/heartbeat/current/configuration-observer-options.html"
|
||||
target="_blank"
|
||||
>
|
||||
{i18n.translate('xpack.uptime.monitorList.geoName.helpLinkAnnotation', {
|
||||
defaultMessage: 'Add location',
|
||||
description:
|
||||
'Text that instructs the user to navigate to our docs to add a geographic location to their data',
|
||||
})}
|
||||
|
||||
<EuiIcon size="s" type="popout" />
|
||||
</EuiLink>
|
||||
),
|
||||
render: (location: string) => <LocationName location={location} />,
|
||||
},
|
||||
{
|
||||
field: 'ping.url.full',
|
||||
|
|
|
@ -28,11 +28,10 @@ type Props = MonitorStatusBarProps & UptimeGraphQLQueryProps<MonitorStatusBarQue
|
|||
|
||||
export const MonitorStatusBarComponent = ({ data, monitorId }: Props) => {
|
||||
if (data && data.monitorStatus && data.monitorStatus.length) {
|
||||
const { monitor, observer, timestamp } = data.monitorStatus[0];
|
||||
const { monitor, timestamp } = data.monitorStatus[0];
|
||||
const duration = get(monitor, 'duration.us', undefined);
|
||||
const status = get<'up' | 'down'>(monitor, 'status', 'down');
|
||||
const full = get(data.monitorStatus[0], 'url.full');
|
||||
const location = get(observer, 'geo.name');
|
||||
const full = get<string>(data.monitorStatus[0], 'url.full');
|
||||
return (
|
||||
<EuiPanel>
|
||||
<EuiFlexGroup gutterSize="l">
|
||||
|
@ -98,16 +97,6 @@ export const MonitorStatusBarComponent = ({ data, monitorId }: Props) => {
|
|||
>
|
||||
{moment(new Date(timestamp).valueOf()).fromNow()}
|
||||
</EuiFlexItem>
|
||||
{!!location && (
|
||||
<EuiFlexItem
|
||||
aria-label={i18n.translate('xpack.uptime.monitorStatusBar.locationName', {
|
||||
defaultMessage: 'Location',
|
||||
})}
|
||||
grow={false}
|
||||
>
|
||||
{location}
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
);
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
EuiToolTip,
|
||||
EuiFormRow,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
@ -27,6 +28,7 @@ import { Ping, PingResults } from '../../../common/graphql/types';
|
|||
import { convertMicrosecondsToMilliseconds as microsToMillis } from '../../lib/helper';
|
||||
import { UptimeGraphQLQueryProps, withUptimeGraphQL } from '../higher_order';
|
||||
import { pingsQuery } from '../../queries';
|
||||
import { LocationName } from './location_name';
|
||||
|
||||
interface PingListQueryResult {
|
||||
allPings?: PingResults;
|
||||
|
@ -36,16 +38,22 @@ interface PingListProps {
|
|||
onUpdateApp: () => void;
|
||||
onSelectedStatusUpdate: (status: string | null) => void;
|
||||
selectedOption: string;
|
||||
selectedLocation: EuiComboBoxOptionProps[];
|
||||
setSelectedLocation: (location: EuiComboBoxOptionProps[]) => void;
|
||||
}
|
||||
|
||||
type Props = UptimeGraphQLQueryProps<PingListQueryResult> & PingListProps;
|
||||
|
||||
export const BaseLocationOptions = [{ label: 'All', value: 'All' }];
|
||||
|
||||
export const PingListComponent = ({
|
||||
data,
|
||||
loading,
|
||||
onSelectedStatusUpdate,
|
||||
onUpdateApp,
|
||||
selectedOption,
|
||||
selectedLocation,
|
||||
setSelectedLocation,
|
||||
}: Props) => {
|
||||
const statusOptions: EuiComboBoxOptionProps[] = [
|
||||
{
|
||||
|
@ -67,6 +75,15 @@ export const PingListComponent = ({
|
|||
value: 'down',
|
||||
},
|
||||
];
|
||||
const locations = get<string[]>(data, 'allPings.locations');
|
||||
const locationOptions: EuiComboBoxOptionProps[] = !locations
|
||||
? BaseLocationOptions
|
||||
: BaseLocationOptions.concat(
|
||||
locations.map(name => {
|
||||
return { label: name, value: name };
|
||||
})
|
||||
);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'monitor.status',
|
||||
|
@ -95,6 +112,14 @@ export const PingListComponent = ({
|
|||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
field: 'observer.geo.name',
|
||||
dataType: 'number',
|
||||
name: i18n.translate('xpack.uptime.pingList.locationNameColumnLabel', {
|
||||
defaultMessage: 'Location',
|
||||
}),
|
||||
render: (location: string) => <LocationName location={location} />,
|
||||
},
|
||||
{
|
||||
field: 'monitor.ip',
|
||||
dataType: 'number',
|
||||
|
@ -191,25 +216,58 @@ export const PingListComponent = ({
|
|||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem style={{ minWidth: 200 }}>
|
||||
<EuiComboBox
|
||||
isClearable={false}
|
||||
singleSelection={{ asPlainText: true }}
|
||||
selectedOptions={[
|
||||
statusOptions.find(({ value }) => value === selectedOption) || statusOptions[2],
|
||||
]}
|
||||
options={statusOptions}
|
||||
aria-label={i18n.translate('xpack.uptime.pingList.statusLabel', {
|
||||
defaultMessage: 'Status',
|
||||
})}
|
||||
onChange={(selectedOptions: EuiComboBoxOptionProps[]) => {
|
||||
if (typeof selectedOptions[0].value === 'string') {
|
||||
onSelectedStatusUpdate(
|
||||
// @ts-ignore it's definitely a string
|
||||
selectedOptions[0].value !== '' ? selectedOptions[0].value : null
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow
|
||||
label="Status"
|
||||
aria-label={i18n.translate('xpack.uptime.pingList.statusLabel', {
|
||||
defaultMessage: 'Status',
|
||||
})}
|
||||
>
|
||||
<EuiComboBox
|
||||
isClearable={false}
|
||||
singleSelection={{ asPlainText: true }}
|
||||
selectedOptions={[
|
||||
statusOptions.find(({ value }) => value === selectedOption) ||
|
||||
statusOptions[2],
|
||||
]}
|
||||
options={statusOptions}
|
||||
aria-label={i18n.translate('xpack.uptime.pingList.statusLabel', {
|
||||
defaultMessage: 'Status',
|
||||
})}
|
||||
onChange={(selectedOptions: EuiComboBoxOptionProps[]) => {
|
||||
if (typeof selectedOptions[0].value === 'string') {
|
||||
onSelectedStatusUpdate(
|
||||
// @ts-ignore it's definitely a string
|
||||
selectedOptions[0].value !== '' ? selectedOptions[0].value : null
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFormRow
|
||||
label="Location"
|
||||
aria-label={i18n.translate('xpack.uptime.pingList.locationLabel', {
|
||||
defaultMessage: 'Location',
|
||||
})}
|
||||
>
|
||||
<EuiComboBox
|
||||
isClearable={false}
|
||||
singleSelection={{ asPlainText: true }}
|
||||
selectedOptions={selectedLocation}
|
||||
options={locationOptions}
|
||||
aria-label={i18n.translate('xpack.uptime.pingList.locationLabel', {
|
||||
defaultMessage: 'Location',
|
||||
})}
|
||||
onChange={(selectedOptions: EuiComboBoxOptionProps[]) => {
|
||||
setSelectedLocation(selectedOptions);
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -4,14 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiEmptyPrompt,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiPanel,
|
||||
EuiStat,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiStat, EuiTitle } from '@elastic/eui';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
@ -20,7 +13,6 @@ import { Snapshot as SnapshotType } from '../../../common/graphql/types';
|
|||
import { UptimeAppColors } from '../../uptime_app';
|
||||
import { UptimeGraphQLQueryProps, withUptimeGraphQL } from '../higher_order';
|
||||
import { snapshotQuery } from '../../queries';
|
||||
import { SnapshotHistogram } from './charts';
|
||||
import { SnapshotLoading } from './snapshot_loading';
|
||||
|
||||
interface SnapshotQueryResult {
|
||||
|
@ -56,102 +48,57 @@ export const SnapshotComponent = ({
|
|||
data,
|
||||
}: Props) =>
|
||||
data && data.snapshot ? (
|
||||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem grow={4}>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.endpointStatusTitle"
|
||||
defaultMessage="Current status"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiPanel paddingSize="s">
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiSpacer size="s" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup justifyContent="spaceEvenly" gutterSize="s">
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.upDescription', {
|
||||
defaultMessage: 'Up',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.up}
|
||||
titleColor="secondary"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.downDescription', {
|
||||
defaultMessage: 'Down',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.down}
|
||||
titleColor="danger"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.totalDescription', {
|
||||
defaultMessage: 'Total',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.total}
|
||||
titleColor="subdued"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={8}>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.statusOverTimeTitle"
|
||||
defaultMessage="Status over time"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiPanel paddingSize="s" style={{ height: 170 }}>
|
||||
{data.snapshot.histogram && (
|
||||
<SnapshotHistogram
|
||||
absoluteStartDate={absoluteStartDate}
|
||||
absoluteEndDate={absoluteEndDate}
|
||||
dangerColor={danger}
|
||||
histogram={data.snapshot.histogram}
|
||||
successColor={success}
|
||||
/>
|
||||
)}
|
||||
{!data.snapshot.histogram && (
|
||||
<EuiEmptyPrompt
|
||||
title={
|
||||
<EuiTitle>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.noDataTitle"
|
||||
defaultMessage="No histogram data available"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
}
|
||||
body={
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.noDataDescription"
|
||||
defaultMessage="Sorry, there is no data available for the histogram"
|
||||
/>
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<React.Fragment>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.snapshot.endpointStatusTitle"
|
||||
defaultMessage="Current status"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
<EuiPanel paddingSize="s">
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiSpacer size="s" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup justifyContent="spaceEvenly" gutterSize="s">
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.upDescription', {
|
||||
defaultMessage: 'Up',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.up}
|
||||
titleColor="secondary"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.downDescription', {
|
||||
defaultMessage: 'Down',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.down}
|
||||
titleColor="danger"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.uptime.snapshot.stats.totalDescription', {
|
||||
defaultMessage: 'Total',
|
||||
})}
|
||||
textAlign="center"
|
||||
title={data.snapshot.total}
|
||||
titleColor="subdued"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<SnapshotLoading />
|
||||
);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import {
|
||||
// @ts-ignore No typings for EuiSpacer
|
||||
EuiSpacer,
|
||||
EuiComboBoxOptionProps,
|
||||
} from '@elastic/eui';
|
||||
import { ApolloQueryResult, OperationVariables, QueryOptions } from 'apollo-client';
|
||||
import gql from 'graphql-tag';
|
||||
|
@ -22,6 +23,7 @@ import { UMUpdateBreadcrumbs } from '../lib/lib';
|
|||
import { UptimeSettingsContext } from '../contexts';
|
||||
import { useUrlParams } from '../hooks';
|
||||
import { stringifyUrlParams } from '../lib/helper/stringify_url_params';
|
||||
import { BaseLocationOptions } from '../components/functional/ping_list';
|
||||
|
||||
interface MonitorPageProps {
|
||||
history: { push: any };
|
||||
|
@ -44,9 +46,6 @@ export const MonitorPage = ({
|
|||
}: MonitorPageProps) => {
|
||||
const parsedPath = location.pathname.replace(/^(\/monitor\/)/, '').split('/');
|
||||
const [monitorId] = useState<string>(decodeURI(parsedPath[0]));
|
||||
const [geoLocation] = useState<string | undefined>(
|
||||
parsedPath[1] ? decodeURI(parsedPath[1]) : undefined
|
||||
);
|
||||
const { colors, refreshApp, setHeadingText } = useContext(UptimeSettingsContext);
|
||||
const [params, updateUrlParams] = useUrlParams(history, location);
|
||||
const { dateRangeStart, dateRangeEnd, selectedPingStatus } = params;
|
||||
|
@ -76,18 +75,36 @@ export const MonitorPage = ({
|
|||
[params]
|
||||
);
|
||||
|
||||
const [selectedLocation, setSelectedLocation] = useState<EuiComboBoxOptionProps[]>(
|
||||
BaseLocationOptions
|
||||
);
|
||||
|
||||
const selLocationVal = selectedLocation[0].value === 'All' ? null : selectedLocation[0].value;
|
||||
|
||||
const sharedVariables = {
|
||||
dateRangeStart,
|
||||
dateRangeEnd,
|
||||
location: selLocationVal,
|
||||
monitorId,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
logMonitorPageLoad();
|
||||
}, []);
|
||||
|
||||
const sharedVariables = { dateRangeStart, dateRangeEnd, location: geoLocation, monitorId };
|
||||
return (
|
||||
<Fragment>
|
||||
<MonitorPageTitle monitorId={monitorId} variables={{ monitorId }} />
|
||||
<EuiSpacer size="s" />
|
||||
<MonitorStatusBar monitorId={monitorId} variables={sharedVariables} />
|
||||
<EuiSpacer size="s" />
|
||||
<MonitorCharts {...colors} variables={sharedVariables} />
|
||||
<MonitorCharts
|
||||
{...colors}
|
||||
monitorId={monitorId}
|
||||
variables={sharedVariables}
|
||||
dateRangeStart={dateRangeStart}
|
||||
dateRangeEnd={dateRangeEnd}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
<PingList
|
||||
onSelectedStatusUpdate={(selectedStatus: string | null) =>
|
||||
|
@ -95,6 +112,8 @@ export const MonitorPage = ({
|
|||
}
|
||||
onUpdateApp={refreshApp}
|
||||
selectedOption={selectedPingStatus}
|
||||
selectedLocation={selectedLocation}
|
||||
setSelectedLocation={setSelectedLocation}
|
||||
variables={{
|
||||
...sharedVariables,
|
||||
status: selectedPingStatus,
|
||||
|
|
|
@ -5,11 +5,18 @@
|
|||
*/
|
||||
|
||||
// @ts-ignore EuiSearchBar missing
|
||||
import { EuiSearchBar, EuiSpacer } from '@elastic/eui';
|
||||
import { EuiSearchBar, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { Fragment, useContext, useEffect } from 'react';
|
||||
import { getOverviewPageBreadcrumbs } from '../breadcrumbs';
|
||||
import { EmptyState, ErrorList, FilterBar, MonitorList, Snapshot } from '../components/functional';
|
||||
import {
|
||||
EmptyState,
|
||||
ErrorList,
|
||||
FilterBar,
|
||||
MonitorList,
|
||||
Snapshot,
|
||||
SnapshotHistogram,
|
||||
} from '../components/functional';
|
||||
import { UMUpdateBreadcrumbs } from '../lib/lib';
|
||||
import { UptimeSettingsContext } from '../contexts';
|
||||
import { useUrlParams } from '../hooks';
|
||||
|
@ -92,12 +99,25 @@ export const OverviewPage = ({
|
|||
variables={sharedProps}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
<Snapshot
|
||||
absoluteStartDate={absoluteStartDate}
|
||||
absoluteEndDate={absoluteEndDate}
|
||||
colors={colors}
|
||||
variables={sharedProps}
|
||||
/>
|
||||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem grow={4}>
|
||||
<Snapshot
|
||||
absoluteStartDate={absoluteStartDate}
|
||||
absoluteEndDate={absoluteEndDate}
|
||||
colors={colors}
|
||||
variables={sharedProps}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={8}>
|
||||
<SnapshotHistogram
|
||||
absoluteStartDate={absoluteStartDate}
|
||||
absoluteEndDate={absoluteEndDate}
|
||||
successColor={colors.success}
|
||||
dangerColor={colors.danger}
|
||||
variables={sharedProps}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
<MonitorList
|
||||
absoluteStartDate={absoluteStartDate}
|
||||
|
|
|
@ -14,14 +14,12 @@ query MonitorCharts($dateRangeStart: String!, $dateRangeEnd: String!, $monitorId
|
|||
dateRangeEnd: $dateRangeEnd
|
||||
location: $location
|
||||
) {
|
||||
durationArea {
|
||||
x
|
||||
yMin
|
||||
yMax
|
||||
}
|
||||
durationLine {
|
||||
x
|
||||
y
|
||||
locationDurationLines {
|
||||
name
|
||||
line {
|
||||
x
|
||||
y
|
||||
}
|
||||
}
|
||||
status {
|
||||
x
|
||||
|
|
|
@ -26,6 +26,7 @@ query PingList(
|
|||
location: $location
|
||||
) {
|
||||
total
|
||||
locations
|
||||
pings {
|
||||
timestamp
|
||||
http {
|
||||
|
@ -48,6 +49,11 @@ query PingList(
|
|||
status
|
||||
type
|
||||
}
|
||||
observer {
|
||||
geo {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 gql from 'graphql-tag';
|
||||
|
||||
export const snapshotHistogramQueryString = `
|
||||
query SnapshotHistogram(
|
||||
$dateRangeStart: String!
|
||||
$dateRangeEnd: String!
|
||||
$filters: String
|
||||
$monitorId: String
|
||||
) {
|
||||
histogram: getSnapshotHistogram(
|
||||
dateRangeStart: $dateRangeStart
|
||||
dateRangeEnd: $dateRangeEnd
|
||||
filters: $filters
|
||||
monitorId: $monitorId
|
||||
) {
|
||||
upCount
|
||||
downCount
|
||||
x
|
||||
x0
|
||||
y
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const snapshotHistogramQuery = gql`
|
||||
${snapshotHistogramQueryString}
|
||||
`;
|
|
@ -12,21 +12,14 @@ query Snapshot(
|
|||
$dateRangeEnd: String!
|
||||
$filters: String
|
||||
) {
|
||||
snapshot: getSnapshot(
|
||||
dateRangeStart: $dateRangeStart
|
||||
dateRangeEnd: $dateRangeEnd
|
||||
filters: $filters
|
||||
) {
|
||||
up
|
||||
down
|
||||
total
|
||||
histogram {
|
||||
upCount
|
||||
downCount
|
||||
x
|
||||
x0
|
||||
y
|
||||
}
|
||||
snapshot: getSnapshot(
|
||||
dateRangeStart: $dateRangeStart
|
||||
dateRangeEnd: $dateRangeEnd
|
||||
filters: $filters
|
||||
) {
|
||||
up
|
||||
down
|
||||
total
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -19,6 +19,8 @@ import {
|
|||
MonitorPageTitle,
|
||||
Ping,
|
||||
Snapshot,
|
||||
HistogramDataPoint,
|
||||
GetSnapshotHistogramQueryArgs,
|
||||
} from '../../../common/graphql/types';
|
||||
import { UMServerLibs } from '../../lib/lib';
|
||||
import { CreateUMGraphQLResolvers, UMContext } from '../types';
|
||||
|
@ -74,12 +76,20 @@ export type UMGetMontiorPageTitleResolver = UMResolver<
|
|||
UMContext
|
||||
>;
|
||||
|
||||
export type UMGetSnapshotHistogram = UMResolver<
|
||||
HistogramDataPoint[] | Promise<HistogramDataPoint[]>,
|
||||
any,
|
||||
GetSnapshotHistogramQueryArgs,
|
||||
UMContext
|
||||
>;
|
||||
|
||||
export const createMonitorsResolvers: CreateUMGraphQLResolvers = (
|
||||
libs: UMServerLibs
|
||||
): {
|
||||
Query: {
|
||||
getMonitors: UMGetMonitorsResolver;
|
||||
getSnapshot: UMSnapshotResolver;
|
||||
getSnapshotHistogram: UMGetSnapshotHistogram;
|
||||
getMonitorChartsData: UMGetMonitorChartsResolver;
|
||||
getLatestMonitors: UMLatestMonitorsResolver;
|
||||
getFilterBar: UMGetFilterBarResolver;
|
||||
|
@ -95,7 +105,11 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = (
|
|||
monitors: result,
|
||||
};
|
||||
},
|
||||
async getSnapshot(resolver, { dateRangeStart, dateRangeEnd, filters }, { req }): Promise<any> {
|
||||
async getSnapshot(
|
||||
resolver,
|
||||
{ dateRangeStart, dateRangeEnd, filters },
|
||||
{ req }
|
||||
): Promise<Snapshot> {
|
||||
const { up, down, total } = await libs.monitors.getSnapshotCount(
|
||||
req,
|
||||
dateRangeStart,
|
||||
|
@ -107,9 +121,21 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = (
|
|||
up,
|
||||
down,
|
||||
total,
|
||||
histogram: await libs.pings.getPingHistogram(req, dateRangeStart, dateRangeEnd, filters),
|
||||
};
|
||||
},
|
||||
async getSnapshotHistogram(
|
||||
resolver,
|
||||
{ dateRangeStart, dateRangeEnd, filters, monitorId },
|
||||
{ req }
|
||||
): Promise<HistogramDataPoint[]> {
|
||||
return await libs.pings.getPingHistogram(
|
||||
req,
|
||||
dateRangeStart,
|
||||
dateRangeEnd,
|
||||
filters,
|
||||
monitorId
|
||||
);
|
||||
},
|
||||
async getMonitorChartsData(
|
||||
resolver,
|
||||
{ monitorId, dateRangeStart, dateRangeEnd, location },
|
||||
|
|
|
@ -35,7 +35,6 @@ export const monitorsSchema = gql`
|
|||
up: Int
|
||||
down: Int
|
||||
total: Int
|
||||
histogram: [HistogramDataPoint!]!
|
||||
}
|
||||
|
||||
type DataPoint {
|
||||
|
@ -57,10 +56,8 @@ export const monitorsSchema = gql`
|
|||
|
||||
"The data used to populate the monitor charts."
|
||||
type MonitorChart {
|
||||
"The max and min values for the monitor duration."
|
||||
durationArea: [MonitorDurationAreaPoint!]!
|
||||
"The average values for the monitor duration."
|
||||
durationLine: [MonitorDurationAveragePoint!]!
|
||||
locationDurationLines: [LocationDurationLine!]!
|
||||
"The counts of up/down checks for the monitor."
|
||||
status: [StatusData!]!
|
||||
"The maximum status doc count in this chart."
|
||||
|
@ -69,6 +66,11 @@ export const monitorsSchema = gql`
|
|||
durationMaxValue: Int!
|
||||
}
|
||||
|
||||
type LocationDurationLine {
|
||||
name: String!
|
||||
line: [MonitorDurationAveragePoint!]!
|
||||
}
|
||||
|
||||
type MonitorKey {
|
||||
key: String!
|
||||
url: String
|
||||
|
@ -148,6 +150,13 @@ export const monitorsSchema = gql`
|
|||
|
||||
getSnapshot(dateRangeStart: String!, dateRangeEnd: String!, filters: String): Snapshot
|
||||
|
||||
getSnapshotHistogram(
|
||||
dateRangeStart: String!
|
||||
dateRangeEnd: String!
|
||||
filters: String
|
||||
monitorId: String
|
||||
): [HistogramDataPoint!]!
|
||||
|
||||
getMonitorChartsData(
|
||||
monitorId: String!
|
||||
dateRangeStart: String!
|
||||
|
|
|
@ -12,7 +12,11 @@ export const pingsSchema = gql`
|
|||
}
|
||||
|
||||
type PingResults {
|
||||
"Total number of matching pings"
|
||||
total: UnsignedInteger!
|
||||
"Unique list of all locations the query matched"
|
||||
locations: [String!]!
|
||||
"List of pings "
|
||||
pings: [Ping!]!
|
||||
}
|
||||
|
||||
|
|
|
@ -8,16 +8,24 @@ Array [
|
|||
"aggs": Object {
|
||||
"timeseries": Object {
|
||||
"aggs": Object {
|
||||
"duration": Object {
|
||||
"stats": Object {
|
||||
"field": "monitor.duration.us",
|
||||
"location": Object {
|
||||
"aggs": Object {
|
||||
"duration": Object {
|
||||
"stats": Object {
|
||||
"field": "monitor.duration.us",
|
||||
},
|
||||
},
|
||||
"status": Object {
|
||||
"terms": Object {
|
||||
"field": "monitor.status",
|
||||
"shard_size": 2,
|
||||
"size": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"status": Object {
|
||||
"terms": Object {
|
||||
"field": "monitor.status",
|
||||
"shard_size": 2,
|
||||
"size": 2,
|
||||
"field": "observer.geo.name",
|
||||
"missing": "N/A",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -66,16 +74,24 @@ Array [
|
|||
"aggs": Object {
|
||||
"timeseries": Object {
|
||||
"aggs": Object {
|
||||
"duration": Object {
|
||||
"stats": Object {
|
||||
"field": "monitor.duration.us",
|
||||
"location": Object {
|
||||
"aggs": Object {
|
||||
"duration": Object {
|
||||
"stats": Object {
|
||||
"field": "monitor.duration.us",
|
||||
},
|
||||
},
|
||||
"status": Object {
|
||||
"terms": Object {
|
||||
"field": "monitor.status",
|
||||
"shard_size": 2,
|
||||
"size": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"status": Object {
|
||||
"terms": Object {
|
||||
"field": "monitor.status",
|
||||
"shard_size": 2,
|
||||
"size": 2,
|
||||
"field": "observer.geo.name",
|
||||
"missing": "N/A",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
MonitorPageTitle,
|
||||
MonitorSeriesPoint,
|
||||
Ping,
|
||||
LocationDurationLine,
|
||||
} from '../../../../common/graphql/types';
|
||||
import {
|
||||
dropLatestBucket,
|
||||
|
@ -85,8 +86,16 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
|
|||
fixed_interval: getHistogramInterval(dateRangeStart, dateRangeEnd),
|
||||
},
|
||||
aggs: {
|
||||
status: { terms: { field: 'monitor.status', size: 2, shard_size: 2 } },
|
||||
duration: { stats: { field: 'monitor.duration.us' } },
|
||||
location: {
|
||||
terms: {
|
||||
field: 'observer.geo.name',
|
||||
missing: 'N/A',
|
||||
},
|
||||
aggs: {
|
||||
status: { terms: { field: 'monitor.status', size: 2, shard_size: 2 } },
|
||||
duration: { stats: { field: 'monitor.duration.us' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -94,7 +103,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
|
|||
};
|
||||
|
||||
const result = await this.database.search(request, params);
|
||||
const buckets = dropLatestBucket(get(result, 'aggregations.timeseries.buckets', []));
|
||||
const dateBuckets = dropLatestBucket(get(result, 'aggregations.timeseries.buckets', []));
|
||||
|
||||
/**
|
||||
* The code below is responsible for formatting the aggregation data we fetched above in a way
|
||||
|
@ -108,34 +117,35 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
|
|||
* what the domain size should be.
|
||||
*/
|
||||
const monitorChartsData: MonitorChart = {
|
||||
durationArea: [],
|
||||
durationLine: [],
|
||||
locationDurationLines: [],
|
||||
status: [],
|
||||
durationMaxValue: 0,
|
||||
statusMaxCount: 0,
|
||||
};
|
||||
|
||||
buckets.forEach(bucket => {
|
||||
const x = get(bucket, 'key');
|
||||
const docCount = get(bucket, 'doc_count', 0);
|
||||
// update the maximum value for each point
|
||||
monitorChartsData.statusMaxCount = Math.max(docCount, monitorChartsData.statusMaxCount);
|
||||
monitorChartsData.durationMaxValue = Math.max(
|
||||
monitorChartsData.durationMaxValue,
|
||||
get(bucket, 'duration.max', 0)
|
||||
const linesByLocation: { [key: string]: LocationDurationLine } = {};
|
||||
dateBuckets.forEach(dateBucket => {
|
||||
const x = get(dateBucket, 'key');
|
||||
const docCount = get(dateBucket, 'doc_count', 0);
|
||||
|
||||
dateBucket.location.buckets.forEach(
|
||||
(locationBucket: { key: string; duration: { avg: number } }) => {
|
||||
const locationName = locationBucket.key;
|
||||
let ldl: LocationDurationLine = get(linesByLocation, locationName);
|
||||
if (!ldl) {
|
||||
ldl = { name: locationName, line: [] };
|
||||
linesByLocation[locationName] = ldl;
|
||||
monitorChartsData.locationDurationLines.push(ldl);
|
||||
}
|
||||
ldl.line.push({ x, y: get(locationBucket, 'duration.avg', null) });
|
||||
}
|
||||
);
|
||||
|
||||
// these points express a range that will be displayed as an area chart
|
||||
monitorChartsData.durationArea.push({
|
||||
x,
|
||||
yMin: get(bucket, 'duration.min', null),
|
||||
yMax: get(bucket, 'duration.max', null),
|
||||
});
|
||||
monitorChartsData.durationLine.push({ x, y: get(bucket, 'duration.avg', null) });
|
||||
monitorChartsData.status.push(
|
||||
formatStatusBuckets(x, get(bucket, 'status.buckets', []), docCount)
|
||||
formatStatusBuckets(x, get(dateBucket, 'status.buckets', []), docCount)
|
||||
);
|
||||
});
|
||||
|
||||
return monitorChartsData;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,11 @@ describe('ElasticsearchPingsAdapter class', () => {
|
|||
},
|
||||
hits: mockHits,
|
||||
},
|
||||
aggregations: {
|
||||
locations: {
|
||||
buckets: [{ key: 'foo' }],
|
||||
},
|
||||
},
|
||||
};
|
||||
mockEsCountResult = {
|
||||
count: mockHits.length,
|
||||
|
@ -365,6 +370,15 @@ describe('ElasticsearchPingsAdapter class', () => {
|
|||
filter: [{ range: { '@timestamp': { gte: 'now-1h', lte: 'now' } } }],
|
||||
},
|
||||
},
|
||||
aggregations: {
|
||||
locations: {
|
||||
terms: {
|
||||
field: 'observer.geo.name',
|
||||
missing: 'N/A',
|
||||
size: 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
sort: [{ '@timestamp': { order: 'desc' } }],
|
||||
size: 12,
|
||||
},
|
||||
|
|
|
@ -30,7 +30,8 @@ export interface UMPingsAdapter {
|
|||
request: any,
|
||||
dateRangeStart: string,
|
||||
dateRangeEnd: string,
|
||||
filters?: string | null
|
||||
filters?: string | null,
|
||||
monitorId?: string | null
|
||||
): Promise<HistogramDataPoint[]>;
|
||||
|
||||
getDocCount(request: any): Promise<DocCount>;
|
||||
|
|
|
@ -49,8 +49,10 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
|
|||
if (status) {
|
||||
filter.push({ term: { 'monitor.status': status } });
|
||||
}
|
||||
|
||||
let postFilterClause = {};
|
||||
if (location) {
|
||||
filter.push({ term: { 'observer.geo.name': location } });
|
||||
postFilterClause = { post_filter: { term: { 'observer.geo.name': location } } };
|
||||
}
|
||||
const queryContext = { bool: { filter } };
|
||||
const params = {
|
||||
|
@ -61,12 +63,26 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
|
|||
},
|
||||
...sortParam,
|
||||
...sizeParam,
|
||||
aggregations: {
|
||||
locations: {
|
||||
terms: {
|
||||
field: 'observer.geo.name',
|
||||
missing: 'N/A',
|
||||
size: 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
...postFilterClause,
|
||||
},
|
||||
};
|
||||
|
||||
const {
|
||||
hits: { hits, total },
|
||||
aggregations: aggs,
|
||||
} = await this.database.search(request, params);
|
||||
|
||||
const locations = get(aggs, 'locations', { buckets: [{ key: 'N/A', doc_count: 0 }] });
|
||||
|
||||
const pings: Ping[] = hits.map(({ _source }: any) => {
|
||||
const timestamp = _source['@timestamp'];
|
||||
return { timestamp, ..._source };
|
||||
|
@ -74,6 +90,7 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
|
|||
|
||||
const results: PingResults = {
|
||||
total: total.value,
|
||||
locations: locations.buckets.map((bucket: { key: string }) => bucket.key),
|
||||
pings,
|
||||
};
|
||||
|
||||
|
@ -163,17 +180,27 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
|
|||
request: any,
|
||||
dateRangeStart: string,
|
||||
dateRangeEnd: string,
|
||||
filters?: string | null
|
||||
filters?: string | null,
|
||||
monitorId?: string | null
|
||||
): Promise<HistogramDataPoint[]> {
|
||||
const { statusFilter, query } = getFilteredQueryAndStatusFilter(
|
||||
dateRangeStart,
|
||||
dateRangeEnd,
|
||||
filters
|
||||
);
|
||||
|
||||
const combinedQuery = !monitorId
|
||||
? query
|
||||
: {
|
||||
bool: {
|
||||
filter: [{ match: { 'monitor.id': monitorId } }, query],
|
||||
},
|
||||
};
|
||||
|
||||
const params = {
|
||||
index: INDEX_NAMES.HEARTBEAT,
|
||||
body: {
|
||||
query,
|
||||
query: combinedQuery,
|
||||
size: 0,
|
||||
aggs: {
|
||||
timeseries: {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { take } from 'lodash';
|
||||
import { get, take } from 'lodash';
|
||||
import { DocCount, HistogramDataPoint, Ping, PingResults } from '../../../../common/graphql/types';
|
||||
import { UMPingsAdapter } from './adapter_types';
|
||||
|
||||
|
@ -34,10 +34,17 @@ export class MemoryPingsAdapter implements UMPingsAdapter {
|
|||
pings = pings.filter(ping => ping.monitor && ping.monitor.id === monitorId);
|
||||
}
|
||||
|
||||
const locations =
|
||||
this.pingsDB
|
||||
.map(ping => {
|
||||
return get<string>(ping, 'observer.geo.name');
|
||||
})
|
||||
.filter(location => !location) || [];
|
||||
size = size ? size : 10;
|
||||
return {
|
||||
total: size,
|
||||
pings: take(sort ? pings.sort(sortPings(sort)) : pings, size),
|
||||
locations,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -56,7 +63,8 @@ export class MemoryPingsAdapter implements UMPingsAdapter {
|
|||
request: any,
|
||||
dateRangeStart: string,
|
||||
dateRangeEnd: string,
|
||||
filters?: string | null | undefined
|
||||
filters?: string | null | undefined,
|
||||
monitorId?: string | null | undefined
|
||||
): Promise<HistogramDataPoint[]> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
|
|
@ -54,9 +54,10 @@ export class UMPingsDomain {
|
|||
request: any,
|
||||
dateRangeStart: string,
|
||||
dateRangeEnd: string,
|
||||
filters?: string | null
|
||||
filters?: string | null,
|
||||
monitorId?: string | null
|
||||
): Promise<HistogramDataPoint[]> {
|
||||
return this.adapter.getPingHistogram(request, dateRangeStart, dateRangeEnd, filters);
|
||||
return this.adapter.getPingHistogram(request, dateRangeStart, dateRangeEnd, filters, monitorId);
|
||||
}
|
||||
|
||||
public async getDocCount(request: any): Promise<DocCount> {
|
||||
|
|
|
@ -9533,8 +9533,6 @@
|
|||
"xpack.uptime.monitorCharts.checkStatus.series.upCountLabel": "アップカウント",
|
||||
"xpack.uptime.monitorCharts.checkStatus.title": "ステータスを確認",
|
||||
"xpack.uptime.monitorCharts.loadingMessage": "読み込み中…",
|
||||
"xpack.uptime.monitorCharts.monitorDuration.series.durationRangeLabel": "期間",
|
||||
"xpack.uptime.monitorCharts.monitorDuration.series.meanDurationLabel": "平均期間",
|
||||
"xpack.uptime.monitorCharts.monitorDuration.titleLabel": "ミリ秒単位の監視時間",
|
||||
"xpack.uptime.monitorList.downLineSeries.downLabel": "ダウン",
|
||||
"xpack.uptime.monitorList.idColumnLabel": "ID",
|
||||
|
|
|
@ -7494,8 +7494,6 @@
|
|||
"xpack.uptime.monitorCharts.checkStatus.series.upCountLabel": "运行计数",
|
||||
"xpack.uptime.monitorCharts.checkStatus.title": "检查状态",
|
||||
"xpack.uptime.monitorCharts.loadingMessage": "正在加载……",
|
||||
"xpack.uptime.monitorCharts.monitorDuration.series.durationRangeLabel": "持续时间范围",
|
||||
"xpack.uptime.monitorCharts.monitorDuration.series.meanDurationLabel": "平均持续时间",
|
||||
"xpack.uptime.monitorCharts.monitorDuration.titleLabel": "监测持续时间 (ms)",
|
||||
"xpack.uptime.monitorList.downLineSeries.downLabel": "关闭",
|
||||
"xpack.uptime.monitorList.monitorHistoryColumnLabel": "监测历史记录",
|
||||
|
|
|
@ -1,63 +1,49 @@
|
|||
{
|
||||
"monitorChartsData": {
|
||||
"durationArea": [
|
||||
{ "x": 1548697571840, "yMin": 106421, "yMax": 3083061 },
|
||||
{ "x": 1548697764160, "yMin": 118349, "yMax": 3120392 },
|
||||
{ "x": 1548697956480, "yMin": 121653, "yMax": 3955186 },
|
||||
{ "x": 1548698148800, "yMin": 123670, "yMax": 3693429 },
|
||||
{ "x": 1548698341120, "yMin": 118224, "yMax": 3705359 },
|
||||
{ "x": 1548698533440, "yMin": 123345, "yMax": 4130464 },
|
||||
{ "x": 1548698725760, "yMin": 118849, "yMax": 6669234 },
|
||||
{ "x": 1548698918080, "yMin": 117268, "yMax": 3955729 },
|
||||
{ "x": 1548699110400, "yMin": 122110, "yMax": 3704761 },
|
||||
{ "x": 1548699302720, "yMin": 120015, "yMax": 4045216 },
|
||||
{ "x": 1548699495040, "yMin": 121018, "yMax": 3682859 },
|
||||
{ "x": 1548699687360, "yMin": 122788, "yMax": 3618679 },
|
||||
{ "x": 1548699879680, "yMin": 114751, "yMax": 3701297 },
|
||||
{ "x": 1548700072000, "yMin": 111949, "yMax": 3632224 },
|
||||
{ "x": 1548700264320, "yMin": 106875, "yMax": 3801401 },
|
||||
{ "x": 1548700456640, "yMin": 105126, "yMax": 3696367 },
|
||||
{ "x": 1548700648960, "yMin": 123639, "yMax": 3925269 }
|
||||
],
|
||||
"durationLine": [
|
||||
{ "x": 1548697571840, "y": 790701.3428571429 },
|
||||
{ "x": 1548697764160, "y": 661065.4375 },
|
||||
{ "x": 1548697956480, "y": 806260.8541666666 },
|
||||
{ "x": 1548698148800, "y": 773767.7291666666 },
|
||||
{ "x": 1548698341120, "y": 767945.0208333334 },
|
||||
{ "x": 1548698533440, "y": 744078.7234042553 },
|
||||
{ "x": 1548698725760, "y": 837049.4893617021 },
|
||||
{ "x": 1548698918080, "y": 778723.1041666666 },
|
||||
{ "x": 1548699110400, "y": 723974.1875 },
|
||||
{ "x": 1548699302720, "y": 771744.3191489362 },
|
||||
{ "x": 1548699495040, "y": 718773.081632653 },
|
||||
{ "x": 1548699687360, "y": 724448.6458333334 },
|
||||
{ "x": 1548699879680, "y": 747848.0833333334 },
|
||||
{ "x": 1548700072000, "y": 748932.125 },
|
||||
{ "x": 1548700264320, "y": 753010.2291666666 },
|
||||
{ "x": 1548700456640, "y": 762055.6875 },
|
||||
{ "x": 1548700648960, "y": 745954.7708333334 }
|
||||
"locationDurationLines": [
|
||||
{
|
||||
"name": "N/A",
|
||||
"line": [
|
||||
{ "x": 1548697571840, "y": 790701.3428571429 },
|
||||
{ "x": 1548697764160, "y": 661065.4375 },
|
||||
{ "x": 1548697956480, "y": 806260.8541666666 },
|
||||
{ "x": 1548698148800, "y": 773767.7291666666 },
|
||||
{ "x": 1548698341120, "y": 767945.0208333334 },
|
||||
{ "x": 1548698533440, "y": 744078.7234042553 },
|
||||
{ "x": 1548698725760, "y": 837049.4893617021 },
|
||||
{ "x": 1548698918080, "y": 778723.1041666666 },
|
||||
{ "x": 1548699110400, "y": 723974.1875 },
|
||||
{ "x": 1548699302720, "y": 771744.3191489362 },
|
||||
{ "x": 1548699495040, "y": 718773.081632653 },
|
||||
{ "x": 1548699687360, "y": 724448.6458333334 },
|
||||
{ "x": 1548699879680, "y": 747848.0833333334 },
|
||||
{ "x": 1548700072000, "y": 748932.125 },
|
||||
{ "x": 1548700264320, "y": 753010.2291666666 },
|
||||
{ "x": 1548700456640, "y": 762055.6875 },
|
||||
{ "x": 1548700648960, "y": 745954.7708333334 }
|
||||
]
|
||||
}
|
||||
],
|
||||
"status": [
|
||||
{ "x": 1548697571840, "up": 35, "down": null, "total": 35 },
|
||||
{ "x": 1548697764160, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548697956480, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548698148800, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548698341120, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548698533440, "up": 47, "down": null, "total": 47 },
|
||||
{ "x": 1548698725760, "up": 47, "down": null, "total": 47 },
|
||||
{ "x": 1548698918080, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548699110400, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548699302720, "up": 47, "down": null, "total": 47 },
|
||||
{ "x": 1548699495040, "up": 49, "down": null, "total": 49 },
|
||||
{ "x": 1548699687360, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548699879680, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548700072000, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548700264320, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548700456640, "up": 48, "down": null, "total": 48 },
|
||||
{ "x": 1548700648960, "up": 48, "down": null, "total": 48 }
|
||||
{ "x": 1548697571840, "up": null, "down": null, "total": 35 },
|
||||
{ "x": 1548697764160, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548697956480, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548698148800, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548698341120, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548698533440, "up": null, "down": null, "total": 47 },
|
||||
{ "x": 1548698725760, "up": null, "down": null, "total": 47 },
|
||||
{ "x": 1548698918080, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548699110400, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548699302720, "up": null, "down": null, "total": 47 },
|
||||
{ "x": 1548699495040, "up": null, "down": null, "total": 49 },
|
||||
{ "x": 1548699687360, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548699879680, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548700072000, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548700264320, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548700456640, "up": null, "down": null, "total": 48 },
|
||||
{ "x": 1548700648960, "up": null, "down": null, "total": 48 }
|
||||
],
|
||||
"statusMaxCount": 49,
|
||||
"durationMaxValue": 6669234
|
||||
"statusMaxCount": 0,
|
||||
"durationMaxValue": 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
{
|
||||
"monitorChartsData": {
|
||||
"durationArea": [],
|
||||
"durationLine": [],
|
||||
"status": [],
|
||||
"locationDurationLines": [],
|
||||
"statusMaxCount": 0,
|
||||
"durationMaxValue": 0
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"allPings": {
|
||||
"total": 9231,
|
||||
"locations": ["N/A"],
|
||||
"pings": [
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:16.078Z",
|
||||
|
@ -14,7 +15,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -31,7 +33,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -45,7 +48,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -59,7 +63,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -73,7 +78,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -87,7 +93,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:14.080Z",
|
||||
|
@ -101,7 +108,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:13.075Z",
|
||||
|
@ -115,7 +123,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:13.074Z",
|
||||
|
@ -129,7 +138,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:13.074Z",
|
||||
|
@ -143,7 +153,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"allPings": {
|
||||
"total": 9231,
|
||||
"locations": ["N/A"],
|
||||
"pings": [
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:16.078Z",
|
||||
|
@ -14,7 +15,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -31,7 +33,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -45,7 +48,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -59,7 +63,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -73,7 +78,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -87,7 +93,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:14.080Z",
|
||||
|
@ -101,7 +108,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:13.075Z",
|
||||
|
@ -115,7 +123,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:13.074Z",
|
||||
|
@ -129,7 +138,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:13.074Z",
|
||||
|
@ -143,7 +153,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:12.075Z",
|
||||
|
@ -157,7 +168,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:11.075Z",
|
||||
|
@ -171,7 +183,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:11.074Z",
|
||||
|
@ -188,7 +201,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:11.074Z",
|
||||
|
@ -202,7 +216,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:11.074Z",
|
||||
|
@ -216,7 +231,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:10.075Z",
|
||||
|
@ -230,7 +246,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:10.074Z",
|
||||
|
@ -244,7 +261,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:09.079Z",
|
||||
|
@ -258,7 +276,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:08.075Z",
|
||||
|
@ -272,7 +291,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:07.078Z",
|
||||
|
@ -286,7 +306,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:07.078Z",
|
||||
|
@ -303,7 +324,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:07.078Z",
|
||||
|
@ -317,7 +339,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:07.078Z",
|
||||
|
@ -331,7 +354,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:07.078Z",
|
||||
|
@ -345,7 +369,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:07.078Z",
|
||||
|
@ -359,7 +384,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:07.078Z",
|
||||
|
@ -373,7 +399,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:06.075Z",
|
||||
|
@ -387,7 +414,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:05.076Z",
|
||||
|
@ -401,7 +429,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:05.076Z",
|
||||
|
@ -415,7 +444,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:04.077Z",
|
||||
|
@ -429,7 +459,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:04.077Z",
|
||||
|
@ -443,7 +474,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:04.077Z",
|
||||
|
@ -457,7 +489,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:03.077Z",
|
||||
|
@ -471,7 +504,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:03.077Z",
|
||||
|
@ -488,7 +522,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:03.077Z",
|
||||
|
@ -502,7 +537,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:03.077Z",
|
||||
|
@ -516,7 +552,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:03.077Z",
|
||||
|
@ -530,7 +567,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:02.080Z",
|
||||
|
@ -544,7 +582,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:01.077Z",
|
||||
|
@ -558,7 +597,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:01.077Z",
|
||||
|
@ -572,7 +612,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:01.077Z",
|
||||
|
@ -586,7 +627,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:00.078Z",
|
||||
|
@ -600,7 +642,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:00.078Z",
|
||||
|
@ -614,7 +657,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:42:59.075Z",
|
||||
|
@ -631,7 +675,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:42:59.075Z",
|
||||
|
@ -645,7 +690,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:42:59.075Z",
|
||||
|
@ -659,7 +705,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:42:59.075Z",
|
||||
|
@ -673,7 +720,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:42:59.075Z",
|
||||
|
@ -687,7 +735,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:42:58.075Z",
|
||||
|
@ -701,7 +750,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:42:58.074Z",
|
||||
|
@ -715,7 +765,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "http"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"allPings": {
|
||||
"total": 3371,
|
||||
"locations": ["N/A"],
|
||||
"pings": [
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:16.078Z",
|
||||
|
@ -14,7 +15,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:15.077Z",
|
||||
|
@ -28,7 +30,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:14.080Z",
|
||||
|
@ -42,7 +45,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:13.075Z",
|
||||
|
@ -56,7 +60,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:12.075Z",
|
||||
|
@ -70,7 +75,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:11.075Z",
|
||||
|
@ -84,7 +90,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:10.075Z",
|
||||
|
@ -98,7 +105,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:09.079Z",
|
||||
|
@ -112,7 +120,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:08.075Z",
|
||||
|
@ -126,7 +135,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:07.078Z",
|
||||
|
@ -140,7 +150,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:06.075Z",
|
||||
|
@ -154,7 +165,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:05.076Z",
|
||||
|
@ -168,7 +180,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:04.077Z",
|
||||
|
@ -182,7 +195,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:03.077Z",
|
||||
|
@ -196,7 +210,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T18:43:02.080Z",
|
||||
|
@ -210,7 +225,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"allPings": {
|
||||
"total": 3371,
|
||||
"locations": ["N/A"],
|
||||
"pings": [
|
||||
{
|
||||
"timestamp": "2019-01-28T17:47:06.077Z",
|
||||
|
@ -14,7 +15,8 @@
|
|||
"scheme": null,
|
||||
"status": "up",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T17:47:07.075Z",
|
||||
|
@ -31,7 +33,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T17:47:08.078Z",
|
||||
|
@ -48,7 +51,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T17:47:09.075Z",
|
||||
|
@ -65,7 +69,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
},
|
||||
{
|
||||
"timestamp": "2019-01-28T17:47:10.075Z",
|
||||
|
@ -82,7 +87,8 @@
|
|||
"scheme": null,
|
||||
"status": "down",
|
||||
"type": "tcp"
|
||||
}
|
||||
},
|
||||
"observer": null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -2,25 +2,6 @@
|
|||
"snapshot": {
|
||||
"up": 8,
|
||||
"down": 2,
|
||||
"total": 10,
|
||||
"histogram": [
|
||||
{ "upCount": 7, "downCount": 3, "x": 1548697764160, "x0": 1548697571840, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 3, "x": 1548697956480, "x0": 1548697764160, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 3, "x": 1548698148800, "x0": 1548697956480, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 3, "x": 1548698341120, "x0": 1548698148800, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 3, "x": 1548698533440, "x0": 1548698341120, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 3, "x": 1548698725760, "x0": 1548698533440, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548698918080, "x0": 1548698725760, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548699110400, "x0": 1548698918080, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548699302720, "x0": 1548699110400, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548699495040, "x0": 1548699302720, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548699687360, "x0": 1548699495040, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548699879680, "x0": 1548699687360, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548700072000, "x0": 1548699879680, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548700264320, "x0": 1548700072000, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548700456640, "x0": 1548700264320, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548700648960, "x0": 1548700456640, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 2, "x": 1548700841280, "x0": 1548700648960, "y": 1 }
|
||||
]
|
||||
"total": 10
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{ "snapshot": { "up": 0, "down": 0, "total": 0, "histogram": [] } }
|
||||
{ "snapshot": { "up": 0, "down": 0, "total": 0 } }
|
||||
|
|
|
@ -1,26 +1 @@
|
|||
{
|
||||
"snapshot": {
|
||||
"up": 0,
|
||||
"down": 2,
|
||||
"total": 2,
|
||||
"histogram": [
|
||||
{ "upCount": 0, "downCount": 3, "x": 1548697764160, "x0": 1548697571840, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 3, "x": 1548697956480, "x0": 1548697764160, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 3, "x": 1548698148800, "x0": 1548697956480, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 3, "x": 1548698341120, "x0": 1548698148800, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 3, "x": 1548698533440, "x0": 1548698341120, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 3, "x": 1548698725760, "x0": 1548698533440, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548698918080, "x0": 1548698725760, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548699110400, "x0": 1548698918080, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548699302720, "x0": 1548699110400, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548699495040, "x0": 1548699302720, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548699687360, "x0": 1548699495040, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548699879680, "x0": 1548699687360, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548700072000, "x0": 1548699879680, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548700264320, "x0": 1548700072000, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548700456640, "x0": 1548700264320, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548700648960, "x0": 1548700456640, "y": 1 },
|
||||
{ "upCount": 0, "downCount": 2, "x": 1548700841280, "x0": 1548700648960, "y": 1 }
|
||||
]
|
||||
}
|
||||
}
|
||||
{ "snapshot": { "up": 0, "down": 2, "total": 2 } }
|
||||
|
|
|
@ -2,25 +2,6 @@
|
|||
"snapshot": {
|
||||
"up": 8,
|
||||
"down": 0,
|
||||
"total": 8,
|
||||
"histogram": [
|
||||
{ "upCount": 7, "downCount": 0, "x": 1548697764160, "x0": 1548697571840, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 0, "x": 1548697956480, "x0": 1548697764160, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 0, "x": 1548698148800, "x0": 1548697956480, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 0, "x": 1548698341120, "x0": 1548698148800, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 0, "x": 1548698533440, "x0": 1548698341120, "y": 1 },
|
||||
{ "upCount": 7, "downCount": 0, "x": 1548698725760, "x0": 1548698533440, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548698918080, "x0": 1548698725760, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548699110400, "x0": 1548698918080, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548699302720, "x0": 1548699110400, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548699495040, "x0": 1548699302720, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548699687360, "x0": 1548699495040, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548699879680, "x0": 1548699687360, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548700072000, "x0": 1548699879680, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548700264320, "x0": 1548700072000, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548700456640, "x0": 1548700264320, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548700648960, "x0": 1548700456640, "y": 1 },
|
||||
{ "upCount": 8, "downCount": 0, "x": 1548700841280, "x0": 1548700648960, "y": 1 }
|
||||
]
|
||||
"total": 8
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue