Files
medusa-store/packages/medusa-telemetry/src/telemeter.js
2022-11-20 22:01:46 +01:00

183 lines
4.5 KiB
JavaScript

import fs from "fs"
import isDocker from "is-docker"
import os from "os"
import { join, sep } from "path"
import { v4 as uuidv4 } from "uuid"
import Store from "./store"
import createFlush from "./util/create-flush"
import getTermProgram from "./util/get-term-program"
import { getCIName, isCI } from "./util/is-ci"
import isTruthy from "./util/is-truthy"
import showAnalyticsNotification from "./util/show-notification"
const MEDUSA_TELEMETRY_VERBOSE = process.env.MEDUSA_TELEMETRY_VERBOSE || false
class Telemeter {
constructor(options = {}) {
this.store_ = new Store()
this.flushAt = Math.max(options.flushAt, 1) || 20
this.maxQueueSize = options.maxQueueSize || 1024 * 500
this.flushInterval = options.flushInterval || 10 * 1000
this.flushed = false
this.queueSize_ = this.store_.getQueueSize()
this.queueCount_ = this.store_.getQueueCount()
this.featureFlags_ = new Set()
this.modules_ = new Set()
this.plugins_ = []
}
getMachineId() {
if (this.machineId) {
return this.machineId
}
let machineId = this.store_.getConfig(`telemetry.machine_id`)
if (typeof machineId !== `string`) {
machineId = uuidv4()
this.store_.setConfig(`telemetry.machine_id`, machineId)
}
this.machineId = machineId
return machineId
}
isTrackingEnabled() {
// Cache the result
if (this.trackingEnabled !== undefined) {
return this.trackingEnabled
}
let enabled = this.store_.getConfig(`telemetry.enabled`)
if (enabled === undefined || enabled === null) {
if (!isCI()) {
showAnalyticsNotification()
}
enabled = true
this.store_.setConfig(`telemetry.enabled`, enabled)
}
this.trackingEnabled = enabled
return enabled
}
getOsInfo() {
if (this.osInfo) {
return this.osInfo
}
const cpus = os.cpus()
const osInfo = {
node_version: process.version,
platform: os.platform(),
release: os.release(),
cpus: (cpus && cpus.length > 0 && cpus[0].model) || undefined,
is_ci: isCI(),
ci_name: getCIName(),
arch: os.arch(),
docker: isDocker(),
term_program: getTermProgram(),
}
this.osInfo = osInfo
return osInfo
}
getMedusaVersion() {
try {
const packageJson = require.resolve(`@medusajs/medusa/package.json`)
const { version } = JSON.parse(fs.readFileSync(packageJson, `utf-8`))
return version
} catch (e) {
if (isTruthy(MEDUSA_TELEMETRY_VERBOSE)) {
console.error("failed to get medusa version", e)
}
}
return `-0.0.0`
}
getCliVersion() {
try {
const jsonfile = join(
require
.resolve(`@medusajs/medusa-cli`) // Resolve where current gatsby-cli would be loaded from.
.split(sep)
.slice(0, -2) // drop lib/index.js
.join(sep),
`package.json`
)
const { version } = require(jsonfile)
return version
} catch (e) {
if (isTruthy(MEDUSA_TELEMETRY_VERBOSE)) {
console.error("failed to get medusa version", e)
}
}
return `-0.0.0`
}
setTelemetryEnabled(enabled) {
this.trackingEnabled = enabled
this.store_.setConfig(`telemetry.enabled`, enabled)
}
track(event, data) {
return this.enqueue_(event, data)
}
enqueue_(type, data) {
const event = {
id: `te_${uuidv4()}`,
type,
properties: data,
timestamp: new Date(),
machine_id: this.getMachineId(),
os_info: this.getOsInfo(),
medusa_version: this.getMedusaVersion(),
cli_version: this.getCliVersion(),
feature_flags: Array.from(this.featureFlags_),
modules: Array.from(this.modules_),
plugins: this.plugins_,
}
this.store_.addEvent(event)
this.queueCount_ += 1
this.queueSize_ += JSON.stringify(event).length
const hasReachedFlushAt = this.queueCount_ >= this.flushAt
const hasReachedQueueSize = this.queueSize_ >= this.maxQueueSize
if (hasReachedQueueSize || hasReachedFlushAt) {
const flush = createFlush(this.isTrackingEnabled())
flush && flush()
}
if (this.flushInterval && !this.timer) {
const flush = createFlush(this.isTrackingEnabled())
if (flush) {
this.timer = setTimeout(flush, this.flushInterval)
}
}
}
trackFeatureFlag(flag) {
if (flag) {
this.featureFlags_.add(flag)
}
}
trackModule(module) {
if (module) {
this.modules_.add(module)
}
}
trackPlugin(plugin) {
if (plugin) {
this.plugins_.push(plugin)
}
}
}
export default Telemeter