Files
overleaf-cep/services/clsi/app/js/StatsManager.js
Brian Gough da3f366643 Merge pull request #28959 from overleaf/bg-exclude-health-checks-from-performance-logs
exclude health checks from performance logs

GitOrigin-RevId: 88db63e00b32b2b015ee25c7d555546ed7d9a95b
2025-10-13 08:05:18 +00:00

51 lines
2.1 KiB
JavaScript

const crypto = require('node:crypto')
/**
* Consistently sample a keyspace with a given sample percentage.
* The same key will always produce a consistent percentile value that
* can be compared against the sample percentage.
* Example: if key is the userId and the samplePercentage is 10, then
* we see all the activity for the 10% of users who are selected.
*
* @param {string} key - The unique identifier to be hashed and checked.
* @param {number} samplePercentage - The percentage (0-100) of keys that should return true.
* @returns {boolean} - True if the key is within the sample, false otherwise.
*/
function sampleByHash(key, samplePercentage) {
if (samplePercentage <= 0) {
return false
}
const hash = crypto.createHash('md5').update(key).digest()
const hashValue = hash.readUInt32BE(0)
const percentile = Math.floor((hashValue / 0xffffffff) * 100)
return percentile < samplePercentage
}
const EXCLUDED_METRICS_OPTS_PATHS = new Set(['health-check', 'clsi-perf'])
/**
* Determines whether a given request should be sampled based on user ID and sampling percentage.
* The request will not be sampled if it lacks a user_id, if its metrics path is in the exclusion list,
* or if the sampling percentage is zero or less.
*
* @param {object} request - The request object to check.
* @param {string} [request.user_id] - The ID of the user making the request.
* @param {object} [request.metricsOpts] - Metrics options for the request.
* @param {string} [request.metricsOpts.path] - The path associated with the request metrics.
* @param {number} samplingPercentage - The percentage of requests to sample (e.g., 10 for 10%).
* @returns {boolean|undefined} The result from sampleByHash if the request is eligible for sampling, otherwise undefined.
*/
function sampleRequest(request, samplingPercentage) {
if (!request.user_id) {
return
}
if (EXCLUDED_METRICS_OPTS_PATHS.has(request.metricsOpts?.path)) {
return
}
if (samplingPercentage > 0) {
return sampleByHash(request.user_id, samplingPercentage)
}
}
module.exports = { sampleByHash, sampleRequest }