mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* [TSVB] Fix shard failures are not reported (#123474)
* [TSVB] Fix shard failures are not reported #122944
Closes: #122944
* fix PR comments
* Update ui_settings.ts
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
(cherry picked from commit 7e1b780672
)
# Conflicts:
# src/plugins/vis_types/timeseries/kibana.json
# src/plugins/vis_types/timeseries/public/metrics_type.ts
* fix
* fix telemetry
Co-authored-by: Alexey Antonov <alexwizp@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
b2c4f039c1
commit
95ffb91fd6
29 changed files with 219 additions and 80 deletions
|
@ -203,6 +203,7 @@ export {
|
|||
isEsError,
|
||||
SearchSessionState,
|
||||
SortDirection,
|
||||
handleResponse,
|
||||
} from './search';
|
||||
|
||||
export type {
|
||||
|
|
|
@ -52,6 +52,7 @@ export {
|
|||
waitUntilNextSessionCompletes$,
|
||||
} from './session';
|
||||
export { getEsPreference } from './es_search';
|
||||
export { handleResponse } from './fetch';
|
||||
|
||||
export type { SearchInterceptorDeps } from './search_interceptor';
|
||||
export { SearchInterceptor } from './search_interceptor';
|
||||
|
|
|
@ -51,7 +51,7 @@ export class RequestResponder {
|
|||
}
|
||||
|
||||
public finish(status: RequestStatus, response: Response): void {
|
||||
this.request.time = Date.now() - this.request.startTime;
|
||||
this.request.time = response.time ?? Date.now() - this.request.startTime;
|
||||
this.request.status = status;
|
||||
this.request.response = response;
|
||||
this.onChange();
|
||||
|
|
|
@ -53,4 +53,5 @@ export interface RequestStatistic {
|
|||
|
||||
export interface Response {
|
||||
json?: object;
|
||||
time?: number;
|
||||
}
|
||||
|
|
|
@ -284,6 +284,10 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
|
|||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'metrics:allowCheckingForFailedShards': {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'query:allowLeadingWildcards': {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
|
|
|
@ -94,6 +94,7 @@ export interface UsageStats {
|
|||
'savedObjects:listingLimit': number;
|
||||
'query:queryString:options': string;
|
||||
'metrics:max_buckets': number;
|
||||
'metrics:allowCheckingForFailedShards': boolean;
|
||||
'metrics:allowStringIndices': boolean;
|
||||
'query:allowLeadingWildcards': boolean;
|
||||
metaFields: string[];
|
||||
|
|
|
@ -7577,6 +7577,12 @@
|
|||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"metrics:allowCheckingForFailedShards": {
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"query:allowLeadingWildcards": {
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
export const UI_SETTINGS = {
|
||||
MAX_BUCKETS_SETTING: 'metrics:max_buckets',
|
||||
ALLOW_STRING_INDICES: 'metrics:allowStringIndices',
|
||||
ALLOW_CHECKING_FOR_FAILED_SHARDS: 'metrics:allowCheckingForFailedShards',
|
||||
};
|
||||
export const INDEXES_SEPARATOR = ',';
|
||||
export const AUTO_INTERVAL = 'auto';
|
||||
|
|
|
@ -10,7 +10,15 @@ import { Filter, IndexPattern, Query } from '../../../../data/common';
|
|||
import { Panel } from './panel_model';
|
||||
|
||||
export type { Metric, Series, Panel, MetricType } from './panel_model';
|
||||
export type { TimeseriesVisData, PanelData, SeriesData, TableData } from './vis_data';
|
||||
export type {
|
||||
TimeseriesVisData,
|
||||
PanelData,
|
||||
SeriesData,
|
||||
TableData,
|
||||
DataResponseMeta,
|
||||
TrackedEsSearches,
|
||||
PanelSeries,
|
||||
} from './vis_data';
|
||||
|
||||
export interface FetchedIndexPattern {
|
||||
indexPattern: IndexPattern | undefined | null;
|
||||
|
|
|
@ -7,30 +7,38 @@
|
|||
*/
|
||||
|
||||
import { PANEL_TYPES } from '../enums';
|
||||
import { TimeseriesUIRestrictions } from '../ui_restrictions';
|
||||
import type { TimeseriesUIRestrictions } from '../ui_restrictions';
|
||||
|
||||
export type TimeseriesVisData = SeriesData | TableData;
|
||||
|
||||
export interface TableData {
|
||||
type: PANEL_TYPES.TABLE;
|
||||
export type TrackedEsSearches = Record<
|
||||
string,
|
||||
{
|
||||
body: Record<string, any>;
|
||||
label?: string;
|
||||
time: number;
|
||||
response?: Record<string, any>;
|
||||
}
|
||||
>;
|
||||
|
||||
export interface DataResponseMeta {
|
||||
type: PANEL_TYPES;
|
||||
uiRestrictions: TimeseriesUIRestrictions;
|
||||
trackedEsSearches: TrackedEsSearches;
|
||||
}
|
||||
|
||||
export interface TableData extends DataResponseMeta {
|
||||
series?: PanelData[];
|
||||
pivot_label?: string;
|
||||
}
|
||||
|
||||
// series data is not fully typed yet
|
||||
export type SeriesData = {
|
||||
type: Exclude<PANEL_TYPES, PANEL_TYPES.TABLE>;
|
||||
uiRestrictions: TimeseriesUIRestrictions;
|
||||
export type SeriesData = DataResponseMeta & {
|
||||
error?: string;
|
||||
} & {
|
||||
[key: string]: PanelSeries;
|
||||
};
|
||||
} & Record<string, PanelSeries>;
|
||||
|
||||
export interface PanelSeries {
|
||||
annotations: {
|
||||
[key: string]: Annotation[];
|
||||
};
|
||||
annotations: Record<string, Annotation[]>;
|
||||
id: string;
|
||||
series: PanelData[];
|
||||
error?: string;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
"kibanaVersion": "kibana",
|
||||
"server": true,
|
||||
"ui": true,
|
||||
"requiredPlugins": ["charts", "data", "expressions", "visualizations", "visualize"],
|
||||
"optionalPlugins": ["usageCollection"],
|
||||
"requiredPlugins": ["charts", "data", "expressions", "visualizations", "visualize", "inspector"],
|
||||
"optionalPlugins": ["home","usageCollection"],
|
||||
"requiredBundles": ["kibanaUtils", "kibanaReact", "fieldFormats"],
|
||||
"owner": {
|
||||
"name": "Vis Editors",
|
||||
|
|
|
@ -80,7 +80,9 @@ export const AnnotationRow = ({
|
|||
|
||||
try {
|
||||
fetchedIndexPattern = index
|
||||
? await fetchIndexPattern(index, indexPatterns)
|
||||
? await fetchIndexPattern(index, indexPatterns, {
|
||||
fetchKibanaIndexForStringIndexes: true,
|
||||
})
|
||||
: {
|
||||
...fetchedIndexPattern,
|
||||
defaultIndex: await indexPatterns.getDefault(),
|
||||
|
|
|
@ -37,7 +37,7 @@ export const FieldTextSelect = ({
|
|||
|
||||
useDebounce(
|
||||
() => {
|
||||
if (inputValue !== indexPatternString) {
|
||||
if ((inputValue ?? '') !== (indexPatternString ?? '')) {
|
||||
onIndexChange(inputValue);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -111,7 +111,7 @@ export const IndexPatternSelect = ({
|
|||
label={indexPatternLabel}
|
||||
helpText={fetchedIndex.defaultIndex && getIndexPatternHelpText(useKibanaIndices)}
|
||||
labelAppend={
|
||||
fetchedIndex.indexPatternString && !fetchedIndex.indexPattern ? (
|
||||
!useKibanaIndices && fetchedIndex.indexPatternString && !fetchedIndex.indexPattern ? (
|
||||
<EuiLink onClick={navigateToCreateIndexPatternPage}>
|
||||
<EuiText size="xs">
|
||||
<FormattedMessage
|
||||
|
|
|
@ -54,7 +54,11 @@ export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({
|
|||
help: '',
|
||||
},
|
||||
},
|
||||
async fn(input, args, { getSearchSessionId, isSyncColorsEnabled, getExecutionContext }) {
|
||||
async fn(
|
||||
input,
|
||||
args,
|
||||
{ getSearchSessionId, isSyncColorsEnabled, getExecutionContext, inspectorAdapters }
|
||||
) {
|
||||
const visParams: TimeseriesVisParams = JSON.parse(args.params);
|
||||
const uiState = JSON.parse(args.uiState);
|
||||
const syncColors = isSyncColorsEnabled?.() ?? false;
|
||||
|
@ -65,6 +69,7 @@ export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({
|
|||
uiState,
|
||||
searchSessionId: getSearchSessionId(),
|
||||
executionContext: getExecutionContext(),
|
||||
inspectorAdapters,
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
} from '../../../visualizations/public';
|
||||
import { getDataStart } from './services';
|
||||
import type { TimeseriesVisDefaultParams, TimeseriesVisParams } from './types';
|
||||
import { RequestAdapter } from '../../../inspector/public';
|
||||
|
||||
export const withReplacedIds = (
|
||||
vis: Vis<TimeseriesVisParams | TimeseriesVisDefaultParams>
|
||||
|
@ -118,7 +119,9 @@ export const metricsVisDefinition: VisTypeDefinition<
|
|||
}
|
||||
return [];
|
||||
},
|
||||
inspectorAdapters: {},
|
||||
inspectorAdapters: () => ({
|
||||
requests: new RequestAdapter(),
|
||||
}),
|
||||
requiresSearch: true,
|
||||
getUsedIndexPattern: async (params: VisParams) => {
|
||||
const { indexPatterns } = getDataStart();
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
import type { KibanaExecutionContext } from 'src/core/public';
|
||||
import type { Adapters } from 'src/plugins/inspector';
|
||||
import { getTimezone } from './application/lib/get_timezone';
|
||||
import { getUISettings, getDataStart, getCoreStart } from './services';
|
||||
import { ROUTES } from '../common/constants';
|
||||
import { ROUTES, UI_SETTINGS } from '../common/constants';
|
||||
import { KibanaContext, handleResponse } from '../../../data/public';
|
||||
|
||||
import type { TimeseriesVisParams } from './types';
|
||||
import type { TimeseriesVisData } from '../common/types';
|
||||
import type { KibanaContext } from '../../../data/public';
|
||||
|
||||
interface MetricsRequestHandlerParams {
|
||||
input: KibanaContext | null;
|
||||
|
@ -20,6 +21,7 @@ interface MetricsRequestHandlerParams {
|
|||
visParams: TimeseriesVisParams;
|
||||
searchSessionId?: string;
|
||||
executionContext?: KibanaExecutionContext;
|
||||
inspectorAdapters?: Adapters;
|
||||
}
|
||||
|
||||
export const metricsRequestHandler = async ({
|
||||
|
@ -28,6 +30,7 @@ export const metricsRequestHandler = async ({
|
|||
visParams,
|
||||
searchSessionId,
|
||||
executionContext,
|
||||
inspectorAdapters,
|
||||
}: MetricsRequestHandlerParams): Promise<TimeseriesVisData | {}> => {
|
||||
const config = getUISettings();
|
||||
const data = getDataStart();
|
||||
|
@ -48,7 +51,8 @@ export const metricsRequestHandler = async ({
|
|||
|
||||
try {
|
||||
const searchSessionOptions = dataSearch.session.getSearchOptions(searchSessionId);
|
||||
return await getCoreStart().http.post(ROUTES.VIS_DATA, {
|
||||
|
||||
const visData: TimeseriesVisData = await getCoreStart().http.post(ROUTES.VIS_DATA, {
|
||||
body: JSON.stringify({
|
||||
timerange: {
|
||||
timezone,
|
||||
|
@ -64,6 +68,21 @@ export const metricsRequestHandler = async ({
|
|||
}),
|
||||
context: executionContext,
|
||||
});
|
||||
|
||||
inspectorAdapters?.requests?.reset();
|
||||
|
||||
Object.entries(visData.trackedEsSearches || {}).forEach(([key, query]) => {
|
||||
inspectorAdapters?.requests
|
||||
?.start(query.label ?? key, { searchSessionId })
|
||||
.json(query.body)
|
||||
.ok({ time: query.time });
|
||||
|
||||
if (query.response && config.get(UI_SETTINGS.ALLOW_CHECKING_FOR_FAILED_SHARDS)) {
|
||||
handleResponse({ body: query.body }, { rawResponse: query.response });
|
||||
}
|
||||
});
|
||||
|
||||
return visData;
|
||||
} finally {
|
||||
if (untrackSearch && dataSearch.session.isCurrentSession(searchSessionId)) {
|
||||
// untrack if this search still belongs to current session
|
||||
|
|
|
@ -11,6 +11,7 @@ import { AbstractSearchStrategy } from './strategies';
|
|||
|
||||
export { SearchStrategyRegistry } from './search_strategy_registry';
|
||||
export { AbstractSearchStrategy, RollupSearchStrategy, DefaultSearchStrategy } from './strategies';
|
||||
export type { EsSearchRequest } from './strategies/abstract_search_strategy';
|
||||
|
||||
export type SearchCapabilities = DefaultSearchCapabilities;
|
||||
export type SearchStrategy = AbstractSearchStrategy;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import { IndexPatternsService } from '../../../../../../data/common';
|
||||
|
||||
import { from } from 'rxjs';
|
||||
import { AbstractSearchStrategy } from './abstract_search_strategy';
|
||||
import { AbstractSearchStrategy, EsSearchRequest } from './abstract_search_strategy';
|
||||
import type { FieldSpec } from '../../../../../../data/common';
|
||||
import type { CachedIndexPatternFetcher } from '../lib/cached_index_pattern_fetcher';
|
||||
import type {
|
||||
|
@ -64,7 +64,7 @@ describe('AbstractSearchStrategy', () => {
|
|||
});
|
||||
|
||||
test('should return response', async () => {
|
||||
const searches = [{ body: 'body', index: 'index' }];
|
||||
const searches: EsSearchRequest[] = [{ body: {}, index: 'index' }];
|
||||
|
||||
const responses = await abstractSearchStrategy.search(
|
||||
requestContext,
|
||||
|
@ -84,7 +84,7 @@ describe('AbstractSearchStrategy', () => {
|
|||
expect(requestContext.search.search).toHaveBeenCalledWith(
|
||||
{
|
||||
params: {
|
||||
body: 'body',
|
||||
body: {},
|
||||
index: 'index',
|
||||
},
|
||||
indexType: undefined,
|
||||
|
|
|
@ -6,40 +6,67 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { omit } from 'lodash';
|
||||
import { IndexPatternsService } from '../../../../../../data/server';
|
||||
import { toSanitizedFieldType } from '../../../../common/fields_utils';
|
||||
|
||||
import type { FetchedIndexPattern } from '../../../../common/types';
|
||||
import type { FetchedIndexPattern, TrackedEsSearches } from '../../../../common/types';
|
||||
import type {
|
||||
VisTypeTimeseriesRequest,
|
||||
VisTypeTimeseriesRequestHandlerContext,
|
||||
VisTypeTimeseriesVisDataRequest,
|
||||
} from '../../../types';
|
||||
|
||||
export interface EsSearchRequest {
|
||||
body: Record<string, any>;
|
||||
index?: string;
|
||||
trackingEsSearchMeta?: {
|
||||
requestId: string;
|
||||
requestLabel?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export abstract class AbstractSearchStrategy {
|
||||
async search(
|
||||
requestContext: VisTypeTimeseriesRequestHandlerContext,
|
||||
req: VisTypeTimeseriesVisDataRequest,
|
||||
bodies: any[],
|
||||
esRequests: EsSearchRequest[],
|
||||
trackedEsSearches?: TrackedEsSearches,
|
||||
indexType?: string
|
||||
) {
|
||||
const requests: any[] = [];
|
||||
|
||||
bodies.forEach((body) => {
|
||||
esRequests.forEach(({ body, index, trackingEsSearchMeta }) => {
|
||||
const startTime = Date.now();
|
||||
requests.push(
|
||||
requestContext.search
|
||||
.search(
|
||||
{
|
||||
indexType,
|
||||
params: {
|
||||
...body,
|
||||
body,
|
||||
index,
|
||||
},
|
||||
},
|
||||
req.body.searchSession
|
||||
)
|
||||
.pipe(
|
||||
tap((data) => {
|
||||
if (trackingEsSearchMeta?.requestId && trackedEsSearches) {
|
||||
trackedEsSearches[trackingEsSearchMeta.requestId] = {
|
||||
body,
|
||||
time: Date.now() - startTime,
|
||||
label: trackingEsSearchMeta.requestLabel,
|
||||
response: omit(data.rawResponse, 'aggregations'),
|
||||
};
|
||||
}
|
||||
})
|
||||
)
|
||||
.toPromise()
|
||||
);
|
||||
});
|
||||
|
||||
return Promise.all(requests);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,10 @@ import {
|
|||
getCapabilitiesForRollupIndices,
|
||||
IndexPatternsService,
|
||||
} from '../../../../../../data/server';
|
||||
import { AbstractSearchStrategy } from './abstract_search_strategy';
|
||||
import { AbstractSearchStrategy, EsSearchRequest } from './abstract_search_strategy';
|
||||
import { RollupSearchCapabilities } from '../capabilities/rollup_search_capabilities';
|
||||
|
||||
import type { FetchedIndexPattern } from '../../../../common/types';
|
||||
import type { FetchedIndexPattern, TrackedEsSearches } from '../../../../common/types';
|
||||
import type { CachedIndexPatternFetcher } from '../lib/cached_index_pattern_fetcher';
|
||||
import type {
|
||||
VisTypeTimeseriesRequest,
|
||||
|
@ -29,9 +29,10 @@ export class RollupSearchStrategy extends AbstractSearchStrategy {
|
|||
async search(
|
||||
requestContext: VisTypeTimeseriesRequestHandlerContext,
|
||||
req: VisTypeTimeseriesVisDataRequest,
|
||||
bodies: any[]
|
||||
esRequests: EsSearchRequest[],
|
||||
trackedEsSearches?: TrackedEsSearches
|
||||
) {
|
||||
return super.search(requestContext, req, bodies, 'rollup');
|
||||
return super.search(requestContext, req, esRequests, trackedEsSearches, 'rollup');
|
||||
}
|
||||
|
||||
async getRollupData(
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { Annotation, Panel } from '../../../../common/types';
|
||||
import { buildAnnotationRequest } from './build_request_body';
|
||||
import type {
|
||||
|
@ -13,7 +13,7 @@ import type {
|
|||
VisTypeTimeseriesRequestServices,
|
||||
VisTypeTimeseriesVisDataRequest,
|
||||
} from '../../../types';
|
||||
import type { SearchStrategy, SearchCapabilities } from '../../search_strategies';
|
||||
import type { SearchStrategy, SearchCapabilities, EsSearchRequest } from '../../search_strategies';
|
||||
|
||||
export type AnnotationServices = VisTypeTimeseriesRequestServices & {
|
||||
capabilities: SearchCapabilities;
|
||||
|
@ -32,7 +32,7 @@ export async function getAnnotationRequestParams(
|
|||
uiSettings,
|
||||
cachedIndexPatternFetcher,
|
||||
}: AnnotationServices
|
||||
) {
|
||||
): Promise<EsSearchRequest> {
|
||||
const annotationIndex = await cachedIndexPatternFetcher(annotation.index_pattern);
|
||||
|
||||
const request = await buildAnnotationRequest({
|
||||
|
@ -52,5 +52,14 @@ export async function getAnnotationRequestParams(
|
|||
runtime_mappings: annotationIndex.indexPattern?.getComputedFields().runtimeFields ?? {},
|
||||
timeout: esShardTimeout > 0 ? `${esShardTimeout}ms` : undefined,
|
||||
},
|
||||
trackingEsSearchMeta: {
|
||||
requestId: annotation.id,
|
||||
requestLabel: i18n.translate('visTypeTimeseries.annotationRequest.label', {
|
||||
defaultMessage: 'Annotation: {id}',
|
||||
values: {
|
||||
id: annotation.id,
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ import { handleAnnotationResponse } from './response_processors/annotations';
|
|||
import { AnnotationServices, getAnnotationRequestParams } from './annotations/get_request_params';
|
||||
import { getLastSeriesTimestamp } from './helpers/timestamp';
|
||||
import type { VisTypeTimeseriesVisDataRequest } from '../../types';
|
||||
import type { Annotation, Panel } from '../../../common/types';
|
||||
import type { PanelSeries } from '../../../common/types/vis_data';
|
||||
import type { Annotation, Panel, TrackedEsSearches, PanelSeries } from '../../../common/types';
|
||||
|
||||
function validAnnotation(annotation: Annotation) {
|
||||
return annotation.fields && annotation.icon && annotation.template && !annotation.hidden;
|
||||
|
@ -22,26 +21,33 @@ interface GetAnnotationsParams {
|
|||
panel: Panel;
|
||||
series: Array<PanelSeries['series']>;
|
||||
services: AnnotationServices;
|
||||
trackedEsSearches: TrackedEsSearches;
|
||||
}
|
||||
|
||||
export async function getAnnotations({ req, panel, series, services }: GetAnnotationsParams) {
|
||||
export async function getAnnotations({
|
||||
req,
|
||||
panel,
|
||||
series,
|
||||
services,
|
||||
trackedEsSearches,
|
||||
}: GetAnnotationsParams) {
|
||||
const annotations = panel.annotations!.filter(validAnnotation);
|
||||
const lastSeriesTimestamp = getLastSeriesTimestamp(series);
|
||||
const handleAnnotationResponseBy = handleAnnotationResponse(lastSeriesTimestamp);
|
||||
|
||||
const bodiesPromises = annotations.map((annotation) =>
|
||||
getAnnotationRequestParams(req, panel, annotation, services)
|
||||
);
|
||||
|
||||
const searches = (await Promise.all(bodiesPromises)).reduce(
|
||||
(acc, items) => acc.concat(items as any),
|
||||
[]
|
||||
const searches = await Promise.all(
|
||||
annotations.map((annotation) => getAnnotationRequestParams(req, panel, annotation, services))
|
||||
);
|
||||
|
||||
if (!searches.length) return { responses: [] };
|
||||
|
||||
try {
|
||||
const data = await services.searchStrategy.search(services.requestContext, req, searches);
|
||||
const data = await services.searchStrategy.search(
|
||||
services.requestContext,
|
||||
req,
|
||||
searches,
|
||||
trackedEsSearches
|
||||
);
|
||||
|
||||
return annotations.reduce((acc, annotation, index) => {
|
||||
acc[annotation.id] = handleAnnotationResponseBy(data[index].rawResponse, annotation);
|
||||
|
|
|
@ -20,7 +20,7 @@ import type {
|
|||
VisTypeTimeseriesVisDataRequest,
|
||||
VisTypeTimeseriesRequestServices,
|
||||
} from '../../types';
|
||||
import type { Panel } from '../../../common/types';
|
||||
import type { Panel, DataResponseMeta } from '../../../common/types';
|
||||
import { PANEL_TYPES } from '../../../common/enums';
|
||||
|
||||
export async function getSeriesData(
|
||||
|
@ -52,13 +52,14 @@ export async function getSeriesData(
|
|||
}
|
||||
|
||||
const { searchStrategy, capabilities } = strategy;
|
||||
const meta = {
|
||||
const handleError = handleErrorResponse(panel);
|
||||
|
||||
const meta: DataResponseMeta = {
|
||||
type: panel.type,
|
||||
uiRestrictions: capabilities.uiRestrictions,
|
||||
trackedEsSearches: {},
|
||||
};
|
||||
|
||||
const handleError = handleErrorResponse(panel);
|
||||
|
||||
try {
|
||||
const bodiesPromises = getActiveSeries(panel).map((series) => {
|
||||
if (isEntireTimeRangeMode(panel, series)) {
|
||||
|
@ -83,7 +84,7 @@ export async function getSeriesData(
|
|||
);
|
||||
|
||||
const searches = await Promise.all(bodiesPromises);
|
||||
const data = await searchStrategy.search(requestContext, req, searches);
|
||||
const data = await searchStrategy.search(requestContext, req, searches, meta.trackedEsSearches);
|
||||
|
||||
const series = await Promise.all(
|
||||
data.map(
|
||||
|
@ -104,6 +105,7 @@ export async function getSeriesData(
|
|||
searchStrategy,
|
||||
capabilities,
|
||||
},
|
||||
trackedEsSearches: meta.trackedEsSearches,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ import type {
|
|||
VisTypeTimeseriesRequestServices,
|
||||
VisTypeTimeseriesVisDataRequest,
|
||||
} from '../../types';
|
||||
import type { Panel } from '../../../common/types';
|
||||
import type { Panel, DataResponseMeta } from '../../../common/types';
|
||||
import type { EsSearchRequest } from '../search_strategies';
|
||||
|
||||
export async function getTableData(
|
||||
requestContext: VisTypeTimeseriesRequestHandlerContext,
|
||||
|
@ -68,11 +69,11 @@ export async function getTableData(
|
|||
return panel.pivot_id;
|
||||
};
|
||||
|
||||
const meta = {
|
||||
const meta: DataResponseMeta = {
|
||||
type: panel.type,
|
||||
uiRestrictions: capabilities.uiRestrictions,
|
||||
trackedEsSearches: {},
|
||||
};
|
||||
|
||||
const handleError = handleErrorResponse(panel);
|
||||
|
||||
try {
|
||||
|
@ -82,29 +83,38 @@ export async function getTableData(
|
|||
});
|
||||
}
|
||||
|
||||
const body = await buildTableRequest({
|
||||
req,
|
||||
panel,
|
||||
esQueryConfig: services.esQueryConfig,
|
||||
seriesIndex: panelIndex,
|
||||
capabilities,
|
||||
uiSettings: services.uiSettings,
|
||||
buildSeriesMetaParams: () =>
|
||||
services.buildSeriesMetaParams(panelIndex, Boolean(panel.use_kibana_indexes)),
|
||||
});
|
||||
|
||||
const [resp] = await searchStrategy.search(requestContext, req, [
|
||||
const searches: EsSearchRequest[] = [
|
||||
{
|
||||
index: panelIndex.indexPatternString,
|
||||
body: {
|
||||
...body,
|
||||
...(await buildTableRequest({
|
||||
req,
|
||||
panel,
|
||||
esQueryConfig: services.esQueryConfig,
|
||||
seriesIndex: panelIndex,
|
||||
capabilities,
|
||||
uiSettings: services.uiSettings,
|
||||
buildSeriesMetaParams: () =>
|
||||
services.buildSeriesMetaParams(panelIndex, Boolean(panel.use_kibana_indexes)),
|
||||
})),
|
||||
runtime_mappings: panelIndex.indexPattern?.getComputedFields().runtimeFields ?? {},
|
||||
},
|
||||
index: panelIndex.indexPatternString,
|
||||
trackingEsSearchMeta: {
|
||||
requestId: panel.id,
|
||||
requestLabel: i18n.translate('visTypeTimeseries.tableRequest.label', {
|
||||
defaultMessage: 'Table: {id}',
|
||||
values: {
|
||||
id: panel.id,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
]);
|
||||
];
|
||||
|
||||
const data = await searchStrategy.search(requestContext, req, searches, meta.trackedEsSearches);
|
||||
|
||||
const buckets = get(
|
||||
resp.rawResponse ? resp.rawResponse : resp,
|
||||
data[0].rawResponse ? data[0].rawResponse : data[0],
|
||||
'aggregations.pivot.buckets',
|
||||
[]
|
||||
);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { buildRequestBody } from './build_request_body';
|
||||
|
||||
import type { FetchedIndexPattern, Panel, Series } from '../../../../common/types';
|
||||
|
@ -13,7 +13,7 @@ import type {
|
|||
VisTypeTimeseriesRequestServices,
|
||||
VisTypeTimeseriesVisDataRequest,
|
||||
} from '../../../types';
|
||||
import type { SearchCapabilities } from '../../search_strategies';
|
||||
import type { SearchCapabilities, EsSearchRequest } from '../../search_strategies';
|
||||
|
||||
export async function getSeriesRequestParams(
|
||||
req: VisTypeTimeseriesVisDataRequest,
|
||||
|
@ -28,7 +28,7 @@ export async function getSeriesRequestParams(
|
|||
cachedIndexPatternFetcher,
|
||||
buildSeriesMetaParams,
|
||||
}: VisTypeTimeseriesRequestServices
|
||||
) {
|
||||
): Promise<EsSearchRequest> {
|
||||
let seriesIndex = panelIndex;
|
||||
|
||||
if (series.override_index_pattern) {
|
||||
|
@ -53,5 +53,14 @@ export async function getSeriesRequestParams(
|
|||
runtime_mappings: seriesIndex.indexPattern?.getComputedFields().runtimeFields ?? {},
|
||||
timeout: esShardTimeout > 0 ? `${esShardTimeout}ms` : undefined,
|
||||
},
|
||||
trackingEsSearchMeta: {
|
||||
requestId: series.id,
|
||||
requestLabel: i18n.translate('visTypeTimeseries.seriesRequest.label', {
|
||||
defaultMessage: 'Series: {id}',
|
||||
values: {
|
||||
id: series.id,
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -36,4 +36,18 @@ export const getUiSettings: () => Record<string, UiSettingsParams> = () => ({
|
|||
}),
|
||||
schema: schema.boolean(),
|
||||
},
|
||||
[UI_SETTINGS.ALLOW_CHECKING_FOR_FAILED_SHARDS]: {
|
||||
name: i18n.translate('visTypeTimeseries.advancedSettings.allowCheckingForFailedShardsTitle', {
|
||||
defaultMessage: 'Show TSVB request shard failures',
|
||||
}),
|
||||
value: true,
|
||||
description: i18n.translate(
|
||||
'visTypeTimeseries.advancedSettings.allowCheckingForFailedShardsText',
|
||||
{
|
||||
defaultMessage:
|
||||
'Show warning message for partial data in TSVB charts if the request succeeds for some shards but fails for others.',
|
||||
}
|
||||
),
|
||||
schema: schema.boolean(),
|
||||
},
|
||||
});
|
||||
|
|
|
@ -52,8 +52,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await visualBuilder.clickDataTab('metric');
|
||||
});
|
||||
|
||||
it('should not have inspector enabled', async () => {
|
||||
await inspector.expectIsNotEnabled();
|
||||
it('should have inspector enabled', async () => {
|
||||
await inspector.expectIsEnabled();
|
||||
});
|
||||
|
||||
it('should show correct data', async () => {
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { flatten, get } from 'lodash';
|
||||
import { KibanaRequest } from 'src/core/server';
|
||||
import { flatten, get } from 'lodash';
|
||||
import { TIMESTAMP_FIELD } from '../../../../common/constants';
|
||||
import { NodeDetailsMetricData } from '../../../../common/http_api/node_details_api';
|
||||
import { KibanaFramework } from '../framework/kibana_framework_adapter';
|
||||
|
@ -63,7 +63,7 @@ export class KibanaMetricsAdapter implements InfraMetricsAdapter {
|
|||
.then((results) => {
|
||||
return results.filter(isVisSeriesData).map((result) => {
|
||||
const metricIds = Object.keys(result).filter(
|
||||
(k) => !['type', 'uiRestrictions'].includes(k)
|
||||
(k) => !['type', 'uiRestrictions', 'trackedEsSearches'].includes(k)
|
||||
);
|
||||
|
||||
return metricIds.map((id: string) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue