[APM] Use the outcome field to calculate the transaction error rate chart (#75528)

* replacing error rate to use event.outcome field

* addressing PR comment

* fixing api test

* fixing API test

* fixing api tests

* rmeoving snapshot from api test

* testing error rate

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Cauê Marcondes 2020-09-07 10:23:22 +01:00 committed by GitHub
parent 113936a649
commit 7f323a19bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 63555 additions and 984 deletions

View file

@ -34,6 +34,8 @@ exports[`Error ERROR_LOG_MESSAGE 1`] = `undefined`;
exports[`Error ERROR_PAGE_URL 1`] = `undefined`;
exports[`Error EVENT_OUTCOME 1`] = `undefined`;
exports[`Error HOST_NAME 1`] = `"my hostname"`;
exports[`Error HTTP_REQUEST_METHOD 1`] = `undefined`;
@ -186,6 +188,8 @@ exports[`Span ERROR_LOG_MESSAGE 1`] = `undefined`;
exports[`Span ERROR_PAGE_URL 1`] = `undefined`;
exports[`Span EVENT_OUTCOME 1`] = `undefined`;
exports[`Span HOST_NAME 1`] = `undefined`;
exports[`Span HTTP_REQUEST_METHOD 1`] = `undefined`;
@ -338,6 +342,8 @@ exports[`Transaction ERROR_LOG_MESSAGE 1`] = `undefined`;
exports[`Transaction ERROR_PAGE_URL 1`] = `undefined`;
exports[`Transaction EVENT_OUTCOME 1`] = `undefined`;
exports[`Transaction HOST_NAME 1`] = `"my hostname"`;
exports[`Transaction HTTP_REQUEST_METHOD 1`] = `"GET"`;

View file

@ -45,6 +45,8 @@ export const TRANSACTION_SAMPLED = 'transaction.sampled';
export const TRANSACTION_BREAKDOWN_COUNT = 'transaction.breakdown.count';
export const TRANSACTION_PAGE_URL = 'transaction.page.url';
export const EVENT_OUTCOME = 'event.outcome';
export const TRACE_ID = 'trace.id';
export const SPAN_DURATION = 'span.duration.us';

View file

@ -0,0 +1,11 @@
/*
* 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.
*/
export enum EventOutcome {
success = 'success',
failure = 'failure',
unknown = 'unknown',
}

View file

@ -4,11 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { mean } from 'lodash';
import { EventOutcome } from '../../../common/event_outcome';
import {
HTTP_RESPONSE_STATUS_CODE,
TRANSACTION_NAME,
TRANSACTION_TYPE,
SERVICE_NAME,
EVENT_OUTCOME,
} from '../../../common/elasticsearch_fieldnames';
import { ProcessorEvent } from '../../../common/processor_event';
import { rangeFilter } from '../../../common/utils/range_filter';
@ -42,7 +43,9 @@ export async function getErrorRate({
const filter = [
{ term: { [SERVICE_NAME]: serviceName } },
{ range: rangeFilter(start, end) },
{ exists: { field: HTTP_RESPONSE_STATUS_CODE } },
{
terms: { [EVENT_OUTCOME]: [EventOutcome.failure, EventOutcome.success] },
},
...transactionNamefilter,
...transactionTypefilter,
...uiFiltersES,
@ -65,7 +68,7 @@ export async function getErrorRate({
},
aggs: {
erroneous_transactions: {
filter: { range: { [HTTP_RESPONSE_STATUS_CODE]: { gte: 400 } } },
filter: { term: { [EVENT_OUTCOME]: EventOutcome.failure } },
},
},
},

View file

@ -130,13 +130,24 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte
it('returns all services', async () => {
const { body } = await getServices();
expect(body).to.eql(['ALL_OPTION_VALUE', 'client', 'opbeans-java', 'opbeans-node']);
expect(body).to.eql([
'ALL_OPTION_VALUE',
'client',
'opbeans-dotnet',
'opbeans-go',
'opbeans-java',
'opbeans-node',
'opbeans-python',
'opbeans-ruby',
'opbeans-rum',
]);
});
it('returns the environments', async () => {
const { body } = await getEnvironments('opbeans-node');
expect(body).to.eql([
{ name: 'ALL_OPTION_VALUE', alreadyConfigured: false },
{ name: 'testing', alreadyConfigured: false },
{ name: 'production', alreadyConfigured: false },
]);
});

View file

@ -4,23 +4,23 @@
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { first, last } from 'lodash';
import { FtrProviderContext } from '../../../common/ftr_provider_context';
import expectedErrorRate from './expectation/error_rate.json';
export default function ApiTest({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
// url parameters
const start = encodeURIComponent('2020-06-29T06:45:00.000Z');
const end = encodeURIComponent('2020-06-29T06:49:00.000Z');
const start = encodeURIComponent('2020-08-26T11:00:00.000Z');
const end = encodeURIComponent('2020-08-26T11:30:00.000Z');
const uiFilters = encodeURIComponent(JSON.stringify({}));
describe('Error rate', () => {
describe('when data is not loaded', () => {
it('handles the empty state', async () => {
const response = await supertest.get(
`/api/apm/services/opbeans-node/transaction_groups/error_rate?start=${start}&end=${end}&uiFilters=${uiFilters}`
`/api/apm/services/opbeans-java/transaction_groups/error_rate?start=${start}&end=${end}&uiFilters=${uiFilters}`
);
expect(response.status).to.be(200);
expect(response.body).to.eql({
@ -34,13 +34,37 @@ export default function ApiTest({ getService }: FtrProviderContext) {
before(() => esArchiver.load('8.0.0'));
after(() => esArchiver.unload('8.0.0'));
it('returns the transaction error rate', async () => {
const response = await supertest.get(
`/api/apm/services/opbeans-node/transaction_groups/error_rate?start=${start}&end=${end}&uiFilters=${uiFilters}`
);
describe('returns the transaction error rate', () => {
let errorRateResponse: {
erroneousTransactionsRate: Array<{ x: number; y: number | null }>;
average: number;
};
before(async () => {
const response = await supertest.get(
`/api/apm/services/opbeans-java/transaction_groups/error_rate?start=${start}&end=${end}&uiFilters=${uiFilters}`
);
errorRateResponse = response.body;
});
expect(response.status).to.be(200);
expect(response.body).to.eql(expectedErrorRate);
it('has the correct start date', async () => {
expect(first(errorRateResponse.erroneousTransactionsRate)?.x).to.be(1598439600000);
});
it('has the correct end date', async () => {
expect(last(errorRateResponse.erroneousTransactionsRate)?.x).to.be(1598441400000);
});
it('has the correct number of buckets', async () => {
expect(errorRateResponse.erroneousTransactionsRate.length).to.be(61);
});
it('has the correct calculation for average', async () => {
expect(errorRateResponse.average).to.be(0.18894993894993897);
});
it('has the correct error rate', async () => {
expect(first(errorRateResponse.erroneousTransactionsRate)?.y).to.be(0.5);
});
});
});
});

View file

@ -1,970 +0,0 @@
{
"noHits": false,
"erroneousTransactionsRate": [
{
"x": 1593413100000,
"y": null
},
{
"x": 1593413101000,
"y": null
},
{
"x": 1593413102000,
"y": null
},
{
"x": 1593413103000,
"y": null
},
{
"x": 1593413104000,
"y": null
},
{
"x": 1593413105000,
"y": null
},
{
"x": 1593413106000,
"y": null
},
{
"x": 1593413107000,
"y": null
},
{
"x": 1593413108000,
"y": null
},
{
"x": 1593413109000,
"y": null
},
{
"x": 1593413110000,
"y": null
},
{
"x": 1593413111000,
"y": null
},
{
"x": 1593413112000,
"y": null
},
{
"x": 1593413113000,
"y": null
},
{
"x": 1593413114000,
"y": null
},
{
"x": 1593413115000,
"y": null
},
{
"x": 1593413116000,
"y": null
},
{
"x": 1593413117000,
"y": null
},
{
"x": 1593413118000,
"y": null
},
{
"x": 1593413119000,
"y": null
},
{
"x": 1593413120000,
"y": null
},
{
"x": 1593413121000,
"y": null
},
{
"x": 1593413122000,
"y": null
},
{
"x": 1593413123000,
"y": null
},
{
"x": 1593413124000,
"y": null
},
{
"x": 1593413125000,
"y": null
},
{
"x": 1593413126000,
"y": null
},
{
"x": 1593413127000,
"y": null
},
{
"x": 1593413128000,
"y": null
},
{
"x": 1593413129000,
"y": null
},
{
"x": 1593413130000,
"y": null
},
{
"x": 1593413131000,
"y": null
},
{
"x": 1593413132000,
"y": null
},
{
"x": 1593413133000,
"y": null
},
{
"x": 1593413134000,
"y": null
},
{
"x": 1593413135000,
"y": null
},
{
"x": 1593413136000,
"y": null
},
{
"x": 1593413137000,
"y": null
},
{
"x": 1593413138000,
"y": null
},
{
"x": 1593413139000,
"y": null
},
{
"x": 1593413140000,
"y": null
},
{
"x": 1593413141000,
"y": null
},
{
"x": 1593413142000,
"y": null
},
{
"x": 1593413143000,
"y": null
},
{
"x": 1593413144000,
"y": null
},
{
"x": 1593413145000,
"y": null
},
{
"x": 1593413146000,
"y": null
},
{
"x": 1593413147000,
"y": null
},
{
"x": 1593413148000,
"y": null
},
{
"x": 1593413149000,
"y": null
},
{
"x": 1593413150000,
"y": null
},
{
"x": 1593413151000,
"y": null
},
{
"x": 1593413152000,
"y": null
},
{
"x": 1593413153000,
"y": null
},
{
"x": 1593413154000,
"y": null
},
{
"x": 1593413155000,
"y": null
},
{
"x": 1593413156000,
"y": null
},
{
"x": 1593413157000,
"y": null
},
{
"x": 1593413158000,
"y": null
},
{
"x": 1593413159000,
"y": null
},
{
"x": 1593413160000,
"y": null
},
{
"x": 1593413161000,
"y": null
},
{
"x": 1593413162000,
"y": null
},
{
"x": 1593413163000,
"y": null
},
{
"x": 1593413164000,
"y": null
},
{
"x": 1593413165000,
"y": null
},
{
"x": 1593413166000,
"y": null
},
{
"x": 1593413167000,
"y": null
},
{
"x": 1593413168000,
"y": null
},
{
"x": 1593413169000,
"y": null
},
{
"x": 1593413170000,
"y": null
},
{
"x": 1593413171000,
"y": null
},
{
"x": 1593413172000,
"y": null
},
{
"x": 1593413173000,
"y": null
},
{
"x": 1593413174000,
"y": null
},
{
"x": 1593413175000,
"y": null
},
{
"x": 1593413176000,
"y": null
},
{
"x": 1593413177000,
"y": null
},
{
"x": 1593413178000,
"y": null
},
{
"x": 1593413179000,
"y": null
},
{
"x": 1593413180000,
"y": null
},
{
"x": 1593413181000,
"y": null
},
{
"x": 1593413182000,
"y": null
},
{
"x": 1593413183000,
"y": null
},
{
"x": 1593413184000,
"y": null
},
{
"x": 1593413185000,
"y": null
},
{
"x": 1593413186000,
"y": null
},
{
"x": 1593413187000,
"y": null
},
{
"x": 1593413188000,
"y": null
},
{
"x": 1593413189000,
"y": null
},
{
"x": 1593413190000,
"y": null
},
{
"x": 1593413191000,
"y": null
},
{
"x": 1593413192000,
"y": null
},
{
"x": 1593413193000,
"y": null
},
{
"x": 1593413194000,
"y": null
},
{
"x": 1593413195000,
"y": null
},
{
"x": 1593413196000,
"y": null
},
{
"x": 1593413197000,
"y": null
},
{
"x": 1593413198000,
"y": null
},
{
"x": 1593413199000,
"y": null
},
{
"x": 1593413200000,
"y": null
},
{
"x": 1593413201000,
"y": null
},
{
"x": 1593413202000,
"y": null
},
{
"x": 1593413203000,
"y": null
},
{
"x": 1593413204000,
"y": null
},
{
"x": 1593413205000,
"y": null
},
{
"x": 1593413206000,
"y": null
},
{
"x": 1593413207000,
"y": null
},
{
"x": 1593413208000,
"y": null
},
{
"x": 1593413209000,
"y": null
},
{
"x": 1593413210000,
"y": null
},
{
"x": 1593413211000,
"y": null
},
{
"x": 1593413212000,
"y": null
},
{
"x": 1593413213000,
"y": null
},
{
"x": 1593413214000,
"y": null
},
{
"x": 1593413215000,
"y": null
},
{
"x": 1593413216000,
"y": null
},
{
"x": 1593413217000,
"y": null
},
{
"x": 1593413218000,
"y": null
},
{
"x": 1593413219000,
"y": null
},
{
"x": 1593413220000,
"y": null
},
{
"x": 1593413221000,
"y": null
},
{
"x": 1593413222000,
"y": null
},
{
"x": 1593413223000,
"y": null
},
{
"x": 1593413224000,
"y": null
},
{
"x": 1593413225000,
"y": null
},
{
"x": 1593413226000,
"y": null
},
{
"x": 1593413227000,
"y": null
},
{
"x": 1593413228000,
"y": null
},
{
"x": 1593413229000,
"y": null
},
{
"x": 1593413230000,
"y": null
},
{
"x": 1593413231000,
"y": null
},
{
"x": 1593413232000,
"y": null
},
{
"x": 1593413233000,
"y": null
},
{
"x": 1593413234000,
"y": null
},
{
"x": 1593413235000,
"y": null
},
{
"x": 1593413236000,
"y": null
},
{
"x": 1593413237000,
"y": null
},
{
"x": 1593413238000,
"y": null
},
{
"x": 1593413239000,
"y": null
},
{
"x": 1593413240000,
"y": null
},
{
"x": 1593413241000,
"y": null
},
{
"x": 1593413242000,
"y": null
},
{
"x": 1593413243000,
"y": null
},
{
"x": 1593413244000,
"y": null
},
{
"x": 1593413245000,
"y": null
},
{
"x": 1593413246000,
"y": null
},
{
"x": 1593413247000,
"y": null
},
{
"x": 1593413248000,
"y": null
},
{
"x": 1593413249000,
"y": null
},
{
"x": 1593413250000,
"y": null
},
{
"x": 1593413251000,
"y": null
},
{
"x": 1593413252000,
"y": null
},
{
"x": 1593413253000,
"y": null
},
{
"x": 1593413254000,
"y": null
},
{
"x": 1593413255000,
"y": null
},
{
"x": 1593413256000,
"y": null
},
{
"x": 1593413257000,
"y": null
},
{
"x": 1593413258000,
"y": null
},
{
"x": 1593413259000,
"y": null
},
{
"x": 1593413260000,
"y": null
},
{
"x": 1593413261000,
"y": null
},
{
"x": 1593413262000,
"y": null
},
{
"x": 1593413263000,
"y": null
},
{
"x": 1593413264000,
"y": null
},
{
"x": 1593413265000,
"y": null
},
{
"x": 1593413266000,
"y": null
},
{
"x": 1593413267000,
"y": null
},
{
"x": 1593413268000,
"y": null
},
{
"x": 1593413269000,
"y": null
},
{
"x": 1593413270000,
"y": null
},
{
"x": 1593413271000,
"y": null
},
{
"x": 1593413272000,
"y": 0
},
{
"x": 1593413273000,
"y": 0
},
{
"x": 1593413274000,
"y": null
},
{
"x": 1593413275000,
"y": null
},
{
"x": 1593413276000,
"y": null
},
{
"x": 1593413277000,
"y": 0
},
{
"x": 1593413278000,
"y": null
},
{
"x": 1593413279000,
"y": null
},
{
"x": 1593413280000,
"y": null
},
{
"x": 1593413281000,
"y": 0
},
{
"x": 1593413282000,
"y": null
},
{
"x": 1593413283000,
"y": null
},
{
"x": 1593413284000,
"y": 0
},
{
"x": 1593413285000,
"y": 0
},
{
"x": 1593413286000,
"y": 0.125
},
{
"x": 1593413287000,
"y": 0.5
},
{
"x": 1593413288000,
"y": 0
},
{
"x": 1593413289000,
"y": 0.5
},
{
"x": 1593413290000,
"y": 0
},
{
"x": 1593413291000,
"y": 0
},
{
"x": 1593413292000,
"y": 0.5
},
{
"x": 1593413293000,
"y": 0
},
{
"x": 1593413294000,
"y": 0
},
{
"x": 1593413295000,
"y": 0
},
{
"x": 1593413296000,
"y": 0
},
{
"x": 1593413297000,
"y": 0
},
{
"x": 1593413298000,
"y": 0
},
{
"x": 1593413299000,
"y": 0.5
},
{
"x": 1593413300000,
"y": 0.3333333333333333
},
{
"x": 1593413301000,
"y": 0.14285714285714285
},
{
"x": 1593413302000,
"y": 0
},
{
"x": 1593413303000,
"y": 0
},
{
"x": 1593413304000,
"y": 0
},
{
"x": 1593413305000,
"y": 0.6666666666666666
},
{
"x": 1593413306000,
"y": 0
},
{
"x": 1593413307000,
"y": 0
},
{
"x": 1593413308000,
"y": 0.3333333333333333
},
{
"x": 1593413309000,
"y": 0.3333333333333333
},
{
"x": 1593413310000,
"y": 0.3333333333333333
},
{
"x": 1593413311000,
"y": 0.5
},
{
"x": 1593413312000,
"y": 0
},
{
"x": 1593413313000,
"y": 0
},
{
"x": 1593413314000,
"y": 0
},
{
"x": 1593413315000,
"y": 0.5
},
{
"x": 1593413316000,
"y": 0
},
{
"x": 1593413317000,
"y": 0
},
{
"x": 1593413318000,
"y": 0
},
{
"x": 1593413319000,
"y": 0
},
{
"x": 1593413320000,
"y": 0.3333333333333333
},
{
"x": 1593413321000,
"y": 0
},
{
"x": 1593413322000,
"y": 0.5
},
{
"x": 1593413323000,
"y": null
},
{
"x": 1593413324000,
"y": null
},
{
"x": 1593413325000,
"y": null
},
{
"x": 1593413326000,
"y": null
},
{
"x": 1593413327000,
"y": null
},
{
"x": 1593413328000,
"y": null
},
{
"x": 1593413329000,
"y": null
},
{
"x": 1593413330000,
"y": null
},
{
"x": 1593413331000,
"y": null
},
{
"x": 1593413332000,
"y": null
},
{
"x": 1593413333000,
"y": null
},
{
"x": 1593413334000,
"y": null
},
{
"x": 1593413335000,
"y": null
},
{
"x": 1593413336000,
"y": null
},
{
"x": 1593413337000,
"y": null
},
{
"x": 1593413338000,
"y": null
},
{
"x": 1593413339000,
"y": null
},
{
"x": 1593413340000,
"y": null
}
],
"average": 0.14188815060908083
}

File diff suppressed because it is too large Load diff

View file

@ -285,5 +285,37 @@ export default function serviceMapsApiTests({ getService }: FtrProviderContext)
});
});
});
describe('when there is data with anomalies', () => {
before(() => esArchiver.load('ml_8.0.0'));
after(() => esArchiver.unload('ml_8.0.0'));
it('returns service map elements', async () => {
const response = await supertest.get(
'/api/apm/service-map?start=2020-08-26T11%3A00%3A00.000Z&end=2020-08-26T11%3A30%3A00.000Z'
);
expect(response.status).to.be(200);
const opbeansJavaWithAnomaly = response.body.elements.filter(
(el: { data: { id: string } }) => el.data.id === 'opbeans-java'
);
expect(opbeansJavaWithAnomaly).to.eql([
{
data: {
id: 'opbeans-java',
'service.environment': 'production',
'service.name': 'opbeans-java',
'agent.name': 'java',
serviceAnomalyStats: {
transactionType: 'request',
anomalyScore: 0.21359169006333134,
actualValue: 1526662.1320754716,
jobId: 'apm-production-229a-high_mean_transaction_duration',
},
},
},
]);
});
});
});
}