2022-03-01 15:09:36 +00:00
|
|
|
const logger = require('@overleaf/logger')
|
2021-05-13 13:07:54 +00:00
|
|
|
const Metrics = require('./Metrics')
|
2021-06-23 08:15:05 +00:00
|
|
|
const os = require('os')
|
|
|
|
|
|
|
|
let CACHED_LOAD = {
|
|
|
|
expires: -1,
|
2021-07-13 11:04:48 +00:00
|
|
|
load: [0, 0, 0],
|
2021-06-23 08:15:05 +00:00
|
|
|
}
|
|
|
|
function getSystemLoad() {
|
|
|
|
if (CACHED_LOAD.expires < Date.now()) {
|
|
|
|
CACHED_LOAD = {
|
|
|
|
expires: Date.now() + 10 * 1000,
|
2021-07-13 11:04:48 +00:00
|
|
|
load: os.loadavg(),
|
2021-06-23 08:15:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return CACHED_LOAD.load
|
|
|
|
}
|
2021-05-13 13:07:54 +00:00
|
|
|
|
|
|
|
const ONE_MB = 1024 * 1024
|
|
|
|
|
2022-03-01 15:09:55 +00:00
|
|
|
function emitPdfStats(stats, timings, request) {
|
2021-05-13 13:07:54 +00:00
|
|
|
if (timings['compute-pdf-caching']) {
|
2022-03-01 15:09:55 +00:00
|
|
|
emitPdfCachingStats(stats, timings, request)
|
2021-05-13 13:07:54 +00:00
|
|
|
} else {
|
|
|
|
// How much bandwidth will the pdf incur when downloaded in full?
|
2022-06-30 09:39:11 +00:00
|
|
|
Metrics.summary('pdf-bandwidth', stats['pdf-size'], request.metricsOpts)
|
2021-05-13 13:07:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-01 15:09:55 +00:00
|
|
|
function emitPdfCachingStats(stats, timings, request) {
|
2021-05-13 13:07:54 +00:00
|
|
|
if (!stats['pdf-size']) return // double check
|
|
|
|
|
2022-11-01 14:50:02 +00:00
|
|
|
if (stats['pdf-caching-timed-out']) {
|
|
|
|
Metrics.inc('pdf-caching-timed-out', 1, request.metricsOpts)
|
|
|
|
}
|
|
|
|
if (timings['pdf-caching-overhead-delete-stale-hashes'] !== undefined) {
|
|
|
|
Metrics.summary(
|
|
|
|
'pdf-caching-overhead-delete-stale-hashes',
|
|
|
|
timings['pdf-caching-overhead-delete-stale-hashes'],
|
|
|
|
request.metricsOpts
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-06-23 10:28:31 +00:00
|
|
|
// How much extra time did we spent in PDF.js?
|
2022-03-01 15:09:55 +00:00
|
|
|
Metrics.timing(
|
|
|
|
'compute-pdf-caching',
|
|
|
|
timings['compute-pdf-caching'],
|
|
|
|
1,
|
|
|
|
request.metricsOpts
|
|
|
|
)
|
2021-06-23 10:28:31 +00:00
|
|
|
|
2021-05-13 13:07:54 +00:00
|
|
|
// How large is the overhead of hashing up-front?
|
|
|
|
const fraction =
|
|
|
|
timings.compileE2E - timings['compute-pdf-caching'] !== 0
|
|
|
|
? timings.compileE2E /
|
|
|
|
(timings.compileE2E - timings['compute-pdf-caching'])
|
|
|
|
: 1
|
2021-06-23 10:27:19 +00:00
|
|
|
if (fraction > 1.5 && timings.compileE2E > 10 * 1000) {
|
2021-06-23 08:15:05 +00:00
|
|
|
logger.warn(
|
|
|
|
{
|
|
|
|
stats,
|
|
|
|
timings,
|
2021-07-13 11:04:48 +00:00
|
|
|
load: getSystemLoad(),
|
2021-06-23 08:15:05 +00:00
|
|
|
},
|
|
|
|
'slow pdf caching'
|
|
|
|
)
|
|
|
|
}
|
2022-03-01 15:09:55 +00:00
|
|
|
Metrics.summary(
|
|
|
|
'overhead-compute-pdf-ranges',
|
|
|
|
fraction * 100 - 100,
|
|
|
|
request.metricsOpts
|
|
|
|
)
|
2021-05-13 13:07:54 +00:00
|
|
|
|
|
|
|
// How does the hashing scale to pdf size in MB?
|
|
|
|
Metrics.timing(
|
|
|
|
'compute-pdf-caching-relative-to-pdf-size',
|
2022-03-01 15:09:55 +00:00
|
|
|
timings['compute-pdf-caching'] / (stats['pdf-size'] / ONE_MB),
|
|
|
|
1,
|
|
|
|
request.metricsOpts
|
2021-05-13 13:07:54 +00:00
|
|
|
)
|
|
|
|
if (stats['pdf-caching-total-ranges-size']) {
|
|
|
|
// How does the hashing scale to total ranges size in MB?
|
|
|
|
Metrics.timing(
|
|
|
|
'compute-pdf-caching-relative-to-total-ranges-size',
|
|
|
|
timings['compute-pdf-caching'] /
|
2022-03-01 15:09:55 +00:00
|
|
|
(stats['pdf-caching-total-ranges-size'] / ONE_MB),
|
|
|
|
1,
|
|
|
|
request.metricsOpts
|
2021-05-13 13:07:54 +00:00
|
|
|
)
|
|
|
|
// How fast is the hashing per range on average?
|
|
|
|
Metrics.timing(
|
|
|
|
'compute-pdf-caching-relative-to-ranges-count',
|
2022-03-01 15:09:55 +00:00
|
|
|
timings['compute-pdf-caching'] / stats['pdf-caching-n-ranges'],
|
|
|
|
1,
|
|
|
|
request.metricsOpts
|
2021-05-13 13:07:54 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// How many ranges are new?
|
|
|
|
Metrics.summary(
|
|
|
|
'new-pdf-ranges-relative-to-total-ranges',
|
2022-03-01 15:09:55 +00:00
|
|
|
(stats['pdf-caching-n-new-ranges'] / stats['pdf-caching-n-ranges']) * 100,
|
|
|
|
request.metricsOpts
|
2021-05-13 13:07:54 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
// How much content is cacheable?
|
|
|
|
Metrics.summary(
|
|
|
|
'cacheable-ranges-to-pdf-size',
|
2022-03-01 15:09:55 +00:00
|
|
|
(stats['pdf-caching-total-ranges-size'] / stats['pdf-size']) * 100,
|
|
|
|
request.metricsOpts
|
2021-05-13 13:07:54 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const sizeWhenDownloadedInFull =
|
|
|
|
// All of the pdf
|
|
|
|
stats['pdf-size'] -
|
|
|
|
// These ranges are potentially cached.
|
|
|
|
stats['pdf-caching-total-ranges-size'] +
|
|
|
|
// These ranges are not cached.
|
|
|
|
stats['pdf-caching-new-ranges-size']
|
|
|
|
|
|
|
|
// How much bandwidth can we save when downloading the pdf in full?
|
|
|
|
Metrics.summary(
|
|
|
|
'pdf-bandwidth-savings',
|
2022-03-01 15:09:55 +00:00
|
|
|
100 - (sizeWhenDownloadedInFull / stats['pdf-size']) * 100,
|
|
|
|
request.metricsOpts
|
2021-05-13 13:07:54 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// How much bandwidth will the pdf incur when downloaded in full?
|
2022-03-01 15:09:55 +00:00
|
|
|
Metrics.summary(
|
|
|
|
'pdf-bandwidth',
|
|
|
|
sizeWhenDownloadedInFull,
|
|
|
|
request.metricsOpts
|
|
|
|
)
|
2021-05-13 13:07:54 +00:00
|
|
|
|
|
|
|
// How much space do the ranges use?
|
|
|
|
// This will accumulate the ranges size over time, skipping already written ranges.
|
2021-05-18 17:06:15 +00:00
|
|
|
Metrics.summary(
|
|
|
|
'pdf-ranges-disk-size',
|
2022-03-01 15:09:55 +00:00
|
|
|
stats['pdf-caching-new-ranges-size'] - stats['pdf-caching-reclaimed-space'],
|
|
|
|
request.metricsOpts
|
2021-05-18 17:06:15 +00:00
|
|
|
)
|
2021-05-13 13:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
2021-07-13 11:04:48 +00:00
|
|
|
emitPdfStats,
|
2021-05-13 13:07:54 +00:00
|
|
|
}
|