• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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