[APM]Remove observer-version-major from apm queries (#125962)

* [APM]Remove observer-version-major from apm queries

* Remove constant from apm, not observability

* fix tests and ts types

* remove Promise.all()

* fix types
This commit is contained in:
Miriam 2022-02-22 11:12:22 +00:00 committed by GitHub
parent 6bf91d77ad
commit eb05eb593d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 20 additions and 311 deletions

View file

@ -133,8 +133,6 @@ exports[`Error OBSERVER_HOSTNAME 1`] = `undefined`;
exports[`Error OBSERVER_LISTENING 1`] = `undefined`;
exports[`Error OBSERVER_VERSION_MAJOR 1`] = `8`;
exports[`Error PARENT_ID 1`] = `"parentId"`;
exports[`Error POD_NAME 1`] = `undefined`;
@ -382,8 +380,6 @@ exports[`Span OBSERVER_HOSTNAME 1`] = `undefined`;
exports[`Span OBSERVER_LISTENING 1`] = `undefined`;
exports[`Span OBSERVER_VERSION_MAJOR 1`] = `8`;
exports[`Span PARENT_ID 1`] = `"parentId"`;
exports[`Span POD_NAME 1`] = `undefined`;
@ -637,8 +633,6 @@ exports[`Transaction OBSERVER_HOSTNAME 1`] = `undefined`;
exports[`Transaction OBSERVER_LISTENING 1`] = `undefined`;
exports[`Transaction OBSERVER_VERSION_MAJOR 1`] = `8`;
exports[`Transaction PARENT_ID 1`] = `"parentId"`;
exports[`Transaction POD_NAME 1`] = `undefined`;

View file

@ -41,7 +41,6 @@ export const USER_AGENT_NAME = 'user_agent.name';
export const DESTINATION_ADDRESS = 'destination.address';
export const OBSERVER_HOSTNAME = 'observer.hostname';
export const OBSERVER_VERSION_MAJOR = 'observer.version_major';
export const OBSERVER_LISTENING = 'observer.listening';
export const PROCESSOR_EVENT = 'processor.event';

View file

@ -1,20 +1,20 @@
# Query Debugging
When debugging an issue with the APM UI it can be very helpful to see the exact Elasticsearch queries and responses that was made for a given API request.
When debugging an issue with the APM UI it can be very helpful to see the exact Elasticsearch queries and responses that was made for a given API request.
To enable debugging of Elasticsearch queries in APM UI do the following:
1. Go to "Stack Management"
1. Go to "Stack Management"
2. Under "Kibana" on the left-hand side, select "Advanced Settings"
3. Search for "Observability"
4. Enable "Inspect ES queries" setting
5. Click "Save"
When you navigate back to APM UI you can now inspect Elasticsearch queries by opening your browser's Developer Tools and selecting an api request to APM's api.
When you navigate back to APM UI you can now inspect Elasticsearch queries by opening your browser's Developer Tools and selecting an api request to APM's api.
There will be an `_inspect` key containing every Elasticsearch query made during that request including both requests and responses to and from Elasticsearch.
![image](https://user-images.githubusercontent.com/209966/140500012-b075adf0-8401-40fd-99f8-85b68711de17.png)
## Example
## Example
When "Inspect ES queries" are enabed all API calls to the APM API will be include the query param `_inspect=true`. For the environments API the request / response will be:
@ -24,11 +24,7 @@ GET /internal/apm/environments?start=<start>&end=<end>&_inspect=true
```json
{
"environments": [
"production",
"testing",
"ENVIRONMENT_NOT_DEFINED"
],
"environments": ["production", "testing", "ENVIRONMENT_NOT_DEFINED"],
"_inspect": [
{
"id": "get_environments (/internal/apm/environments)",
@ -48,18 +44,7 @@ GET /internal/apm/environments?start=<start>&end=<end>&_inspect=true
},
{
"terms": {
"processor.event": [
"transaction",
"metric",
"error"
]
}
},
{
"range": {
"observer.version_major": {
"gte": 7
}
"processor.event": ["transaction", "metric", "error"]
}
}
]

View file

@ -114,7 +114,7 @@ function useServicesFetcher() {
);
useEffect(() => {
if (mainStatisticsData.hasLegacyData && !hasDisplayedToast) {
if (!hasDisplayedToast) {
hasDisplayedToast = true;
core.notifications.toasts.addWarning({
@ -141,11 +141,7 @@ function useServicesFetcher() {
),
});
}
}, [
mainStatisticsData.hasLegacyData,
upgradeAssistantHref,
core.notifications.toasts,
]);
}, [upgradeAssistantHref, core.notifications.toasts]);
return {
mainStatisticsData,

View file

@ -1,32 +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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { cloneDeep } from 'lodash';
import { OBSERVER_VERSION_MAJOR } from '../../../../../common/elasticsearch_fieldnames';
import {
ESSearchRequest,
ESFilter,
} from '../../../../../../../../src/core/types/elasticsearch';
/*
Adds a range query to the ES request to exclude legacy data
*/
export function addFilterToExcludeLegacyData(
params: ESSearchRequest & {
body: { query: { bool: { filter: ESFilter[] } } };
}
) {
const nextParams = cloneDeep(params);
// add filter for omitting pre-7.x data
nextParams.body.query.bool.filter.push({
range: { [OBSERVER_VERSION_MAJOR]: { gte: 7 } },
});
return nextParams;
}

View file

@ -33,7 +33,6 @@ import {
getDebugTitle,
} from '../call_async_with_debug';
import { cancelEsRequestOnAbort } from '../cancel_es_request_on_abort';
import { addFilterToExcludeLegacyData } from './add_filter_to_exclude_legacy_data';
import { unpackProcessorEvents } from './unpack_processor_events';
export type APMEventESSearchRequest = Omit<ESSearchRequest, 'index'> & {
@ -97,14 +96,8 @@ export class APMEventClient {
this.indices
);
const { includeLegacyData = false } = params.apm;
const withPossibleLegacyDataFilter = !includeLegacyData
? addFilterToExcludeLegacyData(withProcessorEventFilter)
: withProcessorEventFilter;
const searchParams = {
...withPossibleLegacyDataFilter,
...withProcessorEventFilter,
...(this.includeFrozen ? { ignore_throttled: false } : {}),
ignore_unavailable: true,
preference: 'any',

View file

@ -10,7 +10,6 @@ import { setupRequest } from './setup_request';
import { APMConfig } from '../..';
import { APMRouteHandlerResources } from '../../routes/typings';
import { ProcessorEvent } from '../../../common/processor_event';
import { PROCESSOR_EVENT } from '../../../common/elasticsearch_fieldnames';
import { getApmIndices } from '../../routes/settings/apm_indices/get_apm_indices';
jest.mock('../../routes/settings/apm_indices/get_apm_indices', () => ({
@ -121,10 +120,7 @@ describe('setupRequest', () => {
foo: 'bar',
query: {
bool: {
filter: [
{ terms: { 'processor.event': ['transaction'] } },
{ range: { 'observer.version_major': { gte: 7 } } },
],
filter: [{ terms: { 'processor.event': ['transaction'] } }],
},
},
},
@ -161,94 +157,6 @@ describe('setupRequest', () => {
);
});
});
describe('with a bool filter', () => {
it('adds a range filter for `observer.version_major` to the existing filter', async () => {
const mockResources = getMockResources();
const { apmEventClient } = await setupRequest(mockResources);
await apmEventClient.search('foo', {
apm: {
events: [ProcessorEvent.transaction],
},
body: {
query: { bool: { filter: [{ term: { field: 'someTerm' } }] } },
},
});
const params =
mockResources.context.core.elasticsearch.client.asCurrentUser.search
.mock.calls[0][0];
// @ts-expect-error missing body definition
expect(params.body).toEqual({
query: {
bool: {
filter: [
{ term: { field: 'someTerm' } },
{ terms: { [PROCESSOR_EVENT]: ['transaction'] } },
{ range: { 'observer.version_major': { gte: 7 } } },
],
},
},
});
});
it('does not add a range filter for `observer.version_major` if includeLegacyData=true', async () => {
const mockResources = getMockResources();
const { apmEventClient } = await setupRequest(mockResources);
await apmEventClient.search('foo', {
apm: {
events: [ProcessorEvent.error],
includeLegacyData: true,
},
body: {
query: { bool: { filter: [{ term: { field: 'someTerm' } }] } },
},
});
const params =
mockResources.context.core.elasticsearch.client.asCurrentUser.search
.mock.calls[0][0];
// @ts-expect-error missing body definition
expect(params.body).toEqual({
query: {
bool: {
filter: [
{ term: { field: 'someTerm' } },
{
terms: {
[PROCESSOR_EVENT]: ['error'],
},
},
],
},
},
});
});
});
});
describe('without a bool filter', () => {
it('adds a range filter for `observer.version_major`', async () => {
const mockResources = getMockResources();
const { apmEventClient } = await setupRequest(mockResources);
await apmEventClient.search('foo', {
apm: {
events: [ProcessorEvent.error],
},
});
const params =
mockResources.context.core.elasticsearch.client.asCurrentUser.search.mock
.calls[0][0];
// @ts-expect-error missing body definition
expect(params.body).toEqual({
query: {
bool: {
filter: [
{ terms: { [PROCESSOR_EVENT]: ['error'] } },
{ range: { 'observer.version_major': { gte: 7 } } },
],
},
},
});
});
});
describe('with includeFrozen=false', () => {

View file

@ -16,43 +16,6 @@ Object {
}
`;
exports[`services queries fetches the legacy data status 1`] = `
Object {
"apm": Object {
"events": Array [
"transaction",
],
"includeLegacyData": true,
},
"body": Object {
"query": Object {
"bool": Object {
"filter": Array [
Object {
"range": Object {
"observer.version_major": Object {
"lt": 7,
},
},
},
Object {
"range": Object {
"@timestamp": Object {
"format": "epoch_millis",
"gte": 1,
"lte": 50000,
},
},
},
],
},
},
"size": 0,
},
"terminate_after": 1,
}
`;
exports[`services queries fetches the service agent name 1`] = `
Object {
"apm": Object {

View file

@ -1,43 +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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { rangeQuery } from '../../../../../observability/server';
import { ProcessorEvent } from '../../../../common/processor_event';
import { OBSERVER_VERSION_MAJOR } from '../../../../common/elasticsearch_fieldnames';
import { Setup } from '../../../lib/helpers/setup_request';
// returns true if 6.x data is found
export async function getLegacyDataStatus(
setup: Setup,
start: number,
end: number
) {
const { apmEventClient } = setup;
const params = {
terminate_after: 1,
apm: {
events: [ProcessorEvent.transaction],
includeLegacyData: true,
},
body: {
size: 0,
query: {
bool: {
filter: [
{ range: { [OBSERVER_VERSION_MAJOR]: { lt: 7 } } },
...rangeQuery(start, end),
],
},
},
},
};
const resp = await apmEventClient.search('get_legacy_data_status', params);
const hasLegacyData = resp.hits.total.value > 0;
return hasLegacyData;
}

View file

@ -8,7 +8,6 @@
import { Logger } from '@kbn/logging';
import { withApmSpan } from '../../../utils/with_apm_span';
import { Setup } from '../../../lib/helpers/setup_request';
import { getLegacyDataStatus } from './get_legacy_data_status';
import { getServicesItems } from './get_services_items';
export async function getServices({
@ -29,22 +28,18 @@ export async function getServices({
end: number;
}) {
return withApmSpan('get_services', async () => {
const [items, hasLegacyData] = await Promise.all([
getServicesItems({
environment,
kuery,
setup,
searchAggregatedTransactions,
logger,
start,
end,
}),
getLegacyDataStatus(setup, start, end),
]);
const items = await getServicesItems({
environment,
kuery,
setup,
searchAggregatedTransactions,
logger,
start,
end,
});
return {
items,
hasLegacyData,
};
});
}

View file

@ -8,7 +8,6 @@
import { getServiceAgent } from './get_service_agent';
import { getServiceTransactionTypes } from './get_service_transaction_types';
import { getServicesItems } from './get_services/get_services_items';
import { getLegacyDataStatus } from './get_services/get_legacy_data_status';
import { hasHistoricalAgentData } from '../../routes/historical_data/has_historical_agent_data';
import {
SearchParamsMock,
@ -68,16 +67,6 @@ describe('services queries', () => {
expect(allParams).toMatchSnapshot();
});
it('fetches the legacy data status', async () => {
const start = 1;
const end = 50000;
mock = await inspectSearchParams((setup) =>
getLegacyDataStatus(setup, start, end)
);
expect(mock.params).toMatchSnapshot();
});
it('fetches the agent status', async () => {
mock = await inspectSearchParams((setup) => hasHistoricalAgentData(setup));

View file

@ -96,7 +96,6 @@ const servicesRoute = createApmServerRoute({
healthStatus: import('./../../../common/service_health_status').ServiceHealthStatus;
}
>;
hasLegacyData: boolean;
}> {
const setup = await setupRequest(resources);
const { params, logger } = resources;

View file

@ -128,7 +128,6 @@ export function onPremInstructions({
'processor.event': ['error', 'transaction', 'metric'],
},
},
{ range: { 'observer.version_major': { gte: 7 } } },
],
},
},

View file

@ -124,10 +124,7 @@ export function getOnPremApmServerInstructionSet({
index: apmConfig.indices.onboarding,
query: {
bool: {
filter: [
{ term: { 'processor.event': 'onboarding' } },
{ range: { 'observer.version_major': { gte: 7 } } },
],
filter: [{ term: { 'processor.event': 'onboarding' } }],
},
},
},

View file

@ -49,9 +49,6 @@ export function createServiceDependencyDocs({
processor: {
event: 'metric' as const,
},
observer: {
version_major: 7,
},
'@timestamp': new Date(time).toISOString(),
service,
agent: {
@ -78,9 +75,6 @@ export function createServiceDependencyDocs({
processor: {
event: 'span' as const,
},
observer: {
version_major: 7,
},
'@timestamp': new Date(time).toISOString(),
service,
agent: {
@ -106,9 +100,6 @@ export function createServiceDependencyDocs({
processor: {
event: 'transaction' as const,
},
observer: {
version_major: 7,
},
'@timestamp': new Date(time + 1).toISOString(),
event: {
outcome: 'unknown',

View file

@ -204,13 +204,6 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
'@timestamp': {
type: 'date',
},
observer: {
properties: {
version_major: {
type: 'long',
},
},
},
},
},
},
@ -227,9 +220,6 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
name: serviceName,
version: '1.1',
},
observer: {
version_major: 8,
},
},
refresh: 'wait_for',
});
@ -246,9 +236,6 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
version: '1.2',
environment: 'production',
},
observer: {
version_major: 8,
},
},
refresh: 'wait_for',
});

View file

@ -67,13 +67,6 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
},
},
},
observer: {
properties: {
version_major: {
type: 'byte',
},
},
},
processor: {
properties: {
event: {
@ -98,9 +91,6 @@ export default function annotationApiTests({ getService }: FtrProviderContext) {
environment: 'production',
version: index + 1,
},
observer: {
version_major: 8,
},
processor: {
event: 'transaction',
},

View file

@ -45,7 +45,6 @@ export default function ApiTest({ getService }: FtrProviderContext) {
);
expect(response.status).to.be(200);
expect(response.body.hasLegacyData).to.be(false);
expect(response.body.items.length).to.be(0);
});
}