Skip to content

Commit 31f1ce7

Browse files
authored
[APM] Add cloud attributes to data telemetry (#71008) (#71023)
Add cloud provider, region, and availability zone to the data telemetry mappings and queries. Fixes #70465
1 parent b030f5f commit 31f1ce7

File tree

9 files changed

+204
-0
lines changed

9 files changed

+204
-0
lines changed

x-pack/plugins/apm/common/__snapshots__/apm_telemetry.test.ts.snap

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugins/apm/common/apm_telemetry.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ export function getApmTelemetryMapping() {
9191
{}
9292
),
9393
},
94+
cloud: {
95+
properties: {
96+
availability_zone: keyword,
97+
provider: keyword,
98+
region: keyword,
99+
},
100+
},
94101
counts: {
95102
properties: {
96103
agent_configuration: allProperties,

x-pack/plugins/apm/common/elasticsearch_fieldnames.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ describe('Transaction', () => {
2222
name: 'java',
2323
version: 'agent version',
2424
},
25+
cloud: {
26+
availability_zone: 'europe-west1-c',
27+
provider: 'gcp',
28+
region: 'europe-west1',
29+
},
2530
http: {
2631
request: { method: 'GET' },
2732
response: { status_code: 200 },
@@ -73,6 +78,11 @@ describe('Span', () => {
7378
name: 'java',
7479
version: 'agent version',
7580
},
81+
cloud: {
82+
availability_zone: 'europe-west1-c',
83+
provider: 'gcp',
84+
region: 'europe-west1',
85+
},
7686
processor: {
7787
name: 'transaction',
7888
event: 'span',
@@ -120,6 +130,11 @@ describe('Error', () => {
120130
name: 'java',
121131
version: 'agent version',
122132
},
133+
cloud: {
134+
availability_zone: 'europe-west1-c',
135+
provider: 'gcp',
136+
region: 'europe-west1',
137+
},
123138
error: {
124139
exception: [
125140
{

x-pack/plugins/apm/common/elasticsearch_fieldnames.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7+
export const CLOUD_AVAILABILITY_ZONE = 'cloud.availability_zone';
8+
export const CLOUD_PROVIDER = 'cloud.provider';
9+
export const CLOUD_REGION = 'cloud.region';
10+
711
export const SERVICE_NAME = 'service.name';
812
export const SERVICE_ENVIRONMENT = 'service.environment';
913
export const SERVICE_FRAMEWORK_NAME = 'service.framework.name';

x-pack/plugins/apm/dev_docs/telemetry.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ and/or config/kibana.dev.yml files.
4040

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

43+
If you're using an Elasticsearch instance without TLS verification (if you have `elasticsearch.ssl.verificationMode: none` set in your kibana.yml)
44+
you can run the script with `env NODE_TLS_REJECT_UNAUTHORIZED=0` to avoid TLS connection errors.
45+
4346
After running the script you should see sample telemetry data in the "xpack-phone-home" index.
4447

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

6366
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.
6467

68+
The queries for the stats are in the [collect data telemetry tasks](../server/lib/apm_telemetry/collect_data_telemetry/tasks.ts).
69+
70+
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.
71+
6572
## Behavioral Telemetry
6673

6774
Behavioral telemetry is recorded with the ui_metrics and application_usage methods from the Usage Collection plugin.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { tasks } from './tasks';
8+
import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
9+
10+
describe('data telemetry collection tasks', () => {
11+
const indices = {
12+
'apm_oss.errorIndices': 'apm-8.0.0-error',
13+
'apm_oss.metricsIndices': 'apm-8.0.0-metric',
14+
'apm_oss.spanIndices': 'apm-8.0.0-span',
15+
'apm_oss.transactionIndices': 'apm-8.0.0-transaction',
16+
} as ApmIndicesConfig;
17+
18+
describe('cloud', () => {
19+
const cloudTask = tasks.find((task) => task.name === 'cloud');
20+
21+
it('returns a map of cloud provider data', async () => {
22+
const search = jest.fn().mockResolvedValueOnce({
23+
aggregations: {
24+
availability_zone: {
25+
buckets: [
26+
{ doc_count: 1, key: 'us-west-1' },
27+
{ doc_count: 1, key: 'europe-west1-c' },
28+
],
29+
},
30+
provider: {
31+
buckets: [
32+
{ doc_count: 1, key: 'aws' },
33+
{ doc_count: 1, key: 'gcp' },
34+
],
35+
},
36+
region: {
37+
buckets: [
38+
{ doc_count: 1, key: 'us-west' },
39+
{ doc_count: 1, key: 'europe-west1' },
40+
],
41+
},
42+
},
43+
});
44+
45+
expect(await cloudTask?.executor({ indices, search } as any)).toEqual({
46+
cloud: {
47+
availability_zone: ['us-west-1', 'europe-west1-c'],
48+
provider: ['aws', 'gcp'],
49+
region: ['us-west', 'europe-west1'],
50+
},
51+
});
52+
});
53+
54+
describe('with no results', () => {
55+
it('returns an empty map', async () => {
56+
const search = jest.fn().mockResolvedValueOnce({});
57+
58+
expect(await cloudTask?.executor({ indices, search } as any)).toEqual({
59+
cloud: {
60+
availability_zone: [],
61+
provider: [],
62+
region: [],
63+
},
64+
});
65+
});
66+
});
67+
});
68+
});

x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import {
2222
SERVICE_RUNTIME_NAME,
2323
SERVICE_RUNTIME_VERSION,
2424
USER_AGENT_ORIGINAL,
25+
CLOUD_AVAILABILITY_ZONE,
26+
CLOUD_PROVIDER,
27+
CLOUD_REGION,
2528
} from '../../../../common/elasticsearch_fieldnames';
2629
import { Span } from '../../../../typings/es_schemas/ui/span';
2730
import { APMError } from '../../../../typings/es_schemas/ui/apm_error';
@@ -32,6 +35,66 @@ const TIME_RANGES = ['1d', 'all'] as const;
3235
type TimeRange = typeof TIME_RANGES[number];
3336

3437
export const tasks: TelemetryTask[] = [
38+
{
39+
name: 'cloud',
40+
executor: async ({ indices, search }) => {
41+
function getBucketKeys({
42+
buckets,
43+
}: {
44+
buckets: Array<{
45+
doc_count: number;
46+
key: string | number;
47+
}>;
48+
}) {
49+
return buckets.map((bucket) => bucket.key as string);
50+
}
51+
52+
const az = 'availability_zone';
53+
const region = 'region';
54+
const provider = 'provider';
55+
56+
const response = await search({
57+
index: [
58+
indices['apm_oss.errorIndices'],
59+
indices['apm_oss.metricsIndices'],
60+
indices['apm_oss.spanIndices'],
61+
indices['apm_oss.transactionIndices'],
62+
],
63+
body: {
64+
size: 0,
65+
aggs: {
66+
[az]: {
67+
terms: {
68+
field: CLOUD_AVAILABILITY_ZONE,
69+
},
70+
},
71+
[provider]: {
72+
terms: {
73+
field: CLOUD_PROVIDER,
74+
},
75+
},
76+
[region]: {
77+
terms: {
78+
field: CLOUD_REGION,
79+
},
80+
},
81+
},
82+
},
83+
});
84+
85+
const { aggregations } = response;
86+
87+
if (!aggregations) {
88+
return { cloud: { [az]: [], [provider]: [], [region]: [] } };
89+
}
90+
const cloud = {
91+
[az]: getBucketKeys(aggregations[az]),
92+
[provider]: getBucketKeys(aggregations[provider]),
93+
[region]: getBucketKeys(aggregations[region]),
94+
};
95+
return { cloud };
96+
},
97+
},
3598
{
3699
name: 'processor_events',
37100
executor: async ({ indices, search }) => {

x-pack/plugins/apm/server/lib/apm_telemetry/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ export type APMDataTelemetry = DeepPartial<{
2525
patch: number;
2626
};
2727
};
28+
cloud: {
29+
availability_zone: string[];
30+
provider: string[];
31+
region: string[];
32+
};
2833
counts: {
2934
transaction: TimeframeMap;
3035
span: TimeframeMap;
@@ -102,6 +107,7 @@ export type APMDataTelemetry = DeepPartial<{
102107
};
103108
};
104109
tasks: Record<
110+
| 'cloud'
105111
| 'processor_events'
106112
| 'agent_configuration'
107113
| 'services'

0 commit comments

Comments
 (0)