Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6.x] [APM] Add missing trace_id to transaction histogram (#27591) #27817

Closed
wants to merge 1 commit into from
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -34,7 +34,7 @@ describe('StickyProperties', () => {
{
label: 'Handled',
fieldName: 'error.exception.handled',
val: 'true'
val: true
},
{
label: 'User ID',
Expand Down
Expand Up @@ -101,7 +101,7 @@ function getPropertyValue({
);
}

return <PropertyValue>{val}</PropertyValue>;
return <PropertyValue>{String(val)}</PropertyValue>;
}

export function StickyProperties({
Expand Down
Expand Up @@ -40,6 +40,7 @@ export async function loadTransactionDistribution({
transactionName,
transactionType = 'request',
transactionId,
traceId,
kuery
}: Required<IUrlParams>) {
return callApi<ITransactionDistributionAPIResponse>({
Expand All @@ -50,6 +51,7 @@ export async function loadTransactionDistribution({
start,
end,
transactionId,
traceId,
esFilterQuery: await getEncodedEsQuery(kuery)
}
});
Expand Down
38 changes: 25 additions & 13 deletions x-pack/plugins/apm/public/services/rest/apm/transactions.ts
Expand Up @@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { KFetchError } from 'ui/kfetch/kfetch_error';
import { TransactionAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/get_transaction';
import { SpanListAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/spans/get_spans';
import { Span } from 'x-pack/plugins/apm/typings/es_schemas/Span';
Expand Down Expand Up @@ -43,20 +44,31 @@ export async function loadTransaction({
traceId,
kuery
}: IUrlParams) {
const result = await callApi<TransactionAPIResponse>(
{
pathname: `/api/apm/services/${serviceName}/transactions/${transactionId}`,
query: {
traceId,
start,
end,
esFilterQuery: await getEncodedEsQuery(kuery)
try {
const result = await callApi<TransactionAPIResponse>(
{
pathname: `/api/apm/services/${serviceName}/transactions/${transactionId}`,
query: {
traceId,
start,
end,
esFilterQuery: await getEncodedEsQuery(kuery)
}
},
{
camelcase: false
}
},
{
camelcase: false
);
return addVersion(result);
} catch (e) {
const err: KFetchError = e;

// swallow 404 errors
if (err.res.status === 404) {
return;
}
);

return addVersion(result);
// re-throw all other errors
throw err;
}
}
Expand Up @@ -47,6 +47,7 @@ export function TransactionDistributionRequest({
serviceName,
transactionType,
transactionId,
traceId,
start,
end,
transactionName,
Expand All @@ -66,6 +67,7 @@ export function TransactionDistributionRequest({
serviceName,
transactionType,
transactionId,
traceId,
start,
end,
transactionName,
Expand Down
Expand Up @@ -45,6 +45,7 @@ export function bucketFetcher(
transactionName: string,
transactionType: string,
transactionId: string,
traceId: string,
bucketSize: number,
setup: Setup
): Promise<ESResponse> {
Expand Down Expand Up @@ -77,6 +78,7 @@ export function bucketFetcher(
bool: {
filter,
should: [
{ term: { [TRACE_ID]: traceId } },
{ term: { [TRANSACTION_ID]: transactionId } },
{ term: { [TRANSACTION_SAMPLED]: true } }
]
Expand Down
Expand Up @@ -13,6 +13,7 @@ export async function getBuckets(
transactionName: string,
transactionType: string,
transactionId: string,
traceId: string,
bucketSize: number,
setup: Setup
) {
Expand All @@ -21,6 +22,7 @@ export async function getBuckets(
transactionName,
transactionType,
transactionId,
traceId,
bucketSize,
setup
);
Expand Down
Expand Up @@ -21,6 +21,7 @@ export async function getDistribution(
transactionName: string,
transactionType: string,
transactionId: string,
traceId: string,
setup: Setup
): Promise<ITransactionDistributionAPIResponse> {
const bucketSize = await calculateBucketSize(
Expand All @@ -35,6 +36,7 @@ export async function getDistribution(
transactionName,
transactionType,
transactionId,
traceId,
bucketSize,
setup
);
Expand Down
48 changes: 25 additions & 23 deletions x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { SearchParams } from 'elasticsearch';
import { ESFilter } from 'elasticsearch';
import { oc } from 'ts-optchain';
import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/Transaction';
import {
Expand All @@ -23,38 +23,40 @@ export async function getTransaction(
): Promise<TransactionAPIResponse> {
const { start, end, esFilterQuery, client, config } = setup;

const params: SearchParams = {
index: config.get('apm_oss.transactionIndices'),
body: {
size: 1,
query: {
bool: {
filter: [
{ term: { [PROCESSOR_EVENT]: 'transaction' } },
{ term: { [TRANSACTION_ID]: transactionId } },
{
range: {
'@timestamp': {
gte: start,
lte: end,
format: 'epoch_millis'
}
}
}
]
const filter: ESFilter[] = [
{ term: { [PROCESSOR_EVENT]: 'transaction' } },
{ term: { [TRANSACTION_ID]: transactionId } },
{
range: {
'@timestamp': {
gte: start,
lte: end,
format: 'epoch_millis'
}
}
}
};
];

if (esFilterQuery) {
params.body.query.bool.filter.push(esFilterQuery);
filter.push(esFilterQuery);
}

if (traceId) {
params.body.query.bool.filter.push({ term: { [TRACE_ID]: traceId } });
filter.push({ term: { [TRACE_ID]: traceId } });
}

const params = {
index: config.get<string>('apm_oss.transactionIndices'),
body: {
size: 1,
query: {
bool: {
filter
}
}
}
};

const resp = await client<Transaction>('search', params);
return oc(resp).hits.hits[0]._source();
}
Expand Up @@ -14,6 +14,7 @@ import { Setup } from '../../helpers/setup_request';

export type SpanListAPIResponse = Span[];

// Deprecated and will be removed in 7.0. Only needed for backwards compatability pre 6.5 (introducition of v2 API and distributed tracing)
export async function getSpans(
transactionId: string,
setup: Setup
Expand Down
Expand Up @@ -12,7 +12,6 @@ import { initServicesApi } from '../services';
// @ts-ignore
import { initStatusApi } from '../status_check';
import { initTracesApi } from '../traces';
import { initTransactionsApi } from '../transactions';

describe('route handlers should fail with a Boom error', () => {
let consoleErrorSpy: any;
Expand Down Expand Up @@ -76,8 +75,4 @@ describe('route handlers should fail with a Boom error', () => {
describe('trace routes', async () => {
await testRouteFailures(initTracesApi);
});

describe('transaction routes', async () => {
await testRouteFailures(initTransactionsApi);
});
});
9 changes: 7 additions & 2 deletions x-pack/plugins/apm/server/routes/transaction_groups.ts
Expand Up @@ -109,19 +109,24 @@ export function initTransactionGroupsApi(server: Server) {
options: {
validate: {
query: withDefaultValidators({
transactionId: Joi.string().default('')
transactionId: Joi.string().default(''),
traceId: Joi.string().default('')
})
}
},
handler: req => {
const setup = setupRequest(req);
const { serviceName, transactionType, transactionName } = req.params;
const { transactionId } = req.query as { transactionId: string };
const { transactionId, traceId } = req.query as {
transactionId: string;
traceId: string;
};
return getDistribution(
serviceName,
transactionName,
transactionType,
transactionId,
traceId,
setup
).catch(defaultErrorHandler);
}
Expand Down
19 changes: 8 additions & 11 deletions x-pack/plugins/apm/server/routes/transactions.ts
Expand Up @@ -12,12 +12,6 @@ import { setupRequest } from '../lib/helpers/setup_request';
import { getTransaction } from '../lib/transactions/get_transaction';
import { getSpans } from '../lib/transactions/spans/get_spans';

const defaultErrorHandler = (err: Error) => {
// tslint:disable-next-line
console.error(err.stack);
throw Boom.boomify(err, { statusCode: 400 });
};

export function initTransactionsApi(server: Server) {
server.route({
method: 'GET',
Expand All @@ -29,13 +23,16 @@ export function initTransactionsApi(server: Server) {
})
}
},
handler: req => {
handler: async req => {
const { transactionId } = req.params;
const { traceId } = req.query as { traceId: string };
const setup = setupRequest(req);
return getTransaction(transactionId, traceId, setup).catch(
defaultErrorHandler
);
const transaction = await getTransaction(transactionId, traceId, setup);
if (transaction) {
return transaction;
} else {
throw Boom.notFound('Cannot find the requested page');
}
}
});

Expand All @@ -51,7 +48,7 @@ export function initTransactionsApi(server: Server) {
handler: req => {
const { transactionId } = req.params;
const setup = setupRequest(req);
return getSpans(transactionId, setup).catch(defaultErrorHandler);
return getSpans(transactionId, setup);
}
});
}
48 changes: 20 additions & 28 deletions x-pack/plugins/monitoring/public/directives/main/index.js
Expand Up @@ -82,35 +82,27 @@ uiModule.directive('monitoringMain', (breadcrumbs, license, kbnUrl, config) => {
link(scope, _element, attributes, controller) {
config.watch('k7design', (val) => scope.showPluginBreadcrumbs = !val);

function getSetupObj() {
return {
licenseService: license,
breadcrumbsService: breadcrumbs,
kbnUrlService: kbnUrl,
attributes: {
name: attributes.name,
product: attributes.product,
instance: attributes.instance,
resolver: attributes.resolver,
page: attributes.page,
tabIconClass: attributes.tabIconClass,
tabIconLabel: attributes.tabIconLabel,
pipelineId: attributes.pipelineId,
pipelineHash: attributes.pipelineHash,
pipelineVersions: get(scope, 'pageData.versions')
},
clusterName: get(scope, 'cluster.cluster_name')
};
}

const setupObj = getSetupObj();
controller.setup(setupObj);
Object.keys(setupObj.attributes).forEach(key => {
attributes.$observe(key, () => controller.setup(getSetupObj()));
});
scope.$watch('pageData.versions', versions => {
controller.pipelineVersions = versions;
controller.setup({
licenseService: license,
breadcrumbsService: breadcrumbs,
kbnUrlService: kbnUrl,
attributes: {
name: attributes.name,
product: attributes.product,
instance: attributes.instance,
resolver: attributes.resolver,
page: attributes.page,
tabIconClass: attributes.tabIconClass,
tabIconLabel: attributes.tabIconLabel,
pipelineId: attributes.pipelineId,
pipelineHash: attributes.pipelineHash,
pipelineVersions: get(scope, 'pageData.versions')
},
clusterName: get(scope, 'cluster.cluster_name')
});

attributes.$observe('instance', instance => controller.instance = instance);
attributes.$observe('resolver', resolver => controller.resolver = resolver);
}
};
});
Expand Up @@ -98,9 +98,6 @@ uiRoutes.when('/logstash/pipelines/:id/:hash?', {
getPageData,
reactNodeId: 'monitoringLogstashPipelineApp',
$scope,
options: {
enableTimeFilter: false,
},
$injector
});

Expand Down