[APM] Fix anomalies not showing up on transaction charts (#76930) (#79253)

* [APM] Fix anomalies not showing up on transaction charts

* Added API tests to check transaction groups charts for anomaly data

* Improve test names and assertions from PR feedback

* Updated the transaction groups chart API to make `environment` a
required param while making `uiFilters` optional

* updates the basic API tests for transaction_groups/charts with the
required `environment` param

* makes uiFIltersES default to [] on core setup and removes SetupUIFilters type

* fixes vertical shade

* - replaces uiFiltersES with esFilter & uiFilters and cleans up related code around these
- deduplicates the required environment in the transaction_groups/charts API

* updates basic apm_api_integration tests

* pr feedback

* updates api test snapshots with correct anomaly data

* removed environment query param from useTransactionCharts and ensures
it's included in uiFilters returned from useUrlParams

Co-authored-by: Oliver Gupte <olivergupte@gmail.com>
# Conflicts:
#	x-pack/plugins/apm/public/utils/testHelpers.tsx
#	x-pack/plugins/apm/server/lib/rum_client/get_long_task_metrics.ts

Co-authored-by: Søren Louv-Jansen <sorenlouv@gmail.com>
This commit is contained in:
Oliver Gupte 2020-10-02 15:54:37 -07:00 committed by GitHub
parent 49b2038900
commit f9b629fc9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
87 changed files with 528 additions and 548 deletions

View file

@ -83,7 +83,7 @@
"id": "opbeans-go~>postgresql",
"sourceData": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go"
},
@ -103,7 +103,7 @@
"id": "opbeans-go~opbeans-java",
"sourceData": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go"
},
@ -123,13 +123,13 @@
"id": "opbeans-go~opbeans-node",
"sourceData": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go"
},
"targetData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
},
@ -143,7 +143,7 @@
"id": "opbeans-go~opbeans-ruby",
"sourceData": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go"
},
@ -189,7 +189,7 @@
},
"targetData": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go"
},
@ -209,7 +209,7 @@
},
"targetData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
}
@ -242,7 +242,7 @@
"id": "opbeans-node~>postgresql",
"sourceData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
},
@ -262,7 +262,7 @@
"id": "opbeans-node~>redis",
"sourceData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
},
@ -282,13 +282,13 @@
"id": "opbeans-node~opbeans-go",
"sourceData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
},
"targetData": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go"
},
@ -302,7 +302,7 @@
"id": "opbeans-node~opbeans-python",
"sourceData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
},
@ -322,7 +322,7 @@
"id": "opbeans-node~opbeans-ruby",
"sourceData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
},
@ -408,7 +408,7 @@
},
"targetData": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go"
}
@ -427,7 +427,7 @@
},
"targetData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
},
@ -487,7 +487,7 @@
},
"targetData": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go"
},
@ -527,7 +527,7 @@
},
"targetData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
},
@ -566,7 +566,7 @@
},
"targetData": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go"
}
@ -602,7 +602,7 @@
},
"targetData": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
}
@ -673,7 +673,7 @@
{
"data": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs",
"anomaly_score": 41.31593099784474,
@ -733,7 +733,7 @@
{
"data": {
"id": "opbeans-go",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-go",
"agent.name": "go",
"anomaly_score": 0.2633884161762746,

View file

@ -25,6 +25,7 @@ import {
import { pickKeys } from '../../../common/utils/pick_keys';
import { useDeepObjectIdentity } from '../../hooks/useDeepObjectIdentity';
import { LocalUIFilterName } from '../../../common/ui_filter';
import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values';
interface TimeRange {
rangeFrom: string;
@ -38,7 +39,11 @@ function useUiFilters(params: IUrlParams): UIFilters {
(val) => (val ? val.split(',') : [])
) as Partial<Record<LocalUIFilterName, string[]>>;
return useDeepObjectIdentity({ kuery, environment, ...localUiFilters });
return useDeepObjectIdentity({
kuery,
environment: environment || ENVIRONMENT_ALL.value,
...localUiFilters,
});
}
const defaultRefresh = (_time: TimeRange) => {};

View file

@ -24,6 +24,7 @@ import {
ESSearchRequest,
} from '../../typings/elasticsearch';
import { MockApmPluginContextWrapper } from '../context/ApmPluginContext/MockApmPluginContext';
import { UIFilters } from '../../typings/ui_filters';
const originalConsoleWarn = console.warn; // eslint-disable-line no-console
/**
@ -115,7 +116,8 @@ interface MockSetup {
apmEventClient: any;
internalClient: any;
config: APMConfig;
uiFiltersES: ESFilter[];
uiFilters: UIFilters;
esFilter: ESFilter[];
indices: {
/* eslint-disable @typescript-eslint/naming-convention */
'apm_oss.sourcemapIndices': string;
@ -176,7 +178,8 @@ export async function inspectSearchParams(
},
}
) as APMConfig,
uiFiltersES: [{ term: { 'my.custom.ui.filter': 'foo-bar' } }],
uiFilters: { environment: 'test' },
esFilter: [{ term: { 'service.environment': 'test' } }],
indices: {
/* eslint-disable @typescript-eslint/naming-convention */
'apm_oss.sourcemapIndices': 'myIndex',

View file

@ -32,7 +32,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -119,7 +119,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -194,7 +194,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],

View file

@ -40,7 +40,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -91,7 +91,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {

View file

@ -41,7 +41,10 @@ describe('timeseriesFetcher', () => {
get: () => 'myIndex',
}
) as APMConfig,
uiFiltersES: [
uiFilters: {
environment: 'prod',
},
esFilter: [
{
term: { 'service.environment': 'prod' },
},

View file

@ -11,11 +11,7 @@ import {
SERVICE_NAME,
} from '../../../../common/elasticsearch_fieldnames';
import { rangeFilter } from '../../../../common/utils/range_filter';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
export async function getBuckets({
serviceName,
@ -26,13 +22,13 @@ export async function getBuckets({
serviceName: string;
groupId?: string;
bucketSize: number;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
}) {
const { start, end, uiFiltersES, apmEventClient } = setup;
const { start, end, esFilter, apmEventClient } = setup;
const filter: ESFilter[] = [
{ term: { [SERVICE_NAME]: serviceName } },
{ range: rangeFilter(start, end) },
...uiFiltersES,
...esFilter,
];
if (groupId) {

View file

@ -5,11 +5,7 @@
*/
import { PromiseReturnType } from '../../../../typings/common';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import { getBuckets } from './get_buckets';
import { BUCKET_TARGET_COUNT } from '../../transactions/constants';
@ -28,7 +24,7 @@ export async function getErrorDistribution({
}: {
serviceName: string;
groupId?: string;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
}) {
const bucketSize = getBucketSize({ start: setup.start, end: setup.end });
const { buckets, noHits } = await getBuckets({

View file

@ -12,11 +12,7 @@ import {
} from '../../../common/elasticsearch_fieldnames';
import { PromiseReturnType } from '../../../typings/common';
import { rangeFilter } from '../../../common/utils/range_filter';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { getTransaction } from '../transactions/get_transaction';
export type ErrorGroupAPIResponse = PromiseReturnType<typeof getErrorGroup>;
@ -29,9 +25,9 @@ export async function getErrorGroup({
}: {
serviceName: string;
groupId: string;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
}) {
const { start, end, uiFiltersES, apmEventClient } = setup;
const { start, end, esFilter, apmEventClient } = setup;
const params = {
apm: {
@ -45,7 +41,7 @@ export async function getErrorGroup({
{ term: { [SERVICE_NAME]: serviceName } },
{ term: { [ERROR_GROUP_ID]: groupId } },
{ range: rangeFilter(start, end) },
...uiFiltersES,
...esFilter,
],
should: [{ term: { [TRANSACTION_SAMPLED]: true } }],
},

View file

@ -13,11 +13,7 @@ import {
ERROR_LOG_MESSAGE,
} from '../../../common/elasticsearch_fieldnames';
import { PromiseReturnType } from '../../../typings/common';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { getErrorGroupsProjection } from '../../projections/errors';
import { mergeProjection } from '../../projections/util/merge_projection';
import { SortOptions } from '../../../typings/elasticsearch/aggregations';
@ -35,7 +31,7 @@ export async function getErrorGroups({
serviceName: string;
sortField?: string;
sortDirection?: 'asc' | 'desc';
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
}) {
const { apmEventClient } = setup;

View file

@ -13,7 +13,7 @@ import {
} from '../../ui_filters/local_ui_filters/config';
import { esKuery } from '../../../../../../../src/plugins/data/server';
export function getUiFiltersES(uiFilters: UIFilters) {
export function getEsFilter(uiFilters: UIFilters) {
const { kuery, environment, ...localFilterValues } = uiFilters;
const mappedFilters = localUIFilterNames
.filter((name) => name in localFilterValues)

View file

@ -1,23 +0,0 @@
/*
* 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 { Logger } from 'src/core/server';
import { UIFilters } from '../../../../typings/ui_filters';
export function getParsedUiFilters({
uiFilters,
logger,
}: {
uiFilters: string;
logger: Logger;
}): UIFilters {
try {
return JSON.parse(uiFilters);
} catch (error) {
logger.error(error);
}
return {};
}

View file

@ -5,6 +5,7 @@
*/
import moment from 'moment';
import { Logger } from 'kibana/server';
import { isActivePlatinumLicense } from '../../../common/service_map';
import { UI_SETTINGS } from '../../../../../../src/plugins/data/common';
import { KibanaRequest } from '../../../../../../src/core/server';
@ -14,7 +15,7 @@ import {
ApmIndicesConfig,
} from '../settings/apm_indices/get_apm_indices';
import { ESFilter } from '../../../typings/elasticsearch';
import { getUiFiltersES } from './convert_ui_filters/get_ui_filters_es';
import { getEsFilter } from './convert_ui_filters/get_es_filter';
import { APMRequestHandlerContext } from '../../routes/typings';
import { ProcessorEvent } from '../../../common/processor_event';
import {
@ -25,14 +26,8 @@ import {
APMInternalClient,
createInternalESClient,
} from './create_es_client/create_internal_es_client';
import { UIFilters } from '../../../typings/ui_filters';
function decodeUiFilters(uiFiltersEncoded?: string) {
if (!uiFiltersEncoded) {
return [];
}
const uiFilters = JSON.parse(uiFiltersEncoded);
return getUiFiltersES(uiFilters);
}
// Explicitly type Setup to prevent TS initialization errors
// https://github.com/microsoft/TypeScript/issues/34933
@ -42,6 +37,8 @@ export interface Setup {
ml?: ReturnType<typeof getMlSetup>;
config: APMConfig;
indices: ApmIndicesConfig;
uiFilters: UIFilters;
esFilter: ESFilter[];
}
export interface SetupTimeRange {
@ -49,10 +46,6 @@ export interface SetupTimeRange {
end: number;
}
export interface SetupUIFilters {
uiFiltersES: ESFilter[];
}
interface SetupRequestParams {
query?: {
_debug?: boolean;
@ -65,16 +58,13 @@ interface SetupRequestParams {
type InferSetup<TParams extends SetupRequestParams> = Setup &
(TParams extends { query: { start: string } } ? { start: number } : {}) &
(TParams extends { query: { end: string } } ? { end: number } : {}) &
(TParams extends { query: { uiFilters: string } }
? { uiFiltersES: ESFilter[] }
: {});
(TParams extends { query: { end: string } } ? { end: number } : {});
export async function setupRequest<TParams extends SetupRequestParams>(
context: APMRequestHandlerContext<TParams>,
request: KibanaRequest
): Promise<InferSetup<TParams>> {
const { config } = context;
const { config, logger } = context;
const { query } = context.params;
const [indices, includeFrozen] = await Promise.all([
@ -85,7 +75,7 @@ export async function setupRequest<TParams extends SetupRequestParams>(
context.core.uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN),
]);
const uiFiltersES = decodeUiFilters(query.uiFilters);
const uiFilters = decodeUiFilters(logger, query.uiFilters);
const coreSetupRequest = {
indices,
@ -108,12 +98,13 @@ export async function setupRequest<TParams extends SetupRequestParams>(
)
: undefined,
config,
uiFilters,
esFilter: getEsFilter(uiFilters),
};
return {
...('start' in query ? { start: moment.utc(query.start).valueOf() } : {}),
...('end' in query ? { end: moment.utc(query.end).valueOf() } : {}),
...('uiFilters' in query ? { uiFiltersES } : {}),
...coreSetupRequest,
} as InferSetup<TParams>;
}
@ -129,3 +120,15 @@ function getMlSetup(
modules: ml.modulesProvider(request, savedObjectsClient),
};
}
function decodeUiFilters(logger: Logger, uiFiltersEncoded?: string): UIFilters {
if (!uiFiltersEncoded) {
return {};
}
try {
return JSON.parse(uiFiltersEncoded);
} catch (error) {
logger.error(error);
return {};
}
}

View file

@ -87,7 +87,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -175,7 +175,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -206,7 +206,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -231,7 +231,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -258,7 +258,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -283,7 +283,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -338,7 +338,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -431,7 +431,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -514,7 +514,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -623,7 +623,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -717,7 +717,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -748,7 +748,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -773,7 +773,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -800,7 +800,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -825,7 +825,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -886,7 +886,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -985,7 +985,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -1074,7 +1074,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -1172,7 +1172,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -1255,7 +1255,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -1286,7 +1286,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -1311,7 +1311,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -1338,7 +1338,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -1363,7 +1363,7 @@ Object {
"lang": "painless",
"source": "
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -1413,7 +1413,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -1501,7 +1501,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -1579,7 +1579,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {

View file

@ -4,16 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import { getCPUChartData } from './shared/cpu';
import { getMemoryChartData } from './shared/memory';
export async function getDefaultMetricsCharts(
setup: Setup & SetupTimeRange & SetupUIFilters,
setup: Setup & SetupTimeRange,
serviceName: string
) {
const charts = await Promise.all([

View file

@ -11,11 +11,7 @@
import { sum, round } from 'lodash';
import theme from '@elastic/eui/dist/eui_theme_light.json';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../../helpers/setup_request';
import { getMetricsDateHistogramParams } from '../../../../helpers/metrics';
import { ChartBase } from '../../../types';
import { getMetricsProjection } from '../../../../../projections/metrics';
@ -36,7 +32,7 @@ export async function fetchAndTransformGcMetrics({
chartBase,
fieldName,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
serviceName: string;
serviceNodeName?: string;
chartBase: ChartBase;

View file

@ -7,11 +7,7 @@
import theme from '@elastic/eui/dist/eui_theme_light.json';
import { i18n } from '@kbn/i18n';
import { METRIC_JAVA_GC_COUNT } from '../../../../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../../helpers/setup_request';
import { fetchAndTransformGcMetrics } from './fetch_and_transform_gc_metrics';
import { ChartBase } from '../../../types';
@ -35,7 +31,7 @@ const chartBase: ChartBase = {
};
const getGcRateChart = (
setup: Setup & SetupTimeRange & SetupUIFilters,
setup: Setup & SetupTimeRange,
serviceName: string,
serviceNodeName?: string
) => {

View file

@ -7,11 +7,7 @@
import theme from '@elastic/eui/dist/eui_theme_light.json';
import { i18n } from '@kbn/i18n';
import { METRIC_JAVA_GC_TIME } from '../../../../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../../helpers/setup_request';
import { fetchAndTransformGcMetrics } from './fetch_and_transform_gc_metrics';
import { ChartBase } from '../../../types';
@ -35,7 +31,7 @@ const chartBase: ChartBase = {
};
const getGcTimeChart = (
setup: Setup & SetupTimeRange & SetupUIFilters,
setup: Setup & SetupTimeRange,
serviceName: string,
serviceNodeName?: string
) => {

View file

@ -12,11 +12,7 @@ import {
METRIC_JAVA_HEAP_MEMORY_USED,
AGENT_NAME,
} from '../../../../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../../helpers/setup_request';
import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics';
import { ChartBase } from '../../../types';
@ -55,7 +51,7 @@ const chartBase: ChartBase = {
};
export async function getHeapMemoryChart(
setup: Setup & SetupTimeRange & SetupUIFilters,
setup: Setup & SetupTimeRange,
serviceName: string,
serviceNodeName?: string
) {

View file

@ -5,11 +5,7 @@
*/
import { getHeapMemoryChart } from './heap_memory';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../helpers/setup_request';
import { getNonHeapMemoryChart } from './non_heap_memory';
import { getThreadCountChart } from './thread_count';
import { getCPUChartData } from '../shared/cpu';
@ -18,7 +14,7 @@ import { getGcRateChart } from './gc/get_gc_rate_chart';
import { getGcTimeChart } from './gc/get_gc_time_chart';
export async function getJavaMetricsCharts(
setup: Setup & SetupTimeRange & SetupUIFilters,
setup: Setup & SetupTimeRange,
serviceName: string,
serviceNodeName?: string
) {

View file

@ -12,11 +12,7 @@ import {
METRIC_JAVA_NON_HEAP_MEMORY_USED,
AGENT_NAME,
} from '../../../../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../../helpers/setup_request';
import { ChartBase } from '../../../types';
import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics';
@ -52,7 +48,7 @@ const chartBase: ChartBase = {
};
export async function getNonHeapMemoryChart(
setup: Setup & SetupUIFilters & SetupTimeRange,
setup: Setup & SetupTimeRange,
serviceName: string,
serviceNodeName?: string
) {

View file

@ -10,11 +10,7 @@ import {
METRIC_JAVA_THREAD_COUNT,
AGENT_NAME,
} from '../../../../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../../helpers/setup_request';
import { ChartBase } from '../../../types';
import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics';
@ -44,7 +40,7 @@ const chartBase: ChartBase = {
};
export async function getThreadCountChart(
setup: Setup & SetupTimeRange & SetupUIFilters,
setup: Setup & SetupTimeRange,
serviceName: string,
serviceNodeName?: string
) {

View file

@ -10,11 +10,7 @@ import {
METRIC_SYSTEM_CPU_PERCENT,
METRIC_PROCESS_CPU_PERCENT,
} from '../../../../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../../helpers/setup_request';
import { ChartBase } from '../../../types';
import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics';
@ -56,7 +52,7 @@ const chartBase: ChartBase = {
};
export async function getCPUChartData(
setup: Setup & SetupTimeRange & SetupUIFilters,
setup: Setup & SetupTimeRange,
serviceName: string,
serviceNodeName?: string
) {

View file

@ -11,11 +11,7 @@ import {
METRIC_SYSTEM_FREE_MEMORY,
METRIC_SYSTEM_TOTAL_MEMORY,
} from '../../../../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../../helpers/setup_request';
import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics';
import { ChartBase } from '../../../types';
@ -54,7 +50,7 @@ export const percentCgroupMemoryUsedScript = {
lang: 'painless',
source: `
/*
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants.
This number represents the max possible value for the limit field.
*/
double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L;
@ -73,7 +69,7 @@ export const percentCgroupMemoryUsedScript = {
};
export async function getMemoryChartData(
setup: Setup & SetupTimeRange & SetupUIFilters,
setup: Setup & SetupTimeRange,
serviceName: string,
serviceNodeName?: string
) {

View file

@ -5,11 +5,7 @@
*/
import { Unionize, Overwrite } from 'utility-types';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { getMetricsDateHistogramParams } from '../helpers/metrics';
import { ChartBase } from './types';
import { transformDataToMetricsChart } from './transform_metrics_chart';
@ -58,7 +54,7 @@ export async function fetchAndTransformMetrics<T extends MetricAggs>({
aggs,
additionalFilters = [],
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
serviceName: string;
serviceNodeName?: string;
chartBase: ChartBase;

View file

@ -3,11 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { getJavaMetricsCharts } from './by_agent/java';
import { getDefaultMetricsCharts } from './by_agent/default';
import { GenericMetricsChart } from './transform_metrics_chart';
@ -22,7 +18,7 @@ export async function getMetricsChartDataByAgent({
serviceNodeName,
agentName,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
serviceName: string;
serviceNodeName?: string;
agentName: string;

View file

@ -61,7 +61,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -151,7 +151,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -230,7 +230,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -500,7 +500,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -552,7 +552,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -667,7 +667,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -723,7 +723,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],

View file

@ -7,11 +7,7 @@
import { TRANSACTION_DURATION } from '../../../common/elasticsearch_fieldnames';
import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions';
import { mergeProjection } from '../../projections/util/merge_projection';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import {
TRANSACTION_DOM_INTERACTIVE,
TRANSACTION_TIME_TO_FIRST_BYTE,
@ -22,7 +18,7 @@ export async function getClientMetrics({
urlQuery,
percentile = 50,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
urlQuery?: string;
percentile?: number;
}) {

View file

@ -5,11 +5,7 @@
*/
import { mergeProjection } from '../../projections/util/merge_projection';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { getRumErrorsProjection } from '../../projections/rum_page_load_transactions';
import {
ERROR_EXC_MESSAGE,
@ -23,7 +19,7 @@ export async function getJSErrors({
pageSize,
pageIndex,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
pageSize: number;
pageIndex: number;
}) {

View file

@ -6,11 +6,7 @@
import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions';
import { mergeProjection } from '../../projections/util/merge_projection';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
const LONG_TASK_SUM_FIELD = 'transaction.experience.longtask.sum';
const LONG_TASK_COUNT_FIELD = 'transaction.experience.longtask.count';
@ -21,7 +17,7 @@ export async function getLongTaskMetrics({
urlQuery,
percentile = 50,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
urlQuery?: string;
percentile?: number;
}) {

View file

@ -7,11 +7,7 @@
import { TRANSACTION_DURATION } from '../../../common/elasticsearch_fieldnames';
import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions';
import { mergeProjection } from '../../projections/util/merge_projection';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
export const MICRO_TO_SEC = 1000000;
@ -56,7 +52,7 @@ export async function getPageLoadDistribution({
maxPercentile,
urlQuery,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
minPercentile?: string;
maxPercentile?: string;
urlQuery?: string;
@ -168,7 +164,7 @@ const getPercentilesDistribution = async ({
minDuration,
maxDuration,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
minDuration: number;
maxDuration: number;
}) => {

View file

@ -5,11 +5,7 @@
*/
import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions';
import { mergeProjection } from '../../projections/util/merge_projection';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { BreakdownItem } from '../../../typings/ui_filters';
export async function getPageViewTrends({
@ -17,7 +13,7 @@ export async function getPageViewTrends({
breakdowns,
urlQuery,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
breakdowns?: string;
urlQuery?: string;
}) {

View file

@ -7,11 +7,7 @@
import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions';
import { ProcessorEvent } from '../../../common/processor_event';
import { mergeProjection } from '../../projections/util/merge_projection';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import {
CLIENT_GEO_COUNTRY_ISO_CODE,
USER_AGENT_DEVICE,
@ -46,7 +42,7 @@ export const getPageLoadDistBreakdown = async ({
breakdown,
urlQuery,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
minPercentile: number;
maxPercentile: number;
breakdown: string;

View file

@ -5,18 +5,14 @@
*/
import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions';
import { mergeProjection } from '../../projections/util/merge_projection';
export async function getRumServices({
setup,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
}) {
const projection = getRumPageLoadTransactionsProjection({
setup,

View file

@ -5,11 +5,7 @@
*/
import { mergeProjection } from '../../projections/util/merge_projection';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions';
import {
TRANSACTION_DURATION,
@ -21,7 +17,7 @@ export async function getUrlSearch({
urlQuery,
percentile,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
urlQuery?: string;
percentile: number;
}) {

View file

@ -6,11 +6,7 @@
import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions';
import { mergeProjection } from '../../projections/util/merge_projection';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import {
USER_AGENT_NAME,
USER_AGENT_OS,
@ -20,7 +16,7 @@ export async function getVisitorBreakdown({
setup,
urlQuery,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
urlQuery?: string;
}) {
const projection = getRumPageLoadTransactionsProjection({

View file

@ -6,11 +6,7 @@
import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions';
import { mergeProjection } from '../../projections/util/merge_projection';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import {
CLS_FIELD,
FCP_FIELD,
@ -25,7 +21,7 @@ export async function getWebCoreVitals({
urlQuery,
percentile = 50,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
urlQuery?: string;
percentile?: number;
}) {

View file

@ -82,7 +82,7 @@ async function getServicesData(options: IEnvOptions) {
const { setup, searchAggregatedTransactions } = options;
const projection = getServicesProjection({
setup: { ...setup, uiFiltersES: [] },
setup: { ...setup, esFilter: [] },
searchAggregatedTransactions,
});

View file

@ -19,11 +19,10 @@ describe('getServiceMapServiceNodeInfo', () => {
}),
},
indices: {},
uiFilters: { environment: 'test environment' },
} as unknown) as Setup & SetupTimeRange;
const environment = 'test environment';
const serviceName = 'test service name';
const result = await getServiceMapServiceNodeInfo({
uiFilters: { environment },
setup,
serviceName,
searchAggregatedTransactions: false,
@ -67,11 +66,10 @@ describe('getServiceMapServiceNodeInfo', () => {
config: {
'xpack.apm.metricsInterval': 30,
},
uiFilters: { environment: 'test environment' },
} as unknown) as Setup & SetupTimeRange;
const environment = 'test environment';
const serviceName = 'test service name';
const result = await getServiceMapServiceNodeInfo({
uiFilters: { environment },
setup,
serviceName,
searchAggregatedTransactions: false,

View file

@ -8,7 +8,6 @@ import {
TRANSACTION_REQUEST,
TRANSACTION_PAGE_LOAD,
} from '../../../common/transaction_types';
import { UIFilters } from '../../../typings/ui_filters';
import {
SERVICE_NAME,
METRIC_SYSTEM_CPU_PERCENT,
@ -53,9 +52,8 @@ export async function getServiceMapServiceNodeInfo({
serviceName,
setup,
searchAggregatedTransactions,
uiFilters,
}: Options & { serviceName: string; uiFilters: UIFilters }) {
const { start, end } = setup;
}: Options & { serviceName: string }) {
const { start, end, uiFilters } = setup;
const filter: ESFilter[] = [
{ range: rangeFilter(start, end) },
@ -105,7 +103,8 @@ async function getErrorStats({
}) {
const setupWithBlankUiFilters = {
...setup,
uiFiltersES: getEnvironmentUiFilterES(environment),
uiFilters: { environment },
esFilter: getEnvironmentUiFilterES(environment),
};
const { noHits, average } = await getErrorRate({
setup: setupWithBlankUiFilters,

View file

@ -3,7 +3,7 @@
{
"data": {
"id": "opbeans-rum",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-rum",
"agent.name": "rum-js"
}
@ -18,7 +18,7 @@
{
"data": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
}

View file

@ -3,7 +3,7 @@
{
"data": {
"id": "opbeans-rum",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-rum",
"agent.name": "rum-js"
}
@ -18,7 +18,7 @@
{
"data": {
"id": "opbeans-node",
"service.environment": "testing",
"service.environment": "test",
"service.name": "opbeans-node",
"agent.name": "nodejs"
}

View file

@ -51,7 +51,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -119,7 +119,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -188,7 +188,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],

View file

@ -4,11 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { getServiceNodesProjection } from '../../projections/service_nodes';
import { mergeProjection } from '../../projections/util/merge_projection';
import { SERVICE_NODE_NAME_MISSING } from '../../../common/service_nodes';
@ -23,7 +19,7 @@ const getServiceNodes = async ({
setup,
serviceName,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
serviceName: string;
}) => {
const { apmEventClient } = setup;

View file

@ -144,7 +144,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -194,7 +194,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -257,7 +257,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -334,7 +334,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -389,7 +389,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],

View file

@ -4,11 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import {
HOST_NAME,
CONTAINER_ID,
@ -24,7 +20,7 @@ export async function getServiceNodeMetadata({
}: {
serviceName: string;
serviceNodeName: string;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
}) {
const { apmEventClient } = setup;

View file

@ -5,11 +5,7 @@
*/
import { joinByKey } from '../../../../common/utils/join_by_key';
import { PromiseReturnType } from '../../../../typings/common';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import { getServicesProjection } from '../../../projections/services';
import {
getTransactionDurationAverages,
@ -21,17 +17,15 @@ import {
} from './get_services_items_stats';
export type ServiceListAPIResponse = PromiseReturnType<typeof getServicesItems>;
export type ServicesItemsSetup = Setup & SetupTimeRange & SetupUIFilters;
export type ServicesItemsSetup = Setup & SetupTimeRange;
export type ServicesItemsProjection = ReturnType<typeof getServicesProjection>;
export async function getServicesItems({
setup,
searchAggregatedTransactions,
mlAnomaliesEnvironment,
}: {
setup: ServicesItemsSetup;
searchAggregatedTransactions: boolean;
mlAnomaliesEnvironment?: string;
}) {
const params = {
projection: getServicesProjection({
@ -55,7 +49,7 @@ export async function getServicesItems({
getTransactionRates(params),
getTransactionErrorRates(params),
getEnvironments(params),
getHealthStatuses(params, mlAnomaliesEnvironment),
getHealthStatuses(params, setup.uiFilters.environment),
]);
const allMetrics = [

View file

@ -6,11 +6,7 @@
import { isEmpty } from 'lodash';
import { PromiseReturnType } from '../../../../typings/common';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import { hasHistoricalAgentData } from './has_historical_agent_data';
import { getLegacyDataStatus } from './get_legacy_data_status';
import { getServicesItems } from './get_services_items';
@ -20,17 +16,14 @@ export type ServiceListAPIResponse = PromiseReturnType<typeof getServices>;
export async function getServices({
setup,
searchAggregatedTransactions,
mlAnomaliesEnvironment,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
searchAggregatedTransactions: boolean;
mlAnomaliesEnvironment?: string;
}) {
const [items, hasLegacyData] = await Promise.all([
getServicesItems({
setup,
searchAggregatedTransactions,
mlAnomaliesEnvironment,
}),
getLegacyDataStatus(setup),
]);

View file

@ -61,7 +61,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -128,7 +128,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -195,7 +195,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -270,7 +270,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -325,7 +325,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -380,7 +380,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -441,7 +441,7 @@ Array [
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],

View file

@ -15,11 +15,7 @@ import { getTransactionGroupsProjection } from '../../projections/transaction_gr
import { mergeProjection } from '../../projections/util/merge_projection';
import { PromiseReturnType } from '../../../../observability/typings/common';
import { AggregationOptionsByType } from '../../../typings/elasticsearch/aggregations';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import {
getAverages,
getSums,
@ -57,7 +53,7 @@ export type TransactionGroupRequestBase = ReturnType<
};
};
export type TransactionGroupSetup = Setup & SetupTimeRange & SetupUIFilters;
export type TransactionGroupSetup = Setup & SetupTimeRange;
function getItemsWithRelativeImpact(
setup: TransactionGroupSetup,

View file

@ -12,11 +12,7 @@ import {
EVENT_OUTCOME,
} from '../../../common/elasticsearch_fieldnames';
import { rangeFilter } from '../../../common/utils/range_filter';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { getBucketSize } from '../helpers/get_bucket_size';
import {
getProcessorEventForAggregatedTransactions,
@ -33,10 +29,10 @@ export async function getErrorRate({
serviceName: string;
transactionType?: string;
transactionName?: string;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
searchAggregatedTransactions: boolean;
}) {
const { start, end, uiFiltersES, apmEventClient } = setup;
const { start, end, esFilter, apmEventClient } = setup;
const transactionNamefilter = transactionName
? [{ term: { [TRANSACTION_NAME]: transactionName } }]
@ -53,7 +49,7 @@ export async function getErrorRate({
},
...transactionNamefilter,
...transactionTypefilter,
...uiFiltersES,
...esFilter,
];
const params = {

View file

@ -12,11 +12,7 @@ import {
} from '../../../common/elasticsearch_fieldnames';
import { ProcessorEvent } from '../../../common/processor_event';
import { rangeFilter } from '../../../common/utils/range_filter';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
export async function getTransactionSampleForGroup({
serviceName,
@ -25,9 +21,9 @@ export async function getTransactionSampleForGroup({
}: {
serviceName: string;
transactionName: string;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
}) {
const { apmEventClient, start, end, uiFiltersES } = setup;
const { apmEventClient, start, end, esFilter } = setup;
const filter = [
{
@ -43,7 +39,7 @@ export async function getTransactionSampleForGroup({
[TRANSACTION_NAME]: transactionName,
},
},
...uiFiltersES,
...esFilter,
];
const getSampledTransaction = async () => {

View file

@ -4,16 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../helpers/setup_request';
import { Setup, SetupTimeRange } from '../helpers/setup_request';
import { transactionGroupsFetcher, Options } from './fetcher';
export async function getTransactionGroupList(
options: Options,
setup: Setup & SetupTimeRange & SetupUIFilters
setup: Setup & SetupTimeRange
) {
const bucketSize = setup.config['xpack.apm.ui.transactionGroupBucketSize'];
return await transactionGroupsFetcher(options, setup, bucketSize);

View file

@ -161,7 +161,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -295,7 +295,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -401,7 +401,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],
@ -502,7 +502,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -608,7 +608,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
Object {
@ -673,7 +673,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],

View file

@ -36,7 +36,8 @@ function getMockSetup(esResponse: any) {
get: () => 'myIndex',
}
) as APMConfig,
uiFiltersES: [],
uiFilters: {},
esFilter: [],
indices: mockIndices,
dynamicIndexPattern: null as any,
};

View file

@ -16,11 +16,7 @@ import {
TRANSACTION_NAME,
TRANSACTION_BREAKDOWN_COUNT,
} from '../../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import { rangeFilter } from '../../../../common/utils/range_filter';
import { getMetricsDateHistogramParams } from '../../helpers/metrics';
import { MAX_KPIS } from './constants';
@ -32,12 +28,12 @@ export async function getTransactionBreakdown({
transactionName,
transactionType,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
serviceName: string;
transactionName?: string;
transactionType: string;
}) {
const { uiFiltersES, apmEventClient, start, end, config } = setup;
const { esFilter, apmEventClient, start, end, config } = setup;
const subAggs = {
sum_all_self_times: {
@ -84,7 +80,7 @@ export async function getTransactionBreakdown({
{ term: { [SERVICE_NAME]: serviceName } },
{ term: { [TRANSACTION_TYPE]: transactionType } },
{ range: rangeFilter(start, end) },
...uiFiltersES,
...esFilter,
];
if (transactionName) {

View file

@ -5,6 +5,7 @@
*/
import { Logger } from 'kibana/server';
import { ESSearchResponse } from '../../../../../typings/elasticsearch';
import { PromiseReturnType } from '../../../../../../observability/typings/common';
import { Setup, SetupTimeRange } from '../../../helpers/setup_request';
@ -47,7 +48,7 @@ export async function anomalySeriesFetcher({
filter: [
{ term: { job_id: jobId } },
{ exists: { field: 'bucket_span' } },
{ term: { result_type: 'model_plot' } },
{ terms: { result_type: ['model_plot', 'record'] } },
{ term: { partition_field_value: serviceName } },
{ term: { by_field_value: transactionType } },
{
@ -67,7 +68,7 @@ export async function anomalySeriesFetcher({
extended_bounds: { min: newStart, max: end },
},
aggs: {
anomaly_score: { max: { field: 'anomaly_score' } },
anomaly_score: { max: { field: 'record_score' } },
lower: { min: { field: 'model_lower' } },
upper: { max: { field: 'model_upper' } },
},
@ -77,7 +78,11 @@ export async function anomalySeriesFetcher({
};
try {
const response = await ml.mlSystem.mlAnomalySearch(params);
const response: ESSearchResponse<
unknown,
typeof params
> = (await ml.mlSystem.mlAnomalySearch(params)) as any;
return response;
} catch (err) {
const isHttpError = 'statusCode' in err;

View file

@ -5,17 +5,13 @@
*/
import { Logger } from 'kibana/server';
import { isNumber } from 'lodash';
import { ENVIRONMENT_ALL } from '../../../../../common/environment_filter_values';
import { getBucketSize } from '../../../helpers/get_bucket_size';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../helpers/setup_request';
import { anomalySeriesFetcher } from './fetcher';
import { getMlBucketSize } from './get_ml_bucket_size';
import { anomalySeriesTransform } from './transform';
import { getMLJobIds } from '../../../service_map/get_service_anomalies';
import { UIFilters } from '../../../../../typings/ui_filters';
export async function getAnomalySeries({
serviceName,
@ -24,15 +20,13 @@ export async function getAnomalySeries({
timeSeriesDates,
setup,
logger,
uiFilters,
}: {
serviceName: string;
transactionType: string | undefined;
transactionName: string | undefined;
timeSeriesDates: number[];
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
logger: Logger;
uiFilters: UIFilters;
}) {
// don't fetch anomalies for transaction details page
if (transactionName) {
@ -44,12 +38,22 @@ export async function getAnomalySeries({
return;
}
const { uiFilters, start, end } = setup;
const { environment } = uiFilters;
// don't fetch anomalies when no specific environment is selected
if (environment === ENVIRONMENT_ALL.value) {
return;
}
// don't fetch anomalies if unknown uiFilters are applied
const knownFilters = ['environment', 'serviceName'];
const uiFilterNames = Object.keys(uiFilters);
if (
uiFilterNames.some((uiFilterName) => !knownFilters.includes(uiFilterName))
) {
const hasUnknownFiltersApplied = Object.entries(setup.uiFilters)
.filter(([key, value]) => !!value)
.map(([key]) => key)
.some((uiFilterName) => !knownFilters.includes(uiFilterName));
if (hasUnknownFiltersApplied) {
return;
}
@ -64,15 +68,8 @@ export async function getAnomalySeries({
return;
}
const mlJobIds = await getMLJobIds(
setup.ml.anomalyDetectors,
uiFilters.environment
);
const mlJobIds = await getMLJobIds(setup.ml.anomalyDetectors, environment);
// don't fetch anomalies if there are isn't exaclty 1 ML job match for the given environment
if (mlJobIds.length !== 1) {
return;
}
const jobId = mlJobIds[0];
const mlBucketSize = await getMlBucketSize({ setup, jobId, logger });
@ -80,7 +77,6 @@ export async function getAnomalySeries({
return;
}
const { start, end } = setup;
const { intervalString, bucketSize } = getBucketSize(start, end);
const esResponse = await anomalySeriesFetcher({

View file

@ -29,7 +29,10 @@ describe('timeseriesFetcher', () => {
get: () => 'myIndex',
}
) as APMConfig,
uiFiltersES: [
uiFilters: {
environment: 'test',
},
esFilter: [
{
term: { 'service.environment': 'test' },
},

View file

@ -14,11 +14,7 @@ import {
import { PromiseReturnType } from '../../../../../../observability/typings/common';
import { getBucketSize } from '../../../helpers/get_bucket_size';
import { rangeFilter } from '../../../../../common/utils/range_filter';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../helpers/setup_request';
import {
getProcessorEventForAggregatedTransactions,
getTransactionDurationFieldForAggregatedTransactions,
@ -36,10 +32,10 @@ export function timeseriesFetcher({
serviceName: string;
transactionType: string | undefined;
transactionName: string | undefined;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
searchAggregatedTransactions: boolean;
}) {
const { start, end, uiFiltersES, apmEventClient } = setup;
const { start, end, apmEventClient } = setup;
const { intervalString } = getBucketSize(start, end);
const filter: ESFilter[] = [
@ -48,7 +44,7 @@ export function timeseriesFetcher({
...getDocumentTypeFilterForAggregatedTransactions(
searchAggregatedTransactions
),
...uiFiltersES,
...setup.esFilter,
];
if (transactionName) {

View file

@ -5,11 +5,7 @@
*/
import { getBucketSize } from '../../../helpers/get_bucket_size';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../helpers/setup_request';
import { timeseriesFetcher } from './fetcher';
import { timeseriesTransformer } from './transform';
@ -17,7 +13,7 @@ export async function getApmTimeseriesData(options: {
serviceName: string;
transactionType: string | undefined;
transactionName: string | undefined;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
searchAggregatedTransactions: boolean;
}) {
const { start, end } = options.setup;

View file

@ -6,15 +6,10 @@
import { Logger } from 'kibana/server';
import { PromiseReturnType } from '../../../../../observability/typings/common';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import { getAnomalySeries } from './get_anomaly_data';
import { getApmTimeseriesData } from './get_timeseries_data';
import { ApmTimeSeriesResponse } from './get_timeseries_data/transform';
import { UIFilters } from '../../../../typings/ui_filters';
function getDates(apmTimeseries: ApmTimeSeriesResponse) {
return apmTimeseries.responseTimes.avg.map((p) => p.x);
@ -27,10 +22,9 @@ export async function getTransactionCharts(options: {
serviceName: string;
transactionType: string | undefined;
transactionName: string | undefined;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
searchAggregatedTransactions: boolean;
logger: Logger;
uiFilters: UIFilters;
}) {
const apmTimeseries = await getApmTimeseriesData(options);
const anomalyTimeseries = await getAnomalySeries({

View file

@ -17,11 +17,7 @@ import {
TRANSACTION_TYPE,
} from '../../../../../common/elasticsearch_fieldnames';
import { rangeFilter } from '../../../../../common/utils/range_filter';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../../helpers/setup_request';
import {
getDocumentTypeFilterForAggregatedTransactions,
getProcessorEventForAggregatedTransactions,
@ -66,17 +62,17 @@ export async function getBuckets({
traceId: string;
distributionMax: number;
bucketSize: number;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
searchAggregatedTransactions: boolean;
}) {
const { start, end, uiFiltersES, apmEventClient } = setup;
const { start, end, esFilter, apmEventClient } = setup;
const commonFilters = [
{ term: { [SERVICE_NAME]: serviceName } },
{ term: { [TRANSACTION_TYPE]: transactionType } },
{ term: { [TRANSACTION_NAME]: transactionName } },
{ range: rangeFilter(start, end) },
...uiFiltersES,
...esFilter,
];
async function getSamplesForDistributionBuckets() {

View file

@ -9,11 +9,7 @@ import {
TRANSACTION_NAME,
TRANSACTION_TYPE,
} from '../../../../common/elasticsearch_fieldnames';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import {
getProcessorEventForAggregatedTransactions,
getTransactionDurationFieldForAggregatedTransactions,
@ -29,10 +25,10 @@ export async function getDistributionMax({
serviceName: string;
transactionName: string;
transactionType: string;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
searchAggregatedTransactions: boolean;
}) {
const { start, end, uiFiltersES, apmEventClient } = setup;
const { start, end, esFilter, apmEventClient } = setup;
const params = {
apm: {
@ -59,7 +55,7 @@ export async function getDistributionMax({
},
},
},
...uiFiltersES,
...esFilter,
],
},
},

View file

@ -5,11 +5,7 @@
*/
import { PromiseReturnType } from '../../../../../observability/typings/common';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import { getBuckets } from './get_buckets';
import { getDistributionMax } from './get_distribution_max';
import { roundToNearestFiveOrTen } from '../../helpers/round_to_nearest_five_or_ten';
@ -39,7 +35,7 @@ export async function getTransactionDistribution({
transactionType: string;
transactionId: string;
traceId: string;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
searchAggregatedTransactions: boolean;
}) {
const distributionMax = await getDistributionMax({

View file

@ -9,11 +9,7 @@ import {
TRANSACTION_ID,
} from '../../../../common/elasticsearch_fieldnames';
import { rangeFilter } from '../../../../common/utils/range_filter';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../helpers/setup_request';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import { ProcessorEvent } from '../../../../common/processor_event';
export async function getTransaction({
@ -23,7 +19,7 @@ export async function getTransaction({
}: {
transactionId: string;
traceId: string;
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
}) {
const { start, end, apmEventClient } = setup;

View file

@ -56,7 +56,6 @@ describe('transaction queries', () => {
setup,
searchAggregatedTransactions: false,
logger: loggerMock.create(),
uiFilters: {},
})
);
expect(mock.params).toMatchSnapshot();
@ -71,7 +70,6 @@ describe('transaction queries', () => {
setup,
searchAggregatedTransactions: false,
logger: loggerMock.create(),
uiFilters: {},
})
);
expect(mock.params).toMatchSnapshot();
@ -86,7 +84,6 @@ describe('transaction queries', () => {
setup,
searchAggregatedTransactions: false,
logger: loggerMock.create(),
uiFilters: {},
})
);

View file

@ -46,7 +46,7 @@ Object {
},
Object {
"term": Object {
"my.custom.ui.filter": "foo-bar",
"service.environment": "test",
},
},
],

View file

@ -8,7 +8,7 @@ import { omit } from 'lodash';
import { mergeProjection } from '../../../projections/util/merge_projection';
import { Projection } from '../../../projections/typings';
import { UIFilters } from '../../../../typings/ui_filters';
import { getUiFiltersES } from '../../helpers/convert_ui_filters/get_ui_filters_es';
import { getEsFilter } from '../../helpers/convert_ui_filters/get_es_filter';
import { localUIFilters } from './config';
import { LocalUIFilterName } from '../../../../common/ui_filter';
@ -22,7 +22,7 @@ export const getLocalFilterQuery = ({
localUIFilterName: LocalUIFilterName;
}) => {
const field = localUIFilters[localUIFilterName];
const filter = getUiFiltersES(omit(uiFilters, field.name));
const filter = getEsFilter(omit(uiFilters, field.name));
const bucketCountAggregation = projection.body.aggs
? {

View file

@ -15,7 +15,7 @@ describe('local ui filter queries', () => {
let mock: SearchParamsMock;
beforeEach(() => {
jest.mock('../../helpers/convert_ui_filters/get_ui_filters_es', () => {
jest.mock('../../helpers/convert_ui_filters/get_es_filter', () => {
return [];
});
});

View file

@ -4,11 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../server/lib/helpers/setup_request';
import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request';
import {
SERVICE_NAME,
ERROR_GROUP_ID,
@ -20,10 +16,10 @@ export function getErrorGroupsProjection({
setup,
serviceName,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
serviceName: string;
}) {
const { start, end, uiFiltersES } = setup;
const { start, end, esFilter } = setup;
return {
apm: {
@ -35,7 +31,7 @@ export function getErrorGroupsProjection({
filter: [
{ term: { [SERVICE_NAME]: serviceName } },
{ range: rangeFilter(start, end) },
...uiFiltersES,
...esFilter,
],
},
},

View file

@ -4,11 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../server/lib/helpers/setup_request';
import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request';
import {
SERVICE_NAME,
SERVICE_NODE_NAME,
@ -34,17 +30,17 @@ export function getMetricsProjection({
serviceName,
serviceNodeName,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
serviceName: string;
serviceNodeName?: string;
}) {
const { start, end, uiFiltersES } = setup;
const { start, end, esFilter } = setup;
const filter = [
{ term: { [SERVICE_NAME]: serviceName } },
{ range: rangeFilter(start, end) },
...getServiceNodeNameFilters(serviceNodeName),
...uiFiltersES,
...esFilter,
];
return {

View file

@ -4,11 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../server/lib/helpers/setup_request';
import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request';
import {
AGENT_NAME,
TRANSACTION_TYPE,
@ -22,10 +18,10 @@ export function getRumPageLoadTransactionsProjection({
setup,
urlQuery,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
urlQuery?: string;
}) {
const { start, end, uiFiltersES } = setup;
const { start, end, esFilter } = setup;
const bool = {
filter: [
@ -49,7 +45,7 @@ export function getRumPageLoadTransactionsProjection({
},
]
: []),
...uiFiltersES,
...esFilter,
],
};
@ -68,9 +64,9 @@ export function getRumPageLoadTransactionsProjection({
export function getRumErrorsProjection({
setup,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
}) {
const { start, end, uiFiltersES } = setup;
const { start, end, esFilter: esFilter } = setup;
const bool = {
filter: [
@ -82,7 +78,7 @@ export function getRumErrorsProjection({
[SERVICE_LANGUAGE_NAME]: 'javascript',
},
},
...uiFiltersES,
...esFilter,
],
};

View file

@ -4,11 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../server/lib/helpers/setup_request';
import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request';
import { SERVICE_NODE_NAME } from '../../common/elasticsearch_fieldnames';
import { mergeProjection } from './util/merge_projection';
import { getMetricsProjection } from './metrics';
@ -18,7 +14,7 @@ export function getServiceNodesProjection({
serviceName,
serviceNodeName,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
serviceName: string;
serviceNodeName?: string;
}) {

View file

@ -4,11 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupUIFilters,
SetupTimeRange,
} from '../../server/lib/helpers/setup_request';
import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request';
import { SERVICE_NAME } from '../../common/elasticsearch_fieldnames';
import { rangeFilter } from '../../common/utils/range_filter';
import { ProcessorEvent } from '../../common/processor_event';
@ -18,10 +14,10 @@ export function getServicesProjection({
setup,
searchAggregatedTransactions,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
searchAggregatedTransactions: boolean;
}) {
const { start, end, uiFiltersES } = setup;
const { start, end, esFilter } = setup;
return {
apm: {
@ -37,7 +33,7 @@ export function getServicesProjection({
size: 0,
query: {
bool: {
filter: [{ range: rangeFilter(start, end) }, ...uiFiltersES],
filter: [{ range: rangeFilter(start, end) }, ...esFilter],
},
},
aggs: {

View file

@ -4,11 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { omit } from 'lodash';
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../server/lib/helpers/setup_request';
import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request';
import {
TRANSACTION_NAME,
PARENT_ID,
@ -22,7 +18,7 @@ export function getTransactionGroupsProjection({
setup,
options,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
options: Options;
}) {
const transactionsProjection = getTransactionsProjection({

View file

@ -4,11 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
Setup,
SetupTimeRange,
SetupUIFilters,
} from '../../server/lib/helpers/setup_request';
import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request';
import {
SERVICE_NAME,
TRANSACTION_TYPE,
@ -27,13 +23,13 @@ export function getTransactionsProjection({
transactionType,
searchAggregatedTransactions,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
setup: Setup & SetupTimeRange;
serviceName?: string;
transactionName?: string;
transactionType?: string;
searchAggregatedTransactions: boolean;
}) {
const { start, end, uiFiltersES } = setup;
const { start, end, esFilter } = setup;
const transactionNameFilter = transactionName
? [{ term: { [TRANSACTION_NAME]: transactionName } }]
@ -51,7 +47,7 @@ export function getTransactionsProjection({
...transactionNameFilter,
...transactionTypeFilter,
...serviceNameFilter,
...uiFiltersES,
...esFilter,
...getDocumentTypeFilterForAggregatedTransactions(
searchAggregatedTransactions
),

View file

@ -17,7 +17,6 @@ import { createRoute } from './create_route';
import { rangeRt, uiFiltersRt } from './default_api_types';
import { notifyFeatureUsage } from '../feature';
import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions';
import { getParsedUiFilters } from '../lib/helpers/convert_ui_filters/get_parsed_ui_filters';
export const serviceMapRoute = createRoute(() => ({
path: '/api/apm/service-map',
@ -77,24 +76,20 @@ export const serviceMapServiceNodeRoute = createRoute(() => ({
if (!isActivePlatinumLicense(context.licensing.license)) {
throw Boom.forbidden(invalidLicenseMessage);
}
const logger = context.logger;
const setup = await setupRequest(context, request);
const {
query: { uiFilters: uiFiltersJson },
path: { serviceName },
} = context.params;
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
setup
);
const uiFilters = getParsedUiFilters({ uiFilters: uiFiltersJson, logger });
return getServiceMapServiceNodeInfo({
setup,
serviceName,
searchAggregatedTransactions,
uiFilters,
});
},
}));

View file

@ -17,7 +17,6 @@ import { uiFiltersRt, rangeRt } from './default_api_types';
import { getServiceAnnotations } from '../lib/services/annotations';
import { dateAsStringRt } from '../../common/runtime_types/date_as_string_rt';
import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions';
import { getParsedUiFilters } from '../lib/helpers/convert_ui_filters/get_parsed_ui_filters';
export const servicesRoute = createRoute(() => ({
path: '/api/apm/services',
@ -25,22 +24,13 @@ export const servicesRoute = createRoute(() => ({
query: t.intersection([uiFiltersRt, rangeRt]),
},
handler: async ({ context, request }) => {
const { environment } = getParsedUiFilters({
uiFilters: context.params.query.uiFilters,
logger: context.logger,
});
const setup = await setupRequest(context, request);
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
setup
);
const services = await getServices({
setup,
searchAggregatedTransactions,
mlAnomaliesEnvironment: environment,
});
const services = await getServices({ setup, searchAggregatedTransactions });
return services;
},

View file

@ -5,6 +5,7 @@
*/
import * as t from 'io-ts';
import Boom from 'boom';
import { setupRequest } from '../lib/helpers/setup_request';
import { getTransactionCharts } from '../lib/transactions/charts';
import { getTransactionDistribution } from '../lib/transactions/distribution';
@ -15,7 +16,6 @@ import { uiFiltersRt, rangeRt } from './default_api_types';
import { getTransactionSampleForGroup } from '../lib/transaction_groups/get_transaction_sample_for_group';
import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions';
import { getErrorRate } from '../lib/transaction_groups/get_error_rate';
import { getParsedUiFilters } from '../lib/helpers/convert_ui_filters/get_parsed_ui_filters';
export const transactionGroupsRoute = createRoute(() => ({
path: '/api/apm/services/{serviceName}/transaction_groups',
@ -71,27 +71,28 @@ export const transactionGroupsChartsRoute = createRoute(() => ({
const setup = await setupRequest(context, request);
const logger = context.logger;
const { serviceName } = context.params.path;
const {
transactionType,
transactionName,
uiFilters: uiFiltersJson,
} = context.params.query;
const { transactionType, transactionName } = context.params.query;
const uiFilters = getParsedUiFilters({ uiFilters: uiFiltersJson, logger });
if (!setup.uiFilters.environment) {
throw Boom.badRequest(
`environment is a required property of the ?uiFilters JSON for transaction_groups/charts.`
);
}
const searchAggregatedTransactions = await getSearchAggregatedTransactions(
setup
);
return getTransactionCharts({
const options = {
serviceName,
transactionType,
transactionName,
setup,
searchAggregatedTransactions,
logger,
uiFilters,
});
};
return getTransactionCharts(options);
},
}));

View file

@ -9,13 +9,12 @@ import { omit } from 'lodash';
import {
setupRequest,
Setup,
SetupUIFilters,
SetupTimeRange,
} from '../lib/helpers/setup_request';
import { getEnvironments } from '../lib/ui_filters/get_environments';
import { Projection } from '../projections/typings';
import { localUIFilterNames } from '../lib/ui_filters/local_ui_filters/config';
import { getUiFiltersES } from '../lib/helpers/convert_ui_filters/get_ui_filters_es';
import { getEsFilter } from '../lib/helpers/convert_ui_filters/get_es_filter';
import { getLocalUIFilters } from '../lib/ui_filters/local_ui_filters';
import { getServicesProjection } from '../projections/services';
import { getTransactionGroupsProjection } from '../projections/transaction_groups';
@ -97,23 +96,23 @@ function createLocalFiltersRoute<
},
handler: async ({ context, request }) => {
const setup = await setupRequest(context, request);
const { uiFilters } = setup;
const { query } = context.params;
const { uiFilters, filterNames } = query;
const parsedUiFilters = JSON.parse(uiFilters);
const { filterNames } = query;
const projection = await getProjection({
query,
context,
setup: {
...setup,
uiFiltersES: getUiFiltersES(omit(parsedUiFilters, filterNames)),
esFilter: getEsFilter(omit(uiFilters, filterNames)),
},
});
return getLocalUIFilters({
projection,
setup,
uiFilters: parsedUiFilters,
uiFilters,
localFilterNames: filterNames,
});
},
@ -271,6 +270,6 @@ type GetProjection<
context,
}: {
query: t.TypeOf<TQueryRT>;
setup: Setup & SetupUIFilters & SetupTimeRange;
setup: Setup & SetupTimeRange;
context: APMRequestHandlerContext;
}) => Promise<TProjection> | TProjection;

View file

@ -9,6 +9,7 @@ import {
ESSearchRequest,
} from '../../typings/elasticsearch';
import { PromiseReturnType } from '../../typings/common';
import { UIFilters } from '../../typings/ui_filters';
import { APMConfig } from '..';
interface Options {
@ -23,7 +24,8 @@ interface MockSetup {
apmEventClient: any;
internalClient: any;
config: APMConfig;
uiFiltersES: ESFilter[];
uiFilters: UIFilters;
esFilter: ESFilter[];
indices: {
/* eslint-disable @typescript-eslint/naming-convention */
'apm_oss.sourcemapIndices': string;
@ -78,7 +80,8 @@ export async function inspectSearchParams(
},
}
) as APMConfig,
uiFiltersES: [{ term: { 'my.custom.ui.filter': 'foo-bar' } }],
uiFilters: { environment: 'test' },
esFilter: [{ term: { 'service.environment': 'test' } }],
indices: {
/* eslint-disable @typescript-eslint/naming-convention */
'apm_oss.sourcemapIndices': 'myIndex',

View file

@ -107,21 +107,21 @@ export default function featureControlsTests({ getService }: FtrProviderContext)
},
{
req: {
url: `/api/apm/services/foo/transaction_groups/charts?start=${start}&end=${end}&transactionType=bar&uiFilters=%7B%7D`,
url: `/api/apm/services/foo/transaction_groups/charts?start=${start}&end=${end}&transactionType=bar&uiFilters=%7B%22environment%22%3A%22testing%22%7D`,
},
expectForbidden: expect404,
expectResponse: expect200,
},
{
req: {
url: `/api/apm/services/foo/transaction_groups/charts?start=${start}&end=${end}&uiFilters=%7B%7D`,
url: `/api/apm/services/foo/transaction_groups/charts?start=${start}&end=${end}&uiFilters=%7B%22environment%22%3A%22testing%22%7D`,
},
expectForbidden: expect404,
expectResponse: expect200,
},
{
req: {
url: `/api/apm/services/foo/transaction_groups/charts?start=${start}&end=${end}&transactionType=bar&transactionName=baz&uiFilters=%7B%7D`,
url: `/api/apm/services/foo/transaction_groups/charts?start=${start}&end=${end}&transactionType=bar&transactionName=baz&uiFilters=%7B%22environment%22%3A%22testing%22%7D`,
},
expectForbidden: expect404,
expectResponse: expect200,

View file

@ -19,7 +19,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
// url parameters
const start = encodeURIComponent(metadata.start);
const end = encodeURIComponent(metadata.end);
const uiFilters = encodeURIComponent(JSON.stringify({}));
const uiFilters = encodeURIComponent(JSON.stringify({ environment: 'testing' }));
describe('Transaction charts', () => {
describe('when data is not loaded ', () => {

View file

@ -16,6 +16,7 @@ export default function observabilityApiIntegrationTests({ loadTestFile }: FtrPr
describe('Services', function () {
loadTestFile(require.resolve('./services/annotations'));
loadTestFile(require.resolve('./services/top_services.ts'));
loadTestFile(require.resolve('./services/transaction_groups_charts'));
});
describe('Settings', function () {

View file

@ -0,0 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`APM Transaction Overview when data is loaded and fetching transaction groups charts with uiFilters when not defined environments selected should return the correct anomaly boundaries 1`] = `Array []`;
exports[`APM Transaction Overview when data is loaded and fetching transaction groups charts with uiFilters with environment selected and empty kuery filter should return a non-empty anomaly series 1`] = `
Array [
Object {
"x": 1601389800000,
"y": 1206111.33487531,
"y0": 10555.1290143587,
},
Object {
"x": 1601390700000,
"y": 1223987.49321778,
"y0": 10177.4677901726,
},
Object {
"x": 1601391600000,
"y": 1223987.49321778,
"y0": 10177.4677901726,
},
]
`;
exports[`APM Transaction Overview when data is loaded and fetching transaction groups charts with uiFilters with environment selected in uiFilters should return a non-empty anomaly series 1`] = `
Array [
Object {
"x": 1601389800000,
"y": 1206111.33487531,
"y0": 10555.1290143587,
},
Object {
"x": 1601390700000,
"y": 1223987.49321778,
"y0": 10177.4677901726,
},
Object {
"x": 1601391600000,
"y": 1223987.49321778,
"y0": 10177.4677901726,
},
]
`;

View file

@ -0,0 +1,161 @@
/*
* 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 expect from '@kbn/expect';
import { expectSnapshot } from '../../../common/match_snapshot';
import { PromiseReturnType } from '../../../../../plugins/apm/typings/common';
import { FtrProviderContext } from '../../../common/ftr_provider_context';
import archives_metadata from '../../../common/archives_metadata';
export default function ApiTest({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
const archiveName = 'apm_8.0.0';
const range = archives_metadata[archiveName];
// url parameters
const start = encodeURIComponent(range.start);
const end = encodeURIComponent(range.end);
const transactionType = 'request';
describe('APM Transaction Overview', () => {
describe('when data is loaded', () => {
before(() => esArchiver.load(archiveName));
after(() => esArchiver.unload(archiveName));
describe('and fetching transaction groups charts with uiFilters', () => {
const serviceName = 'opbeans-java';
let response: PromiseReturnType<typeof supertest.get>;
describe('without environment', () => {
const uiFilters = encodeURIComponent(JSON.stringify({}));
before(async () => {
response = await supertest.get(
`/api/apm/services/${serviceName}/transaction_groups/charts?start=${start}&end=${end}&transactionType=${transactionType}&uiFilters=${uiFilters}`
);
});
it('should return an error response', () => {
expect(response.status).to.eql(400);
});
});
describe('without uiFilters', () => {
before(async () => {
response = await supertest.get(
`/api/apm/services/${serviceName}/transaction_groups/charts?start=${start}&end=${end}&transactionType=${transactionType}`
);
});
it('should return an error response', () => {
expect(response.status).to.eql(400);
});
});
describe('with environment selected in uiFilters', () => {
const uiFilters = encodeURIComponent(JSON.stringify({ environment: 'production' }));
before(async () => {
response = await supertest.get(
`/api/apm/services/${serviceName}/transaction_groups/charts?start=${start}&end=${end}&transactionType=${transactionType}&uiFilters=${uiFilters}`
);
});
it('should have a successful response', () => {
expect(response.status).to.eql(200);
});
it('should return the ML job id for anomalies of the selected environment', () => {
expect(response.body).to.have.property('anomalyTimeseries');
expect(response.body.anomalyTimeseries).to.have.property('jobId');
expectSnapshot(response.body.anomalyTimeseries.jobId).toMatchInline(
`"apm-production-229a-high_mean_transaction_duration"`
);
});
it('should return a non-empty anomaly series', () => {
expect(response.body).to.have.property('anomalyTimeseries');
expect(response.body.anomalyTimeseries.anomalyBoundaries?.length).to.be.greaterThan(0);
expectSnapshot(response.body.anomalyTimeseries.anomalyBoundaries).toMatch();
});
});
describe('when not defined environments selected', () => {
const uiFilters = encodeURIComponent(
JSON.stringify({ environment: 'ENVIRONMENT_NOT_DEFINED' })
);
before(async () => {
response = await supertest.get(
`/api/apm/services/${serviceName}/transaction_groups/charts?start=${start}&end=${end}&transactionType=${transactionType}&uiFilters=${uiFilters}`
);
});
it('should have a successful response', () => {
expect(response.status).to.eql(200);
});
it('should return the ML job id for anomalies with no defined environment', () => {
expect(response.body).to.have.property('anomalyTimeseries');
expect(response.body.anomalyTimeseries).to.have.property('jobId');
expectSnapshot(response.body.anomalyTimeseries.jobId).toMatchInline(
`"apm-environment_not_defined-7ed6-high_mean_transaction_duration"`
);
});
it('should return the correct anomaly boundaries', () => {
expect(response.body).to.have.property('anomalyTimeseries');
expectSnapshot(response.body.anomalyTimeseries.anomalyBoundaries).toMatch();
});
});
describe('with all environments selected', () => {
const uiFilters = encodeURIComponent(JSON.stringify({ environment: 'ENVIRONMENT_ALL' }));
before(async () => {
response = await supertest.get(
`/api/apm/services/${serviceName}/transaction_groups/charts?start=${start}&end=${end}&transactionType=${transactionType}&uiFilters=${uiFilters}`
);
});
it('should have a successful response', () => {
expect(response.status).to.eql(200);
});
it('should not return anomaly timeseries data', () => {
expect(response.body).to.not.have.property('anomalyTimeseries');
});
});
describe('with environment selected and empty kuery filter', () => {
const uiFilters = encodeURIComponent(
JSON.stringify({ kuery: '', environment: 'production' })
);
before(async () => {
response = await supertest.get(
`/api/apm/services/${serviceName}/transaction_groups/charts?start=${start}&end=${end}&transactionType=${transactionType}&uiFilters=${uiFilters}`
);
});
it('should have a successful response', () => {
expect(response.status).to.eql(200);
});
it('should return the ML job id for anomalies of the selected environment', () => {
expect(response.body).to.have.property('anomalyTimeseries');
expect(response.body.anomalyTimeseries).to.have.property('jobId');
expectSnapshot(response.body.anomalyTimeseries.jobId).toMatchInline(
`"apm-production-229a-high_mean_transaction_duration"`
);
});
it('should return a non-empty anomaly series', () => {
expect(response.body).to.have.property('anomalyTimeseries');
expect(response.body.anomalyTimeseries.anomalyBoundaries?.length).to.be.greaterThan(0);
expectSnapshot(response.body.anomalyTimeseries.anomalyBoundaries).toMatch();
});
});
});
});
});
}