mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Synthetics] Enhance telemetry for synthetics monitors (#132150)
This commit is contained in:
parent
0248e9357f
commit
6edf3dc80b
2 changed files with 53 additions and 31 deletions
|
@ -18,6 +18,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks';
|
|||
import { MONITOR_UPDATE_CHANNEL } from './constants';
|
||||
|
||||
import { TelemetryEventsSender } from './sender';
|
||||
import { LicenseGetResponse } from '@elastic/elasticsearch/lib/api/types';
|
||||
|
||||
jest.mock('axios', () => {
|
||||
return {
|
||||
|
@ -25,6 +26,23 @@ jest.mock('axios', () => {
|
|||
};
|
||||
});
|
||||
|
||||
const licenseMock: LicenseGetResponse = {
|
||||
license: {
|
||||
status: 'active',
|
||||
uid: '1d34eb9f-e66f-47d1-8d24-cd60d187587a',
|
||||
type: 'trial',
|
||||
issue_date: '2022-05-05T14:25:00.732Z',
|
||||
issue_date_in_millis: 165176070074432,
|
||||
expiry_date: '2022-06-04T14:25:00.732Z',
|
||||
expiry_date_in_millis: 165435270073332,
|
||||
max_nodes: 1000,
|
||||
max_resource_units: null,
|
||||
issued_to: '2c515bd215ce444441f83ffd36a9d3d2546',
|
||||
issuer: 'elasticsearch',
|
||||
start_date_in_millis: -1,
|
||||
},
|
||||
};
|
||||
|
||||
describe('TelemetryEventsSender', () => {
|
||||
let logger: ReturnType<typeof loggingSystemMock.createLogger>;
|
||||
let sender: TelemetryEventsSender;
|
||||
|
@ -42,6 +60,10 @@ describe('TelemetryEventsSender', () => {
|
|||
beforeEach(() => {
|
||||
logger = loggingSystemMock.createLogger();
|
||||
sender = new TelemetryEventsSender(logger);
|
||||
sender['fetchLicenseInfo'] = jest.fn(async () => {
|
||||
return licenseMock as LicenseGetResponse;
|
||||
});
|
||||
|
||||
sender['fetchClusterInfo'] = jest.fn(async () => {
|
||||
return {
|
||||
cluster_uuid: '1',
|
||||
|
@ -79,7 +101,6 @@ describe('TelemetryEventsSender', () => {
|
|||
|
||||
expect(sender['sendEvents']).toHaveBeenCalledWith(
|
||||
`https://telemetry-staging.elastic.co/v3-dev/send/${MONITOR_UPDATE_CHANNEL}`,
|
||||
{ cluster_name: 'name', cluster_uuid: '1', version: { number: '8.0.0' } },
|
||||
expect.anything()
|
||||
);
|
||||
});
|
||||
|
@ -134,14 +155,17 @@ describe('TelemetryEventsSender', () => {
|
|||
'X-Elastic-Stack-Version': '8.0.0',
|
||||
},
|
||||
};
|
||||
const event1 = { 'event.kind': '1', ...licenseMock };
|
||||
const event2 = { 'event.kind': '2', ...licenseMock };
|
||||
const event3 = { 'event.kind': '3', ...licenseMock };
|
||||
expect(axios.post).toHaveBeenCalledWith(
|
||||
'https://telemetry.elastic.co/v3/send/my-channel',
|
||||
'{"event.kind":"1"}\n{"event.kind":"2"}\n',
|
||||
`${JSON.stringify(event1)}\n${JSON.stringify(event2)}\n`,
|
||||
headers
|
||||
);
|
||||
expect(axios.post).toHaveBeenCalledWith(
|
||||
'https://telemetry.elastic.co/v3/send/my-channel2',
|
||||
'{"event.kind":"3"}\n',
|
||||
`${JSON.stringify(event3)}\n`,
|
||||
headers
|
||||
);
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@ import { cloneDeep } from 'lodash';
|
|||
|
||||
import axios from 'axios';
|
||||
|
||||
import type { InfoResponse } from '@elastic/elasticsearch/lib/api/types';
|
||||
import type { InfoResponse, LicenseGetResponse } from '@elastic/elasticsearch/lib/api/types';
|
||||
|
||||
import { TelemetryQueue } from './queue';
|
||||
|
||||
|
@ -35,6 +35,7 @@ export class TelemetryEventsSender {
|
|||
private isOptedIn?: boolean = true; // Assume true until the first check
|
||||
private esClient?: ElasticsearchClient;
|
||||
private clusterInfo?: InfoResponse;
|
||||
private licenseInfo?: LicenseGetResponse;
|
||||
|
||||
constructor(logger: Logger) {
|
||||
this.logger = logger;
|
||||
|
@ -48,6 +49,7 @@ export class TelemetryEventsSender {
|
|||
this.telemetryStart = telemetryStart;
|
||||
this.esClient = core?.elasticsearch.client.asInternalUser;
|
||||
this.clusterInfo = await this.fetchClusterInfo();
|
||||
this.licenseInfo = await this.fetchLicenseInfo();
|
||||
|
||||
this.logger.debug(`Starting local task`);
|
||||
setTimeout(() => {
|
||||
|
@ -95,11 +97,7 @@ export class TelemetryEventsSender {
|
|||
}
|
||||
|
||||
for (const channel of Object.keys(this.queuesPerChannel)) {
|
||||
await this.sendEvents(
|
||||
await this.fetchTelemetryUrl(channel),
|
||||
this.clusterInfo,
|
||||
this.queuesPerChannel[channel]
|
||||
);
|
||||
await this.sendEvents(await this.fetchTelemetryUrl(channel), this.queuesPerChannel[channel]);
|
||||
}
|
||||
|
||||
this.isSending = false;
|
||||
|
@ -107,22 +105,28 @@ export class TelemetryEventsSender {
|
|||
|
||||
private async fetchClusterInfo(): Promise<InfoResponse> {
|
||||
if (this.esClient === undefined || this.esClient === null) {
|
||||
throw Error('elasticsearch client is unavailable: cannot retrieve cluster infomation');
|
||||
throw Error('elasticsearch client is unavailable: cannot retrieve cluster information');
|
||||
}
|
||||
|
||||
return await this.esClient.info();
|
||||
}
|
||||
|
||||
public async sendEvents(
|
||||
telemetryUrl: string,
|
||||
clusterInfo: InfoResponse | undefined,
|
||||
queue: TelemetryQueue<any>
|
||||
) {
|
||||
const events = queue.getEvents();
|
||||
private async fetchLicenseInfo() {
|
||||
if (this.esClient === undefined || this.esClient === null) {
|
||||
throw Error('elasticsearch client is unavailable: cannot retrieve license information');
|
||||
}
|
||||
|
||||
return await this.esClient.license.get();
|
||||
}
|
||||
|
||||
public async sendEvents(telemetryUrl: string, queue: TelemetryQueue<any>) {
|
||||
let events = queue.getEvents();
|
||||
if (events.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
events = events.map((event) => ({ ...event, license: this.licenseInfo?.license }));
|
||||
|
||||
try {
|
||||
this.logger.debug(`Telemetry URL: ${telemetryUrl}`);
|
||||
|
||||
|
@ -130,13 +134,7 @@ export class TelemetryEventsSender {
|
|||
|
||||
this.logger.debug(JSON.stringify(events));
|
||||
|
||||
await this.send(
|
||||
events,
|
||||
telemetryUrl,
|
||||
clusterInfo?.cluster_uuid,
|
||||
clusterInfo?.version?.number,
|
||||
clusterInfo?.cluster_name
|
||||
);
|
||||
await this.send(events, telemetryUrl);
|
||||
} catch (err) {
|
||||
this.logger.debug(`Error sending telemetry events data: ${err}`);
|
||||
queue.clearEvents();
|
||||
|
@ -159,13 +157,13 @@ export class TelemetryEventsSender {
|
|||
return telemetryUrl.toString();
|
||||
}
|
||||
|
||||
private async send(
|
||||
events: unknown[],
|
||||
telemetryUrl: string,
|
||||
clusterUuid: string | undefined,
|
||||
clusterVersionNumber: string | undefined,
|
||||
clusterName: string | undefined
|
||||
) {
|
||||
private async send(events: unknown[], telemetryUrl: string) {
|
||||
const {
|
||||
cluster_name: clusterName,
|
||||
cluster_uuid: clusterUuid,
|
||||
version: clusterVersion,
|
||||
} = this.clusterInfo ?? {};
|
||||
|
||||
// using ndjson so that each line will be wrapped in json envelope on server side
|
||||
// see https://github.com/elastic/infra/blob/master/docs/telemetry/telemetry-next-dataflow.md#json-envelope
|
||||
const ndjson = this.transformDataToNdjson(events);
|
||||
|
@ -176,7 +174,7 @@ export class TelemetryEventsSender {
|
|||
'Content-Type': 'application/x-ndjson',
|
||||
...(clusterUuid ? { 'X-Elastic-Cluster-ID': clusterUuid } : undefined),
|
||||
...(clusterName ? { 'X-Elastic-Cluster-Name': clusterName } : undefined),
|
||||
'X-Elastic-Stack-Version': clusterVersionNumber ? clusterVersionNumber : '8.2.0',
|
||||
'X-Elastic-Stack-Version': clusterVersion?.number ? clusterVersion.number : '8.2.0',
|
||||
},
|
||||
});
|
||||
this.logger.debug(`Events sent!. Response: ${resp.status} ${JSON.stringify(resp.data)}`);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue