@mastra/core
Version:
189 lines (183 loc) • 6.65 kB
JavaScript
'use strict';
var fs = require('fs');
var os = require('os');
var path = require('path');
var crypto = require('crypto');
var posthogNode = require('posthog-node');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var os__default = /*#__PURE__*/_interopDefault(os);
var path__default = /*#__PURE__*/_interopDefault(path);
var POSTHOG_API_KEY = "phc_SBLpZVAB6jmHOct9CABq3PF0Yn5FU3G2FgT4xUr2XrT";
var POSTHOG_HOST = "https://us.posthog.com";
var TRUTHY_DISABLED_VALUES = /* @__PURE__ */ new Set(["1", "true", "yes"]);
var client = null;
function isEETelemetryEnabled() {
const value = process.env["MASTRA_TELEMETRY_DISABLED"];
if (!value) {
return true;
}
return !TRUTHY_DISABLED_VALUES.has(value.trim().toLowerCase());
}
function hashTelemetryValue(value) {
return crypto.createHash("sha256").update(value).digest("hex");
}
function getHashedHostname() {
return hashTelemetryValue(os__default.default.hostname() || "unknown-host").slice(0, 16);
}
function getEETelemetryFallbackDistinctId() {
return `mastra-${getHashedHostname()}`;
}
function getClient() {
if (!isEETelemetryEnabled()) {
return null;
}
if (!client) {
client = new posthogNode.PostHog(POSTHOG_API_KEY, {
host: POSTHOG_HOST,
flushAt: 1,
flushInterval: 0,
disableGeoip: false
});
}
return client;
}
function getSystemProperties() {
return {
os: process.platform,
os_version: os__default.default.release(),
node_version: process.version,
platform: process.arch,
machine_id: getHashedHostname(),
mastra_version: process.env["npm_package_version"] || "unknown"
};
}
function captureTelemetryEvent(event, distinctId, properties) {
try {
const posthog = getClient();
if (!posthog) {
return;
}
posthog.capture({
distinctId: distinctId || getEETelemetryFallbackDistinctId(),
event,
properties: {
...getSystemProperties(),
...properties
}
});
} catch {
}
}
// src/telemetry/usage-telemetry.ts
var INPUT_TOKENS_METRIC = "mastra_model_total_input_tokens";
var OUTPUT_TOKENS_METRIC = "mastra_model_total_output_tokens";
var BREAKDOWN_LIMIT = 200;
var USAGE_TELEMETRY_EVENT = "mastra_model_token_usage";
function getDefaultCursorPath() {
return path__default.default.join(os__default.default.homedir(), ".mastra", "usage-telemetry.json");
}
function readCursors(cursorPath) {
try {
const parsed = JSON.parse(fs.readFileSync(cursorPath, "utf-8"));
if (parsed && typeof parsed === "object" && parsed.projects && typeof parsed.projects === "object") {
return { projects: parsed.projects };
}
} catch {
}
return { projects: {} };
}
function readCursor(cursorPath, projectId) {
const value = readCursors(cursorPath).projects[projectId];
if (!value) {
return void 0;
}
const date = new Date(value);
return Number.isNaN(date.getTime()) ? void 0 : date;
}
function writeCursor(cursorPath, projectId, syncedAt) {
const cursors = readCursors(cursorPath);
cursors.projects[projectId] = syncedAt.toISOString();
fs.mkdirSync(path__default.default.dirname(cursorPath), { recursive: true });
fs.writeFileSync(cursorPath, JSON.stringify(cursors));
}
function applyBreakdown(rows, response, field) {
for (const group of response.groups) {
const provider = group.dimensions.provider ?? null;
const model = group.dimensions.model ?? null;
const key = `${provider}\0${model}`;
let row = rows.get(key);
if (!row) {
row = { provider, model, inputTokens: 0, outputTokens: 0, totalInputTokens: 0, totalOutputTokens: 0 };
rows.set(key, row);
}
row[field] += group.value ?? 0;
}
}
async function syncUsageTelemetry(mastra, options = {}) {
try {
if (!isEETelemetryEnabled()) {
return;
}
const observability = mastra.getStorage()?.stores?.observability;
if (!observability || typeof observability.getMetricBreakdown !== "function") {
return;
}
const projectRoot = process.env.MASTRA_PROJECT_ROOT || process.cwd();
const projectId = hashTelemetryValue(projectRoot).slice(0, 16);
const cursorPath = options.cursorPath ?? getDefaultCursorPath();
const lastSyncedAt = readCursor(cursorPath, projectId);
const now = options.now ?? /* @__PURE__ */ new Date();
if (lastSyncedAt && lastSyncedAt.getTime() >= now.getTime()) {
return;
}
const baseArgs = {
groupBy: ["provider", "model"],
aggregation: "sum",
limit: BREAKDOWN_LIMIT
};
const deltaFilters = {
timestamp: { ...lastSyncedAt ? { start: lastSyncedAt, startExclusive: true } : {}, end: now }
};
const totalFilters = { timestamp: { end: now } };
const [inputDelta, outputDelta, inputTotal, outputTotal] = await Promise.all([
observability.getMetricBreakdown({ ...baseArgs, name: [INPUT_TOKENS_METRIC], filters: deltaFilters }),
observability.getMetricBreakdown({ ...baseArgs, name: [OUTPUT_TOKENS_METRIC], filters: deltaFilters }),
observability.getMetricBreakdown({ ...baseArgs, name: [INPUT_TOKENS_METRIC], filters: totalFilters }),
observability.getMetricBreakdown({ ...baseArgs, name: [OUTPUT_TOKENS_METRIC], filters: totalFilters })
]);
const rows = /* @__PURE__ */ new Map();
applyBreakdown(rows, inputDelta, "inputTokens");
applyBreakdown(rows, outputDelta, "outputTokens");
applyBreakdown(rows, inputTotal, "totalInputTokens");
applyBreakdown(rows, outputTotal, "totalOutputTokens");
const distinctId = process.env.MASTRA_CLI_DISTINCT_ID || void 0;
const command = process.env.MASTRA_TELEMETRY_COMMAND || "server";
const nodeEnv = process.env.NODE_ENV || "development";
const isFirstSync = !lastSyncedAt;
for (const row of rows.values()) {
if (row.inputTokens <= 0 && row.outputTokens <= 0) {
continue;
}
captureTelemetryEvent(USAGE_TELEMETRY_EVENT, distinctId, {
provider: row.provider,
model: row.model,
input_tokens: row.inputTokens,
output_tokens: row.outputTokens,
total_input_tokens: row.totalInputTokens,
total_output_tokens: row.totalOutputTokens,
command,
node_env: nodeEnv,
project_id: projectId,
is_first_sync: isFirstSync,
window_start: lastSyncedAt?.toISOString() ?? null,
window_end: now.toISOString()
});
}
writeCursor(cursorPath, projectId, now);
} catch {
}
}
exports.USAGE_TELEMETRY_EVENT = USAGE_TELEMETRY_EVENT;
exports.syncUsageTelemetry = syncUsageTelemetry;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map