[Uptime] Fix: Last successful screenshot should be from same location (#116906) (#117186)

* update get_last_successful_step query to include location logic

* adjust types

Co-authored-by: Dominique Clarke <doclarke71@gmail.com>
This commit is contained in:
Kibana Machine 2021-11-02 15:33:22 -04:00 committed by GitHub
parent 2ae9625575
commit 9ff509d4d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 185 additions and 6 deletions

View file

@ -27,6 +27,11 @@ export const JourneyStepType = t.intersection([
lt: t.string,
}),
}),
observer: t.type({
geo: t.type({
name: t.string,
}),
}),
synthetics: t.partial({
error: t.partial({
message: t.string,

View file

@ -36,6 +36,7 @@ export const StepScreenshots = ({ step }: Props) => {
timestamp: step['@timestamp'],
monitorId: step.monitor.id,
stepIndex: step.synthetics?.step?.index!,
location: step.observer?.geo?.name,
});
}
}, [step._id, step['@timestamp']]);

View file

@ -228,6 +228,9 @@ const browserConsoleStep = {
_id: 'IvT1oXwB5ds00bB_FVXP',
observer: {
hostname: '16Elastic',
geo: {
name: 'au-heartbeat',
},
},
agent: {
name: '16Elastic',

View file

@ -49,10 +49,12 @@ export async function fetchLastSuccessfulStep({
monitorId,
timestamp,
stepIndex,
location,
}: {
monitorId: string;
timestamp: string;
stepIndex: number;
location?: string;
}): Promise<JourneyStep> {
return await apiService.get(
`/api/uptime/synthetics/step/success/`,
@ -60,6 +62,7 @@ export async function fetchLastSuccessfulStep({
monitorId,
timestamp,
stepIndex,
location,
},
JourneyStepType
);

View file

@ -0,0 +1,132 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { getLastSuccessfulStepParams } from './get_last_successful_step';
describe('getLastSuccessfulStep', () => {
describe('getLastSuccessfulStepParams', () => {
it('formats ES params with location', () => {
const monitorId = 'my-monitor';
const stepIndex = 1;
const location = 'au-heartbeat';
const timestamp = '2021-10-31T19:47:52.392Z';
const params = getLastSuccessfulStepParams({
monitorId,
stepIndex,
location,
timestamp,
});
expect(params).toEqual({
query: {
bool: {
filter: [
{
range: {
'@timestamp': {
lte: '2021-10-31T19:47:52.392Z',
},
},
},
{
term: {
'monitor.id': monitorId,
},
},
{
term: {
'synthetics.type': 'step/end',
},
},
{
term: {
'synthetics.step.status': 'succeeded',
},
},
{
term: {
'synthetics.step.index': stepIndex,
},
},
{
term: {
'observer.geo.name': location,
},
},
],
},
},
size: 1,
sort: [
{
'@timestamp': {
order: 'desc',
},
},
],
});
});
it('formats ES params without location', () => {
const params = getLastSuccessfulStepParams({
monitorId: 'my-monitor',
stepIndex: 1,
location: undefined,
timestamp: '2021-10-31T19:47:52.392Z',
});
expect(params).toEqual({
query: {
bool: {
filter: [
{
range: {
'@timestamp': {
lte: '2021-10-31T19:47:52.392Z',
},
},
},
{
term: {
'monitor.id': 'my-monitor',
},
},
{
term: {
'synthetics.type': 'step/end',
},
},
{
term: {
'synthetics.step.status': 'succeeded',
},
},
{
term: {
'synthetics.step.index': 1,
},
},
],
must_not: {
exists: {
field: 'observer.geo.name',
},
},
},
},
size: 1,
sort: [
{
'@timestamp': {
order: 'desc',
},
},
],
});
});
});
});

View file

@ -13,13 +13,16 @@ export interface GetStepScreenshotParams {
monitorId: string;
timestamp: string;
stepIndex: number;
location?: string;
}
export const getStepLastSuccessfulStep: UMElasticsearchQueryFn<
GetStepScreenshotParams,
JourneyStep | null
> = async ({ uptimeEsClient, monitorId, stepIndex, timestamp }) => {
const lastSuccessCheckParams: estypes.SearchRequest['body'] = {
export const getLastSuccessfulStepParams = ({
monitorId,
stepIndex,
timestamp,
location,
}: GetStepScreenshotParams): estypes.SearchRequest['body'] => {
return {
size: 1,
sort: [
{
@ -58,10 +61,40 @@ export const getStepLastSuccessfulStep: UMElasticsearchQueryFn<
'synthetics.step.index': stepIndex,
},
},
...(location
? [
{
term: {
'observer.geo.name': location,
},
},
]
: []),
],
...(!location
? {
must_not: {
exists: {
field: 'observer.geo.name',
},
},
}
: {}),
},
},
};
};
export const getStepLastSuccessfulStep: UMElasticsearchQueryFn<
GetStepScreenshotParams,
JourneyStep | null
> = async ({ uptimeEsClient, monitorId, stepIndex, timestamp, location }) => {
const lastSuccessCheckParams = getLastSuccessfulStepParams({
monitorId,
stepIndex,
timestamp,
location,
});
const { body: result } = await uptimeEsClient.search({ body: lastSuccessCheckParams });

View file

@ -22,16 +22,18 @@ export const createLastSuccessfulStepRoute: UMRestApiRouteFactory = (libs: UMSer
monitorId: schema.string(),
stepIndex: schema.number(),
timestamp: schema.string(),
location: schema.maybe(schema.string()),
}),
},
handler: async ({ uptimeEsClient, request, response }) => {
const { timestamp, monitorId, stepIndex } = request.query;
const { timestamp, monitorId, stepIndex, location } = request.query;
const step: JourneyStep | null = await libs.requests.getStepLastSuccessfulStep({
uptimeEsClient,
monitorId,
stepIndex,
timestamp,
location,
});
if (step === null) {