ContentCacheMetrics.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. const logger = require('logger-sharelatex')
  2. const Metrics = require('./Metrics')
  3. const os = require('os')
  4. let CACHED_LOAD = {
  5. expires: -1,
  6. load: [0, 0, 0],
  7. }
  8. function getSystemLoad() {
  9. if (CACHED_LOAD.expires < Date.now()) {
  10. CACHED_LOAD = {
  11. expires: Date.now() + 10 * 1000,
  12. load: os.loadavg(),
  13. }
  14. }
  15. return CACHED_LOAD.load
  16. }
  17. const ONE_MB = 1024 * 1024
  18. function emitPdfStats(stats, timings) {
  19. if (stats['pdf-caching-timed-out']) {
  20. Metrics.inc('pdf-caching-timed-out')
  21. }
  22. if (stats['pdf-caching-queue-limit-reached']) {
  23. Metrics.inc('pdf-caching-queue-limit-reached')
  24. }
  25. if (timings['compute-pdf-caching']) {
  26. emitPdfCachingStats(stats, timings)
  27. } else {
  28. // How much bandwidth will the pdf incur when downloaded in full?
  29. Metrics.summary('pdf-bandwidth', stats['pdf-size'])
  30. }
  31. }
  32. function emitPdfCachingStats(stats, timings) {
  33. if (!stats['pdf-size']) return // double check
  34. // How much extra time did we spent in PDF.js?
  35. Metrics.timing('compute-pdf-caching', timings['compute-pdf-caching'])
  36. // How large is the overhead of hashing up-front?
  37. const fraction =
  38. timings.compileE2E - timings['compute-pdf-caching'] !== 0
  39. ? timings.compileE2E /
  40. (timings.compileE2E - timings['compute-pdf-caching'])
  41. : 1
  42. if (fraction > 1.5 && timings.compileE2E > 10 * 1000) {
  43. logger.warn(
  44. {
  45. stats,
  46. timings,
  47. load: getSystemLoad(),
  48. },
  49. 'slow pdf caching'
  50. )
  51. }
  52. Metrics.summary('overhead-compute-pdf-ranges', fraction * 100 - 100)
  53. // How does the hashing scale to pdf size in MB?
  54. Metrics.timing(
  55. 'compute-pdf-caching-relative-to-pdf-size',
  56. timings['compute-pdf-caching'] / (stats['pdf-size'] / ONE_MB)
  57. )
  58. if (stats['pdf-caching-total-ranges-size']) {
  59. // How does the hashing scale to total ranges size in MB?
  60. Metrics.timing(
  61. 'compute-pdf-caching-relative-to-total-ranges-size',
  62. timings['compute-pdf-caching'] /
  63. (stats['pdf-caching-total-ranges-size'] / ONE_MB)
  64. )
  65. // How fast is the hashing per range on average?
  66. Metrics.timing(
  67. 'compute-pdf-caching-relative-to-ranges-count',
  68. timings['compute-pdf-caching'] / stats['pdf-caching-n-ranges']
  69. )
  70. // How many ranges are new?
  71. Metrics.summary(
  72. 'new-pdf-ranges-relative-to-total-ranges',
  73. (stats['pdf-caching-n-new-ranges'] / stats['pdf-caching-n-ranges']) * 100
  74. )
  75. }
  76. // How much content is cacheable?
  77. Metrics.summary(
  78. 'cacheable-ranges-to-pdf-size',
  79. (stats['pdf-caching-total-ranges-size'] / stats['pdf-size']) * 100
  80. )
  81. const sizeWhenDownloadedInFull =
  82. // All of the pdf
  83. stats['pdf-size'] -
  84. // These ranges are potentially cached.
  85. stats['pdf-caching-total-ranges-size'] +
  86. // These ranges are not cached.
  87. stats['pdf-caching-new-ranges-size']
  88. // How much bandwidth can we save when downloading the pdf in full?
  89. Metrics.summary(
  90. 'pdf-bandwidth-savings',
  91. 100 - (sizeWhenDownloadedInFull / stats['pdf-size']) * 100
  92. )
  93. // How much bandwidth will the pdf incur when downloaded in full?
  94. Metrics.summary('pdf-bandwidth', sizeWhenDownloadedInFull)
  95. // How much space do the ranges use?
  96. // This will accumulate the ranges size over time, skipping already written ranges.
  97. Metrics.summary(
  98. 'pdf-ranges-disk-size',
  99. stats['pdf-caching-new-ranges-size'] - stats['pdf-caching-reclaimed-space']
  100. )
  101. }
  102. module.exports = {
  103. emitPdfStats,
  104. }