2019-05-25 12:18:49 +02:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2019-08-21 15:51:41 +02:00
|
|
|
import * as t from 'io-ts';
|
2019-08-15 10:53:20 +02:00
|
|
|
import { omit } from 'lodash';
|
2019-11-21 15:46:34 +01:00
|
|
|
import {
|
|
|
|
setupRequest,
|
|
|
|
Setup,
|
2020-05-22 09:08:58 +02:00
|
|
|
SetupTimeRange,
|
2019-11-21 15:46:34 +01:00
|
|
|
} from '../lib/helpers/setup_request';
|
2019-05-25 12:18:49 +02:00
|
|
|
import { getEnvironments } from '../lib/ui_filters/get_environments';
|
2020-07-31 15:22:04 +02:00
|
|
|
import { Projection } from '../projections/typings';
|
2020-09-30 10:24:38 +02:00
|
|
|
import { localUIFilterNames } from '../lib/ui_filters/local_ui_filters/config';
|
2020-10-02 09:45:50 +02:00
|
|
|
import { getEsFilter } from '../lib/helpers/convert_ui_filters/get_es_filter';
|
2019-08-15 10:53:20 +02:00
|
|
|
import { getLocalUIFilters } from '../lib/ui_filters/local_ui_filters';
|
2020-07-31 15:22:04 +02:00
|
|
|
import { getServicesProjection } from '../projections/services';
|
|
|
|
import { getTransactionGroupsProjection } from '../projections/transaction_groups';
|
|
|
|
import { getMetricsProjection } from '../projections/metrics';
|
|
|
|
import { getErrorGroupsProjection } from '../projections/errors';
|
|
|
|
import { getTransactionsProjection } from '../projections/transactions';
|
2019-08-21 15:51:41 +02:00
|
|
|
import { createRoute } from './create_route';
|
|
|
|
import { uiFiltersRt, rangeRt } from './default_api_types';
|
|
|
|
import { jsonRt } from '../../common/runtime_types/json_rt';
|
2020-07-31 15:22:04 +02:00
|
|
|
import { getServiceNodesProjection } from '../projections/service_nodes';
|
2020-09-16 19:20:08 +02:00
|
|
|
import { getRumPageLoadTransactionsProjection } from '../projections/rum_page_load_transactions';
|
|
|
|
import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions';
|
|
|
|
import { APMRequestHandlerContext } from './typings';
|
2020-09-30 10:24:38 +02:00
|
|
|
import { LocalUIFilterName } from '../../common/ui_filter';
|
2019-05-25 12:18:49 +02:00
|
|
|
|
2019-08-21 15:51:41 +02:00
|
|
|
export const uiFiltersEnvironmentsRoute = createRoute(() => ({
|
|
|
|
path: '/api/apm/ui_filters/environments',
|
|
|
|
params: {
|
|
|
|
query: t.intersection([
|
|
|
|
t.partial({
|
2020-05-22 09:08:58 +02:00
|
|
|
serviceName: t.string,
|
2019-08-21 15:51:41 +02:00
|
|
|
}),
|
2020-05-22 09:08:58 +02:00
|
|
|
rangeRt,
|
|
|
|
]),
|
2019-08-21 15:51:41 +02:00
|
|
|
},
|
2019-11-21 15:46:34 +01:00
|
|
|
handler: async ({ context, request }) => {
|
|
|
|
const setup = await setupRequest(context, request);
|
|
|
|
const { serviceName } = context.params.query;
|
2020-09-16 19:20:08 +02:00
|
|
|
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
|
|
|
|
setup
|
|
|
|
);
|
|
|
|
|
|
|
|
return getEnvironments({
|
|
|
|
setup,
|
|
|
|
serviceName,
|
|
|
|
searchAggregatedTransactions,
|
|
|
|
});
|
2020-05-22 09:08:58 +02:00
|
|
|
},
|
2019-08-21 15:51:41 +02:00
|
|
|
}));
|
|
|
|
|
|
|
|
const filterNamesRt = t.type({
|
|
|
|
filterNames: jsonRt.pipe(
|
2019-09-06 22:40:51 +02:00
|
|
|
t.array(
|
2019-11-13 17:00:02 +01:00
|
|
|
t.keyof(
|
|
|
|
Object.fromEntries(
|
2020-05-22 09:08:58 +02:00
|
|
|
localUIFilterNames.map((filterName) => [filterName, null])
|
2019-11-13 17:00:02 +01:00
|
|
|
) as Record<LocalUIFilterName, null>
|
|
|
|
)
|
2019-09-06 22:40:51 +02:00
|
|
|
)
|
2020-05-22 09:08:58 +02:00
|
|
|
),
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
const localUiBaseQueryRt = t.intersection([
|
|
|
|
filterNamesRt,
|
|
|
|
uiFiltersRt,
|
2020-05-22 09:08:58 +02:00
|
|
|
rangeRt,
|
2019-08-21 15:51:41 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
function createLocalFiltersRoute<
|
|
|
|
TPath extends string,
|
|
|
|
TProjection extends Projection,
|
|
|
|
TQueryRT extends t.HasProps
|
|
|
|
>({
|
|
|
|
path,
|
|
|
|
getProjection,
|
2020-05-22 09:08:58 +02:00
|
|
|
queryRt,
|
2019-08-21 15:51:41 +02:00
|
|
|
}: {
|
|
|
|
path: TPath;
|
2020-06-11 10:04:09 +02:00
|
|
|
getProjection: GetProjection<
|
|
|
|
TProjection,
|
|
|
|
t.IntersectionC<[TQueryRT, BaseQueryType]>
|
|
|
|
>;
|
2019-08-21 15:51:41 +02:00
|
|
|
queryRt: TQueryRT;
|
|
|
|
}) {
|
|
|
|
return createRoute(() => ({
|
|
|
|
path,
|
|
|
|
params: {
|
2020-05-22 09:08:58 +02:00
|
|
|
query: t.intersection([localUiBaseQueryRt, queryRt]),
|
2019-05-25 12:18:49 +02:00
|
|
|
},
|
2019-11-21 15:46:34 +01:00
|
|
|
handler: async ({ context, request }) => {
|
|
|
|
const setup = await setupRequest(context, request);
|
2020-10-02 09:45:50 +02:00
|
|
|
const { uiFilters } = setup;
|
2019-11-21 15:46:34 +01:00
|
|
|
const { query } = context.params;
|
|
|
|
|
2020-10-02 09:45:50 +02:00
|
|
|
const { filterNames } = query;
|
2020-09-16 19:20:08 +02:00
|
|
|
const projection = await getProjection({
|
2019-08-21 15:51:41 +02:00
|
|
|
query,
|
2020-09-16 19:20:08 +02:00
|
|
|
context,
|
2019-08-21 15:51:41 +02:00
|
|
|
setup: {
|
|
|
|
...setup,
|
2020-10-02 09:45:50 +02:00
|
|
|
esFilter: getEsFilter(omit(uiFilters, filterNames)),
|
2020-05-22 09:08:58 +02:00
|
|
|
},
|
2019-08-15 10:53:20 +02:00
|
|
|
});
|
2019-08-21 15:51:41 +02:00
|
|
|
|
|
|
|
return getLocalUIFilters({
|
|
|
|
projection,
|
2019-08-15 10:53:20 +02:00
|
|
|
setup,
|
2020-10-02 09:45:50 +02:00
|
|
|
uiFilters,
|
2020-05-22 09:08:58 +02:00
|
|
|
localFilterNames: filterNames,
|
2019-08-15 10:53:20 +02:00
|
|
|
});
|
2020-05-22 09:08:58 +02:00
|
|
|
},
|
2019-08-21 15:51:41 +02:00
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
export const servicesLocalFiltersRoute = createLocalFiltersRoute({
|
|
|
|
path: `/api/apm/ui_filters/local_filters/services`,
|
2020-09-16 19:20:08 +02:00
|
|
|
getProjection: async ({ context, setup }) => {
|
|
|
|
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
|
|
|
|
setup
|
|
|
|
);
|
|
|
|
|
|
|
|
return getServicesProjection({ setup, searchAggregatedTransactions });
|
|
|
|
},
|
2020-05-22 09:08:58 +02:00
|
|
|
queryRt: t.type({}),
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
export const transactionGroupsLocalFiltersRoute = createLocalFiltersRoute({
|
|
|
|
path: '/api/apm/ui_filters/local_filters/transactionGroups',
|
2020-09-16 19:20:08 +02:00
|
|
|
getProjection: async ({ context, setup, query }) => {
|
2019-08-21 15:51:41 +02:00
|
|
|
const { transactionType, serviceName, transactionName } = query;
|
2020-09-16 19:20:08 +02:00
|
|
|
|
|
|
|
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
|
|
|
|
setup
|
|
|
|
);
|
|
|
|
|
2019-08-21 15:51:41 +02:00
|
|
|
return getTransactionGroupsProjection({
|
|
|
|
setup,
|
|
|
|
options: {
|
|
|
|
type: 'top_transactions',
|
2019-08-15 10:53:20 +02:00
|
|
|
transactionType,
|
|
|
|
serviceName,
|
2020-05-22 09:08:58 +02:00
|
|
|
transactionName,
|
2020-09-16 19:20:08 +02:00
|
|
|
searchAggregatedTransactions,
|
2020-05-22 09:08:58 +02:00
|
|
|
},
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
},
|
|
|
|
queryRt: t.intersection([
|
|
|
|
t.type({
|
|
|
|
serviceName: t.string,
|
2020-05-22 09:08:58 +02:00
|
|
|
transactionType: t.string,
|
2019-08-21 15:51:41 +02:00
|
|
|
}),
|
|
|
|
t.partial({
|
2020-05-22 09:08:58 +02:00
|
|
|
transactionName: t.string,
|
|
|
|
}),
|
|
|
|
]),
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
export const tracesLocalFiltersRoute = createLocalFiltersRoute({
|
|
|
|
path: '/api/apm/ui_filters/local_filters/traces',
|
2020-09-16 19:20:08 +02:00
|
|
|
getProjection: async ({ setup, context }) => {
|
|
|
|
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
|
|
|
|
setup
|
|
|
|
);
|
|
|
|
|
2019-08-21 15:51:41 +02:00
|
|
|
return getTransactionGroupsProjection({
|
|
|
|
setup,
|
2020-09-16 19:20:08 +02:00
|
|
|
options: { type: 'top_traces', searchAggregatedTransactions },
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
},
|
2020-05-22 09:08:58 +02:00
|
|
|
queryRt: t.type({}),
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
export const transactionsLocalFiltersRoute = createLocalFiltersRoute({
|
|
|
|
path: '/api/apm/ui_filters/local_filters/transactions',
|
2020-09-16 19:20:08 +02:00
|
|
|
getProjection: async ({ context, setup, query }) => {
|
2019-08-21 15:51:41 +02:00
|
|
|
const { transactionType, serviceName, transactionName } = query;
|
2020-09-16 19:20:08 +02:00
|
|
|
|
|
|
|
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
|
|
|
|
setup
|
|
|
|
);
|
|
|
|
|
2019-08-21 15:51:41 +02:00
|
|
|
return getTransactionsProjection({
|
|
|
|
setup,
|
|
|
|
transactionType,
|
|
|
|
serviceName,
|
2020-05-22 09:08:58 +02:00
|
|
|
transactionName,
|
2020-09-16 19:20:08 +02:00
|
|
|
searchAggregatedTransactions,
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
},
|
|
|
|
queryRt: t.type({
|
|
|
|
transactionType: t.string,
|
|
|
|
transactionName: t.string,
|
2020-05-22 09:08:58 +02:00
|
|
|
serviceName: t.string,
|
|
|
|
}),
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
export const metricsLocalFiltersRoute = createLocalFiltersRoute({
|
|
|
|
path: '/api/apm/ui_filters/local_filters/metrics',
|
|
|
|
getProjection: ({ setup, query }) => {
|
2019-10-03 17:41:45 +02:00
|
|
|
const { serviceName, serviceNodeName } = query;
|
2019-08-21 15:51:41 +02:00
|
|
|
return getMetricsProjection({
|
|
|
|
setup,
|
2019-10-03 17:41:45 +02:00
|
|
|
serviceName,
|
2020-05-22 09:08:58 +02:00
|
|
|
serviceNodeName,
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
},
|
2019-10-03 17:41:45 +02:00
|
|
|
queryRt: t.intersection([
|
|
|
|
t.type({
|
2020-05-22 09:08:58 +02:00
|
|
|
serviceName: t.string,
|
2019-10-03 17:41:45 +02:00
|
|
|
}),
|
|
|
|
t.partial({
|
2020-05-22 09:08:58 +02:00
|
|
|
serviceNodeName: t.string,
|
|
|
|
}),
|
|
|
|
]),
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
export const errorGroupsLocalFiltersRoute = createLocalFiltersRoute({
|
|
|
|
path: '/api/apm/ui_filters/local_filters/errorGroups',
|
|
|
|
getProjection: ({ setup, query }) => {
|
|
|
|
const { serviceName } = query;
|
|
|
|
return getErrorGroupsProjection({
|
|
|
|
setup,
|
2020-05-22 09:08:58 +02:00
|
|
|
serviceName,
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
},
|
|
|
|
queryRt: t.type({
|
2020-05-22 09:08:58 +02:00
|
|
|
serviceName: t.string,
|
|
|
|
}),
|
2019-08-21 15:51:41 +02:00
|
|
|
});
|
|
|
|
|
2019-10-03 17:41:45 +02:00
|
|
|
export const serviceNodesLocalFiltersRoute = createLocalFiltersRoute({
|
|
|
|
path: '/api/apm/ui_filters/local_filters/serviceNodes',
|
|
|
|
getProjection: ({ setup, query }) => {
|
2020-06-11 10:04:09 +02:00
|
|
|
const { serviceName } = query;
|
2019-10-03 17:41:45 +02:00
|
|
|
return getServiceNodesProjection({
|
|
|
|
setup,
|
2020-06-11 10:04:09 +02:00
|
|
|
serviceName,
|
2019-10-03 17:41:45 +02:00
|
|
|
});
|
|
|
|
},
|
|
|
|
queryRt: t.type({
|
2020-05-22 09:08:58 +02:00
|
|
|
serviceName: t.string,
|
|
|
|
}),
|
2019-10-03 17:41:45 +02:00
|
|
|
});
|
|
|
|
|
2020-06-18 20:32:10 +02:00
|
|
|
export const rumOverviewLocalFiltersRoute = createLocalFiltersRoute({
|
|
|
|
path: '/api/apm/ui_filters/local_filters/rumOverview',
|
2020-09-16 19:20:08 +02:00
|
|
|
getProjection: async ({ setup }) => {
|
|
|
|
return getRumPageLoadTransactionsProjection({
|
2020-06-18 20:32:10 +02:00
|
|
|
setup,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
queryRt: t.type({}),
|
|
|
|
});
|
|
|
|
|
2019-08-21 15:51:41 +02:00
|
|
|
type BaseQueryType = typeof localUiBaseQueryRt;
|
|
|
|
|
|
|
|
type GetProjection<
|
|
|
|
TProjection extends Projection,
|
|
|
|
TQueryRT extends t.HasProps
|
|
|
|
> = ({
|
|
|
|
query,
|
2020-05-22 09:08:58 +02:00
|
|
|
setup,
|
2020-09-16 19:20:08 +02:00
|
|
|
context,
|
2019-08-21 15:51:41 +02:00
|
|
|
}: {
|
|
|
|
query: t.TypeOf<TQueryRT>;
|
2020-10-02 09:45:50 +02:00
|
|
|
setup: Setup & SetupTimeRange;
|
2020-09-16 19:20:08 +02:00
|
|
|
context: APMRequestHandlerContext;
|
|
|
|
}) => Promise<TProjection> | TProjection;
|