mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `8.6`: - [[Uptime] Ping histogram fix using local timezone or configured (#145412)](https://github.com/elastic/kibana/pull/145412) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Shahzad","email":"shahzad.muhammad@elastic.co"},"sourceCommit":{"committedDate":"2022-11-21T12:43:39Z","message":"[Uptime] Ping histogram fix using local timezone or configured (#145412)\n\nFixes https://github.com/elastic/kibana/issues/144054","sha":"082e4aa71372f8120928d68b6acbdcf329f67b54","branchLabelMapping":{"^v8.7.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:uptime","release_note:skip","v8.6.0","v8.7.0"],"number":145412,"url":"https://github.com/elastic/kibana/pull/145412","mergeCommit":{"message":"[Uptime] Ping histogram fix using local timezone or configured (#145412)\n\nFixes https://github.com/elastic/kibana/issues/144054","sha":"082e4aa71372f8120928d68b6acbdcf329f67b54"}},"sourceBranch":"main","suggestedTargetBranches":["8.6"],"targetPullRequestStates":[{"branch":"8.6","label":"v8.6.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.7.0","labelRegex":"^v8.7.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/145412","number":145412,"mergeCommit":{"message":"[Uptime] Ping histogram fix using local timezone or configured (#145412)\n\nFixes https://github.com/elastic/kibana/issues/144054","sha":"082e4aa71372f8120928d68b6acbdcf329f67b54"}}]}] BACKPORT--> Co-authored-by: Shahzad <shahzad.muhammad@elastic.co>
This commit is contained in:
parent
0cf8fa18f8
commit
c2871d07b8
14 changed files with 99 additions and 8 deletions
|
@ -22,6 +22,7 @@ import moment from 'moment';
|
|||
import React, { useContext } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { ThemeContext } from 'styled-components';
|
||||
import { useTimeZone } from '../../../../hooks/use_time_zone';
|
||||
import { SectionContainer } from '..';
|
||||
import { getDataHandler } from '../../../../data_handler';
|
||||
import { useChartTheme } from '../../../../hooks/use_chart_theme';
|
||||
|
@ -46,19 +47,31 @@ export function UptimeSection({ bucketSize }: Props) {
|
|||
const { relativeStart, relativeEnd, absoluteStart, absoluteEnd, lastUpdated } =
|
||||
useDatePickerContext();
|
||||
|
||||
const timeZone = useTimeZone();
|
||||
|
||||
const { data, status } = useFetcher(
|
||||
() => {
|
||||
if (bucketSize && absoluteStart && absoluteEnd) {
|
||||
return getDataHandler('synthetics')?.fetchData({
|
||||
absoluteTime: { start: absoluteStart, end: absoluteEnd },
|
||||
relativeTime: { start: relativeStart, end: relativeEnd },
|
||||
timeZone,
|
||||
...bucketSize,
|
||||
});
|
||||
}
|
||||
},
|
||||
// `forceUpdate` and `lastUpdated` should trigger a reload
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[bucketSize, relativeStart, relativeEnd, absoluteStart, absoluteEnd, forceUpdate, lastUpdated]
|
||||
[
|
||||
bucketSize,
|
||||
relativeStart,
|
||||
relativeEnd,
|
||||
absoluteStart,
|
||||
absoluteEnd,
|
||||
forceUpdate,
|
||||
lastUpdated,
|
||||
timeZone,
|
||||
]
|
||||
);
|
||||
|
||||
if (!hasDataMap.synthetics?.hasData) {
|
||||
|
|
21
x-pack/plugins/observability/public/hooks/use_time_zone.ts
Normal file
21
x-pack/plugins/observability/public/hooks/use_time_zone.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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 { useUiSetting } from '@kbn/kibana-react-plugin/public';
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
export const useTimeZone = () => {
|
||||
const timeZone = useUiSetting<string | undefined>('dateFormat:tz');
|
||||
|
||||
const localTZ = moment.tz.guess();
|
||||
|
||||
if (!timeZone || timeZone === 'Browser') {
|
||||
return localTZ;
|
||||
}
|
||||
|
||||
return timeZone;
|
||||
};
|
|
@ -80,6 +80,7 @@ export * from './typings';
|
|||
export { useChartTheme } from './hooks/use_chart_theme';
|
||||
export { useBreadcrumbs } from './hooks/use_breadcrumbs';
|
||||
export { useTheme } from './hooks/use_theme';
|
||||
export { useTimeZone } from './hooks/use_time_zone';
|
||||
export { createUseRulesLink } from './hooks/create_use_rules_link';
|
||||
export { useLinkProps, shouldHandleLinkEvent } from './hooks/use_link_props';
|
||||
export type { LinkDescriptor } from './hooks/use_link_props';
|
||||
|
|
|
@ -31,6 +31,7 @@ export interface FetchDataParams {
|
|||
bucketSize: number;
|
||||
// Bucket size in seconds (string)
|
||||
intervalString: string;
|
||||
timeZone?: string;
|
||||
}
|
||||
|
||||
export interface HasDataParams {
|
||||
|
|
|
@ -24,6 +24,7 @@ export interface GetPingHistogramParams {
|
|||
monitorId?: string;
|
||||
bucketSize?: string;
|
||||
query?: string;
|
||||
timeZone: string;
|
||||
}
|
||||
|
||||
export interface HistogramResult {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
import { UptimeFetchDataResponse, FetchDataParams } from '@kbn/observability-plugin/public';
|
||||
import moment from 'moment-timezone';
|
||||
import { fetchIndexStatus, fetchPingHistogram, fetchSnapshotCount } from '../state/api';
|
||||
import { kibanaService } from '../state/kibana_service';
|
||||
|
||||
|
@ -14,6 +15,7 @@ async function fetchUptimeOverviewData({
|
|||
absoluteTime,
|
||||
relativeTime,
|
||||
intervalString,
|
||||
timeZone,
|
||||
}: FetchDataParams) {
|
||||
const start = new Date(absoluteTime.start).toISOString();
|
||||
const end = new Date(absoluteTime.end).toISOString();
|
||||
|
@ -26,6 +28,7 @@ async function fetchUptimeOverviewData({
|
|||
dateStart: start,
|
||||
dateEnd: end,
|
||||
bucketSize: intervalString,
|
||||
timeZone: timeZone ?? moment.tz.guess(),
|
||||
});
|
||||
|
||||
const response: UptimeFetchDataResponse = {
|
||||
|
|
|
@ -28,6 +28,7 @@ describe('PingHistogram component', () => {
|
|||
const props: PingHistogramComponentProps = {
|
||||
absoluteStartDate: 1548697920000,
|
||||
absoluteEndDate: 1548700920000,
|
||||
timeZone: 'UTC',
|
||||
data: {
|
||||
histogram: [
|
||||
{ x: 1581068329000, downCount: 6, upCount: 33, y: 1 },
|
||||
|
|
|
@ -54,6 +54,8 @@ export interface PingHistogramComponentProps {
|
|||
data: HistogramResult | null;
|
||||
|
||||
loading?: boolean;
|
||||
|
||||
timeZone: string;
|
||||
}
|
||||
|
||||
interface BarPoint {
|
||||
|
@ -68,6 +70,7 @@ export const PingHistogramComponent: React.FC<PingHistogramComponentProps> = ({
|
|||
data,
|
||||
loading = false,
|
||||
height,
|
||||
timeZone,
|
||||
}) => {
|
||||
const {
|
||||
colors: { danger, gray },
|
||||
|
@ -181,7 +184,7 @@ export const PingHistogramComponent: React.FC<PingHistogramComponentProps> = ({
|
|||
})}
|
||||
stackAccessors={['x']}
|
||||
splitSeriesAccessors={['type']}
|
||||
timeZone="local"
|
||||
timeZone={timeZone}
|
||||
xAccessor="x"
|
||||
xScaleType={ScaleType.Time}
|
||||
yAccessors={['y']}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useTimeZone } from '@kbn/observability-plugin/public';
|
||||
import { PingHistogramComponent } from '../../common/charts';
|
||||
import { getPingHistogram } from '../../../state/actions';
|
||||
import { esKuerySelector, selectPingHistogram } from '../../../state/selectors';
|
||||
|
@ -39,16 +40,36 @@ const Container: React.FC<Props & ResponsiveWrapperProps> = ({ height }) => {
|
|||
|
||||
const { loading, pingHistogram: data } = useSelector(selectPingHistogram);
|
||||
|
||||
const timeZone = useTimeZone();
|
||||
|
||||
useEffect(() => {
|
||||
if (monitorId) {
|
||||
// we don't need filter check on monitor details page, where we have monitorId defined
|
||||
dispatch(getPingHistogram.get({ monitorId, dateStart, dateEnd, query, filters: esKuery }));
|
||||
dispatch(
|
||||
getPingHistogram.get({
|
||||
monitorId,
|
||||
dateStart,
|
||||
dateEnd,
|
||||
query,
|
||||
filters: esKuery,
|
||||
timeZone,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
filterCheck(() =>
|
||||
dispatch(getPingHistogram.get({ monitorId, dateStart, dateEnd, query, filters: esKuery }))
|
||||
dispatch(
|
||||
getPingHistogram.get({
|
||||
monitorId,
|
||||
dateStart,
|
||||
dateEnd,
|
||||
query,
|
||||
filters: esKuery,
|
||||
timeZone,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}, [filterCheck, dateStart, dateEnd, monitorId, lastRefresh, esKuery, dispatch, query]);
|
||||
}, [filterCheck, dateStart, dateEnd, monitorId, lastRefresh, esKuery, dispatch, query, timeZone]);
|
||||
return (
|
||||
<PingHistogramComponent
|
||||
data={data}
|
||||
|
@ -56,6 +77,7 @@ const Container: React.FC<Props & ResponsiveWrapperProps> = ({ height }) => {
|
|||
absoluteEndDate={absoluteDateRangeEnd}
|
||||
height={height}
|
||||
loading={loading}
|
||||
timeZone={timeZone}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@ export const fetchPingHistogram: APIFn<GetPingHistogramParams, HistogramResult>
|
|||
filters,
|
||||
bucketSize,
|
||||
query,
|
||||
timeZone,
|
||||
}) => {
|
||||
const queryParams = {
|
||||
dateStart,
|
||||
|
@ -36,6 +37,7 @@ export const fetchPingHistogram: APIFn<GetPingHistogramParams, HistogramResult>
|
|||
filters,
|
||||
bucketSize,
|
||||
query,
|
||||
timeZone,
|
||||
};
|
||||
|
||||
return await apiService.get(API_URLS.PING_HISTOGRAM, queryParams);
|
||||
|
|
|
@ -70,6 +70,7 @@ describe('getPingHistogram', () => {
|
|||
uptimeEsClient,
|
||||
dateStart: 'now-15m',
|
||||
dateEnd: 'now',
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(mockEsClient.search).toHaveBeenCalledTimes(1);
|
||||
|
@ -92,6 +93,7 @@ describe('getPingHistogram', () => {
|
|||
dateStart: 'now-15m',
|
||||
dateEnd: 'now',
|
||||
filters: '',
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(mockEsClient.search).toHaveBeenCalledTimes(1);
|
||||
|
@ -157,6 +159,7 @@ describe('getPingHistogram', () => {
|
|||
dateEnd: 'now',
|
||||
filters: JSON.stringify(searchFilter),
|
||||
monitorId: undefined,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(mockEsClient.search).toHaveBeenCalledTimes(1);
|
||||
|
@ -212,6 +215,7 @@ describe('getPingHistogram', () => {
|
|||
dateStart: 'now-15m',
|
||||
dateEnd: 'now',
|
||||
filters,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(mockEsClient.search).toHaveBeenCalledTimes(1);
|
||||
|
@ -232,7 +236,12 @@ describe('getPingHistogram', () => {
|
|||
},
|
||||
} as any);
|
||||
|
||||
const result = await getPingHistogram({ uptimeEsClient, dateStart: 'now-15m', dateEnd: 'now' });
|
||||
const result = await getPingHistogram({
|
||||
uptimeEsClient,
|
||||
dateStart: 'now-15m',
|
||||
dateEnd: 'now',
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result.histogram).toEqual([]);
|
||||
});
|
||||
|
@ -251,7 +260,12 @@ describe('getPingHistogram', () => {
|
|||
},
|
||||
} as any);
|
||||
|
||||
const result = await getPingHistogram({ uptimeEsClient, dateStart: 'now-15m', dateEnd: 'now' });
|
||||
const result = await getPingHistogram({
|
||||
uptimeEsClient,
|
||||
dateStart: 'now-15m',
|
||||
dateEnd: 'now',
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result.histogram).toEqual([]);
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ export const getPingHistogram: UMElasticsearchQueryFn<
|
|||
monitorId,
|
||||
bucketSize,
|
||||
query,
|
||||
timeZone,
|
||||
}) => {
|
||||
const boolFilters = filters ? JSON.parse(filters) : null;
|
||||
const additionalFilters = [];
|
||||
|
@ -73,6 +74,7 @@ export const getPingHistogram: UMElasticsearchQueryFn<
|
|||
field: '@timestamp',
|
||||
fixed_interval: bucketSize || minInterval + 'ms',
|
||||
missing: '0',
|
||||
time_zone: timeZone,
|
||||
},
|
||||
aggs: {
|
||||
down: {
|
||||
|
|
|
@ -21,10 +21,11 @@ export const createGetPingHistogramRoute: UMRestApiRouteFactory = (libs: UMServe
|
|||
filters: schema.maybe(schema.string()),
|
||||
bucketSize: schema.maybe(schema.string()),
|
||||
query: schema.maybe(schema.string()),
|
||||
timeZone: schema.string(),
|
||||
}),
|
||||
},
|
||||
handler: async ({ uptimeEsClient, request }): Promise<any> => {
|
||||
const { dateStart, dateEnd, monitorId, filters, bucketSize, query } = request.query;
|
||||
const { dateStart, dateEnd, monitorId, filters, bucketSize, query, timeZone } = request.query;
|
||||
|
||||
return await libs.requests.getPingHistogram({
|
||||
uptimeEsClient,
|
||||
|
@ -34,6 +35,7 @@ export const createGetPingHistogramRoute: UMRestApiRouteFactory = (libs: UMServe
|
|||
filters,
|
||||
bucketSize,
|
||||
query,
|
||||
timeZone,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -13,6 +13,8 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
describe('pingHistogram', () => {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
const timeZone = 'UTC';
|
||||
|
||||
it('will fetch histogram data for all monitors', async () => {
|
||||
const dateStart = '2019-09-11T03:31:04.380Z';
|
||||
const dateEnd = '2019-09-11T03:40:34.410Z';
|
||||
|
@ -20,6 +22,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
const apiResponse = await supertest.get(API_URLS.PING_HISTOGRAM).query({
|
||||
dateStart,
|
||||
dateEnd,
|
||||
timeZone,
|
||||
});
|
||||
const data = apiResponse.body;
|
||||
|
||||
|
@ -35,6 +38,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
monitorId,
|
||||
dateStart,
|
||||
dateEnd,
|
||||
timeZone,
|
||||
});
|
||||
const data = apiResponse.body;
|
||||
|
||||
|
@ -51,6 +55,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
dateStart,
|
||||
dateEnd,
|
||||
filters,
|
||||
timeZone,
|
||||
});
|
||||
const data = apiResponse.body;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue