metrics.js 2.2 KB

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