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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions x-pack/plugins/apm/common/__snapshots__/apm_telemetry.test.ts.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions x-pack/plugins/apm/common/apm_telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ export function getApmTelemetryMapping() {
{}
),
},
cloud: {
properties: {
availability_zone: keyword,
provider: keyword,
region: keyword,
},
},
counts: {
properties: {
agent_configuration: allProperties,
Expand Down
15 changes: 15 additions & 0 deletions x-pack/plugins/apm/common/elasticsearch_fieldnames.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ describe('Transaction', () => {
name: 'java',
version: 'agent version',
},
cloud: {
availability_zone: 'europe-west1-c',
provider: 'gcp',
region: 'europe-west1',
},
http: {
request: { method: 'GET' },
response: { status_code: 200 },
Expand Down Expand Up @@ -74,6 +79,11 @@ describe('Span', () => {
name: 'java',
version: 'agent version',
},
cloud: {
availability_zone: 'europe-west1-c',
provider: 'gcp',
region: 'europe-west1',
},
processor: {
name: 'transaction',
event: 'span',
Expand Down Expand Up @@ -121,6 +131,11 @@ describe('Error', () => {
name: 'java',
version: 'agent version',
},
cloud: {
availability_zone: 'europe-west1-c',
provider: 'gcp',
region: 'europe-west1',
},
error: {
exception: [
{
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/apm/common/elasticsearch_fieldnames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/

export const CLOUD_AVAILABILITY_ZONE = 'cloud.availability_zone';
export const CLOUD_PROVIDER = 'cloud.provider';
export const CLOUD_REGION = 'cloud.region';

export const SERVICE_NAME = 'service.name';
export const SERVICE_ENVIRONMENT = 'service.environment';
export const SERVICE_FRAMEWORK_NAME = 'service.framework.name';
Expand Down
7 changes: 7 additions & 0 deletions x-pack/plugins/apm/dev_docs/telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ and/or config/kibana.dev.yml files.

Running the script with `--clear` will delete the index first.

If you're using an Elasticsearch instance without TLS verification (if you have `elasticsearch.ssl.verificationMode: none` set in your kibana.yml)
you can run the script with `env NODE_TLS_REJECT_UNAUTHORIZED=0` to avoid TLS connection errors.

After running the script you should see sample telemetry data in the "xpack-phone-home" index.

### Updating Data Telemetry Mappings
Expand All @@ -62,6 +65,10 @@ node ./scripts/merge-telemetry-mapping.js ../../../../telemetry/config/templates

this will replace the contents of the mapping in the repository checkout with the updated mapping. You can then [follow the telemetry team's instructions](https://github.com/elastic/telemetry#mappings) for opening a pull request with the mapping changes.

The queries for the stats are in the [collect data telemetry tasks](../server/lib/apm_telemetry/collect_data_telemetry/tasks.ts).

The collection tasks also use the [`APMDataTelemetry` type](../server/lib/apm_telemetry/types.ts) which also needs to be updated with any changes to the fields.

## Behavioral Telemetry

Behavioral telemetry is recorded with the ui_metrics and application_usage methods from the Usage Collection plugin.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { tasks } from './tasks';
import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';

describe('data telemetry collection tasks', () => {
const indices = {
'apm_oss.errorIndices': 'apm-8.0.0-error',
'apm_oss.metricsIndices': 'apm-8.0.0-metric',
'apm_oss.spanIndices': 'apm-8.0.0-span',
'apm_oss.transactionIndices': 'apm-8.0.0-transaction',
} as ApmIndicesConfig;

describe('cloud', () => {
const cloudTask = tasks.find((task) => task.name === 'cloud');

it('returns a map of cloud provider data', async () => {
const search = jest.fn().mockResolvedValueOnce({
aggregations: {
availability_zone: {
buckets: [
{ doc_count: 1, key: 'us-west-1' },
{ doc_count: 1, key: 'europe-west1-c' },
],
},
provider: {
buckets: [
{ doc_count: 1, key: 'aws' },
{ doc_count: 1, key: 'gcp' },
],
},
region: {
buckets: [
{ doc_count: 1, key: 'us-west' },
{ doc_count: 1, key: 'europe-west1' },
],
},
},
});

expect(await cloudTask?.executor({ indices, search } as any)).toEqual({
cloud: {
availability_zone: ['us-west-1', 'europe-west1-c'],
provider: ['aws', 'gcp'],
region: ['us-west', 'europe-west1'],
},
});
});

describe('with no results', () => {
it('returns an empty map', async () => {
const search = jest.fn().mockResolvedValueOnce({});

expect(await cloudTask?.executor({ indices, search } as any)).toEqual({
cloud: {
availability_zone: [],
provider: [],
region: [],
},
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import {
SERVICE_RUNTIME_NAME,
SERVICE_RUNTIME_VERSION,
USER_AGENT_ORIGINAL,
CLOUD_AVAILABILITY_ZONE,
CLOUD_PROVIDER,
CLOUD_REGION,
} from '../../../../common/elasticsearch_fieldnames';
import { Span } from '../../../../typings/es_schemas/ui/span';
import { APMError } from '../../../../typings/es_schemas/ui/apm_error';
Expand All @@ -32,6 +35,66 @@ const TIME_RANGES = ['1d', 'all'] as const;
type TimeRange = typeof TIME_RANGES[number];

export const tasks: TelemetryTask[] = [
{
name: 'cloud',
executor: async ({ indices, search }) => {
function getBucketKeys({
buckets,
}: {
buckets: Array<{
doc_count: number;
key: string | number;
}>;
}) {
return buckets.map((bucket) => bucket.key as string);
}

const az = 'availability_zone';
const region = 'region';
const provider = 'provider';

const response = await search({
index: [
indices['apm_oss.errorIndices'],
indices['apm_oss.metricsIndices'],
indices['apm_oss.spanIndices'],
indices['apm_oss.transactionIndices'],
],
body: {
size: 0,
aggs: {
[az]: {
terms: {
field: CLOUD_AVAILABILITY_ZONE,
},
},
[provider]: {
terms: {
field: CLOUD_PROVIDER,
},
},
[region]: {
terms: {
field: CLOUD_REGION,
},
},
},
},
});

const { aggregations } = response;

if (!aggregations) {
return { cloud: { [az]: [], [provider]: [], [region]: [] } };
}
const cloud = {
[az]: getBucketKeys(aggregations[az]),
[provider]: getBucketKeys(aggregations[provider]),
[region]: getBucketKeys(aggregations[region]),
};
return { cloud };
},
},
{
name: 'processor_events',
executor: async ({ indices, search }) => {
Expand Down
6 changes: 6 additions & 0 deletions x-pack/plugins/apm/server/lib/apm_telemetry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export type APMDataTelemetry = DeepPartial<{
patch: number;
};
};
cloud: {
availability_zone: string[];
provider: string[];
region: string[];
};
counts: {
transaction: TimeframeMap;
span: TimeframeMap;
Expand Down Expand Up @@ -102,6 +107,7 @@ export type APMDataTelemetry = DeepPartial<{
};
};
tasks: Record<
| 'cloud'
| 'processor_events'
| 'agent_configuration'
| 'services'
Expand Down