mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `8.13`: - [chore(NA): remove prettier custom overrides across codebase (#180958)](https://github.com/elastic/kibana/pull/180958)
This commit is contained in:
parent
16d8629b5f
commit
bc8f57298d
1272 changed files with 11627 additions and 24655 deletions
8
.buildkite/scripts/steps/checks/prettier_topology.sh
Executable file
8
.buildkite/scripts/steps/checks/prettier_topology.sh
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source .buildkite/scripts/common/util.sh
|
||||
|
||||
echo --- Check Prettier Configuration Topology
|
||||
node scripts/prettier_topology_check
|
|
@ -22,3 +22,4 @@ export DISABLE_BOOTSTRAP_VALIDATION=false
|
|||
.buildkite/scripts/steps/checks/test_hardening.sh
|
||||
.buildkite/scripts/steps/checks/ftr_configs.sh
|
||||
.buildkite/scripts/steps/checks/yarn_deduplicate.sh
|
||||
.buildkite/scripts/steps/checks/prettier_topology.sh
|
||||
|
|
10
scripts/prettier_topology_check.js
Normal file
10
scripts/prettier_topology_check.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
require('../src/setup_node_env');
|
||||
require('../src/dev/run_prettier_topology_check');
|
56
src/dev/run_prettier_topology_check.ts
Normal file
56
src/dev/run_prettier_topology_check.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import globby from 'globby';
|
||||
import path from 'path';
|
||||
import { REPO_ROOT } from '@kbn/repo-info';
|
||||
import { createFailError } from '@kbn/dev-cli-errors';
|
||||
import { run } from '@kbn/dev-cli-runner';
|
||||
|
||||
function listPaths(filePaths: string[]) {
|
||||
return filePaths.map((filePath: string) => ` - ${filePath}`).join('\n');
|
||||
}
|
||||
|
||||
run(async ({ log }) => {
|
||||
const filePaths = await globby('**/.prettierrc*', {
|
||||
cwd: REPO_ROOT,
|
||||
onlyFiles: true,
|
||||
gitignore: true,
|
||||
ignore: [
|
||||
// the gitignore: true option makes sure that we don't
|
||||
// include files from node_modules in the result, but it still
|
||||
// loads all of the files from node_modules before filtering
|
||||
// so it's still super slow. This prevents loading the files
|
||||
// and still relies on gitignore to final ignores
|
||||
'**/node_modules',
|
||||
],
|
||||
});
|
||||
|
||||
// const filePaths = paths.map((path) => (new File(path)).getRelativePath());
|
||||
|
||||
if (!filePaths.length) {
|
||||
throw createFailError(`A top level .prettierrc file should exist and no file was found.`);
|
||||
}
|
||||
|
||||
if (filePaths.length > 1) {
|
||||
throw createFailError(
|
||||
`Only a single .prettierrc root file should exist and more than one were found.\n${listPaths(
|
||||
filePaths
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
filePaths.length === 1 &&
|
||||
path.resolve(path.dirname(filePaths[0])) === path.resolve(REPO_ROOT)
|
||||
) {
|
||||
log.success('Only one .prettierrc file found at the root level.');
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
});
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"semi": true
|
||||
}
|
|
@ -8,9 +8,7 @@
|
|||
import t from 'io-ts';
|
||||
import { agentConfigurationIntakeRt } from './runtime_types/agent_configuration_intake_rt';
|
||||
|
||||
export type AgentConfigurationIntake = t.TypeOf<
|
||||
typeof agentConfigurationIntakeRt
|
||||
>;
|
||||
export type AgentConfigurationIntake = t.TypeOf<typeof agentConfigurationIntakeRt>;
|
||||
|
||||
export type AgentConfiguration = {
|
||||
'@timestamp': number;
|
||||
|
|
|
@ -10,22 +10,20 @@ import { settingDefinitions } from '../setting_definitions';
|
|||
import { SettingValidation } from '../setting_definitions/types';
|
||||
|
||||
// retrieve validation from config definitions settings and validate on the server
|
||||
const knownSettings = settingDefinitions.reduce<
|
||||
Record<string, SettingValidation>
|
||||
>((acc, { key, validation }) => {
|
||||
acc[key] = validation;
|
||||
return acc;
|
||||
}, {});
|
||||
const knownSettings = settingDefinitions.reduce<Record<string, SettingValidation>>(
|
||||
(acc, { key, validation }) => {
|
||||
acc[key] = validation;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
export const serviceRt = t.partial({
|
||||
name: t.string,
|
||||
environment: t.string,
|
||||
});
|
||||
|
||||
export const settingsRt = t.intersection([
|
||||
t.record(t.string, t.string),
|
||||
t.partial(knownSettings),
|
||||
]);
|
||||
export const settingsRt = t.intersection([t.record(t.string, t.string), t.partial(knownSettings)]);
|
||||
|
||||
export const agentConfigurationIntakeRt = t.intersection([
|
||||
t.partial({ agent_name: t.string }),
|
||||
|
|
|
@ -39,21 +39,14 @@ export function getBytesRt({ min, max }: { min?: string; max?: string }) {
|
|||
'bytesRt',
|
||||
t.string.is,
|
||||
(input, context) => {
|
||||
return either.chain(
|
||||
t.string.validate(input, context),
|
||||
(inputAsString) => {
|
||||
const inputAsBytes = amountAndUnitToBytes(inputAsString);
|
||||
return either.chain(t.string.validate(input, context), (inputAsString) => {
|
||||
const inputAsBytes = amountAndUnitToBytes(inputAsString);
|
||||
|
||||
const isValidAmount =
|
||||
inputAsBytes !== undefined &&
|
||||
inputAsBytes >= minAsBytes &&
|
||||
inputAsBytes <= maxAsBytes;
|
||||
const isValidAmount =
|
||||
inputAsBytes !== undefined && inputAsBytes >= minAsBytes && inputAsBytes <= maxAsBytes;
|
||||
|
||||
return isValidAmount
|
||||
? t.success(inputAsString)
|
||||
: t.failure(input, context, message);
|
||||
}
|
||||
);
|
||||
return isValidAmount ? t.success(inputAsString) : t.failure(input, context, message);
|
||||
});
|
||||
},
|
||||
t.identity
|
||||
);
|
||||
|
|
|
@ -13,19 +13,7 @@ describe('getDurationRt', () => {
|
|||
describe('must be at least 1m', () => {
|
||||
const customDurationRt = getDurationRt({ min: '1m' });
|
||||
describe('it should not accept', () => {
|
||||
[
|
||||
undefined,
|
||||
null,
|
||||
'',
|
||||
0,
|
||||
'foo',
|
||||
true,
|
||||
false,
|
||||
'0m',
|
||||
'-1m',
|
||||
'1ms',
|
||||
'1s',
|
||||
].map((input) => {
|
||||
[undefined, null, '', 0, 'foo', true, false, '0m', '-1m', '1ms', '1s'].map((input) => {
|
||||
it(`${JSON.stringify(input)}`, () => {
|
||||
expect(isRight(customDurationRt.decode(input))).toBeFalsy();
|
||||
});
|
||||
|
@ -98,13 +86,11 @@ describe('getDurationRt', () => {
|
|||
const customDurationRt = getDurationRt({ max: '1m' });
|
||||
|
||||
describe('it should not accept', () => {
|
||||
[undefined, null, '', 0, 'foo', true, false, '2m', '61s', '60001ms'].map(
|
||||
(input) => {
|
||||
it(`${JSON.stringify(input)}`, () => {
|
||||
expect(isRight(customDurationRt.decode(input))).toBeFalsy();
|
||||
});
|
||||
}
|
||||
);
|
||||
[undefined, null, '', 0, 'foo', true, false, '2m', '61s', '60001ms'].map((input) => {
|
||||
it(`${JSON.stringify(input)}`, () => {
|
||||
expect(isRight(customDurationRt.decode(input))).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('it should return correct error message', () => {
|
||||
['2m', '61s', '60001ms'].map((input) => {
|
||||
|
|
|
@ -33,22 +33,16 @@ export function getDurationRt({ min, max }: { min?: string; max?: string }) {
|
|||
'durationRt',
|
||||
t.string.is,
|
||||
(input, context) => {
|
||||
return either.chain(
|
||||
t.string.validate(input, context),
|
||||
(inputAsString) => {
|
||||
const inputAsMilliseconds =
|
||||
amountAndUnitToMilliseconds(inputAsString);
|
||||
return either.chain(t.string.validate(input, context), (inputAsString) => {
|
||||
const inputAsMilliseconds = amountAndUnitToMilliseconds(inputAsString);
|
||||
|
||||
const isValidAmount =
|
||||
inputAsMilliseconds !== undefined &&
|
||||
inputAsMilliseconds >= minAsMilliseconds &&
|
||||
inputAsMilliseconds <= maxAsMilliseconds;
|
||||
const isValidAmount =
|
||||
inputAsMilliseconds !== undefined &&
|
||||
inputAsMilliseconds >= minAsMilliseconds &&
|
||||
inputAsMilliseconds <= maxAsMilliseconds;
|
||||
|
||||
return isValidAmount
|
||||
? t.success(inputAsString)
|
||||
: t.failure(input, context, message);
|
||||
}
|
||||
);
|
||||
return isValidAmount ? t.success(inputAsString) : t.failure(input, context, message);
|
||||
});
|
||||
},
|
||||
t.identity
|
||||
);
|
||||
|
|
|
@ -14,11 +14,9 @@ export const floatRt = new t.Type<string, string, unknown>(
|
|||
(input, context) => {
|
||||
return either.chain(t.string.validate(input, context), (inputAsString) => {
|
||||
const inputAsFloat = parseFloat(inputAsString);
|
||||
const maxThreeDecimals =
|
||||
parseFloat(inputAsFloat.toFixed(3)) === inputAsFloat;
|
||||
const maxThreeDecimals = parseFloat(inputAsFloat.toFixed(3)) === inputAsFloat;
|
||||
|
||||
const isValid =
|
||||
inputAsFloat >= 0 && inputAsFloat <= 1 && maxThreeDecimals;
|
||||
const isValid = inputAsFloat >= 0 && inputAsFloat <= 1 && maxThreeDecimals;
|
||||
|
||||
return isValid
|
||||
? t.success(inputAsString)
|
||||
|
|
|
@ -19,10 +19,7 @@ function getRangeType(min?: number, max?: number) {
|
|||
}
|
||||
}
|
||||
|
||||
export function getRangeTypeMessage(
|
||||
min?: number | string,
|
||||
max?: number | string
|
||||
) {
|
||||
export function getRangeTypeMessage(min?: number | string, max?: number | string) {
|
||||
return i18n.translate('xpack.apm.agentConfig.range.errorText', {
|
||||
defaultMessage: `{rangeType, select,
|
||||
between {Must be between {min} and {max}}
|
||||
|
|
|
@ -17,13 +17,11 @@ describe('getIntegerRt', () => {
|
|||
});
|
||||
|
||||
describe('it should not accept', () => {
|
||||
[NaN, undefined, null, '', 'foo', 0, 55, '-1', '-55', '33000'].map(
|
||||
(input) => {
|
||||
it(`${JSON.stringify(input)}`, () => {
|
||||
expect(isRight(integerRt.decode(input))).toBe(false);
|
||||
});
|
||||
}
|
||||
);
|
||||
[NaN, undefined, null, '', 'foo', 0, 55, '-1', '-55', '33000'].map((input) => {
|
||||
it(`${JSON.stringify(input)}`, () => {
|
||||
expect(isRight(integerRt.decode(input))).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('it should return correct error message', () => {
|
||||
|
|
|
@ -22,16 +22,11 @@ export function getIntegerRt({
|
|||
'integerRt',
|
||||
t.string.is,
|
||||
(input, context) => {
|
||||
return either.chain(
|
||||
t.string.validate(input, context),
|
||||
(inputAsString) => {
|
||||
const inputAsInt = parseInt(inputAsString, 10);
|
||||
const isValid = inputAsInt >= min && inputAsInt <= max;
|
||||
return isValid
|
||||
? t.success(inputAsString)
|
||||
: t.failure(input, context, message);
|
||||
}
|
||||
);
|
||||
return either.chain(t.string.validate(input, context), (inputAsString) => {
|
||||
const inputAsInt = parseInt(inputAsString, 10);
|
||||
const isValid = inputAsInt >= min && inputAsInt <= max;
|
||||
return isValid ? t.success(inputAsString) : t.failure(input, context, message);
|
||||
});
|
||||
},
|
||||
t.identity
|
||||
);
|
||||
|
|
|
@ -38,34 +38,25 @@ function amountAndUnitToBytes({
|
|||
}
|
||||
|
||||
export function getStorageSizeRt({ min, max }: { min?: string; max?: string }) {
|
||||
const minAsBytes =
|
||||
amountAndUnitToBytes({ value: min, decimalUnitBase: true }) ?? -Infinity;
|
||||
const maxAsBytes =
|
||||
amountAndUnitToBytes({ value: max, decimalUnitBase: true }) ?? Infinity;
|
||||
const minAsBytes = amountAndUnitToBytes({ value: min, decimalUnitBase: true }) ?? -Infinity;
|
||||
const maxAsBytes = amountAndUnitToBytes({ value: max, decimalUnitBase: true }) ?? Infinity;
|
||||
const message = getRangeTypeMessage(min, max);
|
||||
|
||||
return new t.Type<string, string, unknown>(
|
||||
'storageSizeRt',
|
||||
t.string.is,
|
||||
(input, context) => {
|
||||
return either.chain(
|
||||
t.string.validate(input, context),
|
||||
(inputAsString) => {
|
||||
const inputAsBytes = amountAndUnitToBytes({
|
||||
value: inputAsString,
|
||||
decimalUnitBase: true,
|
||||
});
|
||||
return either.chain(t.string.validate(input, context), (inputAsString) => {
|
||||
const inputAsBytes = amountAndUnitToBytes({
|
||||
value: inputAsString,
|
||||
decimalUnitBase: true,
|
||||
});
|
||||
|
||||
const isValidAmount =
|
||||
inputAsBytes !== undefined &&
|
||||
inputAsBytes >= minAsBytes &&
|
||||
inputAsBytes <= maxAsBytes;
|
||||
const isValidAmount =
|
||||
inputAsBytes !== undefined && inputAsBytes >= minAsBytes && inputAsBytes <= maxAsBytes;
|
||||
|
||||
return isValidAmount
|
||||
? t.success(inputAsString)
|
||||
: t.failure(input, context, message);
|
||||
}
|
||||
);
|
||||
return isValidAmount ? t.success(inputAsString) : t.failure(input, context, message);
|
||||
});
|
||||
},
|
||||
t.identity
|
||||
);
|
||||
|
|
|
@ -21,13 +21,10 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.apiRequestSize.label', {
|
||||
defaultMessage: 'API Request Size',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.apiRequestSize.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'The maximum total compressed size of the request body which is sent to the APM Server intake api via a chunked encoding (HTTP streaming).\nNote that a small overshoot is possible.\n\nAllowed byte units are `b`, `kb` and `mb`. `1kb` is equal to `1024b`.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.apiRequestSize.description', {
|
||||
defaultMessage:
|
||||
'The maximum total compressed size of the request body which is sent to the APM Server intake api via a chunked encoding (HTTP streaming).\nNote that a small overshoot is possible.\n\nAllowed byte units are `b`, `kb` and `mb`. `1kb` is equal to `1024b`.',
|
||||
}),
|
||||
excludeAgents: [
|
||||
'js-base',
|
||||
'rum-js',
|
||||
|
@ -48,13 +45,10 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.apiRequestTime.label', {
|
||||
defaultMessage: 'API Request Time',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.apiRequestTime.description',
|
||||
{
|
||||
defaultMessage:
|
||||
"Maximum time to keep an HTTP request to the APM Server open for.\n\nNOTE: This value has to be lower than the APM Server's `read_timeout` setting.",
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.apiRequestTime.description', {
|
||||
defaultMessage:
|
||||
"Maximum time to keep an HTTP request to the APM Server open for.\n\nNOTE: This value has to be lower than the APM Server's `read_timeout` setting.",
|
||||
}),
|
||||
excludeAgents: [
|
||||
'js-base',
|
||||
'rum-js',
|
||||
|
@ -76,13 +70,10 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.captureBody.label', {
|
||||
defaultMessage: 'Capture body',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.captureBody.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'For transactions that are HTTP requests, the agent can optionally capture the request body (e.g. POST variables).\nFor transactions that are initiated by receiving a message from a message broker, the agent can capture the textual message body.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.captureBody.description', {
|
||||
defaultMessage:
|
||||
'For transactions that are HTTP requests, the agent can optionally capture the request body (e.g. POST variables).\nFor transactions that are initiated by receiving a message from a message broker, the agent can capture the textual message body.',
|
||||
}),
|
||||
options: [
|
||||
{ text: 'off', value: 'off' },
|
||||
{ text: 'errors', value: 'errors' },
|
||||
|
@ -95,23 +86,16 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
{
|
||||
key: 'capture_body_content_types',
|
||||
type: 'text',
|
||||
defaultValue:
|
||||
'application/x-www-form-urlencoded*, text/*, application/json*, application/xml*',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.captureBodyContentTypes.label',
|
||||
{
|
||||
defaultMessage: 'Capture Body Content Types',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.captureBodyContentTypes.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Configures which content types should be recorded.\n' +
|
||||
'\n' +
|
||||
'The defaults end with a wildcard so that content types like `text/plain; charset=utf-8` are captured as well.',
|
||||
}
|
||||
),
|
||||
defaultValue: 'application/x-www-form-urlencoded*, text/*, application/json*, application/xml*',
|
||||
label: i18n.translate('xpack.apm.agentConfig.captureBodyContentTypes.label', {
|
||||
defaultMessage: 'Capture Body Content Types',
|
||||
}),
|
||||
description: i18n.translate('xpack.apm.agentConfig.captureBodyContentTypes.description', {
|
||||
defaultMessage:
|
||||
'Configures which content types should be recorded.\n' +
|
||||
'\n' +
|
||||
'The defaults end with a wildcard so that content types like `text/plain; charset=utf-8` are captured as well.',
|
||||
}),
|
||||
includeAgents: ['java', 'dotnet'],
|
||||
},
|
||||
|
||||
|
@ -123,21 +107,11 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.captureHeaders.label', {
|
||||
defaultMessage: 'Capture Headers',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.captureHeaders.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'If set to `true`, the agent will capture HTTP request and response headers (including cookies), as well as message headers/properties when using messaging frameworks (like Kafka).\n\nNOTE: Setting this to `false` reduces network bandwidth, disk space and object allocations.',
|
||||
}
|
||||
),
|
||||
excludeAgents: [
|
||||
'js-base',
|
||||
'rum-js',
|
||||
'nodejs',
|
||||
'php',
|
||||
'android/java',
|
||||
'iOS/swift',
|
||||
],
|
||||
description: i18n.translate('xpack.apm.agentConfig.captureHeaders.description', {
|
||||
defaultMessage:
|
||||
'If set to `true`, the agent will capture HTTP request and response headers (including cookies), as well as message headers/properties when using messaging frameworks (like Kafka).\n\nNOTE: Setting this to `false` reduces network bandwidth, disk space and object allocations.',
|
||||
}),
|
||||
excludeAgents: ['js-base', 'rum-js', 'nodejs', 'php', 'android/java', 'iOS/swift'],
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -147,17 +121,14 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.dedotCustomMetrics.label', {
|
||||
defaultMessage: 'Dedot custom metrics',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.dedotCustomMetrics.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Replaces dots with underscores in the metric names for custom metrics.\n' +
|
||||
'\n' +
|
||||
'WARNING: Setting this to `false` can lead to mapping conflicts as dots indicate nesting in Elasticsearch.\n' +
|
||||
'An example of when a conflict happens is two metrics with the name `foo` and `foo.bar`.\n' +
|
||||
'The first metric maps `foo` to a number and the second metric maps `foo` as an object.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.dedotCustomMetrics.description', {
|
||||
defaultMessage:
|
||||
'Replaces dots with underscores in the metric names for custom metrics.\n' +
|
||||
'\n' +
|
||||
'WARNING: Setting this to `false` can lead to mapping conflicts as dots indicate nesting in Elasticsearch.\n' +
|
||||
'An example of when a conflict happens is two metrics with the name `foo` and `foo.bar`.\n' +
|
||||
'The first metric maps `foo` to a number and the second metric maps `foo` as an object.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -165,24 +136,18 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
key: 'disable_instrumentations',
|
||||
type: 'text',
|
||||
defaultValue: '',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.disableInstrumentations.label',
|
||||
{
|
||||
defaultMessage: 'Disable instrumentations',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.disableInstrumentations.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Comma-separated list of modules to disable instrumentation for.\n' +
|
||||
'When instrumentation is disabled for a module, no spans will be collected for that module.\n' +
|
||||
'\n' +
|
||||
'The up-to-date list of modules for which instrumentation can be disabled is language specific ' +
|
||||
'and can be found under the following links: ' +
|
||||
'[Java](https://www.elastic.co/guide/en/apm/agent/java/current/config-core.html#config-disable-instrumentations)',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.disableInstrumentations.label', {
|
||||
defaultMessage: 'Disable instrumentations',
|
||||
}),
|
||||
description: i18n.translate('xpack.apm.agentConfig.disableInstrumentations.description', {
|
||||
defaultMessage:
|
||||
'Comma-separated list of modules to disable instrumentation for.\n' +
|
||||
'When instrumentation is disabled for a module, no spans will be collected for that module.\n' +
|
||||
'\n' +
|
||||
'The up-to-date list of modules for which instrumentation can be disabled is language specific ' +
|
||||
'and can be found under the following links: ' +
|
||||
'[Java](https://www.elastic.co/guide/en/apm/agent/java/current/config-core.html#config-disable-instrumentations)',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -190,12 +155,9 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
key: 'disable_outgoing_tracecontext_headers',
|
||||
type: 'boolean',
|
||||
defaultValue: 'true',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.disableOutgoingTracecontextHeaders.label',
|
||||
{
|
||||
defaultMessage: 'Disable outgoing tracecontext headers',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.disableOutgoingTracecontextHeaders.label', {
|
||||
defaultMessage: 'Disable outgoing tracecontext headers',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.disableOutgoingTracecontextHeaders.description',
|
||||
{
|
||||
|
@ -216,15 +178,12 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.exitSpanMinDuration.label', {
|
||||
defaultMessage: 'Exit span min duration',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.exitSpanMinDuration.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Exit spans are spans that represent a call to an external service, like a database. If such calls are very short, they are usually not relevant and can be ignored.\n' +
|
||||
'\n' +
|
||||
'NOTE: If a span propagates distributed tracing ids, it will not be ignored, even if it is shorter than the configured threshold. This is to ensure that no broken traces are recorded.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.exitSpanMinDuration.description', {
|
||||
defaultMessage:
|
||||
'Exit spans are spans that represent a call to an external service, like a database. If such calls are very short, they are usually not relevant and can be ignored.\n' +
|
||||
'\n' +
|
||||
'NOTE: If a span propagates distributed tracing ids, it will not be ignored, even if it is shorter than the configured threshold. This is to ensure that no broken traces are recorded.',
|
||||
}),
|
||||
includeAgents: ['java', 'dotnet', 'nodejs', 'python'],
|
||||
},
|
||||
|
||||
|
@ -235,16 +194,13 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.ignoreMessageQueues.label', {
|
||||
defaultMessage: 'Ignore message queues',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.ignoreMessageQueues.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Used to filter out specific messaging queues/topics from being traced. \n' +
|
||||
'\n' +
|
||||
'This property should be set to an array containing one or more strings.\n' +
|
||||
'When set, sends-to and receives-from the specified queues/topic will be ignored.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.ignoreMessageQueues.description', {
|
||||
defaultMessage:
|
||||
'Used to filter out specific messaging queues/topics from being traced. \n' +
|
||||
'\n' +
|
||||
'This property should be set to an array containing one or more strings.\n' +
|
||||
'When set, sends-to and receives-from the specified queues/topic will be ignored.',
|
||||
}),
|
||||
includeAgents: ['java', 'dotnet', 'nodejs'],
|
||||
},
|
||||
|
||||
|
@ -256,15 +212,12 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.logEcsReformatting.label', {
|
||||
defaultMessage: 'Log ECS reformatting',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.logEcsReformatting.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Specifying whether and how the agent should automatically reformat application logs into ' +
|
||||
'[ECS-compatible JSON](https://www.elastic.co/guide/en/ecs-logging/overview/master/intro.html), ' +
|
||||
'suitable for ingestion into Elasticsearch for further Log analysis.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.logEcsReformatting.description', {
|
||||
defaultMessage:
|
||||
'Specifying whether and how the agent should automatically reformat application logs into ' +
|
||||
'[ECS-compatible JSON](https://www.elastic.co/guide/en/ecs-logging/overview/master/intro.html), ' +
|
||||
'suitable for ingestion into Elasticsearch for further Log analysis.',
|
||||
}),
|
||||
options: [
|
||||
{ text: 'off', value: 'off' },
|
||||
{ text: 'shade', value: 'shade' },
|
||||
|
@ -302,12 +255,9 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
key: 'mongodb_capture_statement_commands',
|
||||
type: 'boolean',
|
||||
defaultValue: 'false',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.mongodbCaptureStatementCommands.label',
|
||||
{
|
||||
defaultMessage: 'MongoDB capture statement commands',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.mongodbCaptureStatementCommands.label', {
|
||||
defaultMessage: 'MongoDB capture statement commands',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.mongodbCaptureStatementCommands.description',
|
||||
{
|
||||
|
@ -341,19 +291,13 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
key: 'context_propagation_only',
|
||||
type: 'boolean',
|
||||
defaultValue: 'false',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.context_propagation_only.label',
|
||||
{
|
||||
defaultMessage: 'Context Propagation Only',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.context_propagation_only.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'When set to true, disables log sending, metrics and trace collection. Trace context propagation and log correlation will stay active.',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.context_propagation_only.label', {
|
||||
defaultMessage: 'Context Propagation Only',
|
||||
}),
|
||||
description: i18n.translate('xpack.apm.agentConfig.context_propagation_only.description', {
|
||||
defaultMessage:
|
||||
'When set to true, disables log sending, metrics and trace collection. Trace context propagation and log correlation will stay active.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -365,13 +309,10 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.serverTimeout.label', {
|
||||
defaultMessage: 'Server Timeout',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.serverTimeout.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'If a request to the APM Server takes longer than the configured timeout,\nthe request is cancelled and the event (exception or transaction) is discarded.\nSet to 0 to disable timeouts.\n\nWARNING: If timeouts are disabled or set to a high value, your app could experience memory issues if the APM Server times out.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.serverTimeout.description', {
|
||||
defaultMessage:
|
||||
'If a request to the APM Server takes longer than the configured timeout,\nthe request is cancelled and the event (exception or transaction) is discarded.\nSet to 0 to disable timeouts.\n\nWARNING: If timeouts are disabled or set to a high value, your app could experience memory issues if the APM Server times out.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -379,20 +320,14 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
key: 'span_compression_enabled',
|
||||
type: 'boolean',
|
||||
defaultValue: 'true',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanCompressionEnabled.label',
|
||||
{
|
||||
defaultMessage: 'Span compression enabled',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanCompressionEnabled.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Setting this option to true will enable span compression feature.\n' +
|
||||
'Span compression reduces the collection, processing, and storage overhead, and removes clutter from the UI. The tradeoff is that some information such as DB statements of all the compressed spans will not be collected.',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.spanCompressionEnabled.label', {
|
||||
defaultMessage: 'Span compression enabled',
|
||||
}),
|
||||
description: i18n.translate('xpack.apm.agentConfig.spanCompressionEnabled.description', {
|
||||
defaultMessage:
|
||||
'Setting this option to true will enable span compression feature.\n' +
|
||||
'Span compression reduces the collection, processing, and storage overhead, and removes clutter from the UI. The tradeoff is that some information such as DB statements of all the compressed spans will not be collected.',
|
||||
}),
|
||||
includeAgents: ['java', 'dotnet', 'python'],
|
||||
},
|
||||
|
||||
|
@ -401,12 +336,9 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
type: 'duration',
|
||||
defaultValue: '50ms',
|
||||
min: '0ms',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanCompressionExactMatchMaxDuration.label',
|
||||
{
|
||||
defaultMessage: 'Span compression exact match max duration',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.spanCompressionExactMatchMaxDuration.label', {
|
||||
defaultMessage: 'Span compression exact match max duration',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanCompressionExactMatchMaxDuration.description',
|
||||
{
|
||||
|
@ -421,12 +353,9 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
type: 'duration',
|
||||
defaultValue: '0ms',
|
||||
min: '0ms',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanCompressionSameKindMaxDuration.label',
|
||||
{
|
||||
defaultMessage: 'Span compression same kind max duration',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.spanCompressionSameKindMaxDuration.label', {
|
||||
defaultMessage: 'Span compression same kind max duration',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanCompressionSameKindMaxDuration.description',
|
||||
{
|
||||
|
@ -446,21 +375,11 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.spanFramesMinDuration.label', {
|
||||
defaultMessage: 'Span frames minimum duration',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanFramesMinDuration.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'(Deprecated, use `span_stack_trace_min_duration` instead!) In its default settings, the APM agent will collect a stack trace with every recorded span.\nWhile this is very helpful to find the exact place in your code that causes the span, collecting this stack trace does have some overhead. \nWhen setting this option to a negative value, like `-1ms`, stack traces will be collected for all spans. Setting it to a positive value, e.g. `5ms`, will limit stack trace collection to spans with durations equal to or longer than the given value, e.g. 5 milliseconds.\n\nTo disable stack trace collection for spans completely, set the value to `0ms`.',
|
||||
}
|
||||
),
|
||||
excludeAgents: [
|
||||
'js-base',
|
||||
'rum-js',
|
||||
'nodejs',
|
||||
'php',
|
||||
'android/java',
|
||||
'iOS/swift',
|
||||
],
|
||||
description: i18n.translate('xpack.apm.agentConfig.spanFramesMinDuration.description', {
|
||||
defaultMessage:
|
||||
'(Deprecated, use `span_stack_trace_min_duration` instead!) In its default settings, the APM agent will collect a stack trace with every recorded span.\nWhile this is very helpful to find the exact place in your code that causes the span, collecting this stack trace does have some overhead. \nWhen setting this option to a negative value, like `-1ms`, stack traces will be collected for all spans. Setting it to a positive value, e.g. `5ms`, will limit stack trace collection to spans with durations equal to or longer than the given value, e.g. 5 milliseconds.\n\nTo disable stack trace collection for spans completely, set the value to `0ms`.',
|
||||
}),
|
||||
excludeAgents: ['js-base', 'rum-js', 'nodejs', 'php', 'android/java', 'iOS/swift'],
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -468,24 +387,18 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
type: 'duration',
|
||||
min: '-1ms',
|
||||
defaultValue: '5ms',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanStackTraceMinDuration.label',
|
||||
{
|
||||
defaultMessage: 'Span stack trace minimum duration',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanStackTraceMinDuration.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'While this is very helpful to find the exact place in your code that causes the span, ' +
|
||||
'collecting this stack trace does have some overhead. When setting this option to the value `0ms`, ' +
|
||||
'stack traces will be collected for all spans. Setting it to a positive value, e.g. `5ms`, will limit ' +
|
||||
'stack trace collection to spans with durations equal to or longer than the given value, e.g. 5 milliseconds.\n' +
|
||||
'\n' +
|
||||
'To disable stack trace collection for spans completely, set the value to `-1ms`.',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.spanStackTraceMinDuration.label', {
|
||||
defaultMessage: 'Span stack trace minimum duration',
|
||||
}),
|
||||
description: i18n.translate('xpack.apm.agentConfig.spanStackTraceMinDuration.description', {
|
||||
defaultMessage:
|
||||
'While this is very helpful to find the exact place in your code that causes the span, ' +
|
||||
'collecting this stack trace does have some overhead. When setting this option to the value `0ms`, ' +
|
||||
'stack traces will be collected for all spans. Setting it to a positive value, e.g. `5ms`, will limit ' +
|
||||
'stack trace collection to spans with durations equal to or longer than the given value, e.g. 5 milliseconds.\n' +
|
||||
'\n' +
|
||||
'To disable stack trace collection for spans completely, set the value to `-1ms`.',
|
||||
}),
|
||||
includeAgents: ['java', 'dotnet', 'nodejs', 'python'],
|
||||
},
|
||||
|
||||
|
@ -497,13 +410,10 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.stackTraceLimit.label', {
|
||||
defaultMessage: 'Stack trace limit',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.stackTraceLimit.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Setting it to 0 will disable stack trace collection. Any positive integer value will be used as the maximum number of frames to collect. Setting it -1 means that all frames will be collected.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.stackTraceLimit.description', {
|
||||
defaultMessage:
|
||||
'Setting it to 0 will disable stack trace collection. Any positive integer value will be used as the maximum number of frames to collect. Setting it -1 means that all frames will be collected.',
|
||||
}),
|
||||
includeAgents: ['java', 'dotnet', 'go', 'python'],
|
||||
},
|
||||
|
||||
|
@ -512,31 +422,25 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
validation: traceContinuationStrategyRt,
|
||||
type: 'select',
|
||||
defaultValue: 'continue',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.traceContinuationStrategy.label',
|
||||
{
|
||||
defaultMessage: 'Trace continuation strategy',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.traceContinuationStrategy.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'This option allows some control over how the APM agent handles W3C trace-context headers on incoming requests. By default, the `traceparent` and `tracestate` headers are used per W3C spec for distributed tracing. However, in certain cases it can be helpful to not use the incoming `traceparent` header. Some example use cases:\n' +
|
||||
'\n' +
|
||||
'* An Elastic-monitored service is receiving requests with `traceparent` headers from unmonitored services.\n' +
|
||||
'* An Elastic-monitored service is publicly exposed, and does not want tracing data (trace-ids, sampling decisions) to possibly be spoofed by user requests.\n' +
|
||||
'\n' +
|
||||
'Valid values are:\n' +
|
||||
"* 'continue': The default behavior. An incoming `traceparent` value is used to continue the trace and determine the sampling decision.\n" +
|
||||
"* 'restart': Always ignores the `traceparent` header of incoming requests. A new trace-id will be generated and the sampling decision will be made based on transaction_sample_rate. A span link will be made to the incoming `traceparent`.\n" +
|
||||
"* 'restart_external': If an incoming request includes the `es` vendor flag in `tracestate`, then any `traceparent` will be considered internal and will be handled as described for 'continue' above. Otherwise, any `traceparent` is considered external and will be handled as described for 'restart' above.\n" +
|
||||
'\n' +
|
||||
'Starting with Elastic Observability 8.2, span links are visible in trace views.\n' +
|
||||
'\n' +
|
||||
'This option is case-insensitive.',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.traceContinuationStrategy.label', {
|
||||
defaultMessage: 'Trace continuation strategy',
|
||||
}),
|
||||
description: i18n.translate('xpack.apm.agentConfig.traceContinuationStrategy.description', {
|
||||
defaultMessage:
|
||||
'This option allows some control over how the APM agent handles W3C trace-context headers on incoming requests. By default, the `traceparent` and `tracestate` headers are used per W3C spec for distributed tracing. However, in certain cases it can be helpful to not use the incoming `traceparent` header. Some example use cases:\n' +
|
||||
'\n' +
|
||||
'* An Elastic-monitored service is receiving requests with `traceparent` headers from unmonitored services.\n' +
|
||||
'* An Elastic-monitored service is publicly exposed, and does not want tracing data (trace-ids, sampling decisions) to possibly be spoofed by user requests.\n' +
|
||||
'\n' +
|
||||
'Valid values are:\n' +
|
||||
"* 'continue': The default behavior. An incoming `traceparent` value is used to continue the trace and determine the sampling decision.\n" +
|
||||
"* 'restart': Always ignores the `traceparent` header of incoming requests. A new trace-id will be generated and the sampling decision will be made based on transaction_sample_rate. A span link will be made to the incoming `traceparent`.\n" +
|
||||
"* 'restart_external': If an incoming request includes the `es` vendor flag in `tracestate`, then any `traceparent` will be considered internal and will be handled as described for 'continue' above. Otherwise, any `traceparent` is considered external and will be handled as described for 'restart' above.\n" +
|
||||
'\n' +
|
||||
'Starting with Elastic Observability 8.2, span links are visible in trace views.\n' +
|
||||
'\n' +
|
||||
'This option is case-insensitive.',
|
||||
}),
|
||||
options: [
|
||||
{ text: 'continue', value: 'continue' },
|
||||
{ text: 'restart', value: 'restart' },
|
||||
|
@ -554,13 +458,9 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.transactionMaxSpans.label', {
|
||||
defaultMessage: 'Transaction max spans',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.transactionMaxSpans.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Limits the amount of spans that are recorded per transaction.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.transactionMaxSpans.description', {
|
||||
defaultMessage: 'Limits the amount of spans that are recorded per transaction.',
|
||||
}),
|
||||
excludeAgents: ['js-base', 'rum-js', 'android/java', 'iOS/swift'],
|
||||
},
|
||||
|
||||
|
@ -572,13 +472,10 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.transactionSampleRate.label', {
|
||||
defaultMessage: 'Transaction sample rate',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.transactionSampleRate.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'By default, the agent will sample every transaction (e.g. request to your service). To reduce overhead and storage requirements, you can set the sample rate to a value between 0.0 and 1.0. We still record overall time and the result for unsampled transactions, but not context information, labels, or spans.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.transactionSampleRate.description', {
|
||||
defaultMessage:
|
||||
'By default, the agent will sample every transaction (e.g. request to your service). To reduce overhead and storage requirements, you can set the sample rate to a value between 0.0 and 1.0. We still record overall time and the result for unsampled transactions, but not context information, labels, or spans.',
|
||||
}),
|
||||
excludeAgents: ['android/java', 'iOS/swift'],
|
||||
},
|
||||
|
||||
|
@ -591,13 +488,10 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.sanitizeFiledNames.label', {
|
||||
defaultMessage: 'Sanitize field names',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.sanitizeFiledNames.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Sometimes it is necessary to sanitize, i.e., remove, sensitive data sent to Elastic APM. This config accepts a list of wildcard patterns of field names which should be sanitized. These apply to HTTP headers (including cookies) and `application/x-www-form-urlencoded` data (POST form fields). The query string and the captured request body (such as `application/json` data) will not get sanitized.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.sanitizeFiledNames.description', {
|
||||
defaultMessage:
|
||||
'Sometimes it is necessary to sanitize, i.e., remove, sensitive data sent to Elastic APM. This config accepts a list of wildcard patterns of field names which should be sanitized. These apply to HTTP headers (including cookies) and `application/x-www-form-urlencoded` data (POST form fields). The query string and the captured request body (such as `application/json` data) will not get sanitized.',
|
||||
}),
|
||||
includeAgents: ['java', 'python', 'go', 'dotnet', 'nodejs', 'ruby'],
|
||||
},
|
||||
|
||||
|
@ -610,13 +504,10 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.transactionIgnoreUrl.label', {
|
||||
defaultMessage: 'Ignore transactions based on URLs',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.transactionIgnoreUrl.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Used to restrict requests to certain URLs from being instrumented. This config accepts a comma-separated list of wildcard patterns of URL paths that should be ignored. When an incoming HTTP request is detected, its request path will be tested against each element in this list. For example, adding `/home/index` to this list would match and remove instrumentation from `http://localhost/home/index` as well as `http://whatever.com/home/index?value1=123`',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.transactionIgnoreUrl.description', {
|
||||
defaultMessage:
|
||||
'Used to restrict requests to certain URLs from being instrumented. This config accepts a comma-separated list of wildcard patterns of URL paths that should be ignored. When an incoming HTTP request is detected, its request path will be tested against each element in this list. For example, adding `/home/index` to this list would match and remove instrumentation from `http://localhost/home/index` as well as `http://whatever.com/home/index?value1=123`',
|
||||
}),
|
||||
includeAgents: ['java', 'nodejs', 'python', 'dotnet', 'ruby', 'go'],
|
||||
},
|
||||
|
||||
|
@ -624,23 +515,17 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
key: 'transaction_ignore_user_agents',
|
||||
type: 'text',
|
||||
defaultValue: '',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.transactionIgnoreUserAgents.label',
|
||||
{
|
||||
defaultMessage: 'Transaction ignore user agents',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.transactionIgnoreUserAgents.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Used to restrict requests from certain User-Agents from being instrumented.\n' +
|
||||
'\n' +
|
||||
'When an incoming HTTP request is detected,\n' +
|
||||
'the User-Agent from the request headers will be tested against each element in this list.\n' +
|
||||
'Example: `curl/*`, `*pingdom*`',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.transactionIgnoreUserAgents.label', {
|
||||
defaultMessage: 'Transaction ignore user agents',
|
||||
}),
|
||||
description: i18n.translate('xpack.apm.agentConfig.transactionIgnoreUserAgents.description', {
|
||||
defaultMessage:
|
||||
'Used to restrict requests from certain User-Agents from being instrumented.\n' +
|
||||
'\n' +
|
||||
'When an incoming HTTP request is detected,\n' +
|
||||
'the User-Agent from the request headers will be tested against each element in this list.\n' +
|
||||
'Example: `curl/*`, `*pingdom*`',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -648,25 +533,19 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
key: 'use_path_as_transaction_name',
|
||||
type: 'boolean',
|
||||
defaultValue: 'false',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.usePathAsTransactionName.label',
|
||||
{
|
||||
defaultMessage: 'Use path as transaction name',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.usePathAsTransactionName.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'If set to `true`,\n' +
|
||||
'transaction names of unsupported or partially-supported frameworks will be in the form of `$method $path` instead of just `$method unknown route`.\n' +
|
||||
'\n' +
|
||||
'WARNING: If your URLs contain path parameters like `/user/$userId`,\n' +
|
||||
'you should be very careful when enabling this flag,\n' +
|
||||
'as it can lead to an explosion of transaction groups.\n' +
|
||||
'Take a look at the `transaction_name_groups` option on how to mitigate this problem by grouping URLs together.',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.usePathAsTransactionName.label', {
|
||||
defaultMessage: 'Use path as transaction name',
|
||||
}),
|
||||
description: i18n.translate('xpack.apm.agentConfig.usePathAsTransactionName.description', {
|
||||
defaultMessage:
|
||||
'If set to `true`,\n' +
|
||||
'transaction names of unsupported or partially-supported frameworks will be in the form of `$method $path` instead of just `$method unknown route`.\n' +
|
||||
'\n' +
|
||||
'WARNING: If your URLs contain path parameters like `/user/$userId`,\n' +
|
||||
'you should be very careful when enabling this flag,\n' +
|
||||
'as it can lead to an explosion of transaction groups.\n' +
|
||||
'Take a look at the `transaction_name_groups` option on how to mitigate this problem by grouping URLs together.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -677,18 +556,15 @@ export const generalSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.transactionNameGroups.label', {
|
||||
defaultMessage: 'Transaction name groups',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.transactionNameGroups.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'With this option,\n' +
|
||||
'you can group transaction names that contain dynamic parts with a wildcard expression.\n' +
|
||||
'For example,\n' +
|
||||
'the pattern `GET /user/*/cart` would consolidate transactions,\n' +
|
||||
'such as `GET /users/42/cart` and `GET /users/73/cart` into a single transaction name `GET /users/*/cart`,\n' +
|
||||
'hence reducing the transaction name cardinality.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.transactionNameGroups.description', {
|
||||
defaultMessage:
|
||||
'With this option,\n' +
|
||||
'you can group transaction names that contain dynamic parts with a wildcard expression.\n' +
|
||||
'For example,\n' +
|
||||
'the pattern `GET /user/*/cart` would consolidate transactions,\n' +
|
||||
'such as `GET /users/42/cart` and `GET /users/73/cart` into a single transaction name `GET /users/*/cart`,\n' +
|
||||
'hence reducing the transaction name cardinality.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
];
|
||||
|
|
|
@ -182,25 +182,16 @@ describe('filterByAgent', () => {
|
|||
});
|
||||
|
||||
it('android/java', () => {
|
||||
expect(getSettingKeysForAgent('android/java')).toEqual([
|
||||
'recording',
|
||||
'session_sample_rate',
|
||||
]);
|
||||
expect(getSettingKeysForAgent('android/java')).toEqual(['recording', 'session_sample_rate']);
|
||||
});
|
||||
|
||||
it('iOS/swift', () => {
|
||||
expect(getSettingKeysForAgent('iOS/swift')).toEqual([
|
||||
'recording',
|
||||
'session_sample_rate',
|
||||
]);
|
||||
expect(getSettingKeysForAgent('iOS/swift')).toEqual(['recording', 'session_sample_rate']);
|
||||
});
|
||||
|
||||
it('"All" services (no agent name)', () => {
|
||||
expect(getSettingKeysForAgent(undefined)).toEqual(
|
||||
expect.arrayContaining([
|
||||
'transaction_max_spans',
|
||||
'transaction_sample_rate',
|
||||
])
|
||||
expect.arrayContaining(['transaction_max_spans', 'transaction_sample_rate'])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -132,8 +132,6 @@ export function validateSetting(setting: SettingDefinition, value: unknown) {
|
|||
}
|
||||
|
||||
export const settingDefinitions: SettingDefinition[] = sortBy(
|
||||
[...generalSettings, ...javaSettings, ...mobileSettings].map(
|
||||
getSettingDefaults
|
||||
),
|
||||
[...generalSettings, ...javaSettings, ...mobileSettings].map(getSettingDefaults),
|
||||
'key'
|
||||
);
|
||||
|
|
|
@ -16,18 +16,15 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.applicationPackages.label', {
|
||||
defaultMessage: 'Application packages',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.applicationPackages.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Used to determine whether a stack trace frame is an in-app frame or a library frame. ' +
|
||||
'This allows the APM app to collapse the stack frames of library code, and highlight the stack frames that originate from your application. ' +
|
||||
'Multiple root packages can be set as a comma-separated list; there’s no need to configure sub-packages. ' +
|
||||
'Because this setting helps determine which classes to scan on startup, setting this option can also improve startup time.\n' +
|
||||
'\n' +
|
||||
'You must set this option in order to use the API annotations `@CaptureTransaction` and `@CaptureSpan`.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.applicationPackages.description', {
|
||||
defaultMessage:
|
||||
'Used to determine whether a stack trace frame is an in-app frame or a library frame. ' +
|
||||
'This allows the APM app to collapse the stack frames of library code, and highlight the stack frames that originate from your application. ' +
|
||||
'Multiple root packages can be set as a comma-separated list; there’s no need to configure sub-packages. ' +
|
||||
'Because this setting helps determine which classes to scan on startup, setting this option can also improve startup time.\n' +
|
||||
'\n' +
|
||||
'You must set this option in order to use the API annotations `@CaptureTransaction` and `@CaptureSpan`.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -39,13 +36,10 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.enableLogCorrelation.label', {
|
||||
defaultMessage: 'Enable log correlation',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.enableLogCorrelation.description',
|
||||
{
|
||||
defaultMessage:
|
||||
"A boolean specifying if the agent should integrate into SLF4J's MDC to enable trace-log correlation. If set to `true`, the agent will set the `trace.id` and `transaction.id` for the currently active spans and transactions to the MDC. Since Java agent version 1.16.0, the agent also adds `error.id` of captured error to the MDC just before the error message is logged. NOTE: While it's allowed to enable this setting at runtime, you can't disable it without a restart.",
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.enableLogCorrelation.description', {
|
||||
defaultMessage:
|
||||
"A boolean specifying if the agent should integrate into SLF4J's MDC to enable trace-log correlation. If set to `true`, the agent will set the `trace.id` and `transaction.id` for the currently active spans and transactions to the MDC. Since Java agent version 1.16.0, the agent also adds `error.id` of captured error to the MDC just before the error message is logged. NOTE: While it's allowed to enable this setting at runtime, you can't disable it without a restart.",
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -60,13 +54,10 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
type: 'boolean',
|
||||
category: 'Circuit-Breaker',
|
||||
defaultValue: 'false',
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.circuitBreakerEnabled.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A boolean specifying whether the circuit breaker should be enabled or not. When enabled, the agent periodically polls stress monitors to detect system/process/JVM stress state. If ANY of the monitors detects a stress indication, the agent will pause, as if the `recording` configuration option has been set to `false`, thus reducing resource consumption to a minimum. When paused, the agent continues polling the same monitors in order to detect whether the stress state has been relieved. If ALL monitors approve that the system/process/JVM is not under stress anymore, the agent will resume and become fully functional.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.circuitBreakerEnabled.description', {
|
||||
defaultMessage:
|
||||
'A boolean specifying whether the circuit breaker should be enabled or not. When enabled, the agent periodically polls stress monitors to detect system/process/JVM stress state. If ANY of the monitors detects a stress indication, the agent will pause, as if the `recording` configuration option has been set to `false`, thus reducing resource consumption to a minimum. When paused, the agent continues polling the same monitors in order to detect whether the stress state has been relieved. If ALL monitors approve that the system/process/JVM is not under stress anymore, the agent will resume and become fully functional.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -74,12 +65,9 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
key: 'enable_experimental_instrumentations',
|
||||
type: 'boolean',
|
||||
defaultValue: 'false',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.enableExperimentalInstrumentations.label',
|
||||
{
|
||||
defaultMessage: 'Enable experimental instrumentations',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.enableExperimentalInstrumentations.label', {
|
||||
defaultMessage: 'Enable experimental instrumentations',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.enableExperimentalInstrumentations.description',
|
||||
{
|
||||
|
@ -97,26 +85,20 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
key: 'enable_instrumentations',
|
||||
type: 'text',
|
||||
defaultValue: '',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.enableInstrumentations.label',
|
||||
{
|
||||
defaultMessage: 'Disable instrumentations',
|
||||
}
|
||||
),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.enableInstrumentations.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A list of instrumentations which should be selectively enabled. ' +
|
||||
'Valid options are listed in the ' +
|
||||
'[Java APM Agent documentation](https://www.elastic.co/guide/en/apm/agent/java/current/config-core.html#config-disable-instrumentations).\n' +
|
||||
'\n' +
|
||||
'When set to non-empty value, only listed instrumentations will be enabled ' +
|
||||
'if they are not disabled through `disable_instrumentations`or `enable_experimental_instrumentations`.\n' +
|
||||
'When not set or empty (default), all instrumentations enabled by default will be enabled ' +
|
||||
'unless they are disabled through `disable_instrumentations` or `enable_experimental_instrumentations`.',
|
||||
}
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.enableInstrumentations.label', {
|
||||
defaultMessage: 'Disable instrumentations',
|
||||
}),
|
||||
description: i18n.translate('xpack.apm.agentConfig.enableInstrumentations.description', {
|
||||
defaultMessage:
|
||||
'A list of instrumentations which should be selectively enabled. ' +
|
||||
'Valid options are listed in the ' +
|
||||
'[Java APM Agent documentation](https://www.elastic.co/guide/en/apm/agent/java/current/config-core.html#config-disable-instrumentations).\n' +
|
||||
'\n' +
|
||||
'When set to non-empty value, only listed instrumentations will be enabled ' +
|
||||
'if they are not disabled through `disable_instrumentations`or `enable_experimental_instrumentations`.\n' +
|
||||
'When not set or empty (default), all instrumentations enabled by default will be enabled ' +
|
||||
'unless they are disabled through `disable_instrumentations` or `enable_experimental_instrumentations`.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -127,16 +109,13 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.logSending.label', {
|
||||
defaultMessage: 'Log sending (experimental)',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.logSending.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Experimental, requires latest version of the Java agent.\n' +
|
||||
'\n' +
|
||||
'If set to `true`,\n' +
|
||||
'agent will send logs directly to APM server.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.logSending.description', {
|
||||
defaultMessage:
|
||||
'Experimental, requires latest version of the Java agent.\n' +
|
||||
'\n' +
|
||||
'If set to `true`,\n' +
|
||||
'agent will send logs directly to APM server.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -148,28 +127,24 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.spanMinDuration.label', {
|
||||
defaultMessage: 'Span minimum duration',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.spanMinDuration.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Sets the minimum duration of spans. Spans that execute faster than this threshold are attempted to be discarded.\n' +
|
||||
'\n' +
|
||||
'The attempt fails if they lead up to a span that can’t be discarded. Spans that propagate the trace context to ' +
|
||||
'downstream services, such as outgoing HTTP requests, can’t be discarded. Additionally, spans that lead to an error ' +
|
||||
'or that may be a parent of an async operation can’t be discarded.\n' +
|
||||
'\n' +
|
||||
'However, external calls that don’t propagate context, such as calls to a database, can be discarded using this threshold.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.spanMinDuration.description', {
|
||||
defaultMessage:
|
||||
'Sets the minimum duration of spans. Spans that execute faster than this threshold are attempted to be discarded.\n' +
|
||||
'\n' +
|
||||
'The attempt fails if they lead up to a span that can’t be discarded. Spans that propagate the trace context to ' +
|
||||
'downstream services, such as outgoing HTTP requests, can’t be discarded. Additionally, spans that lead to an error ' +
|
||||
'or that may be a parent of an async operation can’t be discarded.\n' +
|
||||
'\n' +
|
||||
'However, external calls that don’t propagate context, such as calls to a database, can be discarded using this threshold.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
{
|
||||
key: 'stress_monitor_gc_stress_threshold',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.stressMonitorGcStressThreshold.label',
|
||||
{ defaultMessage: 'Stress monitor gc stress threshold' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.stressMonitorGcStressThreshold.label', {
|
||||
defaultMessage: 'Stress monitor gc stress threshold',
|
||||
}),
|
||||
type: 'float',
|
||||
category: 'Circuit-Breaker',
|
||||
defaultValue: '0.95',
|
||||
|
@ -184,10 +159,9 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
},
|
||||
{
|
||||
key: 'stress_monitor_gc_relief_threshold',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.stressMonitorGcReliefThreshold.label',
|
||||
{ defaultMessage: 'Stress monitor gc relief threshold' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.stressMonitorGcReliefThreshold.label', {
|
||||
defaultMessage: 'Stress monitor gc relief threshold',
|
||||
}),
|
||||
|
||||
type: 'float',
|
||||
category: 'Circuit-Breaker',
|
||||
|
@ -203,10 +177,9 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
},
|
||||
{
|
||||
key: 'stress_monitor_cpu_duration_threshold',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.stressMonitorCpuDurationThreshold.label',
|
||||
{ defaultMessage: 'Stress monitor cpu duration threshold' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.stressMonitorCpuDurationThreshold.label', {
|
||||
defaultMessage: 'Stress monitor cpu duration threshold',
|
||||
}),
|
||||
type: 'duration',
|
||||
category: 'Circuit-Breaker',
|
||||
defaultValue: '1m',
|
||||
|
@ -222,10 +195,9 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
},
|
||||
{
|
||||
key: 'stress_monitor_system_cpu_stress_threshold',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.stressMonitorSystemCpuStressThreshold.label',
|
||||
{ defaultMessage: 'Stress monitor system cpu stress threshold' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.stressMonitorSystemCpuStressThreshold.label', {
|
||||
defaultMessage: 'Stress monitor system cpu stress threshold',
|
||||
}),
|
||||
type: 'float',
|
||||
category: 'Circuit-Breaker',
|
||||
defaultValue: '0.95',
|
||||
|
@ -240,10 +212,9 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
},
|
||||
{
|
||||
key: 'stress_monitor_system_cpu_relief_threshold',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.stressMonitorSystemCpuReliefThreshold.label',
|
||||
{ defaultMessage: 'Stress monitor system cpu relief threshold' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.stressMonitorSystemCpuReliefThreshold.label', {
|
||||
defaultMessage: 'Stress monitor system cpu relief threshold',
|
||||
}),
|
||||
type: 'float',
|
||||
category: 'Circuit-Breaker',
|
||||
defaultValue: '0.8',
|
||||
|
@ -263,28 +234,23 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
|
||||
{
|
||||
key: 'profiling_inferred_spans_enabled',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.profilingInferredSpansEnabled.label',
|
||||
{ defaultMessage: 'Profiling inferred spans enabled' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.profilingInferredSpansEnabled.label', {
|
||||
defaultMessage: 'Profiling inferred spans enabled',
|
||||
}),
|
||||
type: 'boolean',
|
||||
category: 'Profiling',
|
||||
defaultValue: 'false',
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.profilingInferredSpansEnabled.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Set to `true` to make the agent create spans for method executions based on async-profiler, a sampling aka statistical profiler. Due to the nature of how sampling profilers work, the duration of the inferred spans are not exact, but only estimations. The `profiling_inferred_spans_sampling_interval` lets you fine tune the trade-off between accuracy and overhead. The inferred spans are created after a profiling session has ended. This means there is a delay between the regular and the inferred spans being visible in the UI. NOTE: This feature is not available on Windows.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.profilingInferredSpansEnabled.description', {
|
||||
defaultMessage:
|
||||
'Set to `true` to make the agent create spans for method executions based on async-profiler, a sampling aka statistical profiler. Due to the nature of how sampling profilers work, the duration of the inferred spans are not exact, but only estimations. The `profiling_inferred_spans_sampling_interval` lets you fine tune the trade-off between accuracy and overhead. The inferred spans are created after a profiling session has ended. This means there is a delay between the regular and the inferred spans being visible in the UI. NOTE: This feature is not available on Windows.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
{
|
||||
key: 'profiling_inferred_spans_sampling_interval',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.profilingInferredSpansSamplingInterval.label',
|
||||
{ defaultMessage: 'Profiling inferred spans sampling interval' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.profilingInferredSpansSamplingInterval.label', {
|
||||
defaultMessage: 'Profiling inferred spans sampling interval',
|
||||
}),
|
||||
type: 'duration',
|
||||
category: 'Profiling',
|
||||
defaultValue: '50ms',
|
||||
|
@ -301,10 +267,9 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
},
|
||||
{
|
||||
key: 'profiling_inferred_spans_min_duration',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.profilingInferredSpansMinDuration.label',
|
||||
{ defaultMessage: 'Profiling inferred spans min duration' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.profilingInferredSpansMinDuration.label', {
|
||||
defaultMessage: 'Profiling inferred spans min duration',
|
||||
}),
|
||||
type: 'duration',
|
||||
category: 'Profiling',
|
||||
defaultValue: '0ms',
|
||||
|
@ -320,10 +285,9 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
},
|
||||
{
|
||||
key: 'profiling_inferred_spans_included_classes',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.profilingInferredSpansIncludedClasses.label',
|
||||
{ defaultMessage: 'Profiling inferred spans included classes' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.profilingInferredSpansIncludedClasses.label', {
|
||||
defaultMessage: 'Profiling inferred spans included classes',
|
||||
}),
|
||||
type: 'text',
|
||||
category: 'Profiling',
|
||||
defaultValue: '*',
|
||||
|
@ -338,10 +302,9 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
},
|
||||
{
|
||||
key: 'profiling_inferred_spans_excluded_classes',
|
||||
label: i18n.translate(
|
||||
'xpack.apm.agentConfig.profilingInferredSpansExcludedClasses.label',
|
||||
{ defaultMessage: 'Profiling inferred spans excluded classes' }
|
||||
),
|
||||
label: i18n.translate('xpack.apm.agentConfig.profilingInferredSpansExcludedClasses.label', {
|
||||
defaultMessage: 'Profiling inferred spans excluded classes',
|
||||
}),
|
||||
type: 'text',
|
||||
category: 'Profiling',
|
||||
defaultValue:
|
||||
|
@ -363,19 +326,16 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.captureJmxMetrics.label', {
|
||||
defaultMessage: 'Capture JMX metrics',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.captureJmxMetrics.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Report metrics from JMX to the APM Server\n' +
|
||||
'\n' +
|
||||
'Can contain multiple comma separated JMX metric definitions:\n' +
|
||||
'\n' +
|
||||
'`object_name[<JMX object name pattern>] attribute[<JMX attribute>:metric_name=<optional metric name>]`\n' +
|
||||
'\n' +
|
||||
'See the Java agent documentation for more details.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.captureJmxMetrics.description', {
|
||||
defaultMessage:
|
||||
'Report metrics from JMX to the APM Server\n' +
|
||||
'\n' +
|
||||
'Can contain multiple comma separated JMX metric definitions:\n' +
|
||||
'\n' +
|
||||
'`object_name[<JMX object name pattern>] attribute[<JMX attribute>:metric_name=<optional metric name>]`\n' +
|
||||
'\n' +
|
||||
'See the Java agent documentation for more details.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -386,14 +346,11 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.ignoreExceptions.label', {
|
||||
defaultMessage: 'Ignore exceptions',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.ignoreExceptions.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A list of exceptions that should be ignored and not reported as errors.\n' +
|
||||
'This allows to ignore exceptions thrown in regular control flow that are not actual errors.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.ignoreExceptions.description', {
|
||||
defaultMessage:
|
||||
'A list of exceptions that should be ignored and not reported as errors.\n' +
|
||||
'This allows to ignore exceptions thrown in regular control flow that are not actual errors.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -404,26 +361,23 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.traceMethods.label', {
|
||||
defaultMessage: 'Trace methods',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.traceMethods.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A list of methods for which to create a transaction or span.\n' +
|
||||
'\n' +
|
||||
'If you want to monitor a large number of methods,\n' +
|
||||
'use `profiling_inferred_spans_enabled`.\n' +
|
||||
'\n' +
|
||||
'This works by instrumenting each matching method to include code that creates a span for the method.\n' +
|
||||
'While creating a span is quite cheap in terms of performance,\n' +
|
||||
'instrumenting a whole code base or a method which is executed in a tight loop leads to significant overhead.\n' +
|
||||
'\n' +
|
||||
'NOTE: Only use wildcards if necessary.\n' +
|
||||
'The more methods you match the more overhead will be caused by the agent.\n' +
|
||||
'Also note that there is a maximum amount of spans per transaction `transaction_max_spans`.\n' +
|
||||
'\n' +
|
||||
'See the Java agent documentation for more details.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.traceMethods.description', {
|
||||
defaultMessage:
|
||||
'A list of methods for which to create a transaction or span.\n' +
|
||||
'\n' +
|
||||
'If you want to monitor a large number of methods,\n' +
|
||||
'use `profiling_inferred_spans_enabled`.\n' +
|
||||
'\n' +
|
||||
'This works by instrumenting each matching method to include code that creates a span for the method.\n' +
|
||||
'While creating a span is quite cheap in terms of performance,\n' +
|
||||
'instrumenting a whole code base or a method which is executed in a tight loop leads to significant overhead.\n' +
|
||||
'\n' +
|
||||
'NOTE: Only use wildcards if necessary.\n' +
|
||||
'The more methods you match the more overhead will be caused by the agent.\n' +
|
||||
'Also note that there is a maximum amount of spans per transaction `transaction_max_spans`.\n' +
|
||||
'\n' +
|
||||
'See the Java agent documentation for more details.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
|
||||
|
@ -434,16 +388,13 @@ export const javaSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.unnestExceptions.label', {
|
||||
defaultMessage: 'Unnest exceptions',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.unnestExceptions.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'When reporting exceptions,\n' +
|
||||
'un-nests the exceptions matching the wildcard pattern.\n' +
|
||||
"This can come in handy for Spring's `org.springframework.web.util.NestedServletException`,\n" +
|
||||
'for example.',
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.unnestExceptions.description', {
|
||||
defaultMessage:
|
||||
'When reporting exceptions,\n' +
|
||||
'un-nests the exceptions matching the wildcard pattern.\n' +
|
||||
"This can come in handy for Spring's `org.springframework.web.util.NestedServletException`,\n" +
|
||||
'for example.',
|
||||
}),
|
||||
includeAgents: ['java'],
|
||||
},
|
||||
];
|
||||
|
|
|
@ -17,13 +17,10 @@ export const mobileSettings: RawSettingDefinition[] = [
|
|||
label: i18n.translate('xpack.apm.agentConfig.sessionSampleRate.label', {
|
||||
defaultMessage: 'Session sample rate',
|
||||
}),
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentConfig.sessionSampleRate.description',
|
||||
{
|
||||
defaultMessage:
|
||||
"By default, the agent will sample all signals generated by your application (e.g. spans, metrics, & logs). To reduce overhead and storage requirements, you can set the sample rate to a value between 0.0 and 1.0. When reduced below 1.0, data will be sampled per session. This is so context in a given session isn't lost.",
|
||||
}
|
||||
),
|
||||
description: i18n.translate('xpack.apm.agentConfig.sessionSampleRate.description', {
|
||||
defaultMessage:
|
||||
"By default, the agent will sample all signals generated by your application (e.g. spans, metrics, & logs). To reduce overhead and storage requirements, you can set the sample rate to a value between 0.0 and 1.0. When reduced below 1.0, data will be sampled per session. This is so context in a given session isn't lost.",
|
||||
}),
|
||||
includeAgents: ['iOS/swift', 'android/java'],
|
||||
},
|
||||
];
|
||||
|
|
|
@ -20,9 +20,7 @@ export function getPreferredServiceAnomalyTimeseries({
|
|||
allAnomalyTimeseries: ServiceAnomalyTimeseries[];
|
||||
fallbackToTransactions: boolean;
|
||||
}) {
|
||||
const seriesForType = allAnomalyTimeseries.filter(
|
||||
(serie) => serie.type === detectorType
|
||||
);
|
||||
const seriesForType = allAnomalyTimeseries.filter((serie) => serie.type === detectorType);
|
||||
|
||||
return seriesForType.find(
|
||||
(serie) =>
|
||||
|
|
|
@ -32,12 +32,9 @@ export function getSeverityColor(score: number) {
|
|||
}
|
||||
|
||||
export const ML_ERRORS = {
|
||||
INVALID_LICENSE: i18n.translate(
|
||||
'xpack.apm.anomaly_detection.error.invalid_license',
|
||||
{
|
||||
defaultMessage: `To use anomaly detection, you must be subscribed to an Elastic Platinum license. With it, you'll be able to monitor your services with the aid of machine learning.`,
|
||||
}
|
||||
),
|
||||
INVALID_LICENSE: i18n.translate('xpack.apm.anomaly_detection.error.invalid_license', {
|
||||
defaultMessage: `To use anomaly detection, you must be subscribed to an Elastic Platinum license. With it, you'll be able to monitor your services with the aid of machine learning.`,
|
||||
}),
|
||||
MISSING_READ_PRIVILEGES: i18n.translate(
|
||||
'xpack.apm.anomaly_detection.error.missing_read_privileges',
|
||||
{
|
||||
|
@ -52,12 +49,9 @@ export const ML_ERRORS = {
|
|||
'You must have "write" privileges to Machine Learning and APM in order to create Anomaly Detection jobs',
|
||||
}
|
||||
),
|
||||
ML_NOT_AVAILABLE: i18n.translate(
|
||||
'xpack.apm.anomaly_detection.error.not_available',
|
||||
{
|
||||
defaultMessage: 'Machine learning is not available',
|
||||
}
|
||||
),
|
||||
ML_NOT_AVAILABLE: i18n.translate('xpack.apm.anomaly_detection.error.not_available', {
|
||||
defaultMessage: 'Machine learning is not available',
|
||||
}),
|
||||
ML_NOT_AVAILABLE_IN_SPACE: i18n.translate(
|
||||
'xpack.apm.anomaly_detection.error.not_available_in_space',
|
||||
{
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
|
||||
type Method = 'get' | 'post' | 'put' | 'delete';
|
||||
|
||||
export function parseEndpoint(
|
||||
endpoint: string,
|
||||
pathParams: Record<string, any> = {}
|
||||
) {
|
||||
export function parseEndpoint(endpoint: string, pathParams: Record<string, any> = {}) {
|
||||
const [method, rawPathname] = endpoint.split(' ');
|
||||
|
||||
// replace template variables with path params
|
||||
|
|
|
@ -60,9 +60,9 @@ export type ApmFeatureFlags = {
|
|||
[TApmFeatureFlagName in keyof ApmFeatureFlagMap]: ValueOfApmFeatureFlag<TApmFeatureFlagName>;
|
||||
};
|
||||
|
||||
export type ValueOfApmFeatureFlag<
|
||||
TApmFeatureFlagName extends ApmFeatureFlagName
|
||||
> = t.OutputOf<ApmFeatureFlagMap[TApmFeatureFlagName]['type']>;
|
||||
export type ValueOfApmFeatureFlag<TApmFeatureFlagName extends ApmFeatureFlagName> = t.OutputOf<
|
||||
ApmFeatureFlagMap[TApmFeatureFlagName]['type']
|
||||
>;
|
||||
|
||||
export function getApmFeatureFlags(): ApmFeatureFlags {
|
||||
return mapValues(apmFeatureFlagMap, (value, key) => value.default);
|
||||
|
|
|
@ -5,10 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
getApmTelemetryMapping,
|
||||
mergeApmTelemetryMapping,
|
||||
} from './apm_telemetry';
|
||||
import { getApmTelemetryMapping, mergeApmTelemetryMapping } from './apm_telemetry';
|
||||
|
||||
// Add this snapshot serializer for this test. The default snapshot serializer
|
||||
// prints "Object" next to objects in the JSON output, but we want to be able to
|
||||
|
@ -80,8 +77,8 @@ describe('APM telemetry helpers', () => {
|
|||
};
|
||||
|
||||
expect(
|
||||
mergeApmTelemetryMapping(validTelemetryMapping)?.mappings.properties
|
||||
.stack_stats.properties.kibana.properties.plugins.properties.apm
|
||||
mergeApmTelemetryMapping(validTelemetryMapping)?.mappings.properties.stack_stats
|
||||
.properties.kibana.properties.plugins.properties.apm
|
||||
).toEqual(getApmTelemetryMapping());
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,10 +21,7 @@ function schemaToMapping(schemaLeaf: any): any {
|
|||
|
||||
return Object.entries<any>(schemaLeaf).reduce((acc, [key, value]) => {
|
||||
const propMapping = schemaToMapping(value);
|
||||
acc[key] =
|
||||
typeof propMapping.type === 'string'
|
||||
? propMapping
|
||||
: { properties: propMapping };
|
||||
acc[key] = typeof propMapping.type === 'string' ? propMapping : { properties: propMapping };
|
||||
|
||||
return acc;
|
||||
}, {} as Record<string, unknown>);
|
||||
|
@ -43,9 +40,7 @@ export function getApmTelemetryMapping() {
|
|||
* Merge a telemetry mapping object (from https://github.com/elastic/telemetry/blob/master/config/templates/xpack-phone-home.json)
|
||||
* with the output from `getApmTelemetryMapping`.
|
||||
*/
|
||||
export function mergeApmTelemetryMapping(
|
||||
xpackPhoneHomeMapping: Record<string, any>
|
||||
) {
|
||||
export function mergeApmTelemetryMapping(xpackPhoneHomeMapping: Record<string, any>) {
|
||||
return produce(xpackPhoneHomeMapping, (draft: Record<string, any>) => {
|
||||
draft.mappings.properties.stack_stats.properties.kibana.properties.plugins.properties.apm =
|
||||
getApmTelemetryMapping();
|
||||
|
|
|
@ -70,7 +70,5 @@ export interface ConnectionStatsItemWithComparisonData {
|
|||
}
|
||||
|
||||
export function getNodeName(node: Node) {
|
||||
return node.type === NodeType.service
|
||||
? node.serviceName
|
||||
: node.dependencyName;
|
||||
return node.type === NodeType.service ? node.serviceName : node.dependencyName;
|
||||
}
|
||||
|
|
|
@ -62,11 +62,7 @@ export const FIELDS_TO_ADD_AS_CANDIDATE = new Set([
|
|||
'process.args',
|
||||
'http.response.status_code',
|
||||
]);
|
||||
export const FIELD_PREFIX_TO_ADD_AS_CANDIDATE = [
|
||||
'cloud.',
|
||||
'labels.',
|
||||
'user_agent.',
|
||||
];
|
||||
export const FIELD_PREFIX_TO_ADD_AS_CANDIDATE = ['cloud.', 'labels.', 'user_agent.'];
|
||||
|
||||
/**
|
||||
* Other constants
|
||||
|
|
|
@ -14,8 +14,7 @@ describe('correlations', () => {
|
|||
{ fieldName: 'the-field-1', fieldValue: 'the-value-1' },
|
||||
{ fieldName: 'the-field-2', fieldValue: 'the-value-2' },
|
||||
];
|
||||
const prioritziedFieldValuePairs =
|
||||
getPrioritizedFieldValuePairs(fieldValuePairs);
|
||||
const prioritziedFieldValuePairs = getPrioritizedFieldValuePairs(fieldValuePairs);
|
||||
expect(prioritziedFieldValuePairs.map((d) => d.fieldName)).toEqual([
|
||||
'the-field-1',
|
||||
'the-field-2',
|
||||
|
@ -27,8 +26,7 @@ describe('correlations', () => {
|
|||
{ fieldName: 'service.version', fieldValue: 'the-value-1' },
|
||||
{ fieldName: 'the-field-2', fieldValue: 'the-value-2' },
|
||||
];
|
||||
const prioritziedFieldValuePairs =
|
||||
getPrioritizedFieldValuePairs(fieldValuePairs);
|
||||
const prioritziedFieldValuePairs = getPrioritizedFieldValuePairs(fieldValuePairs);
|
||||
expect(prioritziedFieldValuePairs.map((d) => d.fieldName)).toEqual([
|
||||
'service.version',
|
||||
'the-field-2',
|
||||
|
@ -40,8 +38,7 @@ describe('correlations', () => {
|
|||
{ fieldName: 'the-field-1', fieldValue: 'the-value-1' },
|
||||
{ fieldName: 'service.version', fieldValue: 'the-value-2' },
|
||||
];
|
||||
const prioritziedFieldValuePairs =
|
||||
getPrioritizedFieldValuePairs(fieldValuePairs);
|
||||
const prioritziedFieldValuePairs = getPrioritizedFieldValuePairs(fieldValuePairs);
|
||||
expect(prioritziedFieldValuePairs.map((d) => d.fieldName)).toEqual([
|
||||
'service.version',
|
||||
'the-field-1',
|
||||
|
@ -54,8 +51,7 @@ describe('correlations', () => {
|
|||
{ fieldName: 'service.version', fieldValue: 'the-value-2' },
|
||||
{ fieldName: 'cloud.the-field-3', fieldValue: 'the-value-3' },
|
||||
];
|
||||
const prioritziedFieldValuePairs =
|
||||
getPrioritizedFieldValuePairs(fieldValuePairs);
|
||||
const prioritziedFieldValuePairs = getPrioritizedFieldValuePairs(fieldValuePairs);
|
||||
expect(prioritziedFieldValuePairs.map((d) => d.fieldName)).toEqual([
|
||||
'service.version',
|
||||
'cloud.the-field-3',
|
||||
|
|
|
@ -10,9 +10,7 @@ import { hasPrefixToInclude } from './has_prefix_to_include';
|
|||
|
||||
import type { FieldValuePair } from '../types';
|
||||
|
||||
export const getPrioritizedFieldValuePairs = (
|
||||
fieldValuePairs: FieldValuePair[]
|
||||
) => {
|
||||
export const getPrioritizedFieldValuePairs = (fieldValuePairs: FieldValuePair[]) => {
|
||||
const prioritizedFields = [...FIELDS_TO_ADD_AS_CANDIDATE];
|
||||
|
||||
return fieldValuePairs.sort((a, b) => {
|
||||
|
|
|
@ -18,9 +18,7 @@ describe('aggregation utils', () => {
|
|||
});
|
||||
it('returns false if the prefix is included', async () => {
|
||||
FIELD_PREFIX_TO_ADD_AS_CANDIDATE.forEach((prefix) => {
|
||||
expect(
|
||||
hasPrefixToInclude(`unknown-prefix-.${prefix}the-field-name`)
|
||||
).toBe(false);
|
||||
expect(hasPrefixToInclude(`unknown-prefix-.${prefix}the-field-name`)).toBe(false);
|
||||
expect(hasPrefixToInclude('the-field-name')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,7 +8,5 @@
|
|||
import { FIELD_PREFIX_TO_ADD_AS_CANDIDATE } from '../constants';
|
||||
|
||||
export const hasPrefixToInclude = (fieldName: string) => {
|
||||
return FIELD_PREFIX_TO_ADD_AS_CANDIDATE.some((prefix) =>
|
||||
fieldName.startsWith(prefix)
|
||||
);
|
||||
return FIELD_PREFIX_TO_ADD_AS_CANDIDATE.some((prefix) => fieldName.startsWith(prefix));
|
||||
};
|
||||
|
|
|
@ -28,29 +28,24 @@ export function getAggregatedCriticalPathRootNodes(params: {
|
|||
|
||||
let numNodes = 0;
|
||||
|
||||
function mergeNodesWithSameOperationId(
|
||||
nodes: CriticalPathTreeNode[]
|
||||
): CriticalPathTreeNode[] {
|
||||
function mergeNodesWithSameOperationId(nodes: CriticalPathTreeNode[]): CriticalPathTreeNode[] {
|
||||
const nodesByOperationId: Record<string, CriticalPathTreeNode> = {};
|
||||
const mergedNodes = nodes.reduce<CriticalPathTreeNode[]>(
|
||||
(prev, node, index, array) => {
|
||||
const nodeId = node.nodeId;
|
||||
const operationId = criticalPath.operationIdByNodeId[nodeId];
|
||||
if (nodesByOperationId[operationId]) {
|
||||
const prevNode = nodesByOperationId[operationId];
|
||||
prevNode.children.push(...node.children);
|
||||
prevNode.countExclusive += node.countExclusive;
|
||||
prevNode.countInclusive += node.countInclusive;
|
||||
return prev;
|
||||
}
|
||||
|
||||
nodesByOperationId[operationId] = node;
|
||||
|
||||
prev.push(node);
|
||||
const mergedNodes = nodes.reduce<CriticalPathTreeNode[]>((prev, node, index, array) => {
|
||||
const nodeId = node.nodeId;
|
||||
const operationId = criticalPath.operationIdByNodeId[nodeId];
|
||||
if (nodesByOperationId[operationId]) {
|
||||
const prevNode = nodesByOperationId[operationId];
|
||||
prevNode.children.push(...node.children);
|
||||
prevNode.countExclusive += node.countExclusive;
|
||||
prevNode.countInclusive += node.countInclusive;
|
||||
return prev;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
nodesByOperationId[operationId] = node;
|
||||
|
||||
prev.push(node);
|
||||
return prev;
|
||||
}, []);
|
||||
|
||||
numNodes += mergedNodes.length;
|
||||
|
||||
|
|
|
@ -17,9 +17,7 @@ describe('getCriticalPath', () => {
|
|||
const entryTransaction = dedot(events[0]!, {}) as Transaction;
|
||||
const waterfall = getWaterfall({
|
||||
traceItems: {
|
||||
traceDocs: events.map(
|
||||
(event) => dedot(event, {}) as Transaction | Span
|
||||
),
|
||||
traceDocs: events.map((event) => dedot(event, {}) as Transaction | Span),
|
||||
errorDocs: [],
|
||||
exceedsMax: false,
|
||||
spanLinksCountById: {},
|
||||
|
@ -45,9 +43,7 @@ describe('getCriticalPath', () => {
|
|||
.transaction('/service-a')
|
||||
.timestamp(1)
|
||||
.duration(100)
|
||||
.children(
|
||||
service.span('foo', 'external', 'db').duration(100).timestamp(1)
|
||||
)
|
||||
.children(service.span('foo', 'external', 'db').duration(100).timestamp(1))
|
||||
.serialize()
|
||||
);
|
||||
|
||||
|
@ -76,9 +72,7 @@ describe('getCriticalPath', () => {
|
|||
.serialize()
|
||||
);
|
||||
|
||||
const longerSpan = waterfall.items.find(
|
||||
(item) => (item.doc as Span).span?.name === 'bar'
|
||||
);
|
||||
const longerSpan = waterfall.items.find((item) => (item.doc as Span).span?.name === 'bar');
|
||||
|
||||
expect(segments).toEqual([
|
||||
{ self: false, duration: 100000, item: waterfall.items[0], offset: 0 },
|
||||
|
@ -103,9 +97,7 @@ describe('getCriticalPath', () => {
|
|||
.transaction('/service-a')
|
||||
.timestamp(1)
|
||||
.duration(100)
|
||||
.children(
|
||||
service.span('foo', 'external', 'db').duration(50).timestamp(11)
|
||||
)
|
||||
.children(service.span('foo', 'external', 'db').duration(50).timestamp(11))
|
||||
.serialize()
|
||||
);
|
||||
|
||||
|
|
|
@ -67,11 +67,7 @@ export function getCriticalPath(waterfall: IWaterfall): CriticalPath {
|
|||
// - The span/tx ends before the start of the initial scan period.
|
||||
// - The span ends _after_ the current scan time.
|
||||
|
||||
(
|
||||
normalizedChildStart >= scanTime ||
|
||||
normalizedChildEnd < start ||
|
||||
childEnd > scanTime
|
||||
)
|
||||
(normalizedChildStart >= scanTime || normalizedChildEnd < start || childEnd > scanTime)
|
||||
);
|
||||
|
||||
if (!isOnCriticalPath) {
|
||||
|
@ -124,8 +120,7 @@ export function getCriticalPath(waterfall: IWaterfall): CriticalPath {
|
|||
|
||||
if (waterfall.entryWaterfallTransaction) {
|
||||
const start =
|
||||
waterfall.entryWaterfallTransaction.skew +
|
||||
waterfall.entryWaterfallTransaction.offset;
|
||||
waterfall.entryWaterfallTransaction.skew + waterfall.entryWaterfallTransaction.offset;
|
||||
scan({
|
||||
item: waterfall.entryWaterfallTransaction,
|
||||
start,
|
||||
|
|
|
@ -28,8 +28,7 @@ describe('Custom link', () => {
|
|||
});
|
||||
|
||||
it('handles complex template with multiple variables', () => {
|
||||
const url =
|
||||
'https://example.com/{{name}}/details/{{age}}?param={{gender}}';
|
||||
const url = 'https://example.com/{{name}}/details/{{age}}?param={{gender}}';
|
||||
const result = extractTemplateVariableNames(url);
|
||||
expect(result).toEqual(['name', 'age', 'gender']);
|
||||
});
|
||||
|
@ -99,9 +98,7 @@ describe('Custom link', () => {
|
|||
service: { name: 'foo & bar' },
|
||||
} as Transaction;
|
||||
const result = getEncodedCustomLinkUrl(url, transaction);
|
||||
expect(result).toBe(
|
||||
'https://kibana.com/app/apm/foo%20%26%20bar/overview'
|
||||
);
|
||||
expect(result).toBe('https://kibana.com/app/apm/foo%20%26%20bar/overview');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,19 +11,15 @@ import { set } from '@kbn/safer-lodash-set';
|
|||
import Mustache from 'mustache';
|
||||
import { Transaction } from '../../typings/es_schemas/ui/transaction';
|
||||
|
||||
export const INVALID_LICENSE = i18n.translate(
|
||||
'xpack.apm.settings.customLink.license.text',
|
||||
{
|
||||
defaultMessage:
|
||||
"To create custom links, you must be subscribed to an Elastic Gold license or above. With it, you'll have the ability to create custom links to improve your workflow when analyzing your services.",
|
||||
}
|
||||
);
|
||||
export const INVALID_LICENSE = i18n.translate('xpack.apm.settings.customLink.license.text', {
|
||||
defaultMessage:
|
||||
"To create custom links, you must be subscribed to an Elastic Gold license or above. With it, you'll have the ability to create custom links to improve your workflow when analyzing your services.",
|
||||
});
|
||||
|
||||
export const NO_PERMISSION_LABEL = i18n.translate(
|
||||
'xpack.apm.settings.customLink.noPermissionTooltipLabel',
|
||||
{
|
||||
defaultMessage:
|
||||
"Your user role doesn't have permissions to create custom links",
|
||||
defaultMessage: "Your user role doesn't have permissions to create custom links",
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -35,10 +31,7 @@ export const extractTemplateVariableNames = (url: string): string[] => {
|
|||
return Array.from(uniqueVariableNames);
|
||||
};
|
||||
|
||||
export function getEncodedCustomLinkUrl(
|
||||
url: string,
|
||||
transaction?: Transaction
|
||||
) {
|
||||
export function getEncodedCustomLinkUrl(url: string, transaction?: Transaction) {
|
||||
try {
|
||||
const templateVariables = extractTemplateVariableNames(url);
|
||||
const encodedTemplateVariables = {};
|
||||
|
|
|
@ -17,16 +17,13 @@ type AnyApmDocumentType =
|
|||
| ApmDocumentType.ErrorEvent
|
||||
| ApmDocumentType.SpanEvent;
|
||||
|
||||
export interface ApmDataSource<
|
||||
TDocumentType extends AnyApmDocumentType = AnyApmDocumentType
|
||||
> {
|
||||
export interface ApmDataSource<TDocumentType extends AnyApmDocumentType = AnyApmDocumentType> {
|
||||
rollupInterval: RollupInterval;
|
||||
documentType: TDocumentType;
|
||||
}
|
||||
|
||||
export type ApmDataSourceWithSummary<
|
||||
T extends AnyApmDocumentType = AnyApmDocumentType
|
||||
> = ApmDataSource<T> & {
|
||||
hasDurationSummaryField: boolean;
|
||||
hasDocs: boolean;
|
||||
};
|
||||
export type ApmDataSourceWithSummary<T extends AnyApmDocumentType = AnyApmDocumentType> =
|
||||
ApmDataSource<T> & {
|
||||
hasDurationSummaryField: boolean;
|
||||
hasDocs: boolean;
|
||||
};
|
||||
|
|
|
@ -7,10 +7,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ProcessorEvent } from '@kbn/observability-plugin/common';
|
||||
import {
|
||||
PROCESSOR_EVENT,
|
||||
SPAN_DESTINATION_SERVICE_RESOURCE,
|
||||
} from './es_fields/apm';
|
||||
import { PROCESSOR_EVENT, SPAN_DESTINATION_SERVICE_RESOURCE } from './es_fields/apm';
|
||||
import { environmentQuery } from './utils/environment_query';
|
||||
|
||||
export const unifiedSearchBarPlaceholder = i18n.translate(
|
||||
|
@ -30,9 +27,7 @@ export const getSearchBarBoolFilter = ({
|
|||
return [
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.metric } },
|
||||
{ exists: { field: SPAN_DESTINATION_SERVICE_RESOURCE } },
|
||||
...(dependencyName
|
||||
? [{ term: { [SPAN_DESTINATION_SERVICE_RESOURCE]: dependencyName } }]
|
||||
: []),
|
||||
...(dependencyName ? [{ term: { [SPAN_DESTINATION_SERVICE_RESOURCE]: dependencyName } }] : []),
|
||||
...environmentQuery(environment),
|
||||
];
|
||||
};
|
||||
|
|
|
@ -13,12 +13,9 @@ import { Environment } from './environment_rt';
|
|||
const ENVIRONMENT_ALL_VALUE = 'ENVIRONMENT_ALL' as const;
|
||||
const ENVIRONMENT_NOT_DEFINED_VALUE = 'ENVIRONMENT_NOT_DEFINED' as const;
|
||||
|
||||
export const allOptionText = i18n.translate(
|
||||
'xpack.apm.filter.environment.allLabel',
|
||||
{
|
||||
defaultMessage: 'All',
|
||||
}
|
||||
);
|
||||
export const allOptionText = i18n.translate('xpack.apm.filter.environment.allLabel', {
|
||||
defaultMessage: 'All',
|
||||
});
|
||||
|
||||
export function getEnvironmentLabel(environment: string): string {
|
||||
if (!environment || environment === ENVIRONMENT_NOT_DEFINED_VALUE) {
|
||||
|
@ -80,10 +77,8 @@ export function getNextEnvironmentUrlParam({
|
|||
requestedEnvironment?: string;
|
||||
currentEnvironmentUrlParam: Environment;
|
||||
}) {
|
||||
const normalizedRequestedEnvironment =
|
||||
requestedEnvironment || ENVIRONMENT_NOT_DEFINED.value;
|
||||
const normalizedQueryEnvironment =
|
||||
currentEnvironmentUrlParam || ENVIRONMENT_ALL.value;
|
||||
const normalizedRequestedEnvironment = requestedEnvironment || ENVIRONMENT_NOT_DEFINED.value;
|
||||
const normalizedQueryEnvironment = currentEnvironmentUrlParam || ENVIRONMENT_ALL.value;
|
||||
|
||||
if (normalizedRequestedEnvironment === normalizedQueryEnvironment) {
|
||||
return currentEnvironmentUrlParam || ENVIRONMENT_ALL.value;
|
||||
|
|
|
@ -6,10 +6,7 @@
|
|||
*/
|
||||
import * as t from 'io-ts';
|
||||
import { nonEmptyStringRt } from '@kbn/io-ts-utils';
|
||||
import {
|
||||
ENVIRONMENT_ALL,
|
||||
ENVIRONMENT_NOT_DEFINED,
|
||||
} from './environment_filter_values';
|
||||
import { ENVIRONMENT_ALL, ENVIRONMENT_NOT_DEFINED } from './environment_filter_values';
|
||||
|
||||
export const environmentStringRt = t.union([
|
||||
t.literal(ENVIRONMENT_NOT_DEFINED.value),
|
||||
|
|
|
@ -36,8 +36,7 @@ export const SERVICE_RUNTIME_VERSION = 'service.runtime.version';
|
|||
export const SERVICE_NODE_NAME = 'service.node.name';
|
||||
export const SERVICE_VERSION = 'service.version';
|
||||
export const SERVICE_TARGET_TYPE = 'service.target.type';
|
||||
export const SERVICE_OVERFLOW_COUNT =
|
||||
'service_transaction.aggregation.overflow_count';
|
||||
export const SERVICE_OVERFLOW_COUNT = 'service_transaction.aggregation.overflow_count';
|
||||
|
||||
export const URL_FULL = 'url.full';
|
||||
export const HTTP_REQUEST_METHOD = 'http.request.method';
|
||||
|
@ -61,12 +60,10 @@ export const TRANSACTION_SAMPLED = 'transaction.sampled';
|
|||
export const TRANSACTION_PAGE_URL = 'transaction.page.url';
|
||||
export const TRANSACTION_FAILURE_COUNT = 'transaction.failure_count';
|
||||
export const TRANSACTION_SUCCESS_COUNT = 'transaction.success_count';
|
||||
export const TRANSACTION_OVERFLOW_COUNT =
|
||||
'transaction.aggregation.overflow_count';
|
||||
export const TRANSACTION_OVERFLOW_COUNT = 'transaction.aggregation.overflow_count';
|
||||
// for transaction metrics
|
||||
export const TRANSACTION_ROOT = 'transaction.root';
|
||||
export const TRANSACTION_PROFILER_STACK_TRACE_IDS =
|
||||
'transaction.profiler_stack_trace_ids';
|
||||
export const TRANSACTION_PROFILER_STACK_TRACE_IDS = 'transaction.profiler_stack_trace_ids';
|
||||
|
||||
export const EVENT_OUTCOME = 'event.outcome';
|
||||
|
||||
|
@ -79,8 +76,7 @@ export const SPAN_SELF_TIME_SUM = 'span.self_time.sum.us';
|
|||
export const SPAN_ACTION = 'span.action';
|
||||
export const SPAN_NAME = 'span.name';
|
||||
export const SPAN_ID = 'span.id';
|
||||
export const SPAN_DESTINATION_SERVICE_RESOURCE =
|
||||
'span.destination.service.resource';
|
||||
export const SPAN_DESTINATION_SERVICE_RESOURCE = 'span.destination.service.resource';
|
||||
export const SPAN_DESTINATION_SERVICE_RESPONSE_TIME_COUNT =
|
||||
'span.destination.service.response_time.count';
|
||||
|
||||
|
@ -93,8 +89,7 @@ export const SPAN_LINKS_SPAN_ID = 'span.links.span.id';
|
|||
|
||||
export const SPAN_COMPOSITE_COUNT = 'span.composite.count';
|
||||
export const SPAN_COMPOSITE_SUM = 'span.composite.sum.us';
|
||||
export const SPAN_COMPOSITE_COMPRESSION_STRATEGY =
|
||||
'span.composite.compression_strategy';
|
||||
export const SPAN_COMPOSITE_COMPRESSION_STRATEGY = 'span.composite.compression_strategy';
|
||||
|
||||
export const SPAN_SYNC = 'span.sync';
|
||||
|
||||
|
@ -119,17 +114,14 @@ export const METRIC_SYSTEM_FREE_MEMORY = 'system.memory.actual.free';
|
|||
export const METRIC_SYSTEM_TOTAL_MEMORY = 'system.memory.total';
|
||||
export const METRIC_SYSTEM_CPU_PERCENT = 'system.cpu.total.norm.pct';
|
||||
export const METRIC_PROCESS_CPU_PERCENT = 'system.process.cpu.total.norm.pct';
|
||||
export const METRIC_CGROUP_MEMORY_LIMIT_BYTES =
|
||||
'system.process.cgroup.memory.mem.limit.bytes';
|
||||
export const METRIC_CGROUP_MEMORY_USAGE_BYTES =
|
||||
'system.process.cgroup.memory.mem.usage.bytes';
|
||||
export const METRIC_CGROUP_MEMORY_LIMIT_BYTES = 'system.process.cgroup.memory.mem.limit.bytes';
|
||||
export const METRIC_CGROUP_MEMORY_USAGE_BYTES = 'system.process.cgroup.memory.mem.usage.bytes';
|
||||
|
||||
export const METRIC_JAVA_HEAP_MEMORY_MAX = 'jvm.memory.heap.max';
|
||||
export const METRIC_JAVA_HEAP_MEMORY_COMMITTED = 'jvm.memory.heap.committed';
|
||||
export const METRIC_JAVA_HEAP_MEMORY_USED = 'jvm.memory.heap.used';
|
||||
export const METRIC_JAVA_NON_HEAP_MEMORY_MAX = 'jvm.memory.non_heap.max';
|
||||
export const METRIC_JAVA_NON_HEAP_MEMORY_COMMITTED =
|
||||
'jvm.memory.non_heap.committed';
|
||||
export const METRIC_JAVA_NON_HEAP_MEMORY_COMMITTED = 'jvm.memory.non_heap.committed';
|
||||
export const METRIC_JAVA_NON_HEAP_MEMORY_USED = 'jvm.memory.non_heap.used';
|
||||
export const METRIC_JAVA_THREAD_COUNT = 'jvm.thread.count';
|
||||
export const METRIC_JAVA_GC_COUNT = 'jvm.gc.count';
|
||||
|
@ -169,21 +161,14 @@ export const FAAS_BILLED_DURATION = 'faas.billed_duration';
|
|||
|
||||
// OpenTelemetry Metrics
|
||||
export const METRIC_OTEL_SYSTEM_CPU_UTILIZATION = 'system.cpu.utilization';
|
||||
export const METRIC_OTEL_SYSTEM_MEMORY_UTILIZATION =
|
||||
'system.memory.utilization';
|
||||
export const METRIC_OTEL_SYSTEM_MEMORY_UTILIZATION = 'system.memory.utilization';
|
||||
|
||||
export const METRIC_OTEL_JVM_PROCESS_CPU_PERCENT =
|
||||
'process.runtime.jvm.cpu.utilization';
|
||||
export const METRIC_OTEL_JVM_PROCESS_MEMORY_USAGE =
|
||||
'process.runtime.jvm.memory.usage';
|
||||
export const METRIC_OTEL_JVM_PROCESS_MEMORY_COMMITTED =
|
||||
'process.runtime.jvm.memory.committed';
|
||||
export const METRIC_OTEL_JVM_PROCESS_MEMORY_LIMIT =
|
||||
'process.runtime.jvm.memory.limit';
|
||||
export const METRIC_OTEL_JVM_PROCESS_THREADS_COUNT =
|
||||
'process.runtime.jvm.threads.count';
|
||||
export const METRIC_OTEL_JVM_SYSTEM_CPU_PERCENT =
|
||||
'process.runtime.jvm.system.cpu.utilization';
|
||||
export const METRIC_OTEL_JVM_PROCESS_CPU_PERCENT = 'process.runtime.jvm.cpu.utilization';
|
||||
export const METRIC_OTEL_JVM_PROCESS_MEMORY_USAGE = 'process.runtime.jvm.memory.usage';
|
||||
export const METRIC_OTEL_JVM_PROCESS_MEMORY_COMMITTED = 'process.runtime.jvm.memory.committed';
|
||||
export const METRIC_OTEL_JVM_PROCESS_MEMORY_LIMIT = 'process.runtime.jvm.memory.limit';
|
||||
export const METRIC_OTEL_JVM_PROCESS_THREADS_COUNT = 'process.runtime.jvm.threads.count';
|
||||
export const METRIC_OTEL_JVM_SYSTEM_CPU_PERCENT = 'process.runtime.jvm.system.cpu.utilization';
|
||||
export const METRIC_OTEL_JVM_GC_DURATION = 'process.runtime.jvm.gc.duration';
|
||||
export const VALUE_OTEL_JVM_PROCESS_MEMORY_HEAP = 'heap';
|
||||
export const VALUE_OTEL_JVM_PROCESS_MEMORY_NON_HEAP = 'non_heap';
|
||||
|
|
|
@ -194,9 +194,7 @@ describe('Error', () => {
|
|||
matchSnapshot(errorDoc);
|
||||
});
|
||||
|
||||
function matchSnapshot(
|
||||
obj: AllowUnknownProperties<Span | Transaction | APMError>
|
||||
) {
|
||||
function matchSnapshot(obj: AllowUnknownProperties<Span | Transaction | APMError>) {
|
||||
Object.entries(fieldnames).forEach(([key, longKey]) => {
|
||||
const value = get(obj, longKey);
|
||||
it(key, () => {
|
||||
|
|
|
@ -42,22 +42,17 @@ export const INPUT_VAR_NAME_TO_SCHEMA_PATH: Record<string, string> = {
|
|||
anonymous_enabled: 'apm-server.auth.anonymous.enabled',
|
||||
anonymous_allow_agent: 'apm-server.auth.anonymous.allow_agent',
|
||||
anonymous_allow_service: 'apm-server.auth.anonymous.allow_service',
|
||||
anonymous_rate_limit_ip_limit:
|
||||
'apm-server.auth.anonymous.rate_limit.ip_limit',
|
||||
anonymous_rate_limit_event_limit:
|
||||
'apm-server.auth.anonymous.rate_limit.event_limit',
|
||||
anonymous_rate_limit_ip_limit: 'apm-server.auth.anonymous.rate_limit.ip_limit',
|
||||
anonymous_rate_limit_event_limit: 'apm-server.auth.anonymous.rate_limit.event_limit',
|
||||
tail_sampling_enabled: 'apm-server.sampling.tail.enabled',
|
||||
tail_sampling_interval: 'apm-server.sampling.tail.interval',
|
||||
tail_sampling_policies: 'apm-server.sampling.tail.policies',
|
||||
};
|
||||
|
||||
export const LEGACY_TO_CURRENT_SCHEMA_PATHS: Record<string, string> = {
|
||||
'apm-server.rum.event_rate.limit':
|
||||
'apm-server.auth.anonymous.rate_limit.event_limit',
|
||||
'apm-server.rum.event_rate.lru_size':
|
||||
'apm-server.auth.anonymous.rate_limit.ip_limit',
|
||||
'apm-server.rum.allow_service_names':
|
||||
'apm-server.auth.anonymous.allow_service',
|
||||
'apm-server.rum.event_rate.limit': 'apm-server.auth.anonymous.rate_limit.event_limit',
|
||||
'apm-server.rum.event_rate.lru_size': 'apm-server.auth.anonymous.rate_limit.ip_limit',
|
||||
'apm-server.rum.allow_service_names': 'apm-server.auth.anonymous.allow_service',
|
||||
'apm-server.secret_token': 'apm-server.auth.secret_token',
|
||||
'apm-server.api_key.enabled': 'apm-server.auth.api_key.enabled',
|
||||
};
|
||||
|
|
|
@ -7,9 +7,6 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const NOT_AVAILABLE_LABEL = i18n.translate(
|
||||
'xpack.apm.notAvailableLabel',
|
||||
{
|
||||
defaultMessage: 'N/A',
|
||||
}
|
||||
);
|
||||
export const NOT_AVAILABLE_LABEL = i18n.translate('xpack.apm.notAvailableLabel', {
|
||||
defaultMessage: 'N/A',
|
||||
});
|
||||
|
|
|
@ -22,6 +22,5 @@ export const latencyAggregationTypeRt = t.union([
|
|||
export const getLatencyAggregationType = (
|
||||
latencyAggregationType: string | null | undefined
|
||||
): LatencyAggregationType => {
|
||||
return (latencyAggregationType ??
|
||||
LatencyAggregationType.avg) as LatencyAggregationType;
|
||||
return (latencyAggregationType ?? LatencyAggregationType.avg) as LatencyAggregationType;
|
||||
};
|
||||
|
|
|
@ -17,8 +17,5 @@ export enum ClusterPrivilegeType {
|
|||
}
|
||||
|
||||
export const privilegesTypeRt = t.array(
|
||||
t.union([
|
||||
t.literal(PrivilegeType.EVENT),
|
||||
t.literal(PrivilegeType.AGENT_CONFIG),
|
||||
])
|
||||
t.union([t.literal(PrivilegeType.EVENT), t.literal(PrivilegeType.AGENT_CONFIG)])
|
||||
);
|
||||
|
|
|
@ -7,11 +7,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { ValuesType } from 'utility-types';
|
||||
import type {
|
||||
AsDuration,
|
||||
AsPercent,
|
||||
TimeUnitChar,
|
||||
} from '@kbn/observability-plugin/common';
|
||||
import type { AsDuration, AsPercent, TimeUnitChar } from '@kbn/observability-plugin/common';
|
||||
import type { ActionGroup } from '@kbn/alerting-plugin/common';
|
||||
import { formatDurationFromTimeUnitChar } from '@kbn/observability-plugin/common';
|
||||
import { ML_ANOMALY_SEVERITY } from '@kbn/ml-anomaly-utils/anomaly_severity';
|
||||
|
@ -64,22 +60,13 @@ const getFieldNameLabel = (field: string): string => {
|
|||
}
|
||||
};
|
||||
|
||||
export const getFieldValueLabel = (
|
||||
field: string,
|
||||
fieldValue: string
|
||||
): string => {
|
||||
return field === SERVICE_ENVIRONMENT
|
||||
? getEnvironmentLabel(fieldValue)
|
||||
: fieldValue;
|
||||
export const getFieldValueLabel = (field: string, fieldValue: string): string => {
|
||||
return field === SERVICE_ENVIRONMENT ? getEnvironmentLabel(fieldValue) : fieldValue;
|
||||
};
|
||||
|
||||
const formatGroupByFields = (groupByFields: Record<string, string>): string => {
|
||||
const groupByFieldLabels = Object.keys(groupByFields).map(
|
||||
(field) =>
|
||||
`${getFieldNameLabel(field)}: ${getFieldValueLabel(
|
||||
field,
|
||||
groupByFields[field]
|
||||
)}`
|
||||
(field) => `${getFieldNameLabel(field)}: ${getFieldValueLabel(field, groupByFields[field])}`
|
||||
);
|
||||
return groupByFieldLabels.join(', ');
|
||||
};
|
||||
|
@ -102,10 +89,7 @@ export function formatErrorCountReason({
|
|||
values: {
|
||||
threshold,
|
||||
measured,
|
||||
interval: formatDurationFromTimeUnitChar(
|
||||
windowSize,
|
||||
windowUnit as TimeUnitChar
|
||||
),
|
||||
interval: formatDurationFromTimeUnitChar(windowSize, windowUnit as TimeUnitChar),
|
||||
group: formatGroupByFields(groupByFields),
|
||||
},
|
||||
});
|
||||
|
@ -128,10 +112,8 @@ export function formatTransactionDurationReason({
|
|||
windowUnit: string;
|
||||
groupByFields: Record<string, string>;
|
||||
}) {
|
||||
let aggregationTypeFormatted =
|
||||
aggregationType.charAt(0).toUpperCase() + aggregationType.slice(1);
|
||||
if (aggregationTypeFormatted === 'Avg')
|
||||
aggregationTypeFormatted = aggregationTypeFormatted + '.';
|
||||
let aggregationTypeFormatted = aggregationType.charAt(0).toUpperCase() + aggregationType.slice(1);
|
||||
if (aggregationTypeFormatted === 'Avg') aggregationTypeFormatted = aggregationTypeFormatted + '.';
|
||||
|
||||
return i18n.translate('xpack.apm.alertTypes.transactionDuration.reason', {
|
||||
defaultMessage: `{aggregationType} latency is {measured} in the last {interval} for {group}. Alert when > {threshold}.`,
|
||||
|
@ -139,10 +121,7 @@ export function formatTransactionDurationReason({
|
|||
threshold: asDuration(threshold),
|
||||
measured: asDuration(measured),
|
||||
aggregationType: aggregationTypeFormatted,
|
||||
interval: formatDurationFromTimeUnitChar(
|
||||
windowSize,
|
||||
windowUnit as TimeUnitChar
|
||||
),
|
||||
interval: formatDurationFromTimeUnitChar(windowSize, windowUnit as TimeUnitChar),
|
||||
group: formatGroupByFields(groupByFields),
|
||||
},
|
||||
});
|
||||
|
@ -168,10 +147,7 @@ export function formatTransactionErrorRateReason({
|
|||
values: {
|
||||
threshold: asPercent(threshold, 100),
|
||||
measured: asPercent(measured, 100),
|
||||
interval: formatDurationFromTimeUnitChar(
|
||||
windowSize,
|
||||
windowUnit as TimeUnitChar
|
||||
),
|
||||
interval: formatDurationFromTimeUnitChar(windowSize, windowUnit as TimeUnitChar),
|
||||
group: formatGroupByFields(groupByFields),
|
||||
},
|
||||
});
|
||||
|
@ -192,22 +168,16 @@ export function formatAnomalyReason({
|
|||
windowUnit: string;
|
||||
detectorType: AnomalyDetectorType;
|
||||
}) {
|
||||
return i18n.translate(
|
||||
'xpack.apm.alertTypes.transactionDurationAnomaly.reason',
|
||||
{
|
||||
defaultMessage: `{severityLevel} {detectorTypeLabel} anomaly with a score of {anomalyScore}, was detected in the last {interval} for {serviceName}.`,
|
||||
values: {
|
||||
serviceName,
|
||||
severityLevel,
|
||||
detectorTypeLabel: getApmMlDetectorLabel(detectorType),
|
||||
anomalyScore,
|
||||
interval: formatDurationFromTimeUnitChar(
|
||||
windowSize,
|
||||
windowUnit as TimeUnitChar
|
||||
),
|
||||
},
|
||||
}
|
||||
);
|
||||
return i18n.translate('xpack.apm.alertTypes.transactionDurationAnomaly.reason', {
|
||||
defaultMessage: `{severityLevel} {detectorTypeLabel} anomaly with a score of {anomalyScore}, was detected in the last {interval} for {serviceName}.`,
|
||||
values: {
|
||||
serviceName,
|
||||
severityLevel,
|
||||
detectorTypeLabel: getApmMlDetectorLabel(detectorType),
|
||||
anomalyScore,
|
||||
interval: formatDurationFromTimeUnitChar(windowSize, windowUnit as TimeUnitChar),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const RULE_TYPES_CONFIG: Record<
|
||||
|
@ -294,9 +264,7 @@ export const ANOMALY_ALERT_SEVERITY_TYPES = [
|
|||
},
|
||||
] as const;
|
||||
|
||||
export type AnomalyAlertSeverityType = ValuesType<
|
||||
typeof ANOMALY_ALERT_SEVERITY_TYPES
|
||||
>['type'];
|
||||
export type AnomalyAlertSeverityType = ValuesType<typeof ANOMALY_ALERT_SEVERITY_TYPES>['type'];
|
||||
|
||||
export function getApmMlDetectorLabel(type: AnomalyDetectorType) {
|
||||
switch (type) {
|
||||
|
@ -305,19 +273,13 @@ export function getApmMlDetectorLabel(type: AnomalyDetectorType) {
|
|||
defaultMessage: 'latency',
|
||||
});
|
||||
case AnomalyDetectorType.txThroughput:
|
||||
return i18n.translate(
|
||||
'xpack.apm.alerts.anomalyDetector.throughputLabel',
|
||||
{
|
||||
defaultMessage: 'throughput',
|
||||
}
|
||||
);
|
||||
return i18n.translate('xpack.apm.alerts.anomalyDetector.throughputLabel', {
|
||||
defaultMessage: 'throughput',
|
||||
});
|
||||
case AnomalyDetectorType.txFailureRate:
|
||||
return i18n.translate(
|
||||
'xpack.apm.alerts.anomalyDetector.failedTransactionRateLabel',
|
||||
{
|
||||
defaultMessage: 'failed transaction rate',
|
||||
}
|
||||
);
|
||||
return i18n.translate('xpack.apm.alerts.anomalyDetector.failedTransactionRateLabel', {
|
||||
defaultMessage: 'failed transaction rate',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,7 @@
|
|||
|
||||
import { union } from 'lodash';
|
||||
import { ApmRuleType } from '@kbn/rule-data-utils';
|
||||
import {
|
||||
SERVICE_ENVIRONMENT,
|
||||
SERVICE_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
} from '../es_fields/apm';
|
||||
import { SERVICE_ENVIRONMENT, SERVICE_NAME, TRANSACTION_TYPE } from '../es_fields/apm';
|
||||
|
||||
export const getAllGroupByFields = (
|
||||
ruleType: string,
|
||||
|
@ -22,11 +18,7 @@ export const getAllGroupByFields = (
|
|||
switch (ruleType) {
|
||||
case ApmRuleType.TransactionDuration:
|
||||
case ApmRuleType.TransactionErrorRate:
|
||||
predefinedGroupByFields = [
|
||||
SERVICE_NAME,
|
||||
SERVICE_ENVIRONMENT,
|
||||
TRANSACTION_TYPE,
|
||||
];
|
||||
predefinedGroupByFields = [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE];
|
||||
break;
|
||||
case ApmRuleType.ErrorCount:
|
||||
predefinedGroupByFields = [SERVICE_NAME, SERVICE_ENVIRONMENT];
|
||||
|
|
|
@ -13,10 +13,7 @@ import { AggregationType } from './apm_rule_types';
|
|||
|
||||
export const searchConfigurationSchema = schema.object({
|
||||
query: schema.object({
|
||||
query: schema.oneOf([
|
||||
schema.string(),
|
||||
schema.recordOf(schema.string(), schema.any()),
|
||||
]),
|
||||
query: schema.oneOf([schema.string(), schema.recordOf(schema.string(), schema.any())]),
|
||||
language: schema.string(),
|
||||
}),
|
||||
});
|
||||
|
@ -86,13 +83,9 @@ export const transactionErrorRateParamsSchema = schema.object({
|
|||
});
|
||||
|
||||
type ErrorCountParamsType = TypeOf<typeof errorCountParamsSchema>;
|
||||
type TransactionDurationParamsType = TypeOf<
|
||||
typeof transactionDurationParamsSchema
|
||||
>;
|
||||
type TransactionDurationParamsType = TypeOf<typeof transactionDurationParamsSchema>;
|
||||
type AnomalyParamsType = TypeOf<typeof anomalyParamsSchema>;
|
||||
type TransactionErrorRateParamsType = TypeOf<
|
||||
typeof transactionErrorRateParamsSchema
|
||||
>;
|
||||
type TransactionErrorRateParamsType = TypeOf<typeof transactionErrorRateParamsSchema>;
|
||||
|
||||
export type SearchConfigurationType = TypeOf<typeof searchConfigurationSchema>;
|
||||
|
||||
|
|
|
@ -13,14 +13,10 @@ describe('getServerlessFunctionNameFromId', () => {
|
|||
|
||||
it('returns correct serverless function name', () => {
|
||||
expect(
|
||||
getServerlessFunctionNameFromId(
|
||||
'arn:aws:lambda:us-west-2:123456789012:function:my-function'
|
||||
)
|
||||
getServerlessFunctionNameFromId('arn:aws:lambda:us-west-2:123456789012:function:my-function')
|
||||
).toEqual('my-function');
|
||||
expect(
|
||||
getServerlessFunctionNameFromId(
|
||||
'arn:aws:lambda:us-west-2:123456789012:function:my:function'
|
||||
)
|
||||
getServerlessFunctionNameFromId('arn:aws:lambda:us-west-2:123456789012:function:my:function')
|
||||
).toEqual('my:function');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -25,17 +25,11 @@ export function getServerlessTypeFromCloudData(
|
|||
cloudProvider?: string,
|
||||
cloudServiceName?: string
|
||||
): ServerlessType | undefined {
|
||||
if (
|
||||
cloudProvider?.toLowerCase() === 'aws' &&
|
||||
cloudServiceName?.toLowerCase() === 'lambda'
|
||||
) {
|
||||
if (cloudProvider?.toLowerCase() === 'aws' && cloudServiceName?.toLowerCase() === 'lambda') {
|
||||
return ServerlessType.AWS_LAMBDA;
|
||||
}
|
||||
|
||||
if (
|
||||
cloudProvider?.toLowerCase() === 'azure' &&
|
||||
cloudServiceName?.toLowerCase() === 'functions'
|
||||
) {
|
||||
if (cloudProvider?.toLowerCase() === 'azure' && cloudServiceName?.toLowerCase() === 'functions') {
|
||||
return ServerlessType.AZURE_FUNCTIONS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,7 @@ import {
|
|||
validateServiceGroupKuery,
|
||||
SERVICE_GROUP_SUPPORTED_FIELDS,
|
||||
} from './service_groups';
|
||||
import {
|
||||
TRANSACTION_TYPE,
|
||||
TRANSACTION_DURATION,
|
||||
SERVICE_FRAMEWORK_VERSION,
|
||||
} from './es_fields/apm';
|
||||
import { TRANSACTION_TYPE, TRANSACTION_DURATION, SERVICE_FRAMEWORK_VERSION } from './es_fields/apm';
|
||||
|
||||
describe('service_groups common utils', () => {
|
||||
describe('isSupportedField', () => {
|
||||
|
@ -24,11 +20,7 @@ describe('service_groups common utils', () => {
|
|||
});
|
||||
});
|
||||
it('should reject unsupported fields', () => {
|
||||
const unsupportedFields = [
|
||||
TRANSACTION_TYPE,
|
||||
TRANSACTION_DURATION,
|
||||
SERVICE_FRAMEWORK_VERSION,
|
||||
];
|
||||
const unsupportedFields = [TRANSACTION_TYPE, TRANSACTION_DURATION, SERVICE_FRAMEWORK_VERSION];
|
||||
unsupportedFields.map((field) => {
|
||||
expect(isSupportedField(field)).toBe(false);
|
||||
});
|
||||
|
@ -36,9 +28,7 @@ describe('service_groups common utils', () => {
|
|||
});
|
||||
describe('validateServiceGroupKuery', () => {
|
||||
it('should validate supported KQL filter for a service group', () => {
|
||||
const result = validateServiceGroupKuery(
|
||||
`service.name: testbeans* or agent.name: "nodejs"`
|
||||
);
|
||||
const result = validateServiceGroupKuery(`service.name: testbeans* or agent.name: "nodejs"`);
|
||||
expect(result).toHaveProperty('isValidFields', true);
|
||||
expect(result).toHaveProperty('isValidSyntax', true);
|
||||
expect(result).not.toHaveProperty('message');
|
||||
|
@ -55,9 +45,7 @@ describe('service_groups common utils', () => {
|
|||
);
|
||||
});
|
||||
it('should return parsing error when KQL is incomplete', () => {
|
||||
const result = validateServiceGroupKuery(
|
||||
`service.name: testbeans* or agent.name: "nod`
|
||||
);
|
||||
const result = validateServiceGroupKuery(`service.name: testbeans* or agent.name: "nod`);
|
||||
expect(result).toHaveProperty('isValidFields', false);
|
||||
expect(result).toHaveProperty('isValidSyntax', false);
|
||||
expect(result).toHaveProperty('message');
|
||||
|
|
|
@ -42,10 +42,7 @@ export const SERVICE_GROUP_SUPPORTED_FIELDS = [
|
|||
];
|
||||
|
||||
export function isSupportedField(fieldName: string) {
|
||||
return (
|
||||
fieldName.startsWith(LABELS) ||
|
||||
SERVICE_GROUP_SUPPORTED_FIELDS.includes(fieldName)
|
||||
);
|
||||
return fieldName.startsWith(LABELS) || SERVICE_GROUP_SUPPORTED_FIELDS.includes(fieldName);
|
||||
}
|
||||
|
||||
export function validateServiceGroupKuery(kuery: string): {
|
||||
|
@ -55,9 +52,7 @@ export function validateServiceGroupKuery(kuery: string): {
|
|||
} {
|
||||
try {
|
||||
const kueryFields = getKueryFields([fromKueryExpression(kuery)]);
|
||||
const unsupportedKueryFields = kueryFields.filter(
|
||||
(fieldName) => !isSupportedField(fieldName)
|
||||
);
|
||||
const unsupportedKueryFields = kueryFields.filter((fieldName) => !isSupportedField(fieldName));
|
||||
if (unsupportedKueryFields.length === 0) {
|
||||
return { isValidFields: true, isValidSyntax: true };
|
||||
}
|
||||
|
|
|
@ -16,11 +16,7 @@ export enum ServiceHealthStatus {
|
|||
unknown = 'unknown',
|
||||
}
|
||||
|
||||
export function getServiceHealthStatus({
|
||||
severity,
|
||||
}: {
|
||||
severity: ML_ANOMALY_SEVERITY;
|
||||
}) {
|
||||
export function getServiceHealthStatus({ severity }: { severity: ML_ANOMALY_SEVERITY }) {
|
||||
switch (severity) {
|
||||
case ML_ANOMALY_SEVERITY.CRITICAL:
|
||||
case ML_ANOMALY_SEVERITY.MAJOR:
|
||||
|
@ -38,10 +34,7 @@ export function getServiceHealthStatus({
|
|||
}
|
||||
}
|
||||
|
||||
export function getServiceHealthStatusColor(
|
||||
theme: EuiTheme,
|
||||
status: ServiceHealthStatus
|
||||
) {
|
||||
export function getServiceHealthStatusColor(theme: EuiTheme, status: ServiceHealthStatus) {
|
||||
switch (status) {
|
||||
case ServiceHealthStatus.healthy:
|
||||
return theme.eui.euiColorVis0;
|
||||
|
@ -54,10 +47,7 @@ export function getServiceHealthStatusColor(
|
|||
}
|
||||
}
|
||||
|
||||
export function getServiceHealthStatusBadgeColor(
|
||||
theme: EuiTheme,
|
||||
status: ServiceHealthStatus
|
||||
) {
|
||||
export function getServiceHealthStatusBadgeColor(theme: EuiTheme, status: ServiceHealthStatus) {
|
||||
switch (status) {
|
||||
case ServiceHealthStatus.healthy:
|
||||
return theme.eui.euiColorVis0_behindText;
|
||||
|
|
|
@ -84,13 +84,10 @@ export interface NodeStats {
|
|||
};
|
||||
}
|
||||
|
||||
export const invalidLicenseMessage = i18n.translate(
|
||||
'xpack.apm.serviceMap.invalidLicenseMessage',
|
||||
{
|
||||
defaultMessage:
|
||||
"In order to access Service Maps, you must be subscribed to an Elastic Platinum license. With it, you'll have the ability to visualize your entire application stack along with your APM data.",
|
||||
}
|
||||
);
|
||||
export const invalidLicenseMessage = i18n.translate('xpack.apm.serviceMap.invalidLicenseMessage', {
|
||||
defaultMessage:
|
||||
"In order to access Service Maps, you must be subscribed to an Elastic Platinum license. With it, you'll have the ability to visualize your entire application stack along with your APM data.",
|
||||
});
|
||||
|
||||
const NONGROUPED_SPANS: Record<string, string[]> = {
|
||||
aws: ['servicename'],
|
||||
|
@ -106,8 +103,7 @@ export function isSpanGroupingSupported(type?: string, subtype?: string) {
|
|||
return true;
|
||||
}
|
||||
return !NONGROUPED_SPANS[type].some(
|
||||
(nongroupedSubType) =>
|
||||
nongroupedSubType === 'all' || nongroupedSubType === subtype
|
||||
(nongroupedSubType) => nongroupedSubType === 'all' || nongroupedSubType === subtype
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,12 +9,9 @@ import { i18n } from '@kbn/i18n';
|
|||
|
||||
export const SERVICE_NODE_NAME_MISSING = '_service_node_name_missing_';
|
||||
|
||||
const UNIDENTIFIED_SERVICE_NODES_LABEL = i18n.translate(
|
||||
'xpack.apm.serviceNodeNameMissing',
|
||||
{
|
||||
defaultMessage: '(Empty)',
|
||||
}
|
||||
);
|
||||
const UNIDENTIFIED_SERVICE_NODES_LABEL = i18n.translate('xpack.apm.serviceNodeNameMissing', {
|
||||
defaultMessage: '(Empty)',
|
||||
});
|
||||
|
||||
export function getServiceNodeName(serviceNodeName?: string) {
|
||||
return serviceNodeName === SERVICE_NODE_NAME_MISSING || !serviceNodeName
|
||||
|
|
|
@ -9,7 +9,5 @@ import { ApmDataSource } from './data_source';
|
|||
|
||||
export interface TimeRangeMetadata {
|
||||
isUsingServiceDestinationMetrics: boolean;
|
||||
sources: Array<
|
||||
ApmDataSource & { hasDocs: boolean; hasDurationSummaryField: boolean }
|
||||
>;
|
||||
sources: Array<ApmDataSource & { hasDocs: boolean; hasDurationSummaryField: boolean }>;
|
||||
}
|
||||
|
|
|
@ -7,17 +7,13 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const createNodeAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createNodeAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.nodeClient.install.title', {
|
||||
defaultMessage: 'Install the APM agent',
|
||||
}),
|
||||
textPre: i18n.translate('xpack.apm.tutorial.nodeClient.install.textPre', {
|
||||
defaultMessage:
|
||||
'Install the APM agent for Node.js as a dependency to your application.',
|
||||
defaultMessage: 'Install the APM agent for Node.js as a dependency to your application.',
|
||||
}),
|
||||
commands: ['npm install elastic-apm-node --save'],
|
||||
},
|
||||
|
@ -32,27 +28,20 @@ APM services are created programmatically based on the `serviceName`. \
|
|||
This agent supports a variety of frameworks but can also be used with your custom stack.',
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.nodeClient.configure.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'See [the documentation]({documentationLink}) for advanced usage, including how to use with \
|
||||
textPost: i18n.translate('xpack.apm.tutorial.nodeClient.configure.textPost', {
|
||||
defaultMessage:
|
||||
'See [the documentation]({documentationLink}) for advanced usage, including how to use with \
|
||||
[Babel/ES Modules]({babelEsModulesLink}).',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/nodejs/current/index.html',
|
||||
babelEsModulesLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/nodejs/current/advanced-setup.html#es-modules',
|
||||
},
|
||||
}
|
||||
),
|
||||
values: {
|
||||
documentationLink: '{config.docs.base_url}guide/en/apm/agent/nodejs/current/index.html',
|
||||
babelEsModulesLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/nodejs/current/advanced-setup.html#es-modules',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const createDjangoAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createDjangoAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.djangoClient.install.title', {
|
||||
defaultMessage: 'Install the APM agent',
|
||||
|
@ -66,33 +55,23 @@ export const createDjangoAgentInstructions = (
|
|||
title: i18n.translate('xpack.apm.tutorial.djangoClient.configure.title', {
|
||||
defaultMessage: 'Configure the agent',
|
||||
}),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.djangoClient.configure.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'Agents are libraries that run inside of your application process. \
|
||||
textPre: i18n.translate('xpack.apm.tutorial.djangoClient.configure.textPre', {
|
||||
defaultMessage:
|
||||
'Agents are libraries that run inside of your application process. \
|
||||
APM services are created programmatically based on the `SERVICE_NAME`.',
|
||||
}
|
||||
),
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.djangoClient.configure.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for advanced usage.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/python/current/django-support.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
textPost: i18n.translate('xpack.apm.tutorial.djangoClient.configure.textPost', {
|
||||
defaultMessage: 'See the [documentation]({documentationLink}) for advanced usage.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/python/current/django-support.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const createFlaskAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createFlaskAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.flaskClient.install.title', {
|
||||
defaultMessage: 'Install the APM agent',
|
||||
|
@ -106,33 +85,23 @@ export const createFlaskAgentInstructions = (
|
|||
title: i18n.translate('xpack.apm.tutorial.flaskClient.configure.title', {
|
||||
defaultMessage: 'Configure the agent',
|
||||
}),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.flaskClient.configure.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'Agents are libraries that run inside of your application process. \
|
||||
textPre: i18n.translate('xpack.apm.tutorial.flaskClient.configure.textPre', {
|
||||
defaultMessage:
|
||||
'Agents are libraries that run inside of your application process. \
|
||||
APM services are created programmatically based on the `SERVICE_NAME`.',
|
||||
}
|
||||
),
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.flaskClient.configure.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for advanced usage.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/python/current/flask-support.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
textPost: i18n.translate('xpack.apm.tutorial.flaskClient.configure.textPost', {
|
||||
defaultMessage: 'See the [documentation]({documentationLink}) for advanced usage.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/python/current/flask-support.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const createRailsAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createRailsAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.railsClient.install.title', {
|
||||
defaultMessage: 'Install the APM agent',
|
||||
|
@ -146,33 +115,23 @@ export const createRailsAgentInstructions = (
|
|||
title: i18n.translate('xpack.apm.tutorial.railsClient.configure.title', {
|
||||
defaultMessage: 'Configure the agent',
|
||||
}),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.railsClient.configure.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'APM is automatically started when your app boots. Configure the agent, by creating the config file {configFile}',
|
||||
values: { configFile: '`config/elastic_apm.yml`' },
|
||||
}
|
||||
),
|
||||
textPre: i18n.translate('xpack.apm.tutorial.railsClient.configure.textPre', {
|
||||
defaultMessage:
|
||||
'APM is automatically started when your app boots. Configure the agent, by creating the config file {configFile}',
|
||||
values: { configFile: '`config/elastic_apm.yml`' },
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.railsClient.configure.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
textPost: i18n.translate('xpack.apm.tutorial.railsClient.configure.textPost', {
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n',
|
||||
values: {
|
||||
documentationLink: '{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const createRackAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createRackAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.rackClient.install.title', {
|
||||
defaultMessage: 'Install the APM agent',
|
||||
|
@ -222,78 +181,56 @@ export const createRackAgentInstructions = (
|
|||
title: i18n.translate('xpack.apm.tutorial.rackClient.createConfig.title', {
|
||||
defaultMessage: 'Create config file',
|
||||
}),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.rackClient.createConfig.textPre',
|
||||
{
|
||||
defaultMessage: 'Create a config file {configFile}:',
|
||||
values: { configFile: '`config/elastic_apm.yml`' },
|
||||
}
|
||||
),
|
||||
textPre: i18n.translate('xpack.apm.tutorial.rackClient.createConfig.textPre', {
|
||||
defaultMessage: 'Create a config file {configFile}:',
|
||||
values: { configFile: '`config/elastic_apm.yml`' },
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.rackClient.createConfig.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
textPost: i18n.translate('xpack.apm.tutorial.rackClient.createConfig.textPost', {
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n',
|
||||
values: {
|
||||
documentationLink: '{config.docs.base_url}guide/en/apm/agent/ruby/current/index.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const createJsAgentInstructions = (apmServerUrl = '') => [
|
||||
{
|
||||
title: i18n.translate(
|
||||
'xpack.apm.tutorial.jsClient.enableRealUserMonitoring.title',
|
||||
{
|
||||
defaultMessage: 'Enable Real User Monitoring support in APM Server',
|
||||
}
|
||||
),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.jsClient.enableRealUserMonitoring.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'APM Server disables RUM support by default. See the [documentation]({documentationLink}) \
|
||||
title: i18n.translate('xpack.apm.tutorial.jsClient.enableRealUserMonitoring.title', {
|
||||
defaultMessage: 'Enable Real User Monitoring support in APM Server',
|
||||
}),
|
||||
textPre: i18n.translate('xpack.apm.tutorial.jsClient.enableRealUserMonitoring.textPre', {
|
||||
defaultMessage:
|
||||
'APM Server disables RUM support by default. See the [documentation]({documentationLink}) \
|
||||
for details on how to enable RUM support. When using the APM integration with Fleet, RUM support is automatically enabled.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/guide/{config.docs.version}/configuration-rum.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/guide/{config.docs.version}/configuration-rum.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: i18n.translate(
|
||||
'xpack.apm.tutorial.jsClient.installDependency.title',
|
||||
{
|
||||
defaultMessage: 'Set up the Agent as a dependency',
|
||||
}
|
||||
),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.jsClient.installDependency.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'You can install the Agent as a dependency to your application with \
|
||||
title: i18n.translate('xpack.apm.tutorial.jsClient.installDependency.title', {
|
||||
defaultMessage: 'Set up the Agent as a dependency',
|
||||
}),
|
||||
textPre: i18n.translate('xpack.apm.tutorial.jsClient.installDependency.textPre', {
|
||||
defaultMessage:
|
||||
'You can install the Agent as a dependency to your application with \
|
||||
`npm install @elastic/apm-rum --save`.\n\n\
|
||||
The Agent can then be initialized and configured in your application like this:',
|
||||
}
|
||||
),
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.jsClient.installDependency.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'Framework integrations, like React or Angular, have custom dependencies. \
|
||||
textPost: i18n.translate('xpack.apm.tutorial.jsClient.installDependency.textPost', {
|
||||
defaultMessage:
|
||||
'Framework integrations, like React or Angular, have custom dependencies. \
|
||||
See the [integration documentation]({docLink}) for more information.',
|
||||
values: {
|
||||
docLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/rum-js/current/framework-integrations.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
values: {
|
||||
docLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/rum-js/current/framework-integrations.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.jsClient.scriptTags.title', {
|
||||
|
@ -306,20 +243,15 @@ Add a `<script>` tag to the HTML page and use the `elasticApm` global object to
|
|||
Don't forget to download the latest version of the RUM Agent from [GitHub]({GitHubLink}) or [UNPKG]({UnpkgLink}), \
|
||||
and host the file on your Server/CDN before deploying to production.",
|
||||
values: {
|
||||
GitHubLink:
|
||||
'https://github.com/elastic/apm-agent-rum-js/releases/latest',
|
||||
UnpkgLink:
|
||||
'https://unpkg.com/@elastic/apm-rum/dist/bundles/elastic-apm-rum.umd.min.js',
|
||||
GitHubLink: 'https://github.com/elastic/apm-agent-rum-js/releases/latest',
|
||||
UnpkgLink: 'https://unpkg.com/@elastic/apm-rum/dist/bundles/elastic-apm-rum.umd.min.js',
|
||||
},
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgentRumScript',
|
||||
},
|
||||
];
|
||||
|
||||
export const createGoAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createGoAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.goClient.install.title', {
|
||||
defaultMessage: 'Install the APM agent',
|
||||
|
@ -341,11 +273,9 @@ file name, or the `ELASTIC_APM_SERVICE_NAME` environment variable.',
|
|||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate('xpack.apm.tutorial.goClient.configure.textPost', {
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for advanced configuration.',
|
||||
defaultMessage: 'See the [documentation]({documentationLink}) for advanced configuration.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/go/current/configuration.html',
|
||||
documentationLink: '{config.docs.base_url}guide/en/apm/agent/go/current/configuration.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
@ -371,25 +301,19 @@ func main() {curlyOpen}
|
|||
http.ListenAndServe(":8080", apmhttp.Wrap(mux))
|
||||
{curlyClose}
|
||||
`.split('\n'),
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.goClient.instrument.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for a detailed \
|
||||
textPost: i18n.translate('xpack.apm.tutorial.goClient.instrument.textPost', {
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for a detailed \
|
||||
guide to instrumenting Go source code.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/go/current/instrumenting-source.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/go/current/instrumenting-source.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const createJavaAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createJavaAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.javaClient.download.title', {
|
||||
defaultMessage: 'Download the APM agent',
|
||||
|
@ -405,88 +329,63 @@ Do **not** add the agent as a dependency to your application.',
|
|||
}),
|
||||
},
|
||||
{
|
||||
title: i18n.translate(
|
||||
'xpack.apm.tutorial.javaClient.startApplication.title',
|
||||
{
|
||||
defaultMessage: 'Start your application with the javaagent flag',
|
||||
}
|
||||
),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.javaClient.startApplication.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'Add the `-javaagent` flag and configure the agent with system properties.\n\n \
|
||||
title: i18n.translate('xpack.apm.tutorial.javaClient.startApplication.title', {
|
||||
defaultMessage: 'Start your application with the javaagent flag',
|
||||
}),
|
||||
textPre: i18n.translate('xpack.apm.tutorial.javaClient.startApplication.textPre', {
|
||||
defaultMessage:
|
||||
'Add the `-javaagent` flag and configure the agent with system properties.\n\n \
|
||||
* Set the required service name (allowed characters: a-z, A-Z, 0-9, -, _, and space)\n \
|
||||
* Set the custom APM Server URL (default: {customApmServerUrl})\n \
|
||||
* Set the APM Server secret token\n \
|
||||
* Set the service environment\n \
|
||||
* Set the base package of your application',
|
||||
values: { customApmServerUrl: 'http://localhost:8200' },
|
||||
}
|
||||
),
|
||||
values: { customApmServerUrl: 'http://localhost:8200' },
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.javaClient.startApplication.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for configuration options and advanced \
|
||||
textPost: i18n.translate('xpack.apm.tutorial.javaClient.startApplication.textPost', {
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for configuration options and advanced \
|
||||
usage.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/java/current/index.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
values: {
|
||||
documentationLink: '{config.docs.base_url}guide/en/apm/agent/java/current/index.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const createDotNetAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createDotNetAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.dotNetClient.download.title', {
|
||||
defaultMessage: 'Download the APM agent',
|
||||
}),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.dotNetClient.download.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'Add the the agent package(s) from [NuGet]({allNuGetPackagesLink}) to your .NET application. There are multiple \
|
||||
textPre: i18n.translate('xpack.apm.tutorial.dotNetClient.download.textPre', {
|
||||
defaultMessage:
|
||||
'Add the the agent package(s) from [NuGet]({allNuGetPackagesLink}) to your .NET application. There are multiple \
|
||||
NuGet packages available for different use cases. \n\nFor an ASP.NET Core application with Entity Framework \
|
||||
Core download the [Elastic.Apm.NetCoreAll]({netCoreAllApmPackageLink}) package. This package will automatically add every \
|
||||
agent component to your application. \n\n In case you would like to minimize the dependencies, you can use the \
|
||||
[Elastic.Apm.AspNetCore]({aspNetCorePackageLink}) package for just \
|
||||
ASP.NET Core monitoring or the [Elastic.Apm.EfCore]({efCorePackageLink}) package for just Entity Framework Core monitoring. \n\n In \
|
||||
case you only want to use the public Agent API for manual instrumentation use the [Elastic.Apm]({elasticApmPackageLink}) package.',
|
||||
values: {
|
||||
allNuGetPackagesLink: 'https://www.nuget.org/packages?q=Elastic.apm',
|
||||
netCoreAllApmPackageLink:
|
||||
'https://www.nuget.org/packages/Elastic.Apm.NetCoreAll',
|
||||
aspNetCorePackageLink:
|
||||
'https://www.nuget.org/packages/Elastic.Apm.AspNetCore',
|
||||
efCorePackageLink:
|
||||
'https://www.nuget.org/packages/Elastic.Apm.EntityFrameworkCore',
|
||||
elasticApmPackageLink: 'https://www.nuget.org/packages/Elastic.Apm',
|
||||
},
|
||||
}
|
||||
),
|
||||
values: {
|
||||
allNuGetPackagesLink: 'https://www.nuget.org/packages?q=Elastic.apm',
|
||||
netCoreAllApmPackageLink: 'https://www.nuget.org/packages/Elastic.Apm.NetCoreAll',
|
||||
aspNetCorePackageLink: 'https://www.nuget.org/packages/Elastic.Apm.AspNetCore',
|
||||
efCorePackageLink: 'https://www.nuget.org/packages/Elastic.Apm.EntityFrameworkCore',
|
||||
elasticApmPackageLink: 'https://www.nuget.org/packages/Elastic.Apm',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: i18n.translate(
|
||||
'xpack.apm.tutorial.dotNetClient.configureApplication.title',
|
||||
{
|
||||
defaultMessage: 'Add the agent to the application',
|
||||
}
|
||||
),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.dotNetClient.configureApplication.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'In case of ASP.NET Core with the `Elastic.Apm.NetCoreAll` package, call the `UseAllElasticApm` \
|
||||
title: i18n.translate('xpack.apm.tutorial.dotNetClient.configureApplication.title', {
|
||||
defaultMessage: 'Add the agent to the application',
|
||||
}),
|
||||
textPre: i18n.translate('xpack.apm.tutorial.dotNetClient.configureApplication.textPre', {
|
||||
defaultMessage:
|
||||
'In case of ASP.NET Core with the `Elastic.Apm.NetCoreAll` package, call the `UseAllElasticApm` \
|
||||
method in the `Configure` method within the `Startup.cs` file.',
|
||||
}
|
||||
),
|
||||
}),
|
||||
commands: `public class Startup
|
||||
{curlyOpen}
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
|
@ -496,45 +395,33 @@ export const createDotNetAgentInstructions = (
|
|||
{curlyClose}
|
||||
//…rest of the class
|
||||
{curlyClose}`.split('\n'),
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.dotNetClient.configureApplication.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'Passing an `IConfiguration` instance is optional and by doing so, the agent will read config settings through this \
|
||||
textPost: i18n.translate('xpack.apm.tutorial.dotNetClient.configureApplication.textPost', {
|
||||
defaultMessage:
|
||||
'Passing an `IConfiguration` instance is optional and by doing so, the agent will read config settings through this \
|
||||
`IConfiguration` instance (e.g. from the `appsettings.json` file).',
|
||||
}
|
||||
),
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: i18n.translate(
|
||||
'xpack.apm.tutorial.dotNetClient.configureAgent.title',
|
||||
{
|
||||
defaultMessage: 'Sample appsettings.json file:',
|
||||
}
|
||||
),
|
||||
title: i18n.translate('xpack.apm.tutorial.dotNetClient.configureAgent.title', {
|
||||
defaultMessage: 'Sample appsettings.json file:',
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.dotNetClient.configureAgent.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'In case you don’t pass an `IConfiguration` instance to the agent (e.g. in case of non ASP.NET Core applications) \
|
||||
textPost: i18n.translate('xpack.apm.tutorial.dotNetClient.configureAgent.textPost', {
|
||||
defaultMessage:
|
||||
'In case you don’t pass an `IConfiguration` instance to the agent (e.g. in case of non ASP.NET Core applications) \
|
||||
you can also configure the agent through environment variables. \n \
|
||||
See [the documentation]({documentationLink}) for advanced usage, including the [Profiler Auto instrumentation]({profilerLink}) quick start.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/dotnet/current/configuration.html',
|
||||
profilerLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/dotnet/current/setup-auto-instrumentation.html#setup-auto-instrumentation',
|
||||
},
|
||||
}
|
||||
),
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/dotnet/current/configuration.html',
|
||||
profilerLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/dotnet/current/setup-auto-instrumentation.html#setup-auto-instrumentation',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const createPhpAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createPhpAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.phpClient.download.title', {
|
||||
defaultMessage: 'Download the APM agent',
|
||||
|
@ -551,55 +438,39 @@ export const createPhpAgentInstructions = (
|
|||
title: i18n.translate('xpack.apm.tutorial.phpClient.installPackage.title', {
|
||||
defaultMessage: 'Install the downloaded package',
|
||||
}),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.phpClient.installPackage.textPre',
|
||||
{
|
||||
defaultMessage: 'For example on Alpine Linux using APK package:',
|
||||
}
|
||||
),
|
||||
textPre: i18n.translate('xpack.apm.tutorial.phpClient.installPackage.textPre', {
|
||||
defaultMessage: 'For example on Alpine Linux using APK package:',
|
||||
}),
|
||||
commands: ['apk add --allow-untrusted <package-file>.apk'],
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.phpClient.installPackage.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for installation commands on other supported platforms and advanced installation.',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/php/current/setup.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
textPost: i18n.translate('xpack.apm.tutorial.phpClient.installPackage.textPost', {
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for installation commands on other supported platforms and advanced installation.',
|
||||
values: {
|
||||
documentationLink: '{config.docs.base_url}guide/en/apm/agent/php/current/setup.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.phpClient.configureAgent.title', {
|
||||
defaultMessage: 'Configure the agent',
|
||||
}),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.phpClient.configureAgent.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'APM is automatically started when your app boots. Configure the agent either via `php.ini` file:',
|
||||
}
|
||||
),
|
||||
textPre: i18n.translate('xpack.apm.tutorial.phpClient.configureAgent.textPre', {
|
||||
defaultMessage:
|
||||
'APM is automatically started when your app boots. Configure the agent either via `php.ini` file:',
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.phpClient.configure.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/php/current/configuration.html',
|
||||
},
|
||||
}
|
||||
),
|
||||
textPost: i18n.translate('xpack.apm.tutorial.phpClient.configure.textPost', {
|
||||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/agent/php/current/configuration.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const createOpenTelemetryAgentInstructions = (
|
||||
apmServerUrl = '',
|
||||
secretToken = ''
|
||||
) => [
|
||||
export const createOpenTelemetryAgentInstructions = (apmServerUrl = '', secretToken = '') => [
|
||||
{
|
||||
title: i18n.translate('xpack.apm.tutorial.otel.download.title', {
|
||||
defaultMessage: 'Download the OpenTelemetry APM Agent or SDK',
|
||||
|
@ -608,8 +479,7 @@ export const createOpenTelemetryAgentInstructions = (
|
|||
defaultMessage:
|
||||
'See the [OpenTelemetry Instrumentation guides]({openTelemetryInstrumentationLink}) to download the OpenTelemetry Agent or SDK for your language.',
|
||||
values: {
|
||||
openTelemetryInstrumentationLink:
|
||||
'https://opentelemetry.io/docs/instrumentation',
|
||||
openTelemetryInstrumentationLink: 'https://opentelemetry.io/docs/instrumentation',
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
@ -623,8 +493,7 @@ export const createOpenTelemetryAgentInstructions = (
|
|||
values: {
|
||||
openTelemetryDocumentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/guide/current/open-telemetry.html',
|
||||
openTelemetryInstrumentationLink:
|
||||
'https://opentelemetry.io/docs/instrumentation',
|
||||
openTelemetryInstrumentationLink: 'https://opentelemetry.io/docs/instrumentation',
|
||||
},
|
||||
}),
|
||||
customComponentName: 'TutorialConfigAgent',
|
||||
|
@ -632,8 +501,7 @@ export const createOpenTelemetryAgentInstructions = (
|
|||
defaultMessage:
|
||||
'See the [documentation]({documentationLink}) for configuration options and advanced usage.\n\n',
|
||||
values: {
|
||||
documentationLink:
|
||||
'{config.docs.base_url}guide/en/apm/guide/current/open-telemetry.html',
|
||||
documentationLink: '{config.docs.base_url}guide/en/apm/guide/current/open-telemetry.html',
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
|
|
@ -122,41 +122,32 @@ export function createWindowsServerInstructions() {
|
|||
return [
|
||||
{
|
||||
title: createDownloadServerTitle(),
|
||||
textPre: i18n.translate(
|
||||
'xpack.apm.tutorial.windowsServerInstructions.textPre',
|
||||
{
|
||||
defaultMessage:
|
||||
'1. Download the APM Server Windows zip file from the \
|
||||
textPre: i18n.translate('xpack.apm.tutorial.windowsServerInstructions.textPre', {
|
||||
defaultMessage:
|
||||
'1. Download the APM Server Windows zip file from the \
|
||||
[Download page]({downloadPageLink}).\n2. Extract the contents of \
|
||||
the zip file into {zipFileExtractFolder}.\n3. Rename the {apmServerDirectory} \
|
||||
directory to `APM-Server`.\n4. Open a PowerShell prompt as an Administrator \
|
||||
(right-click the PowerShell icon and select \
|
||||
**Run As Administrator**). If you are running Windows XP, you might need to download and install \
|
||||
PowerShell.\n5. From the PowerShell prompt, run the following commands to install APM Server as a Windows service:',
|
||||
values: {
|
||||
downloadPageLink: 'https://www.elastic.co/downloads/apm/apm-server',
|
||||
zipFileExtractFolder: '`C:\\Program Files`',
|
||||
apmServerDirectory: '`apm-server-{config.kibana.version}-windows`',
|
||||
},
|
||||
}
|
||||
),
|
||||
commands: [
|
||||
`cd 'C:\\Program Files\\APM-Server'`,
|
||||
`.\\install-service-apm-server.ps1`,
|
||||
],
|
||||
textPost: i18n.translate(
|
||||
'xpack.apm.tutorial.windowsServerInstructions.textPost',
|
||||
{
|
||||
defaultMessage:
|
||||
'Note: If script execution is disabled on your system, \
|
||||
values: {
|
||||
downloadPageLink: 'https://www.elastic.co/downloads/apm/apm-server',
|
||||
zipFileExtractFolder: '`C:\\Program Files`',
|
||||
apmServerDirectory: '`apm-server-{config.kibana.version}-windows`',
|
||||
},
|
||||
}),
|
||||
commands: [`cd 'C:\\Program Files\\APM-Server'`, `.\\install-service-apm-server.ps1`],
|
||||
textPost: i18n.translate('xpack.apm.tutorial.windowsServerInstructions.textPost', {
|
||||
defaultMessage:
|
||||
'Note: If script execution is disabled on your system, \
|
||||
you need to set the execution policy for the current session \
|
||||
to allow the script to run. For example: {command}.',
|
||||
values: {
|
||||
command:
|
||||
'`PowerShell.exe -ExecutionPolicy UnRestricted -File .\\install-service-apm-server.ps1`',
|
||||
},
|
||||
}
|
||||
),
|
||||
values: {
|
||||
command:
|
||||
'`PowerShell.exe -ExecutionPolicy UnRestricted -File .\\install-service-apm-server.ps1`',
|
||||
},
|
||||
}),
|
||||
},
|
||||
createEditConfig(),
|
||||
{
|
||||
|
|
|
@ -18,8 +18,7 @@ export const apmTutorialCustomIntegration: Omit<CustomIntegration, 'type'> = {
|
|||
categories: APM_INTEGRATION_CATEGORIES,
|
||||
uiInternalPath: '/app/apm/onboarding',
|
||||
description: i18n.translate('xpack.apm.tutorial.introduction', {
|
||||
defaultMessage:
|
||||
'Collect performance metrics from your applications with Elastic APM.',
|
||||
defaultMessage: 'Collect performance metrics from your applications with Elastic APM.',
|
||||
}),
|
||||
icons: [
|
||||
{
|
||||
|
|
|
@ -9,8 +9,6 @@ import { ValuesType } from 'utility-types';
|
|||
|
||||
// work around a TypeScript limitation described in https://stackoverflow.com/posts/49511416
|
||||
|
||||
export const arrayUnionToCallable = <T extends any[]>(
|
||||
array: T
|
||||
): Array<ValuesType<T>> => {
|
||||
export const arrayUnionToCallable = <T extends any[]>(array: T): Array<ValuesType<T>> => {
|
||||
return array;
|
||||
};
|
||||
|
|
|
@ -7,15 +7,10 @@
|
|||
|
||||
import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { SERVICE_ENVIRONMENT, SERVICE_NODE_NAME } from '../es_fields/apm';
|
||||
import {
|
||||
ENVIRONMENT_ALL,
|
||||
ENVIRONMENT_NOT_DEFINED,
|
||||
} from '../environment_filter_values';
|
||||
import { ENVIRONMENT_ALL, ENVIRONMENT_NOT_DEFINED } from '../environment_filter_values';
|
||||
import { SERVICE_NODE_NAME_MISSING } from '../service_nodes';
|
||||
|
||||
export function environmentQuery(
|
||||
environment: string | undefined
|
||||
): QueryDslQueryContainer[] {
|
||||
export function environmentQuery(environment: string | undefined): QueryDslQueryContainer[] {
|
||||
if (!environment || environment === ENVIRONMENT_ALL.value) {
|
||||
return [];
|
||||
}
|
||||
|
@ -27,9 +22,7 @@ export function environmentQuery(
|
|||
return [{ term: { [SERVICE_ENVIRONMENT]: environment } }];
|
||||
}
|
||||
|
||||
export function serviceNodeNameQuery(
|
||||
serviceNodeName?: string
|
||||
): QueryDslQueryContainer[] {
|
||||
export function serviceNodeNameQuery(serviceNodeName?: string): QueryDslQueryContainer[] {
|
||||
if (!serviceNodeName) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -8,11 +8,8 @@
|
|||
import moment from 'moment';
|
||||
import { string } from '.';
|
||||
|
||||
export function getEsqlDateRangeFilter(
|
||||
from: number | string,
|
||||
to: number | string
|
||||
) {
|
||||
return `@timestamp >= ${string`${moment(
|
||||
from
|
||||
).toISOString()}`} AND @timestamp < ${string`${moment(to).toISOString()}`}`;
|
||||
export function getEsqlDateRangeFilter(from: number | string, to: number | string) {
|
||||
return `@timestamp >= ${string`${moment(from).toISOString()}`} AND @timestamp < ${string`${moment(
|
||||
to
|
||||
).toISOString()}`}`;
|
||||
}
|
||||
|
|
|
@ -6,10 +6,7 @@
|
|||
*/
|
||||
|
||||
import { identifier, string } from '.';
|
||||
import {
|
||||
ENVIRONMENT_ALL,
|
||||
ENVIRONMENT_NOT_DEFINED,
|
||||
} from '../../environment_filter_values';
|
||||
import { ENVIRONMENT_ALL, ENVIRONMENT_NOT_DEFINED } from '../../environment_filter_values';
|
||||
import { SERVICE_ENVIRONMENT } from '../../es_fields/apm';
|
||||
|
||||
export function getEsqlEnvironmentFilter(environment: string) {
|
||||
|
|
|
@ -5,10 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export function string(
|
||||
parts: TemplateStringsArray,
|
||||
...variables: Array<string | number>
|
||||
): string {
|
||||
export function string(parts: TemplateStringsArray, ...variables: Array<string | number>): string {
|
||||
const joined = Array.from(parts.raw).concat(variables.map(String)).join('');
|
||||
return `"${joined.replaceAll(/[^\\]"/g, '\\"')}"`;
|
||||
}
|
||||
|
|
|
@ -7,20 +7,11 @@
|
|||
import { stringify } from 'querystring';
|
||||
import { ENVIRONMENT_ALL } from '../../environment_filter_values';
|
||||
|
||||
const format = ({
|
||||
pathname,
|
||||
query,
|
||||
}: {
|
||||
pathname: string;
|
||||
query: Record<string, any>;
|
||||
}): string => {
|
||||
const format = ({ pathname, query }: { pathname: string; query: Record<string, any> }): string => {
|
||||
return `${pathname}?${stringify(query)}`;
|
||||
};
|
||||
|
||||
export const getAlertUrlErrorCount = (
|
||||
serviceName: string,
|
||||
serviceEnv: string | undefined
|
||||
) =>
|
||||
export const getAlertUrlErrorCount = (serviceName: string, serviceEnv: string | undefined) =>
|
||||
format({
|
||||
pathname: `/app/apm/services/${serviceName}/errors`,
|
||||
query: {
|
||||
|
|
|
@ -6,11 +6,7 @@
|
|||
*/
|
||||
|
||||
import moment from 'moment-timezone';
|
||||
import {
|
||||
asRelativeDateTimeRange,
|
||||
asAbsoluteDateTime,
|
||||
getDateDifference,
|
||||
} from './datetime';
|
||||
import { asRelativeDateTimeRange, asAbsoluteDateTime, getDateDifference } from './datetime';
|
||||
|
||||
describe('date time formatters', () => {
|
||||
beforeAll(() => {
|
||||
|
@ -18,8 +14,7 @@ describe('date time formatters', () => {
|
|||
});
|
||||
afterAll(() => moment.tz.setDefault(''));
|
||||
describe('asRelativeDateTimeRange', () => {
|
||||
const formatDateToTimezone = (dateTimeString: string) =>
|
||||
moment(dateTimeString).valueOf();
|
||||
const formatDateToTimezone = (dateTimeString: string) => moment(dateTimeString).valueOf();
|
||||
describe('YYYY - YYYY', () => {
|
||||
it('range: 10 years', () => {
|
||||
const start = formatDateToTimezone('2000-01-01 10:01:01');
|
||||
|
@ -113,17 +108,13 @@ describe('date time formatters', () => {
|
|||
const start = formatDateToTimezone('2019-10-29 10:01:01.001');
|
||||
const end = formatDateToTimezone('2019-10-29 10:01:10.002');
|
||||
const dateRange = asRelativeDateTimeRange(start, end);
|
||||
expect(dateRange).toEqual(
|
||||
'Oct 29, 2019, 10:01:01.001 - 10:01:10.002 (UTC+1)'
|
||||
);
|
||||
expect(dateRange).toEqual('Oct 29, 2019, 10:01:01.001 - 10:01:10.002 (UTC+1)');
|
||||
});
|
||||
it('range: 1 second', () => {
|
||||
const start = formatDateToTimezone('2019-10-29 10:01:01.001');
|
||||
const end = formatDateToTimezone('2019-10-29 10:01:02.002');
|
||||
const dateRange = asRelativeDateTimeRange(start, end);
|
||||
expect(dateRange).toEqual(
|
||||
'Oct 29, 2019, 10:01:01.001 - 10:01:02.002 (UTC+1)'
|
||||
);
|
||||
expect(dateRange).toEqual('Oct 29, 2019, 10:01:01.001 - 10:01:02.002 (UTC+1)');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -133,23 +124,17 @@ describe('date time formatters', () => {
|
|||
|
||||
it('should add a leading plus for timezones with positive UTC offset', () => {
|
||||
moment.tz.setDefault('Europe/Copenhagen');
|
||||
expect(asAbsoluteDateTime(1559390400000, 'minutes')).toBe(
|
||||
'Jun 1, 2019, 14:00 (UTC+2)'
|
||||
);
|
||||
expect(asAbsoluteDateTime(1559390400000, 'minutes')).toBe('Jun 1, 2019, 14:00 (UTC+2)');
|
||||
});
|
||||
|
||||
it('should add a leading minus for timezones with negative UTC offset', () => {
|
||||
moment.tz.setDefault('America/Los_Angeles');
|
||||
expect(asAbsoluteDateTime(1559390400000, 'minutes')).toBe(
|
||||
'Jun 1, 2019, 05:00 (UTC-7)'
|
||||
);
|
||||
expect(asAbsoluteDateTime(1559390400000, 'minutes')).toBe('Jun 1, 2019, 05:00 (UTC-7)');
|
||||
});
|
||||
|
||||
it('should use default UTC offset formatting when offset contains minutes', () => {
|
||||
moment.tz.setDefault('Canada/Newfoundland');
|
||||
expect(asAbsoluteDateTime(1559390400000, 'minutes')).toBe(
|
||||
'Jun 1, 2019, 09:30 (UTC-02:30)'
|
||||
);
|
||||
expect(asAbsoluteDateTime(1559390400000, 'minutes')).toBe('Jun 1, 2019, 09:30 (UTC-02:30)');
|
||||
});
|
||||
|
||||
it('should respect DST', () => {
|
||||
|
@ -157,13 +142,9 @@ describe('date time formatters', () => {
|
|||
const timeWithDST = 1559390400000; // Jun 1, 2019
|
||||
const timeWithoutDST = 1575201600000; // Dec 1, 2019
|
||||
|
||||
expect(asAbsoluteDateTime(timeWithDST)).toBe(
|
||||
'Jun 1, 2019, 14:00:00.000 (UTC+2)'
|
||||
);
|
||||
expect(asAbsoluteDateTime(timeWithDST)).toBe('Jun 1, 2019, 14:00:00.000 (UTC+2)');
|
||||
|
||||
expect(asAbsoluteDateTime(timeWithoutDST)).toBe(
|
||||
'Dec 1, 2019, 13:00:00.000 (UTC+1)'
|
||||
);
|
||||
expect(asAbsoluteDateTime(timeWithoutDST)).toBe('Dec 1, 2019, 13:00:00.000 (UTC+1)');
|
||||
});
|
||||
|
||||
it('milliseconds', () => {
|
||||
|
@ -175,46 +156,34 @@ describe('date time formatters', () => {
|
|||
|
||||
it('seconds', () => {
|
||||
moment.tz.setDefault('Europe/Copenhagen');
|
||||
expect(asAbsoluteDateTime(1559390400000, 'seconds')).toBe(
|
||||
'Jun 1, 2019, 14:00:00 (UTC+2)'
|
||||
);
|
||||
expect(asAbsoluteDateTime(1559390400000, 'seconds')).toBe('Jun 1, 2019, 14:00:00 (UTC+2)');
|
||||
});
|
||||
|
||||
it('minutes', () => {
|
||||
moment.tz.setDefault('Europe/Copenhagen');
|
||||
expect(asAbsoluteDateTime(1559390400000, 'minutes')).toBe(
|
||||
'Jun 1, 2019, 14:00 (UTC+2)'
|
||||
);
|
||||
expect(asAbsoluteDateTime(1559390400000, 'minutes')).toBe('Jun 1, 2019, 14:00 (UTC+2)');
|
||||
});
|
||||
|
||||
it('hours', () => {
|
||||
moment.tz.setDefault('Europe/Copenhagen');
|
||||
expect(asAbsoluteDateTime(1559390400000, 'hours')).toBe(
|
||||
'Jun 1, 2019, 14 (UTC+2)'
|
||||
);
|
||||
expect(asAbsoluteDateTime(1559390400000, 'hours')).toBe('Jun 1, 2019, 14 (UTC+2)');
|
||||
});
|
||||
});
|
||||
describe('getDateDifference', () => {
|
||||
it('milliseconds', () => {
|
||||
const start = moment('2019-10-29 08:00:00.001');
|
||||
const end = moment('2019-10-29 08:00:00.005');
|
||||
expect(
|
||||
getDateDifference({ start, end, unitOfTime: 'milliseconds' })
|
||||
).toEqual(4);
|
||||
expect(getDateDifference({ start, end, unitOfTime: 'milliseconds' })).toEqual(4);
|
||||
});
|
||||
it('seconds', () => {
|
||||
const start = moment('2019-10-29 08:00:00');
|
||||
const end = moment('2019-10-29 08:00:10');
|
||||
expect(getDateDifference({ start, end, unitOfTime: 'seconds' })).toEqual(
|
||||
10
|
||||
);
|
||||
expect(getDateDifference({ start, end, unitOfTime: 'seconds' })).toEqual(10);
|
||||
});
|
||||
it('minutes', () => {
|
||||
const start = moment('2019-10-29 08:00:00');
|
||||
const end = moment('2019-10-29 08:15:00');
|
||||
expect(getDateDifference({ start, end, unitOfTime: 'minutes' })).toEqual(
|
||||
15
|
||||
);
|
||||
expect(getDateDifference({ start, end, unitOfTime: 'minutes' })).toEqual(15);
|
||||
});
|
||||
it('hours', () => {
|
||||
const start = moment('2019-10-29 08:00:00');
|
||||
|
@ -229,9 +198,7 @@ describe('date time formatters', () => {
|
|||
it('months', () => {
|
||||
const start = moment('2019-10-29 08:00:00');
|
||||
const end = moment('2019-12-29 08:00:00');
|
||||
expect(getDateDifference({ start, end, unitOfTime: 'months' })).toEqual(
|
||||
2
|
||||
);
|
||||
expect(getDateDifference({ start, end, unitOfTime: 'months' })).toEqual(2);
|
||||
});
|
||||
it('years', () => {
|
||||
const start = moment('2019-10-29 08:00:00');
|
||||
|
@ -241,9 +208,9 @@ describe('date time formatters', () => {
|
|||
it('precise days', () => {
|
||||
const start = moment('2019-10-29 08:00:00');
|
||||
const end = moment('2019-10-30 10:00:00');
|
||||
expect(
|
||||
getDateDifference({ start, end, unitOfTime: 'days', precise: true })
|
||||
).toEqual(1.0833333333333333);
|
||||
expect(getDateDifference({ start, end, unitOfTime: 'days', precise: true })).toEqual(
|
||||
1.0833333333333333
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,8 +18,7 @@ function formatTimezone(momentTime: moment.Moment) {
|
|||
|
||||
const utcOffsetHours = momentTime.utcOffset() / 60;
|
||||
|
||||
const customTimezoneFormat =
|
||||
utcOffsetHours > 0 ? `+${utcOffsetHours}` : utcOffsetHours;
|
||||
const customTimezoneFormat = utcOffsetHours > 0 ? `+${utcOffsetHours}` : utcOffsetHours;
|
||||
|
||||
const utcOffsetFormatted = Number.isInteger(utcOffsetHours)
|
||||
? customTimezoneFormat
|
||||
|
@ -70,10 +69,7 @@ export const getDateDifference = ({
|
|||
precise?: boolean;
|
||||
}) => end.diff(start, unitOfTime, precise);
|
||||
|
||||
function getFormatsAccordingToDateDifference(
|
||||
start: moment.Moment,
|
||||
end: moment.Moment
|
||||
) {
|
||||
function getFormatsAccordingToDateDifference(start: moment.Moment, end: moment.Moment) {
|
||||
if (getDateDifference({ start, end, unitOfTime: 'years' }) >= 5) {
|
||||
return { dateFormat: getDateFormat('years') };
|
||||
}
|
||||
|
@ -117,9 +113,7 @@ export function asAbsoluteDateTime(
|
|||
const momentTime = moment(time);
|
||||
const formattedTz = formatTimezone(momentTime);
|
||||
|
||||
return momentTime.format(
|
||||
`${getDateFormat('days')}, ${getTimeFormat(timeUnit)} ${formattedTz}`
|
||||
);
|
||||
return momentTime.format(`${getDateFormat('days')}, ${getTimeFormat(timeUnit)} ${formattedTz}`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,9 +142,7 @@ export function asRelativeDateTimeRange(start: number, end: number) {
|
|||
);
|
||||
|
||||
if (timeFormat) {
|
||||
const startFormatted = momentStartTime.format(
|
||||
`${dateFormat}, ${timeFormat}`
|
||||
);
|
||||
const startFormatted = momentStartTime.format(`${dateFormat}, ${timeFormat}`);
|
||||
const endFormatted = momentEndTime.format(timeFormat);
|
||||
const formattedTz = formatTimezone(momentStartTime);
|
||||
return `${startFormatted} - ${endFormatted} ${formattedTz}`;
|
||||
|
|
|
@ -20,12 +20,8 @@ describe('duration formatters', () => {
|
|||
expect(asDuration(0)).toEqual('0 μs');
|
||||
expect(asDuration(1)).toEqual('1 μs');
|
||||
expect(asDuration(toMicroseconds(1, 'milliseconds'))).toEqual('1,000 μs');
|
||||
expect(asDuration(toMicroseconds(1000, 'milliseconds'))).toEqual(
|
||||
'1,000 ms'
|
||||
);
|
||||
expect(asDuration(toMicroseconds(10000, 'milliseconds'))).toEqual(
|
||||
'10,000 ms'
|
||||
);
|
||||
expect(asDuration(toMicroseconds(1000, 'milliseconds'))).toEqual('1,000 ms');
|
||||
expect(asDuration(toMicroseconds(10000, 'milliseconds'))).toEqual('10,000 ms');
|
||||
expect(asDuration(toMicroseconds(20, 'seconds'))).toEqual('20 s');
|
||||
expect(asDuration(toMicroseconds(10, 'minutes'))).toEqual('600 s');
|
||||
expect(asDuration(toMicroseconds(11, 'minutes'))).toEqual('11 min');
|
||||
|
@ -44,43 +40,21 @@ describe('duration formatters', () => {
|
|||
// Formatting with a default threshold of 10 for more detail for single values
|
||||
it('formats correctly with defaults', () => {
|
||||
expect(getDurationFormatter(987654)(987654).formatted).toEqual('988 ms');
|
||||
expect(getDurationFormatter(1000000)(1000000).formatted).toEqual(
|
||||
'1,000 ms'
|
||||
);
|
||||
expect(getDurationFormatter(1234567)(1234567).formatted).toEqual(
|
||||
'1,235 ms'
|
||||
);
|
||||
expect(getDurationFormatter(9876543)(9876543).formatted).toEqual(
|
||||
'9,877 ms'
|
||||
);
|
||||
expect(getDurationFormatter(10000000)(10000000).formatted).toEqual(
|
||||
'10,000 ms'
|
||||
);
|
||||
expect(getDurationFormatter(12345678)(12345678).formatted).toEqual(
|
||||
'12 s'
|
||||
);
|
||||
expect(getDurationFormatter(1000000)(1000000).formatted).toEqual('1,000 ms');
|
||||
expect(getDurationFormatter(1234567)(1234567).formatted).toEqual('1,235 ms');
|
||||
expect(getDurationFormatter(9876543)(9876543).formatted).toEqual('9,877 ms');
|
||||
expect(getDurationFormatter(10000000)(10000000).formatted).toEqual('10,000 ms');
|
||||
expect(getDurationFormatter(12345678)(12345678).formatted).toEqual('12 s');
|
||||
});
|
||||
|
||||
// Formatting useful for axis ticks with a lower threshold where less detail is sufficient
|
||||
it('formats correctly with a threshold of 0.9999', () => {
|
||||
expect(getDurationFormatter(987654, 0.9999)(987654).formatted).toEqual(
|
||||
'988 ms'
|
||||
);
|
||||
expect(getDurationFormatter(1000000, 0.9999)(1000000).formatted).toEqual(
|
||||
'1 s'
|
||||
);
|
||||
expect(getDurationFormatter(1234567, 0.9999)(1234567).formatted).toEqual(
|
||||
'1 s'
|
||||
);
|
||||
expect(getDurationFormatter(9876543, 0.9999)(9876543).formatted).toEqual(
|
||||
'10 s'
|
||||
);
|
||||
expect(
|
||||
getDurationFormatter(10000000, 0.9999)(10000000).formatted
|
||||
).toEqual('10 s');
|
||||
expect(
|
||||
getDurationFormatter(12345678, 0.9999)(12345678).formatted
|
||||
).toEqual('12 s');
|
||||
expect(getDurationFormatter(987654, 0.9999)(987654).formatted).toEqual('988 ms');
|
||||
expect(getDurationFormatter(1000000, 0.9999)(1000000).formatted).toEqual('1 s');
|
||||
expect(getDurationFormatter(1234567, 0.9999)(1234567).formatted).toEqual('1 s');
|
||||
expect(getDurationFormatter(9876543, 0.9999)(9876543).formatted).toEqual('10 s');
|
||||
expect(getDurationFormatter(10000000, 0.9999)(10000000).formatted).toEqual('10 s');
|
||||
expect(getDurationFormatter(12345678, 0.9999)(12345678).formatted).toEqual('12 s');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -26,10 +26,7 @@ interface ConvertedDuration {
|
|||
formatted: string;
|
||||
}
|
||||
|
||||
export type TimeFormatter = (
|
||||
value: Maybe<number>,
|
||||
options?: FormatterOptions
|
||||
) => ConvertedDuration;
|
||||
export type TimeFormatter = (value: Maybe<number>, options?: FormatterOptions) => ConvertedDuration;
|
||||
|
||||
type TimeFormatterBuilder = (
|
||||
max: number,
|
||||
|
@ -51,10 +48,7 @@ function getUnitLabelAndConvertedValue(
|
|||
unitLabel: i18n.translate('xpack.apm.formatters.hoursTimeUnitLabel', {
|
||||
defaultMessage: 'h',
|
||||
}),
|
||||
convertedValue: asDecimalOrInteger(
|
||||
moment.duration(ms).asHours(),
|
||||
threshold
|
||||
),
|
||||
convertedValue: asDecimalOrInteger(moment.duration(ms).asHours(), threshold),
|
||||
};
|
||||
}
|
||||
case 'minutes': {
|
||||
|
@ -62,10 +56,7 @@ function getUnitLabelAndConvertedValue(
|
|||
unitLabel: i18n.translate('xpack.apm.formatters.minutesTimeUnitLabel', {
|
||||
defaultMessage: 'min',
|
||||
}),
|
||||
convertedValue: asDecimalOrInteger(
|
||||
moment.duration(ms).asMinutes(),
|
||||
threshold
|
||||
),
|
||||
convertedValue: asDecimalOrInteger(moment.duration(ms).asMinutes(), threshold),
|
||||
};
|
||||
}
|
||||
case 'seconds': {
|
||||
|
@ -73,10 +64,7 @@ function getUnitLabelAndConvertedValue(
|
|||
unitLabel: i18n.translate('xpack.apm.formatters.secondsTimeUnitLabel', {
|
||||
defaultMessage: 's',
|
||||
}),
|
||||
convertedValue: asDecimalOrInteger(
|
||||
moment.duration(ms).asSeconds(),
|
||||
threshold
|
||||
),
|
||||
convertedValue: asDecimalOrInteger(moment.duration(ms).asSeconds(), threshold),
|
||||
};
|
||||
}
|
||||
case 'milliseconds': {
|
||||
|
@ -84,10 +72,7 @@ function getUnitLabelAndConvertedValue(
|
|||
unitLabel: i18n.translate('xpack.apm.formatters.millisTimeUnitLabel', {
|
||||
defaultMessage: 'ms',
|
||||
}),
|
||||
convertedValue: asDecimalOrInteger(
|
||||
moment.duration(ms).asMilliseconds(),
|
||||
threshold
|
||||
),
|
||||
convertedValue: asDecimalOrInteger(moment.duration(ms).asMilliseconds(), threshold),
|
||||
};
|
||||
}
|
||||
case 'microseconds': {
|
||||
|
|
|
@ -21,53 +21,34 @@ describe('get kuery fields', () => {
|
|||
});
|
||||
|
||||
it('returns multiple fields used AND operator', () => {
|
||||
const kuery =
|
||||
'service.name: my-service AND service.environment: production';
|
||||
const kuery = 'service.name: my-service AND service.environment: production';
|
||||
const kueryNode = fromKueryExpression(kuery);
|
||||
expect(getKueryFields([kueryNode])).toEqual([
|
||||
'service.name',
|
||||
'service.environment',
|
||||
]);
|
||||
expect(getKueryFields([kueryNode])).toEqual(['service.name', 'service.environment']);
|
||||
});
|
||||
|
||||
it('returns multiple kuery fields with OR operator', () => {
|
||||
const kuery = 'network.carrier.mcc: test or child.id: 33';
|
||||
const kueryNode = fromKueryExpression(kuery);
|
||||
expect(getKueryFields([kueryNode])).toEqual([
|
||||
'network.carrier.mcc',
|
||||
'child.id',
|
||||
]);
|
||||
expect(getKueryFields([kueryNode])).toEqual(['network.carrier.mcc', 'child.id']);
|
||||
});
|
||||
|
||||
it('returns multiple kuery fields with wildcard', () => {
|
||||
const kuery = 'network.carrier.mcc:* or child.id: *';
|
||||
const kueryNode = fromKueryExpression(kuery);
|
||||
expect(getKueryFields([kueryNode])).toEqual([
|
||||
'network.carrier.mcc',
|
||||
'child.id',
|
||||
]);
|
||||
expect(getKueryFields([kueryNode])).toEqual(['network.carrier.mcc', 'child.id']);
|
||||
});
|
||||
|
||||
it('returns single kuery fields with gt operator', () => {
|
||||
const kuery = 'transaction.duration.aggregate > 10';
|
||||
const kueryNode = fromKueryExpression(kuery);
|
||||
expect(getKueryFields([kueryNode])).toEqual([
|
||||
'transaction.duration.aggregate',
|
||||
]);
|
||||
expect(getKueryFields([kueryNode])).toEqual(['transaction.duration.aggregate']);
|
||||
});
|
||||
|
||||
it('returns dublicate fields', () => {
|
||||
const kueries = [
|
||||
'service.name: my-service',
|
||||
'service.name: my-service and trace.id: trace',
|
||||
];
|
||||
const kueries = ['service.name: my-service', 'service.name: my-service and trace.id: trace'];
|
||||
|
||||
const kueryNodes = kueries.map((kuery) => fromKueryExpression(kuery));
|
||||
expect(getKueryFields(kueryNodes)).toEqual([
|
||||
'service.name',
|
||||
'service.name',
|
||||
'trace.id',
|
||||
]);
|
||||
expect(getKueryFields(kueryNodes)).toEqual(['service.name', 'service.name', 'trace.id']);
|
||||
});
|
||||
|
||||
it('returns multiple fields with multiple logical operators', () => {
|
||||
|
|
|
@ -102,9 +102,7 @@ describe('getKueryWithMobileCrashFilter', () => {
|
|||
groupId: '1',
|
||||
kuery: 'foo.bar: test',
|
||||
});
|
||||
expect(result).toBe(
|
||||
'foo.bar: test and error.type: crash and error.grouping_key: 1'
|
||||
);
|
||||
expect(result).toBe('foo.bar: test and error.type: crash and error.grouping_key: 1');
|
||||
});
|
||||
});
|
||||
describe('getKueryWithMobileErrorFilter', () => {
|
||||
|
@ -134,8 +132,6 @@ describe('getKueryWithMobileErrorFilter', () => {
|
|||
groupId: '1',
|
||||
kuery: 'foo.bar: test',
|
||||
});
|
||||
expect(result).toBe(
|
||||
'foo.bar: test and NOT error.type: crash and error.grouping_key: 1'
|
||||
);
|
||||
expect(result).toBe('foo.bar: test and NOT error.type: crash and error.grouping_key: 1');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -75,27 +75,16 @@ describe('getPreferredBucketSizeAndDataSource', () => {
|
|||
|
||||
tests.forEach((test) => {
|
||||
it(`${test.in} => ${test.out}`, () => {
|
||||
const { source, bucketSizeInSeconds } =
|
||||
getPreferredBucketSizeAndDataSource({
|
||||
sources: [
|
||||
...serviceTransactionMetricSources,
|
||||
...txMetricSources,
|
||||
...txEventSources,
|
||||
],
|
||||
bucketSizeInSeconds: intervalToSeconds(test.in),
|
||||
});
|
||||
const { source, bucketSizeInSeconds } = getPreferredBucketSizeAndDataSource({
|
||||
sources: [...serviceTransactionMetricSources, ...txMetricSources, ...txEventSources],
|
||||
bucketSizeInSeconds: intervalToSeconds(test.in),
|
||||
});
|
||||
|
||||
expect(source.documentType).toBe(
|
||||
ApmDocumentType.ServiceTransactionMetric
|
||||
);
|
||||
expect(source.documentType).toBe(ApmDocumentType.ServiceTransactionMetric);
|
||||
|
||||
expect(intervalToSeconds(source.rollupInterval)).toBe(
|
||||
intervalToSeconds(test.out)
|
||||
);
|
||||
expect(intervalToSeconds(source.rollupInterval)).toBe(intervalToSeconds(test.out));
|
||||
|
||||
expect(bucketSizeInSeconds).toBeGreaterThanOrEqual(
|
||||
intervalToSeconds(test.out)
|
||||
);
|
||||
expect(bucketSizeInSeconds).toBeGreaterThanOrEqual(intervalToSeconds(test.out));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -56,9 +56,7 @@ export function getPreferredBucketSizeAndDataSource({
|
|||
|
||||
preferred =
|
||||
sourcesFromPreferredDocumentType.find((source) => {
|
||||
const rollupIntervalInSeconds = intervalToSeconds(
|
||||
source.rollupInterval
|
||||
);
|
||||
const rollupIntervalInSeconds = intervalToSeconds(source.rollupInterval);
|
||||
|
||||
return rollupIntervalInSeconds <= bucketSizeInSeconds;
|
||||
}) ||
|
||||
|
@ -77,9 +75,6 @@ export function getPreferredBucketSizeAndDataSource({
|
|||
|
||||
return {
|
||||
source: preferred,
|
||||
bucketSizeInSeconds: Math.max(
|
||||
bucketSizeInSeconds,
|
||||
intervalToSeconds(preferred.rollupInterval)
|
||||
),
|
||||
bucketSizeInSeconds: Math.max(bucketSizeInSeconds, intervalToSeconds(preferred.rollupInterval)),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -132,9 +132,11 @@ describe('joinByKey', () => {
|
|||
})
|
||||
);
|
||||
|
||||
expect(
|
||||
joined.find((item) => item.serviceName === 'opbeans-node')?.values
|
||||
).toEqual(['a', 'b', 'c']);
|
||||
expect(joined.find((item) => item.serviceName === 'opbeans-node')?.values).toEqual([
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
]);
|
||||
});
|
||||
|
||||
it('deeply merges objects', () => {
|
||||
|
|
|
@ -52,14 +52,11 @@ export function joinByKey<
|
|||
export function joinByKey(
|
||||
items: Array<Record<string, any>>,
|
||||
key: string | string[],
|
||||
mergeFn: Function = (a: Record<string, any>, b: Record<string, any>) =>
|
||||
merge({}, a, b)
|
||||
mergeFn: Function = (a: Record<string, any>, b: Record<string, any>) => merge({}, a, b)
|
||||
) {
|
||||
const keys = castArray(key);
|
||||
return items.reduce<Array<Record<string, any>>>((prev, current) => {
|
||||
let item = prev.find((prevItem) =>
|
||||
keys.every((k) => isEqual(prevItem[k], current[k]))
|
||||
);
|
||||
let item = prev.find((prevItem) => keys.every((k) => isEqual(prevItem[k], current[k])));
|
||||
|
||||
if (!item) {
|
||||
item = { ...current };
|
||||
|
|
|
@ -33,30 +33,23 @@ describe('toKueryFilterFormat', () => {
|
|||
});
|
||||
|
||||
it('returns only first kuery when second is empty', () => {
|
||||
expect(mergeKueries(['host.name: "foo"', ''])).toEqual(
|
||||
'host.name: "foo"'
|
||||
);
|
||||
expect(mergeKueries(['host.name: "foo"', ''])).toEqual('host.name: "foo"');
|
||||
});
|
||||
|
||||
it('returns second kuery when first is empty', () => {
|
||||
expect(mergeKueries(['', 'host.name: "foo"'])).toEqual(
|
||||
'host.name: "foo"'
|
||||
);
|
||||
expect(mergeKueries(['', 'host.name: "foo"'])).toEqual('host.name: "foo"');
|
||||
});
|
||||
|
||||
it('returns merged kueries with default separator', () => {
|
||||
expect(
|
||||
mergeKueries([
|
||||
'host.name: "foo" OR host.name: "bar"',
|
||||
'process.id: "1"',
|
||||
])
|
||||
).toEqual('host.name: "foo" OR host.name: "bar" AND process.id: "1"');
|
||||
expect(mergeKueries(['host.name: "foo" OR host.name: "bar"', 'process.id: "1"'])).toEqual(
|
||||
'host.name: "foo" OR host.name: "bar" AND process.id: "1"'
|
||||
);
|
||||
});
|
||||
|
||||
it('uses custom separator', () => {
|
||||
expect(
|
||||
mergeKueries(['host.name: "foo"', 'process.id: "1"'], 'OR')
|
||||
).toEqual('host.name: "foo" OR process.id: "1"');
|
||||
expect(mergeKueries(['host.name: "foo"', 'process.id: "1"'], 'OR')).toEqual(
|
||||
'host.name: "foo" OR process.id: "1"'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,11 +9,8 @@ import { isEmpty } from 'lodash';
|
|||
|
||||
type Separator = 'OR' | 'AND';
|
||||
|
||||
export const toKueryFilterFormat = (
|
||||
key: string,
|
||||
values: string[],
|
||||
separator: Separator = 'OR'
|
||||
) => values.map((value) => `${key} : "${value}"`).join(` ${separator} `);
|
||||
export const toKueryFilterFormat = (key: string, values: string[], separator: Separator = 'OR') =>
|
||||
values.map((value) => `${key} : "${value}"`).join(` ${separator} `);
|
||||
|
||||
export const mergeKueries = (filters: string[], separator: Separator = 'AND') =>
|
||||
filters.filter((filter) => !isEmpty(filter)).join(` ${separator} `);
|
||||
|
|
|
@ -48,9 +48,7 @@ describe('Dependencies', () => {
|
|||
|
||||
it('has no detectable a11y violations on load', () => {
|
||||
cy.visitKibana(
|
||||
`/app/apm/services/opbeans-java/dependencies?${new URLSearchParams(
|
||||
timeRange
|
||||
)}`
|
||||
`/app/apm/services/opbeans-java/dependencies?${new URLSearchParams(timeRange)}`
|
||||
);
|
||||
cy.contains('a[role="tab"]', 'Dependencies');
|
||||
// set skipFailures to true to not fail the test when there are accessibility failures
|
||||
|
@ -91,11 +89,7 @@ describe('Dependencies', () => {
|
|||
|
||||
describe('service overview page', () => {
|
||||
it('shows dependency information and you can navigate to a page for a dependency', () => {
|
||||
cy.visitKibana(
|
||||
`/app/apm/services/opbeans-java/overview?${new URLSearchParams(
|
||||
timeRange
|
||||
)}`
|
||||
);
|
||||
cy.visitKibana(`/app/apm/services/opbeans-java/overview?${new URLSearchParams(timeRange)}`);
|
||||
|
||||
cy.contains('a', 'postgresql').click({ force: true });
|
||||
|
||||
|
@ -105,11 +99,7 @@ describe('Dependencies', () => {
|
|||
|
||||
describe('service dependencies tab', () => {
|
||||
it('shows dependency information and you can navigate to a page for a dependency', () => {
|
||||
cy.visitKibana(
|
||||
`/app/apm/services/opbeans-java/overview?${new URLSearchParams(
|
||||
timeRange
|
||||
)}`
|
||||
);
|
||||
cy.visitKibana(`/app/apm/services/opbeans-java/overview?${new URLSearchParams(timeRange)}`);
|
||||
|
||||
cy.contains('a[role="tab"]', 'Dependencies').click();
|
||||
|
||||
|
@ -141,9 +131,7 @@ describe('Dependencies with high volume of data', () => {
|
|||
});
|
||||
|
||||
it('shows dependencies inventory page', () => {
|
||||
cy.visitKibana(
|
||||
`/app/apm/dependencies/inventory?${new URLSearchParams(timeRange)}`
|
||||
);
|
||||
cy.visitKibana(`/app/apm/dependencies/inventory?${new URLSearchParams(timeRange)}`);
|
||||
|
||||
cy.getByTestSubj('dependenciesTable');
|
||||
cy.contains('nav', 'Page 1 of 60');
|
||||
|
|
|
@ -11,13 +11,7 @@ const MAX_DEPENDENCIES = 10000;
|
|||
const MAX_DEPENDENCIES_PER_SERVICE = 500;
|
||||
const MAX_SERVICES = 20;
|
||||
|
||||
export function generateManyDependencies({
|
||||
from,
|
||||
to,
|
||||
}: {
|
||||
from: number;
|
||||
to: number;
|
||||
}) {
|
||||
export function generateManyDependencies({ from, to }: { from: number; to: number }) {
|
||||
const instances = Array.from({ length: MAX_SERVICES }).map((_, index) =>
|
||||
apm
|
||||
.service({
|
||||
|
@ -61,9 +55,6 @@ export function generateManyDependencies({
|
|||
};
|
||||
|
||||
return instances.flatMap((instance, index) =>
|
||||
instanceDependencies(
|
||||
instance,
|
||||
(index * MAX_DEPENDENCIES_PER_SERVICE) % MAX_DEPENDENCIES
|
||||
)
|
||||
instanceDependencies(instance, (index * MAX_DEPENDENCIES_PER_SERVICE) % MAX_DEPENDENCIES)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,41 +16,25 @@ describe('Diagnostics', () => {
|
|||
cy.visitKibana('/app/apm/diagnostics');
|
||||
|
||||
// integration package
|
||||
cy.get('[data-test-subj="integrationPackageStatus_Badge"]').should(
|
||||
'have.text',
|
||||
'OK'
|
||||
);
|
||||
cy.get('[data-test-subj="integrationPackageStatus_Badge"]').should('have.text', 'OK');
|
||||
|
||||
// data stream
|
||||
cy.get('[data-test-subj="dataStreamsStatus_Badge"]').should(
|
||||
'have.text',
|
||||
'OK'
|
||||
);
|
||||
cy.get('[data-test-subj="dataStreamsStatus_Badge"]').should('have.text', 'OK');
|
||||
|
||||
// Index template
|
||||
cy.get('[data-test-subj="indexTemplatesStatus_Badge"]').should(
|
||||
'have.text',
|
||||
'OK'
|
||||
);
|
||||
cy.get('[data-test-subj="indexTemplatesStatus_Badge"]').should('have.text', 'OK');
|
||||
|
||||
// Index template
|
||||
cy.get('[data-test-subj="fieldMappingStatus_Badge"]').should(
|
||||
'have.text',
|
||||
'OK'
|
||||
);
|
||||
cy.get('[data-test-subj="fieldMappingStatus_Badge"]').should('have.text', 'OK');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when importing a file', () => {
|
||||
it('shows the remove button', () => {
|
||||
importBundle();
|
||||
cy.get('[data-test-subj="apmImportCardRemoveReportButton"]').should(
|
||||
'exist'
|
||||
);
|
||||
cy.get('[data-test-subj="apmImportCardRemoveReportButton"]').should('exist');
|
||||
clearBundle();
|
||||
cy.get('[data-test-subj="apmImportCardRemoveReportButton"]').should(
|
||||
'not.exist'
|
||||
);
|
||||
cy.get('[data-test-subj="apmImportCardRemoveReportButton"]').should('not.exist');
|
||||
});
|
||||
|
||||
it('can display summary tab', () => {
|
||||
|
@ -58,10 +42,7 @@ describe('Diagnostics', () => {
|
|||
cy.get('[data-test-subj="summary-tab"]').click();
|
||||
|
||||
// integration package
|
||||
cy.get('[data-test-subj="integrationPackageStatus_Badge"]').should(
|
||||
'have.text',
|
||||
'OK'
|
||||
);
|
||||
cy.get('[data-test-subj="integrationPackageStatus_Badge"]').should('have.text', 'OK');
|
||||
|
||||
cy.get('[data-test-subj="integrationPackageStatus_Content"]').should(
|
||||
'have.text',
|
||||
|
@ -69,22 +50,13 @@ describe('Diagnostics', () => {
|
|||
);
|
||||
|
||||
// data stream
|
||||
cy.get('[data-test-subj="dataStreamsStatus_Badge"]').should(
|
||||
'have.text',
|
||||
'OK'
|
||||
);
|
||||
cy.get('[data-test-subj="dataStreamsStatus_Badge"]').should('have.text', 'OK');
|
||||
|
||||
// Index template
|
||||
cy.get('[data-test-subj="indexTemplatesStatus_Badge"]').should(
|
||||
'have.text',
|
||||
'OK'
|
||||
);
|
||||
cy.get('[data-test-subj="indexTemplatesStatus_Badge"]').should('have.text', 'OK');
|
||||
|
||||
// Index template
|
||||
cy.get('[data-test-subj="fieldMappingStatus_Badge"]').should(
|
||||
'have.text',
|
||||
'Warning'
|
||||
);
|
||||
cy.get('[data-test-subj="fieldMappingStatus_Badge"]').should('have.text', 'Warning');
|
||||
});
|
||||
|
||||
it('can display index template tab', () => {
|
||||
|
@ -103,15 +75,9 @@ describe('Diagnostics', () => {
|
|||
importBundle();
|
||||
cy.get('[data-test-subj="indices-tab"]').click();
|
||||
|
||||
cy.get('[data-test-subj="indicedWithProblems"] .euiTableRow').should(
|
||||
'have.length',
|
||||
138
|
||||
);
|
||||
cy.get('[data-test-subj="indicedWithProblems"] .euiTableRow').should('have.length', 138);
|
||||
|
||||
cy.get('[data-test-subj="indicedWithoutProblems"] .euiTableRow').should(
|
||||
'have.length',
|
||||
27
|
||||
);
|
||||
cy.get('[data-test-subj="indicedWithoutProblems"] .euiTableRow').should('have.length', 27);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -135,9 +101,9 @@ describe('Diagnostics', () => {
|
|||
cy.visitKibana('/app/apm/diagnostics');
|
||||
|
||||
const tabs = ['Summary', 'Documents', 'Import/Export'];
|
||||
cy.get(
|
||||
'[data-test-subj="apmDiagnosticsTemplate"] .euiTabs .euiTab'
|
||||
).each((tab, i) => cy.wrap(tab).should('have.text', tabs[i]));
|
||||
cy.get('[data-test-subj="apmDiagnosticsTemplate"] .euiTabs .euiTab').each((tab, i) =>
|
||||
cy.wrap(tab).should('have.text', tabs[i])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -146,10 +112,7 @@ describe('Diagnostics', () => {
|
|||
importBundle();
|
||||
cy.get('[data-test-subj="documents-tab"]').click();
|
||||
|
||||
cy.get('[data-test-subj="documents-table"] .euiTableRow').should(
|
||||
'have.length',
|
||||
10
|
||||
);
|
||||
cy.get('[data-test-subj="documents-table"] .euiTableRow').should('have.length', 10);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -88,9 +88,7 @@ describe('Error details', () => {
|
|||
it('shows top erroneous transactions table', () => {
|
||||
cy.visitKibana(errorDetailsPageHref);
|
||||
cy.contains('Top 5 affected transactions');
|
||||
cy.getByTestSubj('topErroneousTransactionsTable')
|
||||
.contains('a', 'GET /apple 🍎')
|
||||
.click();
|
||||
cy.getByTestSubj('topErroneousTransactionsTable').contains('a', 'GET /apple 🍎').click();
|
||||
cy.url().should('include', 'opbeans-java/transactions/view');
|
||||
});
|
||||
|
||||
|
|
|
@ -83,19 +83,13 @@ describe('Errors page', () => {
|
|||
|
||||
it('clicking on type adds a filter in the searchbar', () => {
|
||||
cy.visitKibana(javaServiceErrorsPageHref);
|
||||
cy.getByTestSubj('apmUnifiedSearchBar')
|
||||
.invoke('val')
|
||||
.should('be.empty');
|
||||
cy.getByTestSubj('apmUnifiedSearchBar').invoke('val').should('be.empty');
|
||||
// `force: true` because Cypress says the element is 0x0
|
||||
cy.contains('exception 0').click({
|
||||
force: true,
|
||||
});
|
||||
cy.getByTestSubj('apmUnifiedSearchBar')
|
||||
.its('length')
|
||||
.should('be.gt', 0);
|
||||
cy.get('table')
|
||||
.find('td:contains("exception 0")')
|
||||
.should('have.length', 1);
|
||||
cy.getByTestSubj('apmUnifiedSearchBar').its('length').should('be.gt', 0);
|
||||
cy.get('table').find('td:contains("exception 0")').should('have.length', 1);
|
||||
});
|
||||
|
||||
it('sorts by ocurrences', () => {
|
||||
|
@ -133,10 +127,9 @@ describe('Check detailed statistics API with multiple errors', () => {
|
|||
});
|
||||
|
||||
it('calls detailed API with visible items only', () => {
|
||||
cy.intercept(
|
||||
'GET',
|
||||
'/internal/apm/services/opbeans-java/errors/groups/main_statistics?*'
|
||||
).as('errorsMainStatistics');
|
||||
cy.intercept('GET', '/internal/apm/services/opbeans-java/errors/groups/main_statistics?*').as(
|
||||
'errorsMainStatistics'
|
||||
);
|
||||
cy.intercept(
|
||||
'POST',
|
||||
'/internal/apm/services/opbeans-java/errors/groups/detailed_statistics?*'
|
||||
|
|
|
@ -55,9 +55,7 @@ describe('Home page', () => {
|
|||
});
|
||||
|
||||
it('includes services with only metric documents', () => {
|
||||
cy.visitKibana(
|
||||
`${serviceInventoryHref}&kuery=not%20(processor.event%3A%22transaction%22)`
|
||||
);
|
||||
cy.visitKibana(`${serviceInventoryHref}&kuery=not%20(processor.event%3A%22transaction%22)`);
|
||||
cy.contains('opbeans-java');
|
||||
cy.contains('opbeans-node');
|
||||
});
|
||||
|
@ -69,10 +67,7 @@ describe('Home page', () => {
|
|||
cy.contains('Services');
|
||||
cy.contains('opbeans-rum').click({ force: true });
|
||||
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'page-load'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'page-load');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,25 +42,19 @@ describe('Mobile transactions page', () => {
|
|||
describe('when click on tab shows correct table', () => {
|
||||
it('shows version tab', () => {
|
||||
cy.visitKibana(mobileTransactionsPageHref);
|
||||
cy.getByTestSubj('apmAppVersionTab')
|
||||
.click()
|
||||
.should('have.attr', 'aria-selected', 'true');
|
||||
cy.getByTestSubj('apmAppVersionTab').click().should('have.attr', 'aria-selected', 'true');
|
||||
cy.url().should('include', 'mobileSelectedTab=app_version_tab');
|
||||
});
|
||||
|
||||
it('shows OS version tab', () => {
|
||||
cy.visitKibana(mobileTransactionsPageHref);
|
||||
cy.getByTestSubj('apmOsVersionTab')
|
||||
.click()
|
||||
.should('have.attr', 'aria-selected', 'true');
|
||||
cy.getByTestSubj('apmOsVersionTab').click().should('have.attr', 'aria-selected', 'true');
|
||||
cy.url().should('include', 'mobileSelectedTab=os_version_tab');
|
||||
});
|
||||
|
||||
it('shows devices tab', () => {
|
||||
cy.visitKibana(mobileTransactionsPageHref);
|
||||
cy.getByTestSubj('apmDevicesTab')
|
||||
.click()
|
||||
.should('have.attr', 'aria-selected', 'true');
|
||||
cy.getByTestSubj('apmDevicesTab').click().should('have.attr', 'aria-selected', 'true');
|
||||
cy.url().should('include', 'mobileSelectedTab=devices_tab');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -88,9 +88,7 @@ describe('APM Onboarding', () => {
|
|||
cy.visitKibana('/app/apm/onboarding');
|
||||
});
|
||||
it('when no data is present', () => {
|
||||
cy.intercept('GET', '/internal/apm/observability_overview/has_data').as(
|
||||
'hasData'
|
||||
);
|
||||
cy.intercept('GET', '/internal/apm/observability_overview/has_data').as('hasData');
|
||||
cy.getByTestSubj('checkAgentStatus').click();
|
||||
cy.wait('@hasData');
|
||||
cy.getByTestSubj('agentStatusWarningCallout').should('exist');
|
||||
|
@ -103,9 +101,7 @@ describe('APM Onboarding', () => {
|
|||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
cy.intercept('GET', '/internal/apm/observability_overview/has_data').as(
|
||||
'hasData'
|
||||
);
|
||||
cy.intercept('GET', '/internal/apm/observability_overview/has_data').as('hasData');
|
||||
cy.getByTestSubj('checkAgentStatus').click();
|
||||
cy.wait('@hasData');
|
||||
cy.getByTestSubj('agentStatusSuccessCallout').should('exist');
|
||||
|
|
|
@ -58,10 +58,8 @@ describe('Rules', () => {
|
|||
|
||||
describe('Error count', () => {
|
||||
const ruleName = 'Error count threshold';
|
||||
const comboBoxInputSelector =
|
||||
'[data-popover-open] [data-test-subj=comboBoxSearchInput]';
|
||||
const confirmModalButtonSelector =
|
||||
'.euiModal button[data-test-subj=confirmModalConfirmButton]';
|
||||
const comboBoxInputSelector = '[data-popover-open] [data-test-subj=comboBoxSearchInput]';
|
||||
const confirmModalButtonSelector = '.euiModal button[data-test-subj=confirmModalConfirmButton]';
|
||||
|
||||
describe('when created from APM', () => {
|
||||
describe('when created from Service Inventory', () => {
|
||||
|
@ -93,9 +91,7 @@ describe('Rules', () => {
|
|||
cy.loginAsEditorUser();
|
||||
|
||||
// Go to stack management
|
||||
cy.visitKibana(
|
||||
'/app/management/insightsAndAlerting/triggersActions/rules'
|
||||
);
|
||||
cy.visitKibana('/app/management/insightsAndAlerting/triggersActions/rules');
|
||||
|
||||
// Create a rule
|
||||
cy.contains('button', 'Create rule').click();
|
||||
|
|
|
@ -6,13 +6,7 @@
|
|||
*/
|
||||
import { apm, timerange } from '@kbn/apm-synthtrace-client';
|
||||
|
||||
export function generateMultipleServicesData({
|
||||
from,
|
||||
to,
|
||||
}: {
|
||||
from: number;
|
||||
to: number;
|
||||
}) {
|
||||
export function generateMultipleServicesData({ from, to }: { from: number; to: number }) {
|
||||
const range = timerange(from, to);
|
||||
|
||||
const services = Array(50)
|
||||
|
|
|
@ -16,8 +16,7 @@ const serviceOverviewHref = url.format({
|
|||
query: { rangeFrom: start, rangeTo: end },
|
||||
});
|
||||
|
||||
const specialServiceName =
|
||||
'service 1 / ? # [ ] @ ! $ & ( ) * + , ; = < > % {} | ^ ` <>';
|
||||
const specialServiceName = 'service 1 / ? # [ ] @ ! $ & ( ) * + , ; = < > % {} | ^ ` <>';
|
||||
|
||||
describe('Service inventory - header filters', () => {
|
||||
before(() => {
|
||||
|
|
|
@ -32,9 +32,7 @@ const mainApiRequestsToIntercept = [
|
|||
},
|
||||
];
|
||||
|
||||
const mainAliasNames = mainApiRequestsToIntercept.map(
|
||||
({ aliasName }) => `@${aliasName}`
|
||||
);
|
||||
const mainAliasNames = mainApiRequestsToIntercept.map(({ aliasName }) => `@${aliasName}`);
|
||||
|
||||
describe('Service inventory', () => {
|
||||
before(() => {
|
||||
|
@ -166,47 +164,21 @@ describe('Service inventory', () => {
|
|||
cy.intercept('POST', '/internal/apm/services/detailed_statistics?*').as(
|
||||
'detailedStatisticsRequest'
|
||||
);
|
||||
cy.intercept('GET', '/internal/apm/services?*').as(
|
||||
'mainStatisticsRequest'
|
||||
);
|
||||
cy.intercept('GET', '/internal/apm/services?*').as('mainStatisticsRequest');
|
||||
|
||||
cy.visitKibana(
|
||||
`${serviceInventoryHref}&pageSize=10&sortField=serviceName&sortDirection=asc`
|
||||
);
|
||||
cy.visitKibana(`${serviceInventoryHref}&pageSize=10&sortField=serviceName&sortDirection=asc`);
|
||||
cy.wait('@mainStatisticsRequest');
|
||||
cy.contains('Services');
|
||||
cy.get('.euiPagination__list').children().should('have.length', 5);
|
||||
cy.wait('@detailedStatisticsRequest').then((payload) => {
|
||||
expect(payload.request.body.serviceNames).eql(
|
||||
JSON.stringify([
|
||||
'0',
|
||||
'1',
|
||||
'10',
|
||||
'11',
|
||||
'12',
|
||||
'13',
|
||||
'14',
|
||||
'15',
|
||||
'16',
|
||||
'17',
|
||||
])
|
||||
JSON.stringify(['0', '1', '10', '11', '12', '13', '14', '15', '16', '17'])
|
||||
);
|
||||
});
|
||||
cy.getByTestSubj('pagination-button-1').click();
|
||||
cy.wait('@detailedStatisticsRequest').then((payload) => {
|
||||
expect(payload.request.body.serviceNames).eql(
|
||||
JSON.stringify([
|
||||
'18',
|
||||
'19',
|
||||
'2',
|
||||
'20',
|
||||
'21',
|
||||
'22',
|
||||
'23',
|
||||
'24',
|
||||
'25',
|
||||
'26',
|
||||
])
|
||||
JSON.stringify(['18', '19', '2', '20', '21', '22', '23', '24', '25', '26'])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -80,8 +80,7 @@ describe('service map', () => {
|
|||
cy.getByTestSubj('serviceMap').matchImage({
|
||||
imagesPath: '{spec_path}/snapshots',
|
||||
title: 'detailed_service_map',
|
||||
matchAgainstPath:
|
||||
'cypress/e2e/service_map/snapshots/detailed_service_map.png',
|
||||
matchAgainstPath: 'cypress/e2e/service_map/snapshots/detailed_service_map.png',
|
||||
maxDiffThreshold: 0.02, // maximum threshold above which the test should fail
|
||||
})
|
||||
);
|
||||
|
@ -102,11 +101,7 @@ describe('service map', () => {
|
|||
});
|
||||
|
||||
function prepareCanvasForScreenshot() {
|
||||
cy.get('html, body').invoke(
|
||||
'attr',
|
||||
'style',
|
||||
'height: auto; scroll-behavior: auto;'
|
||||
);
|
||||
cy.get('html, body').invoke('attr', 'style', 'height: auto; scroll-behavior: auto;');
|
||||
|
||||
cy.wait(300);
|
||||
cy.getByTestSubj('centerServiceMap').click();
|
||||
|
|
|
@ -38,9 +38,10 @@ describe('Errors table', () => {
|
|||
it('Alerts table with the search bar is populated', () => {
|
||||
cy.visitKibana(serviceOverviewHref);
|
||||
cy.contains('opbeans-java');
|
||||
cy.get(
|
||||
'[data-test-subj="environmentFilter"] [data-test-subj="comboBoxSearchInput"]'
|
||||
).should('have.value', 'All');
|
||||
cy.get('[data-test-subj="environmentFilter"] [data-test-subj="comboBoxSearchInput"]').should(
|
||||
'have.value',
|
||||
'All'
|
||||
);
|
||||
cy.contains('Active');
|
||||
cy.contains('Recovered');
|
||||
cy.getByTestSubj('globalQueryBar').should('exist');
|
||||
|
|
|
@ -17,8 +17,7 @@ const serviceOverviewHref = url.format({
|
|||
});
|
||||
|
||||
const apiToIntercept = {
|
||||
endpoint:
|
||||
'/internal/apm/services/synth-python/transactions/charts/coldstart_rate?*',
|
||||
endpoint: '/internal/apm/services/synth-python/transactions/charts/coldstart_rate?*',
|
||||
name: 'coldStartRequest',
|
||||
};
|
||||
|
||||
|
|
|
@ -17,8 +17,7 @@ const serviceOverviewHref = url.format({
|
|||
});
|
||||
|
||||
const apiToIntercept = {
|
||||
endpoint:
|
||||
'/internal/apm/services/synth-dotnet/transactions/charts/coldstart_rate?*',
|
||||
endpoint: '/internal/apm/services/synth-dotnet/transactions/charts/coldstart_rate?*',
|
||||
name: 'coldStartRequest',
|
||||
};
|
||||
|
||||
|
|
|
@ -18,8 +18,7 @@ const serviceOverviewHref = url.format({
|
|||
|
||||
const apisToIntercept = [
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transactions/charts/latency?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transactions/charts/latency?*',
|
||||
name: 'latencyChartRequest',
|
||||
},
|
||||
{
|
||||
|
@ -27,13 +26,11 @@ const apisToIntercept = [
|
|||
name: 'throughputChartRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transactions/charts/error_rate?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transactions/charts/error_rate?*',
|
||||
name: 'errorRateChartRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transactions/groups/detailed_statistics?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transactions/groups/detailed_statistics?*',
|
||||
name: 'transactionGroupsDetailedRequest',
|
||||
},
|
||||
{
|
||||
|
@ -42,27 +39,22 @@ const apisToIntercept = [
|
|||
name: 'instancesDetailedRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/service_overview_instances/main_statistics?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/service_overview_instances/main_statistics?*',
|
||||
name: 'instancesMainStatisticsRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transaction/charts/breakdown?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transaction/charts/breakdown?*',
|
||||
name: 'transactonBreakdownRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transactions/groups/main_statistics?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transactions/groups/main_statistics?*',
|
||||
name: 'transactionsGroupsMainStatisticsRequest',
|
||||
},
|
||||
];
|
||||
|
||||
describe('Service overview - header filters', () => {
|
||||
before(() => {
|
||||
synthtrace.index(
|
||||
opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime() })
|
||||
);
|
||||
synthtrace.index(opbeans({ from: new Date(start).getTime(), to: new Date(end).getTime() }));
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
@ -77,16 +69,10 @@ describe('Service overview - header filters', () => {
|
|||
cy.visitKibana(serviceOverviewHref);
|
||||
cy.contains('opbeans-node');
|
||||
cy.url().should('not.include', 'transactionType');
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'request'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'request');
|
||||
cy.getByTestSubj('headerFilterTransactionType').select('Worker');
|
||||
cy.url().should('include', 'transactionType=Worker');
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'Worker'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'Worker');
|
||||
});
|
||||
|
||||
it('calls APIs with correct transaction type', () => {
|
||||
|
@ -94,10 +80,7 @@ describe('Service overview - header filters', () => {
|
|||
cy.intercept('GET', endpoint).as(name);
|
||||
});
|
||||
cy.visitKibana(serviceOverviewHref);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'request'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'request');
|
||||
|
||||
cy.expectAPIsToHaveBeenCalledWith({
|
||||
apisIntercepted: apisToIntercept.map(({ name }) => `@${name}`),
|
||||
|
@ -106,10 +89,7 @@ describe('Service overview - header filters', () => {
|
|||
|
||||
cy.getByTestSubj('headerFilterTransactionType').select('Worker');
|
||||
cy.url().should('include', 'transactionType=Worker');
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'Worker'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'Worker');
|
||||
cy.expectAPIsToHaveBeenCalledWith({
|
||||
apisIntercepted: apisToIntercept.map(({ name }) => `@${name}`),
|
||||
value: 'transactionType=Worker',
|
||||
|
@ -131,21 +111,14 @@ describe('Service overview - header filters', () => {
|
|||
cy.contains('opbeans-java');
|
||||
cy.getByTestSubj('apmUnifiedSearchBar').type('transaction.n');
|
||||
cy.contains('transaction.name');
|
||||
cy.getByTestSubj(
|
||||
'autocompleteSuggestion-field-transaction.name-'
|
||||
).click();
|
||||
cy.getByTestSubj('autocompleteSuggestion-field-transaction.name-').click();
|
||||
cy.getByTestSubj('apmUnifiedSearchBar').type(':');
|
||||
cy.getByTestSubj('autoCompleteSuggestionText').should('have.length', 1);
|
||||
cy.getByTestSubj(
|
||||
Cypress.$.escapeSelector(
|
||||
'autocompleteSuggestion-value-"GET-/api/product"-'
|
||||
)
|
||||
Cypress.$.escapeSelector('autocompleteSuggestion-value-"GET-/api/product"-')
|
||||
).click();
|
||||
cy.getByTestSubj('apmUnifiedSearchBar').type('{enter}');
|
||||
cy.url().should(
|
||||
'include',
|
||||
'&kuery=transaction.name%20:%22GET%20%2Fapi%2Fproduct%22%20'
|
||||
);
|
||||
cy.url().should('include', '&kuery=transaction.name%20:%22GET%20%2Fapi%2Fproduct%22%20');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -31,8 +31,7 @@ const serviceNodeName = 'opbeans-java-prod-1';
|
|||
|
||||
const apisToIntercept = [
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-java/service_overview_instances/main_statistics?*',
|
||||
endpoint: '/internal/apm/services/opbeans-java/service_overview_instances/main_statistics?*',
|
||||
name: 'instancesMainRequest',
|
||||
},
|
||||
{
|
||||
|
@ -63,9 +62,7 @@ describe('Instances table', () => {
|
|||
it('shows empty message', () => {
|
||||
cy.visitKibana(testServiveHref);
|
||||
cy.contains('test-service');
|
||||
cy.getByTestSubj('serviceInstancesTableContainer').contains(
|
||||
'No instances found'
|
||||
);
|
||||
cy.getByTestSubj('serviceInstancesTableContainer').contains('No instances found');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -22,9 +22,7 @@ const apiRequestsToIntercept = [
|
|||
},
|
||||
];
|
||||
|
||||
const aliasNames = apiRequestsToIntercept.map(
|
||||
({ aliasName }) => `@${aliasName}`
|
||||
);
|
||||
const aliasNames = apiRequestsToIntercept.map(({ aliasName }) => `@${aliasName}`);
|
||||
|
||||
const apmMobileServiceOverview = url.format({
|
||||
pathname: 'app/apm/mobile-services/synth-android',
|
||||
|
|
|
@ -99,9 +99,7 @@ describe('Service overview page', () => {
|
|||
cy.visitKibana(apmMobileServiceOverview);
|
||||
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.pathname).to.eq(
|
||||
'/app/apm/mobile-services/synth-ios/overview'
|
||||
);
|
||||
expect(loc.pathname).to.eq('/app/apm/mobile-services/synth-ios/overview');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -119,9 +117,7 @@ describe('Service overview page', () => {
|
|||
cy.visitKibana(apmMobileServiceOverview);
|
||||
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.pathname).to.eq(
|
||||
'/app/apm/mobile-services/synth-android/overview'
|
||||
);
|
||||
expect(loc.pathname).to.eq('/app/apm/mobile-services/synth-android/overview');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -22,18 +22,15 @@ const baseUrl = url.format({
|
|||
|
||||
const apiRequestsToIntercept = [
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transactions/groups/main_statistics?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transactions/groups/main_statistics?*',
|
||||
aliasName: 'transactionsGroupsMainStatisticsRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/errors/groups/main_statistics?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/errors/groups/main_statistics?*',
|
||||
aliasName: 'errorsGroupsMainStatisticsRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transaction/charts/breakdown?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transaction/charts/breakdown?*',
|
||||
aliasName: 'transactionsBreakdownRequest',
|
||||
},
|
||||
{
|
||||
|
@ -44,8 +41,7 @@ const apiRequestsToIntercept = [
|
|||
|
||||
const apiRequestsToInterceptWithComparison = [
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transactions/charts/latency?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transactions/charts/latency?*',
|
||||
aliasName: 'latencyRequest',
|
||||
},
|
||||
{
|
||||
|
@ -53,18 +49,15 @@ const apiRequestsToInterceptWithComparison = [
|
|||
aliasName: 'throughputRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transactions/charts/error_rate?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transactions/charts/error_rate?*',
|
||||
aliasName: 'errorRateRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/transactions/groups/detailed_statistics?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/transactions/groups/detailed_statistics?*',
|
||||
aliasName: 'transactionsGroupsDetailedStatisticsRequest',
|
||||
},
|
||||
{
|
||||
endpoint:
|
||||
'/internal/apm/services/opbeans-node/service_overview_instances/main_statistics?*',
|
||||
endpoint: '/internal/apm/services/opbeans-node/service_overview_instances/main_statistics?*',
|
||||
aliasName: 'instancesMainStatisticsRequest',
|
||||
},
|
||||
|
||||
|
@ -75,9 +68,7 @@ const apiRequestsToInterceptWithComparison = [
|
|||
},
|
||||
];
|
||||
|
||||
const aliasNamesNoComparison = apiRequestsToIntercept.map(
|
||||
({ aliasName }) => `@${aliasName}`
|
||||
);
|
||||
const aliasNamesNoComparison = apiRequestsToIntercept.map(({ aliasName }) => `@${aliasName}`);
|
||||
|
||||
const aliasNamesWithComparison = apiRequestsToInterceptWithComparison.map(
|
||||
({ aliasName }) => `@${aliasName}`
|
||||
|
@ -125,55 +116,35 @@ describe('Service Overview', () => {
|
|||
});
|
||||
|
||||
it('persists transaction type selected when clicking on Transactions tab', () => {
|
||||
cy.intercept(
|
||||
'GET',
|
||||
'/internal/apm/services/opbeans-node/transaction_types?*'
|
||||
).as('transactionTypesRequest');
|
||||
cy.intercept('GET', '/internal/apm/services/opbeans-node/transaction_types?*').as(
|
||||
'transactionTypesRequest'
|
||||
);
|
||||
|
||||
cy.visitKibana(baseUrl);
|
||||
|
||||
cy.wait('@transactionTypesRequest');
|
||||
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'request'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'request');
|
||||
cy.getByTestSubj('headerFilterTransactionType').select('Worker');
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'Worker'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'Worker');
|
||||
cy.contains('Transactions').click();
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'Worker'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'Worker');
|
||||
});
|
||||
|
||||
it('persists transaction type selected when clicking on View Transactions link', () => {
|
||||
cy.intercept(
|
||||
'GET',
|
||||
'/internal/apm/services/opbeans-node/transaction_types?*'
|
||||
).as('transactionTypesRequest');
|
||||
cy.intercept('GET', '/internal/apm/services/opbeans-node/transaction_types?*').as(
|
||||
'transactionTypesRequest'
|
||||
);
|
||||
|
||||
cy.visitKibana(baseUrl);
|
||||
|
||||
cy.wait('@transactionTypesRequest');
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'request'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'request');
|
||||
cy.getByTestSubj('headerFilterTransactionType').select('Worker');
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'Worker'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'Worker');
|
||||
|
||||
cy.contains('View transactions').click();
|
||||
cy.getByTestSubj('headerFilterTransactionType').should(
|
||||
'have.value',
|
||||
'Worker'
|
||||
);
|
||||
cy.getByTestSubj('headerFilterTransactionType').should('have.value', 'Worker');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -181,9 +152,7 @@ describe('Service Overview', () => {
|
|||
it('hides dependency tab when RUM service', () => {
|
||||
cy.loginAsViewerUser();
|
||||
|
||||
cy.intercept('GET', '/internal/apm/services/opbeans-rum/agent?*').as(
|
||||
'agentRequest'
|
||||
);
|
||||
cy.intercept('GET', '/internal/apm/services/opbeans-rum/agent?*').as('agentRequest');
|
||||
|
||||
cy.visitKibana(
|
||||
url.format({
|
||||
|
@ -222,9 +191,7 @@ describe('Service Overview', () => {
|
|||
it('with the correct environment when changing the environment', () => {
|
||||
cy.wait(aliasNames);
|
||||
|
||||
cy.intercept('GET', 'internal/apm/suggestions?*').as(
|
||||
'suggestionsRequest'
|
||||
);
|
||||
cy.intercept('GET', 'internal/apm/suggestions?*').as('suggestionsRequest');
|
||||
|
||||
cy.getByTestSubj('environmentFilter')
|
||||
.find('input')
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue