1'use strict' 2exports.start = startMetrics 3exports.stop = stopMetrics 4exports.save = saveMetrics 5exports.send = sendMetrics 6 7const fs = require('fs') 8const path = require('path') 9const npm = require('../npm.js') 10const regFetch = require('libnpm/fetch') 11const uuid = require('uuid') 12const cacheFile = require('./cache-file.js') 13 14let inMetrics = false 15 16function startMetrics () { 17 if (inMetrics) return 18 // loaded on demand to avoid any recursive deps when `./metrics-launch` requires us. 19 var metricsLaunch = require('./metrics-launch.js') 20 npm.metricsProcess = metricsLaunch() 21} 22 23function stopMetrics () { 24 if (inMetrics) return 25 if (npm.metricsProcess) npm.metricsProcess.kill('SIGKILL') 26} 27 28function saveMetrics (itWorked) { 29 if (inMetrics) return 30 // If the metrics reporter hasn't managed to PUT yet then kill it so that it doesn't 31 // step on our updating the anonymous-cli-metrics json 32 stopMetrics() 33 var metricsFile = path.join(npm.config.get('cache'), 'anonymous-cli-metrics.json') 34 var metrics 35 try { 36 metrics = JSON.parse(fs.readFileSync(metricsFile)) 37 metrics.metrics.to = new Date().toISOString() 38 if (itWorked) { 39 ++metrics.metrics.successfulInstalls 40 } else { 41 ++metrics.metrics.failedInstalls 42 } 43 } catch (ex) { 44 metrics = { 45 metricId: uuid.v4(), 46 metrics: { 47 from: new Date().toISOString(), 48 to: new Date().toISOString(), 49 successfulInstalls: itWorked ? 1 : 0, 50 failedInstalls: itWorked ? 0 : 1 51 } 52 } 53 } 54 try { 55 cacheFile.write(metricsFile, JSON.stringify(metrics)) 56 } catch (ex) { 57 // we couldn't write and/or chown the error metrics file, oh well. 58 } 59} 60 61function sendMetrics (metricsFile, metricsRegistry) { 62 inMetrics = true 63 var cliMetrics = JSON.parse(fs.readFileSync(metricsFile)) 64 regFetch( 65 `/-/npm/anon-metrics/v1/${encodeURIComponent(cliMetrics.metricId)}`, 66 // NOTE: skip npmConfig() to prevent auth 67 { 68 registry: metricsRegistry, 69 method: 'PUT', 70 body: cliMetrics.metrics, 71 retry: false 72 } 73 ).then(() => { 74 fs.unlinkSync(metricsFile) 75 }, err => { 76 cacheFile.write(path.join(path.dirname(metricsFile), 'last-send-metrics-error.txt'), err.stack) 77 }) 78} 79