Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions x-pack/legacy/plugins/apm/public/es/aggregations/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/*
* 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 * as t from 'io-ts';

const numberOrNull = t.union([t.number, t.null]);
const sortOrder = t.union([t.literal('asc'), t.literal('desc')]);

const sortInstruction = t.dictionary(
t.string,
t.union([
sortOrder,
t.type({
order: sortOrder
})
])
);

const sort = t.union([sortInstruction, t.array(sortInstruction)]);

const script = t.type({
lang: t.literal('expression'),
source: t.string
});

const metricsRt = {
in: t.union([
t.type({
field: t.string
}),
t.type({
script
})
]),
out: t.type({
value: numberOrNull
})
};

export const aggregationRts = {
terms: {
in: t.intersection([
t.type({
field: t.string
}),
t.partial({
size: t.number,
missing: t.string,
order: sort
})
]),
out: t.type({
buckets: t.array(
t.type({
doc_count: t.number,
key: t.string
})
)
}),
aggs: 'bucket' as const
},
date_histogram: {
in: t.intersection([
t.type({
field: t.string
}),
t.union([
t.type({
calendar_interval: t.string
}),
t.type({
fixed_interval: t.string
})
]),
t.partial({
format: t.string,
min_doc_count: t.number,
extended_bounds: t.type({
min: t.number,
max: t.number
})
})
]),
out: t.type({
buckets: t.array(
t.type({
doc_count: t.number,
key: t.number,
key_as_string: t.string
})
)
}),
aggs: 'bucket' as const
},
histogram: {
in: t.intersection([
t.type({
field: t.string,
interval: t.number
}),
t.partial({
min_doc_count: t.number,
extended_bounds: t.type({
min: t.number,
max: t.number
})
})
]),
out: t.type({
buckets: t.array(
t.type({
doc_count: t.number,
key: t.number
})
)
}),
aggs: 'bucket' as const
},
avg: metricsRt,
max: metricsRt,
min: metricsRt,
sum: metricsRt,
extended_stats: {
in: t.type({
field: t.string
}),
out: t.type({
count: t.number,
min: numberOrNull,
max: numberOrNull,
avg: numberOrNull,
sum: t.number,
sum_of_squares: numberOrNull,
variance: numberOrNull,
std_deviation: numberOrNull,
std_deviation_bounds: t.type({
upper: numberOrNull,
lower: numberOrNull
})
})
},
top_hits: {
in: t.partial({
from: t.number,
size: t.number,
sort,
_source: t.union([t.string, t.array(t.string)])
}),
out: t.type({
hits: t.type({
total: t.type({
value: t.number,
relation: t.keyof({
eq: null,
gte: null
})
}),
max_score: numberOrNull,
hits: t.array(
t.type({
_source: t.undefined
})
)
})
})
},
percentiles: {
in: t.union([
t.type({
field: t.string
}),
t.partial({
percents: t.array(t.number)
})
]),
out: t.type({
values: t.dictionary(t.string, t.number)
})
}
};

export type Aggregations = typeof aggregationRts;
11 changes: 7 additions & 4 deletions x-pack/legacy/plugins/apm/server/lib/errors/get_error_groups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ export async function getErrorGroups({
terms: {
field: ERROR_GROUP_ID,
size: 500,
order: sortByLatestOccurrence
order: (sortByLatestOccurrence
? {
max_timestamp: sortDirection
}
: { _count: sortDirection }
: { _count: sortDirection }) as ({
[key: string]: 'asc' | 'desc';
})
},
aggs: {
sample: {
Expand All @@ -75,7 +77,7 @@ export async function getErrorGroups({
ERROR_GROUP_ID,
'@timestamp'
],
sort: [{ '@timestamp': 'desc' }],
sort: [{ '@timestamp': 'desc' as const }],
size: 1
}
},
Expand Down Expand Up @@ -115,7 +117,8 @@ export async function getErrorGroups({
// this is an exception rather than the rule so the ES type does not account for this.
const hits = (idx(resp, _ => _.aggregations.error_groups.buckets) || []).map(
bucket => {
const source = bucket.sample.hits.hits[0]._source as SampleError;
const source = (bucket.sample.hits.hits[0]
._source as unknown) as SampleError;
const message =
idx(source, _ => _.error.log.message) ||
idx(source, _ => _.error.exception[0].message);
Expand Down
30 changes: 26 additions & 4 deletions x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import {
IndexDocumentParams,
IndicesDeleteParams,
IndicesCreateParams,
AggregationSearchResponse
APMSearchParams,
APMSearchResponse
} from 'elasticsearch';
import { Legacy } from 'kibana';
import { cloneDeep, has, isString, set } from 'lodash';
import * as t from 'io-ts';
import { OBSERVER_VERSION_MAJOR } from '../../../common/elasticsearch_fieldnames';
import { StringMap } from '../../../typings/common';

Expand Down Expand Up @@ -85,15 +87,33 @@ interface APMOptions {
includeLegacyData: boolean;
}

// function search<T extends APMSearchParams, U extends t.Type<any, any, any>>(
// params: T
// ): APMSearchResponse<T, U> {
// return (null as unknown) as APMSearchResponse<T, U>;
// }

// const response = search({
// body: {
// aggs: {
// foo: {
// terms: {
// field: 'bar'
// }
// }
// }
// }
// });

export function getESClient(req: Legacy.Request) {
const cluster = req.server.plugins.elasticsearch.getCluster('data');
const query = req.query as StringMap;

return {
search: async <Hits = unknown, U extends SearchParams = {}>(
search: async <T = null, U extends APMSearchParams = any>(
params: U,
apmOptions?: APMOptions
): Promise<AggregationSearchResponse<Hits, U>> => {
) => {
const nextParams = await getParamsForSearchRequest(
req,
params,
Expand All @@ -111,8 +131,10 @@ export function getESClient(req: Legacy.Request) {
console.log(JSON.stringify(nextParams.body, null, 4));
}

type HitType = t.Type<T>;

return cluster.callWithRequest(req, 'search', nextParams) as Promise<
AggregationSearchResponse<Hits, U>
APMSearchResponse<U, HitType>
>;
},
index: <Body>(params: IndexDocumentParams<Body>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('setupRequest', () => {
it('should call callWithRequest with default args', async () => {
const { mockRequest, callWithRequestSpy } = getMockRequest();
const { client } = await setupRequest(mockRequest);
await client.search({ index: 'apm-*', body: { foo: 'bar' } });
await client.search({ index: 'apm-*', body: { foo: 'bar' } } as any);
expect(callWithRequestSpy).toHaveBeenCalledWith(mockRequest, 'search', {
index: 'apm-*',
body: {
Expand Down Expand Up @@ -71,7 +71,7 @@ describe('setupRequest', () => {
it('should add `observer.version_major` filter if none exists', async () => {
const { mockRequest, callWithRequestSpy } = getMockRequest();
const { client } = await setupRequest(mockRequest);
await client.search({ index: 'apm-*' });
await client.search({ index: 'apm-*' } as any);
const params = callWithRequestSpy.mock.calls[0][2];
expect(params.body).toEqual({
query: {
Expand Down Expand Up @@ -128,7 +128,7 @@ describe('setupRequest', () => {
// mock includeFrozen to return false
mockRequest.getUiSettingsService = () => ({ get: async () => false });
const { client } = await setupRequest(mockRequest);
await client.search({});
await client.search({} as any);
const params = callWithRequestSpy.mock.calls[0][2];
expect(params.ignore_throttled).toBe(true);
});
Expand All @@ -139,7 +139,7 @@ describe('setupRequest', () => {
// mock includeFrozen to return true
mockRequest.getUiSettingsService = () => ({ get: async () => true });
const { client } = await setupRequest(mockRequest);
await client.search({});
await client.search({} as any);
const params = callWithRequestSpy.mock.calls[0][2];
expect(params.ignore_throttled).toBe(false);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const chartBase: ChartBase = {
};

const percentUsedScript = {
lang: 'expression',
lang: 'expression' as const,
source: `1 - doc['${METRIC_SYSTEM_FREE_MEMORY}'] / doc['${METRIC_SYSTEM_TOTAL_MEMORY}']`
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,9 @@ import {
import { Setup } from '../helpers/setup_request';
import { getMetricsDateHistogramParams } from '../helpers/metrics';
import { rangeFilter } from '../helpers/range_filter';
import { ChartBase } from './types';
import { ChartBase, SearchParams } from './types';
import { transformDataToMetricsChart } from './transform_metrics_chart';

interface Aggs {
[key: string]: {
min?: any;
max?: any;
sum?: any;
avg?: any;
};
}

interface Filter {
exists?: {
field: string;
Expand All @@ -32,7 +23,7 @@ interface Filter {
};
}

export async function fetchAndTransformMetrics<T extends Aggs>({
export async function fetchAndTransformMetrics<T extends string>({
setup,
serviceName,
chartBase,
Expand All @@ -42,12 +33,12 @@ export async function fetchAndTransformMetrics<T extends Aggs>({
setup: Setup;
serviceName: string;
chartBase: ChartBase;
aggs: T;
aggs: SearchParams['body']['aggs']['timeseriesData']['aggs'];
additionalFilters?: Filter[];
}) {
const { start, end, uiFiltersES, client, config } = setup;

const params = {
const params: SearchParams = {
index: config.get<string>('apm_oss.metricsIndices'),
body: {
size: 0,
Expand Down
Loading