UNPKG

aws-cdk

Version:

AWS CDK CLI, the command line tool for CDK apps

108 lines 14.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EndpointTelemetrySink = void 0; const https_1 = require("https"); const toolkit_lib_1 = require("@aws-cdk/toolkit-lib"); const network_detector_1 = require("../../../api/network-detector"); const api_private_1 = require("../../../api-private"); const REQUEST_ATTEMPT_TIMEOUT_MS = 500; /** * The telemetry client that hits an external endpoint. */ class EndpointTelemetrySink { events = []; endpoint; ioHelper; agent; constructor(props) { this.endpoint = new URL(props.endpoint); if (!this.endpoint.hostname || !this.endpoint.pathname) { throw new toolkit_lib_1.ToolkitError('MalformedEndpoint', `Telemetry Endpoint malformed. Received hostname: ${this.endpoint.hostname}, pathname: ${this.endpoint.pathname}`); } this.ioHelper = api_private_1.IoHelper.fromActionAwareIoHost(props.ioHost); this.agent = props.agent; // Batch events every 30 seconds setInterval(() => this.flush(), 30000).unref(); } /** * Add an event to the collection. */ async emit(event) { try { this.events.push(event); } catch (e) { // Never throw errors, just log them via ioHost await this.ioHelper.defaults.trace(`Failed to add telemetry event: ${e.message}`); } } async flush() { try { if (this.events.length === 0) { return; } const res = await this.https(this.endpoint, { events: this.events }); // Clear the events array after successful output if (res) { this.events = []; } } catch (e) { // Never throw errors, just log them via ioHost await this.ioHelper.defaults.trace(`Failed to send telemetry event: ${e.message}`); } } /** * Returns true if telemetry successfully posted, false otherwise. */ async https(url, body) { // Check connectivity before attempting network request const hasConnectivity = await network_detector_1.NetworkDetector.hasConnectivity(this.agent); if (!hasConnectivity) { await this.ioHelper.defaults.trace('No internet connectivity detected, skipping telemetry'); return false; } try { const res = await doRequest(url, body, this.agent); // Successfully posted if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) { await this.ioHelper.defaults.trace('Telemetry Sent Successfully'); return true; } await this.ioHelper.defaults.trace(`Telemetry Unsuccessful: POST ${url.hostname}${url.pathname}: ${res.statusCode}:${res.statusMessage}`); return false; } catch (e) { await this.ioHelper.defaults.trace(`Telemetry Error: POST ${url.hostname}${url.pathname}: ${JSON.stringify(e)}`); return false; } } } exports.EndpointTelemetrySink = EndpointTelemetrySink; /** * A Promisified version of `https.request()` */ function doRequest(url, data, agent) { return new Promise((ok, ko) => { const payload = JSON.stringify(data); const req = (0, https_1.request)({ hostname: url.hostname, port: url.port || null, path: url.pathname, method: 'POST', headers: { 'content-type': 'application/json', 'content-length': payload.length, }, agent, timeout: REQUEST_ATTEMPT_TIMEOUT_MS, }, ok); req.on('error', ko); req.on('timeout', () => { const error = new toolkit_lib_1.ToolkitError('RequestTimeout', `Timeout after ${REQUEST_ATTEMPT_TIMEOUT_MS}ms, aborting request`); req.destroy(error); }); req.end(payload); }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5kcG9pbnQtc2luay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImVuZHBvaW50LXNpbmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsaUNBQWdDO0FBQ2hDLHNEQUFvRDtBQUNwRCxvRUFBZ0U7QUFDaEUsc0RBQWdEO0FBS2hELE1BQU0sMEJBQTBCLEdBQUcsR0FBRyxDQUFDO0FBMEJ2Qzs7R0FFRztBQUNILE1BQWEscUJBQXFCO0lBQ3hCLE1BQU0sR0FBc0IsRUFBRSxDQUFDO0lBQy9CLFFBQVEsQ0FBTTtJQUNkLFFBQVEsQ0FBVztJQUNuQixLQUFLLENBQVM7SUFFdEIsWUFBbUIsS0FBaUM7UUFDbEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFeEMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN2RCxNQUFNLElBQUksMEJBQVksQ0FBQyxtQkFBbUIsRUFBRSxvREFBb0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLGVBQWUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ2pLLENBQUM7UUFFRCxJQUFJLENBQUMsUUFBUSxHQUFHLHNCQUFRLENBQUMscUJBQXFCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUV6QixnQ0FBZ0M7UUFDaEMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNqRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQXNCO1FBQ3RDLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxN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QyxDQUFDO1FBQzdDLE1BQU0sR0FBRyxHQUFHLElBQUEsZUFBTyxFQUFDO1lBQ2xCLFFBQVEsRUFBRSxHQUFHLENBQUMsUUFBUTtZQUN0QixJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksSUFBSSxJQUFJO1lBQ3RCLElBQUksRUFBRSxHQUFHLENBQUMsUUFBUTtZQUNsQixNQUFNLEVBQUUsTUFBTTtZQUNkLE9BQU8sRUFBRTtnQkFDUCxjQUFjLEVBQUUsa0JBQWtCO2dCQUNsQyxnQkFBZ0IsRUFBRSxPQUFPLENBQUMsTUFBTTthQUNqQztZQUNELEtBQUs7WUFDTCxPQUFPLEVBQUUsMEJBQTBCO1NBQ3BDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFUCxHQUFHLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNwQixHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7WUFDckIsTUFBTSxLQUFLLEdBQUcsSUFBSSwwQkFBWSxDQUFDLGdCQUFnQixFQUFFLGlCQUFpQiwwQkFBMEIsc0JBQXNCLENBQUMsQ0FBQztZQUNwSCxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JCLENBQUMsQ0FBQyxDQUFDO1FBRUgsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEluY29taW5nTWVzc2FnZSB9IGZyb20gJ2h0dHAnO1xuaW1wb3J0IHR5cGUgeyBBZ2VudCB9IGZyb20gJ2h0dHBzJztcbmltcG9ydCB7IHJlcXVlc3QgfSBmcm9tICdodHRwcyc7XG5pbXBvcnQgeyBUb29sa2l0RXJyb3IgfSBmcm9tICdAYXdzLWNkay90b29sa2l0LWxpYic7XG5pbXBvcnQgeyBOZXR3b3JrRGV0ZWN0b3IgfSBmcm9tICcuLi8uLi8uLi9hcGkvbmV0d29yay1kZXRlY3Rvcic7XG5pbXBvcnQgeyBJb0hlbHBlciB9IGZyb20gJy4uLy4uLy4uL2FwaS1wcml2YXRlJztcbmltcG9ydCB0eXBlIHsgSUlvSG9zdCB9IGZyb20gJy4uLy4uL2lvLWhvc3QnO1xuaW1wb3J0IHR5cGUgeyBUZWxlbWV0cnlTY2hlbWEgfSBmcm9tICcuLi9zY2hlbWEnO1xuaW1wb3J0IHR5cGUgeyBJVGVsZW1ldHJ5U2luayB9IGZyb20gJy4vc2luay1pbnRlcmZhY2UnO1xuXG5jb25zdCBSRVFVRVNUX0FUVEVNUFRfVElNRU9VVF9NUyA9IDUwMDtcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciB0aGUgRW5kcG9pbnQgVGVsZW1ldHJ5IENsaWVudFxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVuZHBvaW50VGVsZW1ldHJ5U2lua1Byb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBleHRlcm5hbCBlbmRwb2ludCB0byBoaXRcbiAgICovXG4gIHJlYWRvbmx5IGVuZHBvaW50OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXJlIG1lc3NhZ2VzIGFyZSBnb2luZyB0byBiZSBzZW50XG4gICAqL1xuICByZWFkb25seSBpb0hvc3Q6IElJb0hvc3Q7XG5cbiAgLyoqXG4gICAqIFRoZSBhZ2VudCByZXNwb25zaWJsZSBmb3IgbWFraW5nIHRoZSBuZXR3b3JrIHJlcXVlc3RzLlxuICAgKlxuICAgKiBVc2UgdGhpcyB0byBzZXQgdXAgYSBwcm94eSBjb25uZWN0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFVzZXMgdGhlIHNoYXJlZCBnbG9iYWwgbm9kZSBhZ2VudFxuICAgKi9cbiAgcmVhZG9ubHkgYWdlbnQ/OiBBZ2VudDtcbn1cblxuLyoqXG4gKiBUaGUgdGVsZW1ldHJ5IGNsaWVudCB0aGF0IGhpdHMgYW4gZXh0ZXJuYWwgZW5kcG9pbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBFbmRwb2ludFRlbGVtZXRyeVNpbmsgaW1wbGVtZW50cyBJVGVsZW1ldHJ5U2luayB7XG4gIHByaXZhdGUgZXZlbnRzOiBUZWxlbWV0cnlTY2hlbWFbXSA9IFtdO1xuICBwcml2YXRlIGVuZHBvaW50OiBVUkw7XG4gIHByaXZhdGUgaW9IZWxwZXI6IElvSGVscGVyO1xuICBwcml2YXRlIGFnZW50PzogQWdlbnQ7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHByb3BzOiBFbmRwb2ludFRlbGVtZXRyeVNpbmtQcm9wcykge1xuICAgIHRoaXMuZW5kcG9pbnQgPSBuZXcgVVJMKHByb3BzLmVuZHBvaW50KTtcblxuICAgIGlmICghdGhpcy5lbmRwb2ludC5ob3N0bmFtZSB8fCAhdGhpcy5lbmRwb2ludC5wYXRobmFtZSkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignTWFsZm9ybWVkRW5kcG9pbnQnLCBgVGVsZW1ldHJ5IEVuZHBvaW50IG1hbGZvcm1lZC4gUmVjZWl2ZWQgaG9zdG5hbWU6ICR7dGhpcy5lbmRwb2ludC5ob3N0bmFtZX0sIHBhdGhuYW1lOiAke3RoaXMuZW5kcG9pbnQucGF0aG5hbWV9YCk7XG4gICAgfVxuXG4gICAgdGhpcy5pb0hlbHBlciA9IElvSGVscGVyLmZyb21BY3Rpb25Bd2FyZUlvSG9zdChwcm9wcy5pb0hvc3QpO1xuICAgIHRoaXMuYWdlbnQgPSBwcm9wcy5hZ2VudDtcblxuICAgIC8vIEJhdGNoIGV2ZW50cyBldmVyeSAzMCBzZWNvbmRzXG4gICAgc2V0SW50ZXJ2YWwoKCkgPT4gdGhpcy5mbHVzaCgpLCAzMDAwMCkudW5yZWYoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYW4gZXZlbnQgdG8gdGhlIGNvbGxlY3Rpb24uXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZW1pdChldmVudDogVGVsZW1ldHJ5U2NoZW1hKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuZXZlbnRzLnB1c2goZXZlbnQpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgLy8gTmV2ZXIgdGhyb3cgZXJyb3JzLCBqdXN0IGxvZyB0aGVtIHZpYSBpb0hvc3RcbiAgICAgIGF3YWl0IHRoaXMuaW9IZWxwZXIuZGVmYXVsdHMudHJhY2UoYEZhaWxlZCB0byBhZGQgdGVsZW1ldHJ5IGV2ZW50OiAke2UubWVzc2FnZX1gKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZmx1c2goKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0aGlzLmV2ZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmh0dHBzKHRoaXMuZW5kcG9pbnQsIHsgZXZlbnRzOiB0aGlzLmV2ZW50cyB9KTtcblxuICAgICAgLy8gQ2xlYXIgdGhlIGV2ZW50cyBhcnJheSBhZnRlciBzdWNjZXNzZnVsIG91dHB1dFxuICAgICAgaWYgKHJlcykge1xuICAgICAgICB0aGlzLmV2ZW50cyA9IFtdO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgLy8gTmV2ZXIgdGhyb3cgZXJyb3JzLCBqdXN0IGxvZyB0aGVtIHZpYSBpb0hvc3RcbiAgICAgIGF3YWl0IHRoaXMuaW9IZWxwZXIuZGVmYXVsdHMudHJhY2UoYEZhaWxlZCB0byBzZW5kIHRlbGVtZXRyeSBldmVudDogJHtlLm1lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0ZWxlbWV0cnkgc3VjY2Vzc2Z1bGx5IHBvc3RlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBodHRwcyhcbiAgICB1cmw6IFVSTCxcbiAgICBib2R5OiB7IGV2ZW50czogVGVsZW1ldHJ5U2NoZW1hW10gfSxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgLy8gQ2hlY2sgY29ubmVjdGl2aXR5IGJlZm9yZSBhdHRlbXB0aW5nIG5ldHdvcmsgcmVxdWVzdFxuICAgIGNvbnN0IGhhc0Nvbm5lY3Rpdml0eSA9IGF3YWl0IE5ldHdvcmtEZXRlY3Rvci5oYXNDb25uZWN0aXZpdHkodGhpcy5hZ2VudCk7XG4gICAgaWYgKCFoYXNDb25uZWN0aXZpdHkpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW9IZWxwZXIuZGVmYXVsdHMudHJhY2UoJ05vIGludGVybmV0IGNvbm5lY3Rpdml0eSBkZXRlY3RlZCwgc2tpcHBpbmcgdGVsZW1ldHJ5Jyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGRvUmVxdWVzdCh1cmwsIGJvZHksIHRoaXMuYWdlbnQpO1xuXG4gICAgICAvLyBTdWNjZXNzZnVsbHkgcG9zdGVkXG4gICAgICBpZiAocmVzLnN0YXR1c0NvZGUgJiYgcmVzLnN0YXR1c0NvZGUgPj0gMjAwICYmIHJlcy5zdGF0dXNDb2RlIDwgMzAwKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW9IZWxwZXIuZGVmYXVsdHMudHJhY2UoJ1RlbGVtZXRyeSBTZW50IFN1Y2Nlc3NmdWxseScpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdGhpcy5pb0hlbHBlci5kZWZhdWx0cy50cmFjZShgVGVsZW1ldHJ5IFVuc3VjY2Vzc2Z1bDogUE9TVCAke3VybC5ob3N0bmFtZX0ke3VybC5wYXRobmFtZX06ICR7cmVzLnN0YXR1c0NvZGV9OiR7cmVzLnN0YXR1c01lc3NhZ2V9YCk7XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW9IZWxwZXIuZGVmYXVsdHMudHJhY2UoYFRlbGVtZXRyeSBFcnJvcjogUE9TVCAke3VybC5ob3N0bmFtZX0ke3VybC5wYXRobmFtZX06ICR7SlNPTi5zdHJpbmdpZnkoZSl9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQSBQcm9taXNpZmllZCB2ZXJzaW9uIG9mIGBodHRwcy5yZXF1ZXN0KClgXG4gKi9cbmZ1bmN0aW9uIGRvUmVxdWVzdChcbiAgdXJsOiBVUkwsXG4gIGRhdGE6IHsgZXZlbnRzOiBUZWxlbWV0cnlTY2hlbWFbXSB9LFxuICBhZ2VudD86IEFnZW50LFxuKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTxJbmNvbWluZ01lc3NhZ2U+KChvaywga28pID0+IHtcbiAgICBjb25zdCBwYXlsb2FkOiBzdHJpbmcgPSBKU09OLnN0cmluZ2lmeShkYXRhKTtcbiAgICBjb25zdCByZXEgPSByZXF1ZXN0KHtcbiAgICAgIGhvc3RuYW1lOiB1cmwuaG9zdG5hbWUsXG4gICAgICBwb3J0OiB1cmwucG9ydCB8fCBudWxsLFxuICAgICAgcGF0aDogdXJsLnBhdGhuYW1lLFxuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICdjb250ZW50LWxlbmd0aCc6IHBheWxvYWQubGVuZ3RoLFxuICAgICAgfSxcbiAgICAgIGFnZW50LFxuICAgICAgdGltZW91dDogUkVRVUVTVF9BVFRFTVBUX1RJTUVPVVRfTVMsXG4gICAgfSwgb2spO1xuXG4gICAgcmVxLm9uKCdlcnJvcicsIGtvKTtcbiAgICByZXEub24oJ3RpbWVvdXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBlcnJvciA9IG5ldyBUb29sa2l0RXJyb3IoJ1JlcXVlc3RUaW1lb3V0JywgYFRpbWVvdXQgYWZ0ZXIgJHtSRVFVRVNUX0FUVEVNUFRfVElNRU9VVF9NU31tcywgYWJvcnRpbmcgcmVxdWVzdGApO1xuICAgICAgcmVxLmRlc3Ryb3koZXJyb3IpO1xuICAgIH0pO1xuXG4gICAgcmVxLmVuZChwYXlsb2FkKTtcbiAgfSk7XG59XG4iXX0=