@grouparoo/core
Version:
The Grouparoo Core
136 lines (135 loc) • 5.67 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Telemetry = void 0;
const path_1 = __importDefault(require("path"));
const os_1 = __importDefault(require("os"));
const actionhero_1 = require("actionhero");
require("isomorphic-fetch");
const plugin_1 = require("../modules/plugin");
const statusReporters_1 = require("./../modules/statusReporters");
var Telemetry;
(function (Telemetry) {
const TELEMETRY_CALL_TRIGGERS = [
"timer",
"team",
"cli_run",
"cli_config",
];
const telemetryPath = "/api/v1/telemetry";
async function send(trigger, errors = [], toThrowOnError = false) {
if (!actionhero_1.config.telemetry.enabled)
return;
const fullUrl = `${actionhero_1.config.telemetry.host}${telemetryPath}`;
try {
const payload = await Telemetry.build(trigger, errors);
const response = await fetch(fullUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
return response.status === 200;
}
catch (error) {
try {
// If there's something wrong with our ability to gather telemetry,
// we should try to report that error to the Telemetry service...
await fetch(fullUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(await generateErrorPayload(error, trigger)),
});
}
catch (newError) {
(0, actionhero_1.log)(`[ telemetry ] ${newError}`, "debug");
}
if (toThrowOnError) {
throw error;
}
else {
(0, actionhero_1.log)(`[ telemetry ] ${error}`, "debug");
}
}
}
Telemetry.send = send;
async function build(trigger, errors = []) {
const metrics = [];
// load settings
const clusterName = (await plugin_1.plugin.readSetting("core", "cluster-name"))
.value;
const customerId = (await plugin_1.plugin.readSetting("telemetry", "customer-id"))
.value;
// information about how Grouparoo is being operated
metrics.push(await statusReporters_1.StatusReporters.Cluster.Workers.countWorkers());
metrics.push(await statusReporters_1.StatusReporters.Cluster.Workers.countErrors());
metrics.push(await statusReporters_1.StatusReporters.Cluster.Process.platform());
metrics.push(await statusReporters_1.StatusReporters.Cluster.Process.sequelizeDialect());
metrics.push(...(await statusReporters_1.StatusReporters.Cluster.Process.env()));
// versions of the plugins installed
metrics.push(...(await statusReporters_1.StatusReporters.Plugins.Versions()));
// usage counts
metrics.push(...(await statusReporters_1.StatusReporters.Totals.Models()));
// usage by source
metrics.push(...(await statusReporters_1.StatusReporters.Totals.SourceTotals()));
// usage by destination
metrics.push(...(await statusReporters_1.StatusReporters.Totals.DestinationTotals()));
// records exported
metrics.push(...(await statusReporters_1.StatusReporters.Totals.UniqueRecordsExported()));
errors.forEach((e, idx) => {
if (e) {
metrics.push({
collection: "telemetry",
topic: "error",
aggregation: "exact",
count: idx,
key: `${process.platform}/${os_1.default.release()}`,
value: e,
});
}
});
return {
name: clusterName,
id: customerId,
trigger,
metrics: metrics,
};
}
Telemetry.build = build;
async function generateErrorPayload(error, trigger) {
const clusterName = (await plugin_1.plugin.readSetting("core", "cluster-name"))
.value;
const customerId = (await plugin_1.plugin.readSetting("telemetry", "customer-id"))
.value;
const sanitizedError = sanitizeErrorPayload(error);
const errorPayload = {
name: clusterName,
id: customerId,
trigger,
metrics: [
{
collection: "telemetry",
topic: "error",
aggregation: "exact",
key: `${process.platform}/${os_1.default.release()}`,
value: sanitizedError,
},
],
};
return errorPayload;
}
function sanitizeErrorPayload(error) {
if (!error.stack)
return error.toString();
return error.stack
.split(os_1.default.EOL)
.map((line) => {
// It's likely the part of the path with 'grouparoo' in it would be safely down in the path structure to not include app-information
// There may be many instances of the word "grouparoo" in the file system, so we'll only take the last part of the path
const chunks = line.split("grouparoo" + path_1.default.sep);
return chunks[chunks.length - 1];
})
.join(os_1.default.EOL);
}
})(Telemetry = exports.Telemetry || (exports.Telemetry = {}));