import { name as agentName, version as agentVersion } from "../package.json"; import { CloudApi } from "./cloud"; import { v4 as uuid } from "uuid"; import { isBrowser } from "./env"; import { rootLogger } from "./logger"; import { dataStore, DataStore } from "./dataStore"; export class AnonymousUsageLogger { private anonymousUsageTrackingApi = new CloudApi(); private logger = rootLogger.child({ component: "AnonymousUsage" }); private systemData = { agent: `${agentName}, ${agentVersion}`, browser: isBrowser ? navigator?.userAgent || "browser" : undefined, node: isBrowser ? undefined : `${process.version} ${process.platform} ${require("os").arch()} ${require("os").release()}`, }; private dataStore: DataStore | null = null; private anonymousId: string; disabled: boolean; private constructor() {} static async create(options: { dataStore: DataStore }): Promise { const logger = new AnonymousUsageLogger(); logger.dataStore = options.dataStore || dataStore; await logger.checkAnonymousId(); return logger; } private async checkAnonymousId() { if (this.dataStore) { try { await this.dataStore.load(); } catch (error) { this.logger.debug({ error }, "Error when loading anonymousId"); } if (typeof this.dataStore.data["anonymousId"] === "string") { this.anonymousId = this.dataStore.data["anonymousId"]; } else { this.anonymousId = uuid(); this.dataStore.data["anonymousId"] = this.anonymousId; try { await this.dataStore.save(); } catch (error) { this.logger.debug({ error }, "Error when saving anonymousId"); } } } else { this.anonymousId = uuid(); } } async event(event: string, data: any) { if (this.disabled) { return; } await this.anonymousUsageTrackingApi.api .usage({ distinctId: this.anonymousId, event, properties: { ...this.systemData, ...data, }, }) .catch((error) => { this.logger.error({ error }, "Error when sending anonymous usage data"); }); } }