| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- /* eslint-disable
- camelcase,
- */
- let EventLogger
- const logger = require('logger-sharelatex')
- const metrics = require('@overleaf/metrics')
- const settings = require('settings-sharelatex')
- // keep track of message counters to detect duplicate and out of order events
- // messsage ids have the format "UNIQUEHOSTKEY-COUNTER"
- const EVENT_LOG_COUNTER = {}
- const EVENT_LOG_TIMESTAMP = {}
- let EVENT_LAST_CLEAN_TIMESTAMP = 0
- // counter for debug logs
- let COUNTER = 0
- module.exports = EventLogger = {
- MAX_STALE_TIME_IN_MS: 3600 * 1000,
- debugEvent(channel, message) {
- if (settings.debugEvents > 0) {
- logger.log({ channel, message, counter: COUNTER++ }, 'logging event')
- settings.debugEvents--
- }
- },
- checkEventOrder(channel, message_id) {
- if (typeof message_id !== 'string') {
- return
- }
- let result
- if (!(result = message_id.match(/^(.*)-(\d+)$/))) {
- return
- }
- const key = result[1]
- const count = parseInt(result[2], 0)
- if (!(count >= 0)) {
- // ignore checks if counter is not present
- return
- }
- // store the last count in a hash for each host
- const previous = EventLogger._storeEventCount(key, count)
- if (!previous || count === previous + 1) {
- metrics.inc(`event.${channel}.valid`, 0.001) // downsample high rate docupdater events
- return // order is ok
- }
- if (count === previous) {
- metrics.inc(`event.${channel}.duplicate`)
- logger.warn({ channel, message_id }, 'duplicate event')
- return 'duplicate'
- } else {
- metrics.inc(`event.${channel}.out-of-order`)
- logger.warn(
- { channel, message_id, key, previous, count },
- 'out of order event'
- )
- return 'out-of-order'
- }
- },
- _storeEventCount(key, count) {
- const previous = EVENT_LOG_COUNTER[key]
- const now = Date.now()
- EVENT_LOG_COUNTER[key] = count
- EVENT_LOG_TIMESTAMP[key] = now
- // periodically remove old counts
- if (now - EVENT_LAST_CLEAN_TIMESTAMP > EventLogger.MAX_STALE_TIME_IN_MS) {
- EventLogger._cleanEventStream(now)
- EVENT_LAST_CLEAN_TIMESTAMP = now
- }
- return previous
- },
- _cleanEventStream(now) {
- Object.entries(EVENT_LOG_TIMESTAMP).forEach(([key, timestamp]) => {
- if (now - timestamp > EventLogger.MAX_STALE_TIME_IN_MS) {
- delete EVENT_LOG_COUNTER[key]
- delete EVENT_LOG_TIMESTAMP[key]
- }
- })
- }
- }
|