mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #4950 from overleaf/bg-realtime-log-relevelling
realtime log re-levelling GitOrigin-RevId: 81d86ba648e7fc1436b638b67371b35fd831a62f
This commit is contained in:
parent
fd36c41368
commit
618cf99548
22 changed files with 150 additions and 81 deletions
|
@ -27,10 +27,10 @@ const DeploymentManager = require('./app/js/DeploymentManager')
|
||||||
// NOTE: debug is invoked for every blob that is put on the wire
|
// NOTE: debug is invoked for every blob that is put on the wire
|
||||||
const socketIoLogger = {
|
const socketIoLogger = {
|
||||||
error(...message) {
|
error(...message) {
|
||||||
logger.info({ fromSocketIo: true, originalLevel: 'error' }, ...message)
|
logger.debug({ fromSocketIo: true, originalLevel: 'error' }, ...message)
|
||||||
},
|
},
|
||||||
warn(...message) {
|
warn(...message) {
|
||||||
logger.info({ fromSocketIo: true, originalLevel: 'warn' }, ...message)
|
logger.debug({ fromSocketIo: true, originalLevel: 'warn' }, ...message)
|
||||||
},
|
},
|
||||||
info() {},
|
info() {},
|
||||||
debug() {},
|
debug() {},
|
||||||
|
@ -60,7 +60,6 @@ const sessionSockets = new SessionSockets(
|
||||||
)
|
)
|
||||||
|
|
||||||
Metrics.injectMetricsRoute(app)
|
Metrics.injectMetricsRoute(app)
|
||||||
app.use(Metrics.http.monitor(logger))
|
|
||||||
|
|
||||||
io.configure(function () {
|
io.configure(function () {
|
||||||
io.enable('browser client minification')
|
io.enable('browser client minification')
|
||||||
|
@ -102,7 +101,7 @@ app.get('/status', function (req, res) {
|
||||||
|
|
||||||
app.get('/debug/events', function (req, res) {
|
app.get('/debug/events', function (req, res) {
|
||||||
Settings.debugEvents = parseInt(req.query.count, 10) || 20
|
Settings.debugEvents = parseInt(req.query.count, 10) || 20
|
||||||
logger.log({ count: Settings.debugEvents }, 'starting debug mode')
|
logger.info({ count: Settings.debugEvents }, 'starting debug mode')
|
||||||
res.send(`debug mode will log next ${Settings.debugEvents} events`)
|
res.send(`debug mode will log next ${Settings.debugEvents} events`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -137,6 +136,9 @@ app.get(
|
||||||
|
|
||||||
app.get('/health_check/redis', healthCheck)
|
app.get('/health_check/redis', healthCheck)
|
||||||
|
|
||||||
|
// log http requests for routes defined from this point onwards
|
||||||
|
app.use(Metrics.http.monitor(logger))
|
||||||
|
|
||||||
const Router = require('./app/js/Router')
|
const Router = require('./app/js/Router')
|
||||||
Router.configure(app, io, sessionSockets)
|
Router.configure(app, io, sessionSockets)
|
||||||
|
|
||||||
|
@ -162,10 +164,10 @@ Error.stackTraceLimit = 10
|
||||||
function shutdownCleanly(signal) {
|
function shutdownCleanly(signal) {
|
||||||
const connectedClients = io.sockets.clients().length
|
const connectedClients = io.sockets.clients().length
|
||||||
if (connectedClients === 0) {
|
if (connectedClients === 0) {
|
||||||
logger.warn('no clients connected, exiting')
|
logger.info('no clients connected, exiting')
|
||||||
process.exit()
|
process.exit()
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
logger.info(
|
||||||
{ connectedClients },
|
{ connectedClients },
|
||||||
'clients still connected, not shutting down yet'
|
'clients still connected, not shutting down yet'
|
||||||
)
|
)
|
||||||
|
@ -175,18 +177,18 @@ function shutdownCleanly(signal) {
|
||||||
|
|
||||||
function drainAndShutdown(signal) {
|
function drainAndShutdown(signal) {
|
||||||
if (Settings.shutDownInProgress) {
|
if (Settings.shutDownInProgress) {
|
||||||
logger.warn({ signal }, 'shutdown already in progress, ignoring signal')
|
logger.info({ signal }, 'shutdown already in progress, ignoring signal')
|
||||||
} else {
|
} else {
|
||||||
Settings.shutDownInProgress = true
|
Settings.shutDownInProgress = true
|
||||||
const { statusCheckInterval } = Settings
|
const { statusCheckInterval } = Settings
|
||||||
if (statusCheckInterval) {
|
if (statusCheckInterval) {
|
||||||
logger.warn(
|
logger.info(
|
||||||
{ signal },
|
{ signal },
|
||||||
`received interrupt, delay drain by ${statusCheckInterval}ms`
|
`received interrupt, delay drain by ${statusCheckInterval}ms`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
logger.warn(
|
logger.info(
|
||||||
{ signal },
|
{ signal },
|
||||||
`received interrupt, starting drain over ${shutdownDrainTimeWindow} mins`
|
`received interrupt, starting drain over ${shutdownDrainTimeWindow} mins`
|
||||||
)
|
)
|
||||||
|
@ -194,7 +196,7 @@ function drainAndShutdown(signal) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const staleClients = io.sockets.clients()
|
const staleClients = io.sockets.clients()
|
||||||
if (staleClients.length !== 0) {
|
if (staleClients.length !== 0) {
|
||||||
logger.warn(
|
logger.info(
|
||||||
{ staleClients: staleClients.map(client => client.id) },
|
{ staleClients: staleClients.map(client => client.id) },
|
||||||
'forcefully disconnecting stale clients'
|
'forcefully disconnecting stale clients'
|
||||||
)
|
)
|
||||||
|
@ -214,7 +216,7 @@ function drainAndShutdown(signal) {
|
||||||
Settings.shutDownInProgress = false
|
Settings.shutDownInProgress = false
|
||||||
const shutdownDrainTimeWindow = parseInt(Settings.shutdownDrainTimeWindow, 10)
|
const shutdownDrainTimeWindow = parseInt(Settings.shutdownDrainTimeWindow, 10)
|
||||||
if (Settings.shutdownDrainTimeWindow) {
|
if (Settings.shutdownDrainTimeWindow) {
|
||||||
logger.log({ shutdownDrainTimeWindow }, 'shutdownDrainTimeWindow enabled')
|
logger.info({ shutdownDrainTimeWindow }, 'shutdownDrainTimeWindow enabled')
|
||||||
for (const signal of [
|
for (const signal of [
|
||||||
'SIGINT',
|
'SIGINT',
|
||||||
'SIGHUP',
|
'SIGHUP',
|
||||||
|
@ -255,7 +257,7 @@ if (Settings.shutdownDrainTimeWindow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.continualPubsubTraffic) {
|
if (Settings.continualPubsubTraffic) {
|
||||||
logger.warn('continualPubsubTraffic enabled')
|
logger.debug('continualPubsubTraffic enabled')
|
||||||
|
|
||||||
const pubsubClient = redis.createClient(Settings.redis.pubsub)
|
const pubsubClient = redis.createClient(Settings.redis.pubsub)
|
||||||
const clusterClient = redis.createClient(Settings.redis.websessions)
|
const clusterClient = redis.createClient(Settings.redis.websessions)
|
||||||
|
|
|
@ -31,7 +31,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(function () {
|
.then(function () {
|
||||||
logger.log({ channel }, 'subscribed to channel')
|
logger.debug({ channel }, 'subscribed to channel')
|
||||||
metrics.inc(`subscribe.${baseChannel}`)
|
metrics.inc(`subscribe.${baseChannel}`)
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
|
@ -50,7 +50,7 @@ module.exports = {
|
||||||
actualSubscribe
|
actualSubscribe
|
||||||
)
|
)
|
||||||
clientChannelMap.set(channel, subscribePromise)
|
clientChannelMap.set(channel, subscribePromise)
|
||||||
logger.log({ channel }, 'planned to subscribe to channel')
|
logger.debug({ channel }, 'planned to subscribe to channel')
|
||||||
return subscribePromise
|
return subscribePromise
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(function () {
|
.then(function () {
|
||||||
logger.log({ channel }, 'unsubscribed from channel')
|
logger.debug({ channel }, 'unsubscribed from channel')
|
||||||
metrics.inc(`unsubscribe.${baseChannel}`)
|
metrics.inc(`unsubscribe.${baseChannel}`)
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
|
@ -82,7 +82,7 @@ module.exports = {
|
||||||
actualUnsubscribe
|
actualUnsubscribe
|
||||||
)
|
)
|
||||||
clientChannelMap.set(channel, unsubscribePromise)
|
clientChannelMap.set(channel, unsubscribePromise)
|
||||||
logger.log({ channel }, 'planned to unsubscribe from channel')
|
logger.debug({ channel }, 'planned to unsubscribe from channel')
|
||||||
return unsubscribePromise
|
return unsubscribePromise
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,10 @@ module.exports = {
|
||||||
// update. This way we don't care if the connected_user key has expired when
|
// update. This way we don't care if the connected_user key has expired when
|
||||||
// we receive a cursor update.
|
// we receive a cursor update.
|
||||||
updateUserPosition(project_id, client_id, user, cursorData, callback) {
|
updateUserPosition(project_id, client_id, user, cursorData, callback) {
|
||||||
logger.log({ project_id, client_id }, 'marking user as joined or connected')
|
logger.debug(
|
||||||
|
{ project_id, client_id },
|
||||||
|
'marking user as joined or connected'
|
||||||
|
)
|
||||||
|
|
||||||
const multi = rclient.multi()
|
const multi = rclient.multi()
|
||||||
|
|
||||||
|
@ -75,7 +78,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
refreshClient(project_id, client_id) {
|
refreshClient(project_id, client_id) {
|
||||||
logger.log({ project_id, client_id }, 'refreshing connected client')
|
logger.debug({ project_id, client_id }, 'refreshing connected client')
|
||||||
const multi = rclient.multi()
|
const multi = rclient.multi()
|
||||||
multi.hset(
|
multi.hset(
|
||||||
Keys.connectedUser({ project_id, client_id }),
|
Keys.connectedUser({ project_id, client_id }),
|
||||||
|
@ -97,7 +100,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
markUserAsDisconnected(project_id, client_id, callback) {
|
markUserAsDisconnected(project_id, client_id, callback) {
|
||||||
logger.log({ project_id, client_id }, 'marking user as disconnected')
|
logger.debug({ project_id, client_id }, 'marking user as disconnected')
|
||||||
const multi = rclient.multi()
|
const multi = rclient.multi()
|
||||||
multi.srem(Keys.clientsInProject({ project_id }), client_id)
|
multi.srem(Keys.clientsInProject({ project_id }), client_id)
|
||||||
multi.expire(Keys.clientsInProject({ project_id }), FOUR_DAYS_IN_S)
|
multi.expire(Keys.clientsInProject({ project_id }), FOUR_DAYS_IN_S)
|
||||||
|
|
|
@ -16,10 +16,10 @@ function updateDeploymentStatus(fileContent) {
|
||||||
if (closed && !settings.serviceIsClosed) {
|
if (closed && !settings.serviceIsClosed) {
|
||||||
settings.serviceIsClosed = true
|
settings.serviceIsClosed = true
|
||||||
serviceCloseTime = Date.now() + 60 * 1000 // delay closing by 1 minute
|
serviceCloseTime = Date.now() + 60 * 1000 // delay closing by 1 minute
|
||||||
logger.warn({ fileContent }, 'closing service')
|
logger.info({ fileContent }, 'closing service')
|
||||||
} else if (!closed && settings.serviceIsClosed) {
|
} else if (!closed && settings.serviceIsClosed) {
|
||||||
settings.serviceIsClosed = false
|
settings.serviceIsClosed = false
|
||||||
logger.warn({ fileContent }, 'opening service')
|
logger.info({ fileContent }, 'opening service')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ function checkStatusFileSync() {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
initialise() {
|
initialise() {
|
||||||
if (statusFile && deploymentColour) {
|
if (statusFile && deploymentColour) {
|
||||||
logger.log(
|
logger.info(
|
||||||
{ statusFile, deploymentColour, interval: FILE_CHECK_INTERVAL },
|
{ statusFile, deploymentColour, interval: FILE_CHECK_INTERVAL },
|
||||||
'monitoring deployment status file'
|
'monitoring deployment status file'
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,7 +18,7 @@ module.exports = DocumentUpdaterController = {
|
||||||
rclientList: RedisClientManager.createClientList(settings.redis.pubsub),
|
rclientList: RedisClientManager.createClientList(settings.redis.pubsub),
|
||||||
|
|
||||||
listenForUpdatesFromDocumentUpdater(io) {
|
listenForUpdatesFromDocumentUpdater(io) {
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ rclients: this.rclientList.length },
|
{ rclients: this.rclientList.length },
|
||||||
'listening for applied-ops events'
|
'listening for applied-ops events'
|
||||||
)
|
)
|
||||||
|
@ -112,7 +112,7 @@ module.exports = DocumentUpdaterController = {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// send updates to clients
|
// send updates to clients
|
||||||
logger.log(
|
logger.debug(
|
||||||
{
|
{
|
||||||
doc_id,
|
doc_id,
|
||||||
version: update.v,
|
version: update.v,
|
||||||
|
@ -127,7 +127,7 @@ module.exports = DocumentUpdaterController = {
|
||||||
if (!seen[client.id]) {
|
if (!seen[client.id]) {
|
||||||
seen[client.id] = true
|
seen[client.id] = true
|
||||||
if (client.publicId === update.meta.source) {
|
if (client.publicId === update.meta.source) {
|
||||||
logger.log(
|
logger.debug(
|
||||||
{
|
{
|
||||||
doc_id,
|
doc_id,
|
||||||
version: update.v,
|
version: update.v,
|
||||||
|
@ -138,7 +138,7 @@ module.exports = DocumentUpdaterController = {
|
||||||
client.emit('otUpdateApplied', { v: update.v, doc: update.doc })
|
client.emit('otUpdateApplied', { v: update.v, doc: update.doc })
|
||||||
} else if (!update.dup) {
|
} else if (!update.dup) {
|
||||||
// Duplicate ops should just be sent back to sending client for acknowledgement
|
// Duplicate ops should just be sent back to sending client for acknowledgement
|
||||||
logger.log(
|
logger.debug(
|
||||||
{
|
{
|
||||||
doc_id,
|
doc_id,
|
||||||
version: update.v,
|
version: update.v,
|
||||||
|
@ -153,7 +153,7 @@ module.exports = DocumentUpdaterController = {
|
||||||
}
|
}
|
||||||
if (Object.keys(seen).length < clientList.length) {
|
if (Object.keys(seen).length < clientList.length) {
|
||||||
metrics.inc('socket-io.duplicate-clients', 0.1)
|
metrics.inc('socket-io.duplicate-clients', 0.1)
|
||||||
logger.log(
|
logger.debug(
|
||||||
{
|
{
|
||||||
doc_id,
|
doc_id,
|
||||||
socketIoClients: clientList.map(client => client.id),
|
socketIoClients: clientList.map(client => client.id),
|
||||||
|
|
|
@ -23,7 +23,7 @@ const DocumentUpdaterManager = {
|
||||||
getDocument(project_id, doc_id, fromVersion, callback) {
|
getDocument(project_id, doc_id, fromVersion, callback) {
|
||||||
const timer = new metrics.Timer('get-document')
|
const timer = new metrics.Timer('get-document')
|
||||||
const url = `${settings.apis.documentupdater.url}/project/${project_id}/doc/${doc_id}?fromVersion=${fromVersion}`
|
const url = `${settings.apis.documentupdater.url}/project/${project_id}/doc/${doc_id}?fromVersion=${fromVersion}`
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ project_id, doc_id, fromVersion },
|
{ project_id, doc_id, fromVersion },
|
||||||
'getting doc from document updater'
|
'getting doc from document updater'
|
||||||
)
|
)
|
||||||
|
@ -34,7 +34,7 @@ const DocumentUpdaterManager = {
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ project_id, doc_id },
|
{ project_id, doc_id },
|
||||||
'got doc from document document updater'
|
'got doc from document document updater'
|
||||||
)
|
)
|
||||||
|
@ -63,7 +63,7 @@ const DocumentUpdaterManager = {
|
||||||
|
|
||||||
flushProjectToMongoAndDelete(project_id, callback) {
|
flushProjectToMongoAndDelete(project_id, callback) {
|
||||||
// this method is called when the last connected user leaves the project
|
// this method is called when the last connected user leaves the project
|
||||||
logger.log({ project_id }, 'deleting project from document updater')
|
logger.debug({ project_id }, 'deleting project from document updater')
|
||||||
const timer = new metrics.Timer('delete.mongo.project')
|
const timer = new metrics.Timer('delete.mongo.project')
|
||||||
// flush the project in the background when all users have left
|
// flush the project in the background when all users have left
|
||||||
const url =
|
const url =
|
||||||
|
@ -75,7 +75,7 @@ const DocumentUpdaterManager = {
|
||||||
OError.tag(err, 'error deleting project from document updater')
|
OError.tag(err, 'error deleting project from document updater')
|
||||||
callback(err)
|
callback(err)
|
||||||
} else if (res.statusCode >= 200 && res.statusCode < 300) {
|
} else if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
logger.log({ project_id }, 'deleted project from document updater')
|
logger.debug({ project_id }, 'deleted project from document updater')
|
||||||
callback(null)
|
callback(null)
|
||||||
} else {
|
} else {
|
||||||
callback(
|
callback(
|
||||||
|
|
|
@ -10,7 +10,7 @@ module.exports = {
|
||||||
startDrain(io, rate, callback) {
|
startDrain(io, rate, callback) {
|
||||||
// Clear out any old interval
|
// Clear out any old interval
|
||||||
clearInterval(this.interval)
|
clearInterval(this.interval)
|
||||||
logger.log({ rate }, 'starting drain')
|
logger.info({ rate }, 'starting drain')
|
||||||
if (rate === 0) {
|
if (rate === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ module.exports = {
|
||||||
for (const client of io.sockets.clients()) {
|
for (const client of io.sockets.clients()) {
|
||||||
if (!this.RECONNECTED_CLIENTS[client.id]) {
|
if (!this.RECONNECTED_CLIENTS[client.id]) {
|
||||||
this.RECONNECTED_CLIENTS[client.id] = true
|
this.RECONNECTED_CLIENTS[client.id] = true
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ client_id: client.id },
|
{ client_id: client.id },
|
||||||
'Asking client to reconnect gracefully'
|
'Asking client to reconnect gracefully'
|
||||||
)
|
)
|
||||||
|
@ -51,7 +51,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (drainedCount < N) {
|
if (drainedCount < N) {
|
||||||
logger.log('All clients have been told to reconnectGracefully')
|
logger.info('All clients have been told to reconnectGracefully')
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -21,7 +21,7 @@ module.exports = EventLogger = {
|
||||||
|
|
||||||
debugEvent(channel, message) {
|
debugEvent(channel, message) {
|
||||||
if (settings.debugEvents > 0) {
|
if (settings.debugEvents > 0) {
|
||||||
logger.log({ channel, message, counter: COUNTER++ }, 'logging event')
|
logger.info({ channel, message, counter: COUNTER++ }, 'logging event')
|
||||||
settings.debugEvents--
|
settings.debugEvents--
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,7 +7,7 @@ const logger = require('logger-sharelatex')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sendMessage(req, res) {
|
sendMessage(req, res) {
|
||||||
logger.log({ message: req.params.message }, 'sending message')
|
logger.debug({ message: req.params.message }, 'sending message')
|
||||||
if (Array.isArray(req.body)) {
|
if (Array.isArray(req.body)) {
|
||||||
for (const payload of req.body) {
|
for (const payload of req.body) {
|
||||||
WebsocketLoadBalancer.emitToRoom(
|
WebsocketLoadBalancer.emitToRoom(
|
||||||
|
@ -30,7 +30,7 @@ module.exports = {
|
||||||
const io = req.app.get('io')
|
const io = req.app.get('io')
|
||||||
let rate = req.query.rate || '4'
|
let rate = req.query.rate || '4'
|
||||||
rate = parseFloat(rate) || 0
|
rate = parseFloat(rate) || 0
|
||||||
logger.log({ rate }, 'setting client drain rate')
|
logger.info({ rate }, 'setting client drain rate')
|
||||||
DrainManager.startDrain(io, rate)
|
DrainManager.startDrain(io, rate)
|
||||||
res.sendStatus(204)
|
res.sendStatus(204)
|
||||||
},
|
},
|
||||||
|
@ -41,11 +41,11 @@ module.exports = {
|
||||||
const client = io.sockets.sockets[client_id]
|
const client = io.sockets.sockets[client_id]
|
||||||
|
|
||||||
if (!client) {
|
if (!client) {
|
||||||
logger.info({ client_id }, 'api: client already disconnected')
|
logger.debug({ client_id }, 'api: client already disconnected')
|
||||||
res.sendStatus(404)
|
res.sendStatus(404)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.warn({ client_id }, 'api: requesting client disconnect')
|
logger.info({ client_id }, 'api: requesting client disconnect')
|
||||||
client.on('disconnect', () => res.sendStatus(204))
|
client.on('disconnect', () => res.sendStatus(204))
|
||||||
client.disconnect()
|
client.disconnect()
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,7 +12,7 @@ module.exports = {
|
||||||
: x.host
|
: x.host
|
||||||
? 'single'
|
? 'single'
|
||||||
: 'unknown'
|
: 'unknown'
|
||||||
logger.log({ redis: redisType }, 'creating redis client')
|
logger.debug({ redis: redisType }, 'creating redis client')
|
||||||
return redis.createClient(x)
|
return redis.createClient(x)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,7 +39,7 @@ module.exports = {
|
||||||
// explicitly, and then socket.io will just regard this as a client that
|
// explicitly, and then socket.io will just regard this as a client that
|
||||||
// has not joined any rooms and do a final disconnection.
|
// has not joined any rooms and do a final disconnection.
|
||||||
const roomsToLeave = this._roomsClientIsIn(client)
|
const roomsToLeave = this._roomsClientIsIn(client)
|
||||||
logger.log({ client: client.id, roomsToLeave }, 'client leaving project')
|
logger.debug({ client: client.id, roomsToLeave }, 'client leaving project')
|
||||||
for (const id of roomsToLeave) {
|
for (const id of roomsToLeave) {
|
||||||
const entity = IdMap.get(id)
|
const entity = IdMap.get(id)
|
||||||
this.leaveEntity(client, entity, id)
|
this.leaveEntity(client, entity, id)
|
||||||
|
@ -63,14 +63,14 @@ module.exports = {
|
||||||
client.join(id)
|
client.join(id)
|
||||||
// is this a new room? if so, subscribe
|
// is this a new room? if so, subscribe
|
||||||
if (beforeCount === 0) {
|
if (beforeCount === 0) {
|
||||||
logger.log({ entity, id }, 'room is now active')
|
logger.debug({ entity, id }, 'room is now active')
|
||||||
RoomEvents.once(`${entity}-subscribed-${id}`, function (err) {
|
RoomEvents.once(`${entity}-subscribed-${id}`, function (err) {
|
||||||
// only allow the client to join when all the relevant channels have subscribed
|
// only allow the client to join when all the relevant channels have subscribed
|
||||||
if (err) {
|
if (err) {
|
||||||
OError.tag(err, 'error joining', { entity, id })
|
OError.tag(err, 'error joining', { entity, id })
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ client: client.id, entity, id, beforeCount },
|
{ client: client.id, entity, id, beforeCount },
|
||||||
'client joined new room and subscribed to channel'
|
'client joined new room and subscribed to channel'
|
||||||
)
|
)
|
||||||
|
@ -81,7 +81,7 @@ module.exports = {
|
||||||
// keep track of the number of listeners
|
// keep track of the number of listeners
|
||||||
metrics.gauge('room-listeners', RoomEvents.eventNames().length)
|
metrics.gauge('room-listeners', RoomEvents.eventNames().length)
|
||||||
} else {
|
} else {
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ client: client.id, entity, id, beforeCount },
|
{ client: client.id, entity, id, beforeCount },
|
||||||
'client joined existing room'
|
'client joined existing room'
|
||||||
)
|
)
|
||||||
|
@ -96,7 +96,7 @@ module.exports = {
|
||||||
// This can now happen all the time, as we skip the join for clients that
|
// This can now happen all the time, as we skip the join for clients that
|
||||||
// disconnect before joinProject/joinDoc completed.
|
// disconnect before joinProject/joinDoc completed.
|
||||||
if (!this._clientAlreadyInRoom(client, id)) {
|
if (!this._clientAlreadyInRoom(client, id)) {
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ client: client.id, entity, id },
|
{ client: client.id, entity, id },
|
||||||
'ignoring request from client to leave room it is not in'
|
'ignoring request from client to leave room it is not in'
|
||||||
)
|
)
|
||||||
|
@ -104,7 +104,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
client.leave(id)
|
client.leave(id)
|
||||||
const afterCount = this._clientsInRoom(client, id)
|
const afterCount = this._clientsInRoom(client, id)
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ client: client.id, entity, id, afterCount },
|
{ client: client.id, entity, id, afterCount },
|
||||||
'client left room'
|
'client left room'
|
||||||
)
|
)
|
||||||
|
@ -114,7 +114,7 @@ module.exports = {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (afterCount === 0) {
|
if (afterCount === 0) {
|
||||||
logger.log({ entity, id }, 'room is now empty')
|
logger.debug({ entity, id }, 'room is now empty')
|
||||||
RoomEvents.emit(`${entity}-empty`, id)
|
RoomEvents.emit(`${entity}-empty`, id)
|
||||||
IdMap.delete(id)
|
IdMap.delete(id)
|
||||||
metrics.gauge('room-listeners', RoomEvents.eventNames().length)
|
metrics.gauge('room-listeners', RoomEvents.eventNames().length)
|
||||||
|
|
|
@ -7,6 +7,7 @@ const settings = require('@overleaf/settings')
|
||||||
const WebsocketController = require('./WebsocketController')
|
const WebsocketController = require('./WebsocketController')
|
||||||
const HttpController = require('./HttpController')
|
const HttpController = require('./HttpController')
|
||||||
const HttpApiController = require('./HttpApiController')
|
const HttpApiController = require('./HttpApiController')
|
||||||
|
const WebsocketAddressManager = require('./WebsocketAddressManager')
|
||||||
const bodyParser = require('body-parser')
|
const bodyParser = require('body-parser')
|
||||||
const base64id = require('base64id')
|
const base64id = require('base64id')
|
||||||
const { UnexpectedArgumentsError } = require('./Errors')
|
const { UnexpectedArgumentsError } = require('./Errors')
|
||||||
|
@ -41,7 +42,7 @@ module.exports = Router = {
|
||||||
attrs.err = error
|
attrs.err = error
|
||||||
attrs.method = method
|
attrs.method = method
|
||||||
if (Joi.isError(error)) {
|
if (Joi.isError(error)) {
|
||||||
logger.warn(attrs, 'validation error')
|
logger.info(attrs, 'validation error')
|
||||||
var message = 'invalid'
|
var message = 'invalid'
|
||||||
try {
|
try {
|
||||||
message = error.details[0].message
|
message = error.details[0].message
|
||||||
|
@ -59,8 +60,8 @@ module.exports = Router = {
|
||||||
const serializedError = { message: error.message, code: error.info.code }
|
const serializedError = { message: error.message, code: error.info.code }
|
||||||
callback(serializedError)
|
callback(serializedError)
|
||||||
} else if (error.message === 'unexpected arguments') {
|
} else if (error.message === 'unexpected arguments') {
|
||||||
// the payload might be very large, put it on level info
|
// the payload might be very large; put it on level debug
|
||||||
logger.log(attrs, 'unexpected arguments')
|
logger.debug(attrs, 'unexpected arguments')
|
||||||
metrics.inc('unexpected-arguments', 1, { status: method })
|
metrics.inc('unexpected-arguments', 1, { status: method })
|
||||||
const serializedError = { message: error.message }
|
const serializedError = { message: error.message }
|
||||||
callback(serializedError)
|
callback(serializedError)
|
||||||
|
@ -107,6 +108,15 @@ module.exports = Router = {
|
||||||
|
|
||||||
configure(app, io, session) {
|
configure(app, io, session) {
|
||||||
app.set('io', io)
|
app.set('io', io)
|
||||||
|
|
||||||
|
if (settings.behindProxy) {
|
||||||
|
app.set('trust proxy', settings.trustedProxyIps)
|
||||||
|
}
|
||||||
|
const websocketAddressManager = new WebsocketAddressManager(
|
||||||
|
settings.behindProxy,
|
||||||
|
settings.trustedProxyIps
|
||||||
|
)
|
||||||
|
|
||||||
app.get('/clients', HttpController.getConnectedClients)
|
app.get('/clients', HttpController.getConnectedClients)
|
||||||
app.get('/clients/:client_id', HttpController.getConnectedClient)
|
app.get('/clients/:client_id', HttpController.getConnectedClient)
|
||||||
|
|
||||||
|
@ -180,10 +190,14 @@ module.exports = Router = {
|
||||||
client.publicId = 'P.' + base64id.generateId()
|
client.publicId = 'P.' + base64id.generateId()
|
||||||
client.emit('connectionAccepted', null, client.publicId)
|
client.emit('connectionAccepted', null, client.publicId)
|
||||||
|
|
||||||
|
client.remoteIp = websocketAddressManager.getRemoteIp(client.handshake)
|
||||||
|
const headers = client.handshake && client.handshake.headers
|
||||||
|
client.userAgent = headers && headers['user-agent']
|
||||||
|
|
||||||
metrics.inc('socket-io.connection', 1, { status: client.transport })
|
metrics.inc('socket-io.connection', 1, { status: client.transport })
|
||||||
metrics.gauge('socket-io.clients', io.sockets.clients().length)
|
metrics.gauge('socket-io.clients', io.sockets.clients().length)
|
||||||
|
|
||||||
logger.log({ session, client_id: client.id }, 'client connected')
|
logger.debug({ session, client_id: client.id }, 'client connected')
|
||||||
|
|
||||||
let user
|
let user
|
||||||
if (session && session.passport && session.passport.user) {
|
if (session && session.passport && session.passport.user) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ const {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
joinProject(project_id, user, callback) {
|
joinProject(project_id, user, callback) {
|
||||||
const user_id = user._id
|
const user_id = user._id
|
||||||
logger.log({ project_id, user_id }, 'sending join project request to web')
|
logger.debug({ project_id, user_id }, 'sending join project request to web')
|
||||||
const url = `${settings.apis.web.url}/project/${project_id}/join`
|
const url = `${settings.apis.web.url}/project/${project_id}/join`
|
||||||
const headers = {}
|
const headers = {}
|
||||||
if (user.anonymousAccessToken) {
|
if (user.anonymousAccessToken) {
|
||||||
|
|
30
services/real-time/app/js/WebsocketAddressManager.js
Normal file
30
services/real-time/app/js/WebsocketAddressManager.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
const proxyaddr = require('proxy-addr')
|
||||||
|
|
||||||
|
module.exports = class WebsocketAddressManager {
|
||||||
|
constructor(behindProxy, trustedProxyIps) {
|
||||||
|
if (behindProxy) {
|
||||||
|
// parse trustedProxyIps comma-separated list the same way as express
|
||||||
|
this.trust = proxyaddr.compile(
|
||||||
|
trustedProxyIps ? trustedProxyIps.split(/ *, */) : []
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getRemoteIp(clientHandshake) {
|
||||||
|
if (this.trust) {
|
||||||
|
// create a dummy req object using the client handshake and
|
||||||
|
// connection.remoteAddress for the proxy-addr module to parse
|
||||||
|
const addressPort = clientHandshake.address
|
||||||
|
const req = Object.create(clientHandshake, {
|
||||||
|
connection: {
|
||||||
|
value: { remoteAddress: addressPort && addressPort.address },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
// return the address parsed from x-forwarded-for
|
||||||
|
return proxyaddr(req, this.trust)
|
||||||
|
} else {
|
||||||
|
// return the address from the client handshake itself
|
||||||
|
return clientHandshake.address && clientHandshake.address.address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,8 +32,14 @@ module.exports = WebsocketController = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const user_id = user._id
|
const user_id = user._id
|
||||||
logger.log(
|
logger.info(
|
||||||
{ user_id, project_id, client_id: client.id },
|
{
|
||||||
|
user_id,
|
||||||
|
project_id,
|
||||||
|
client_id: client.id,
|
||||||
|
remote_ip: client.remoteIp,
|
||||||
|
user_agent: client.userAgent,
|
||||||
|
},
|
||||||
'user joining project'
|
'user joining project'
|
||||||
)
|
)
|
||||||
metrics.inc('editor.join-project', 1, { status: client.transport })
|
metrics.inc('editor.join-project', 1, { status: client.transport })
|
||||||
|
@ -45,6 +51,10 @@ module.exports = WebsocketController = {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
if (client.disconnected) {
|
if (client.disconnected) {
|
||||||
|
logger.info(
|
||||||
|
{ user_id, project_id, client_id: client.id },
|
||||||
|
'client disconnected before joining project'
|
||||||
|
)
|
||||||
metrics.inc('editor.join-project.disconnected', 1, {
|
metrics.inc('editor.join-project.disconnected', 1, {
|
||||||
status: 'after-web-api-call',
|
status: 'after-web-api-call',
|
||||||
})
|
})
|
||||||
|
@ -72,8 +82,14 @@ module.exports = WebsocketController = {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ user_id, project_id, client_id: client.id },
|
{
|
||||||
|
user_id,
|
||||||
|
project_id,
|
||||||
|
client_id: client.id,
|
||||||
|
privilegeLevel,
|
||||||
|
isRestrictedUser,
|
||||||
|
},
|
||||||
'user joined project'
|
'user joined project'
|
||||||
)
|
)
|
||||||
callback(
|
callback(
|
||||||
|
@ -114,7 +130,7 @@ module.exports = WebsocketController = {
|
||||||
} // client did not join project
|
} // client did not join project
|
||||||
|
|
||||||
metrics.inc('editor.leave-project', 1, { status: client.transport })
|
metrics.inc('editor.leave-project', 1, { status: client.transport })
|
||||||
logger.log(
|
logger.info(
|
||||||
{ project_id, user_id, client_id: client.id },
|
{ project_id, user_id, client_id: client.id },
|
||||||
'client leaving project'
|
'client leaving project'
|
||||||
)
|
)
|
||||||
|
@ -171,7 +187,7 @@ module.exports = WebsocketController = {
|
||||||
if (!project_id) {
|
if (!project_id) {
|
||||||
return callback(new NotJoinedError())
|
return callback(new NotJoinedError())
|
||||||
}
|
}
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ user_id, project_id, doc_id, fromVersion, client_id: client.id },
|
{ user_id, project_id, doc_id, fromVersion, client_id: client.id },
|
||||||
'client joining doc'
|
'client joining doc'
|
||||||
)
|
)
|
||||||
|
@ -266,7 +282,7 @@ module.exports = WebsocketController = {
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthorizationManager.addAccessToDoc(client, doc_id, () => {})
|
AuthorizationManager.addAccessToDoc(client, doc_id, () => {})
|
||||||
logger.log(
|
logger.debug(
|
||||||
{
|
{
|
||||||
user_id,
|
user_id,
|
||||||
project_id,
|
project_id,
|
||||||
|
@ -324,7 +340,7 @@ module.exports = WebsocketController = {
|
||||||
client.joinLeaveEpoch++
|
client.joinLeaveEpoch++
|
||||||
metrics.inc('editor.leave-doc', 1, { status: client.transport })
|
metrics.inc('editor.leave-doc', 1, { status: client.transport })
|
||||||
const { project_id, user_id } = client.ol_context
|
const { project_id, user_id } = client.ol_context
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ user_id, project_id, doc_id, client_id: client.id },
|
{ user_id, project_id, doc_id, client_id: client.id },
|
||||||
'client leaving doc'
|
'client leaving doc'
|
||||||
)
|
)
|
||||||
|
@ -346,7 +362,7 @@ module.exports = WebsocketController = {
|
||||||
})
|
})
|
||||||
const { project_id, first_name, last_name, email, user_id } =
|
const { project_id, first_name, last_name, email, user_id } =
|
||||||
client.ol_context
|
client.ol_context
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ user_id, project_id, client_id: client.id, cursorData },
|
{ user_id, project_id, client_id: client.id, cursorData },
|
||||||
'updating client position'
|
'updating client position'
|
||||||
)
|
)
|
||||||
|
@ -356,7 +372,7 @@ module.exports = WebsocketController = {
|
||||||
cursorData.doc_id,
|
cursorData.doc_id,
|
||||||
function (error) {
|
function (error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.info(
|
logger.debug(
|
||||||
{ err: error, client_id: client.id, project_id, user_id },
|
{ err: error, client_id: client.id, project_id, user_id },
|
||||||
"silently ignoring unauthorized updateClientPosition. Client likely hasn't called joinProject yet."
|
"silently ignoring unauthorized updateClientPosition. Client likely hasn't called joinProject yet."
|
||||||
)
|
)
|
||||||
|
@ -420,7 +436,7 @@ module.exports = WebsocketController = {
|
||||||
if (!project_id) {
|
if (!project_id) {
|
||||||
return callback(new NotJoinedError())
|
return callback(new NotJoinedError())
|
||||||
}
|
}
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ user_id, project_id, client_id: client.id },
|
{ user_id, project_id, client_id: client.id },
|
||||||
'getting connected users'
|
'getting connected users'
|
||||||
)
|
)
|
||||||
|
@ -437,7 +453,7 @@ module.exports = WebsocketController = {
|
||||||
if (error) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ user_id, project_id, client_id: client.id },
|
{ user_id, project_id, client_id: client.id },
|
||||||
'got connected users'
|
'got connected users'
|
||||||
)
|
)
|
||||||
|
@ -477,7 +493,7 @@ module.exports = WebsocketController = {
|
||||||
update.meta.user_id = user_id
|
update.meta.user_id = user_id
|
||||||
metrics.inc('editor.doc-update', 0.3, { status: client.transport })
|
metrics.inc('editor.doc-update', 0.3, { status: client.transport })
|
||||||
|
|
||||||
logger.log(
|
logger.debug(
|
||||||
{
|
{
|
||||||
user_id,
|
user_id,
|
||||||
doc_id,
|
doc_id,
|
||||||
|
|
|
@ -40,7 +40,7 @@ module.exports = WebsocketLoadBalancer = {
|
||||||
message,
|
message,
|
||||||
payload,
|
payload,
|
||||||
})
|
})
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ room_id, message, payload, length: data.length },
|
{ room_id, message, payload, length: data.length },
|
||||||
'emitting to room'
|
'emitting to room'
|
||||||
)
|
)
|
||||||
|
@ -55,7 +55,7 @@ module.exports = WebsocketLoadBalancer = {
|
||||||
},
|
},
|
||||||
|
|
||||||
listenForEditorEvents(io) {
|
listenForEditorEvents(io) {
|
||||||
logger.log(
|
logger.debug(
|
||||||
{ rclients: this.rclientSubList.length },
|
{ rclients: this.rclientSubList.length },
|
||||||
'listening for editor events'
|
'listening for editor events'
|
||||||
)
|
)
|
||||||
|
@ -102,7 +102,7 @@ module.exports = WebsocketLoadBalancer = {
|
||||||
message.room_id
|
message.room_id
|
||||||
) {
|
) {
|
||||||
const clientList = io.sockets.clients(message.room_id)
|
const clientList = io.sockets.clients(message.room_id)
|
||||||
logger.log(
|
logger.debug(
|
||||||
{
|
{
|
||||||
channel,
|
channel,
|
||||||
message: message.message,
|
message: message.message,
|
||||||
|
@ -142,7 +142,7 @@ module.exports = WebsocketLoadBalancer = {
|
||||||
if (clientList.length === 0) {
|
if (clientList.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.log(
|
logger.debug(
|
||||||
{
|
{
|
||||||
channel,
|
channel,
|
||||||
message: message.message,
|
message: message.message,
|
||||||
|
|
|
@ -162,6 +162,9 @@ const settings = {
|
||||||
catchUncaughtErrors: true,
|
catchUncaughtErrors: true,
|
||||||
shutdownOnUncaughtError: true,
|
shutdownOnUncaughtError: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
behindProxy: process.env.BEHIND_PROXY === 'true',
|
||||||
|
trustedProxyIps: process.env.TRUSTED_PROXY_IPS,
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log settings.redis
|
// console.log settings.redis
|
||||||
|
|
14
services/real-time/package-lock.json
generated
14
services/real-time/package-lock.json
generated
|
@ -2484,9 +2484,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"forwarded": {
|
"forwarded": {
|
||||||
"version": "0.1.2",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
"integrity": "sha512-Ua9xNhH0b8pwE3yRbFfXJvfdWF0UHNCdeyb2sbi9Ul/M+r3PTdrz7Cv4SCfZRMjmzEM9PhraqfZFbGTIg3OMyA=="
|
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
|
||||||
},
|
},
|
||||||
"fresh": {
|
"fresh": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
|
@ -4424,11 +4424,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"proxy-addr": {
|
"proxy-addr": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"forwarded": "~0.1.2",
|
"forwarded": "0.2.0",
|
||||||
"ipaddr.js": "1.9.1"
|
"ipaddr.js": "1.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-session": "^1.17.1",
|
"express-session": "^1.17.1",
|
||||||
"logger-sharelatex": "^2.2.0",
|
"logger-sharelatex": "^2.2.0",
|
||||||
|
"proxy-addr": "^2.0.7",
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
"socket.io": "https://github.com/overleaf/socket.io/archive/0.9.19-overleaf-5.tar.gz",
|
"socket.io": "https://github.com/overleaf/socket.io/archive/0.9.19-overleaf-5.tar.gz",
|
||||||
"socket.io-client": "https://github.com/overleaf/socket.io-client/archive/0.9.17-overleaf-3.tar.gz",
|
"socket.io-client": "https://github.com/overleaf/socket.io-client/archive/0.9.17-overleaf-3.tar.gz",
|
||||||
|
|
|
@ -30,14 +30,14 @@ describe('leaveDoc', function () {
|
||||||
this.ops = ['mock', 'doc', 'ops']
|
this.ops = ['mock', 'doc', 'ops']
|
||||||
sinon.spy(logger, 'error')
|
sinon.spy(logger, 'error')
|
||||||
sinon.spy(logger, 'warn')
|
sinon.spy(logger, 'warn')
|
||||||
sinon.spy(logger, 'log')
|
sinon.spy(logger, 'debug')
|
||||||
return (this.other_doc_id = FixturesManager.getRandomId())
|
return (this.other_doc_id = FixturesManager.getRandomId())
|
||||||
})
|
})
|
||||||
|
|
||||||
after(function () {
|
after(function () {
|
||||||
logger.error.restore() // remove the spy
|
logger.error.restore() // remove the spy
|
||||||
logger.warn.restore()
|
logger.warn.restore()
|
||||||
return logger.log.restore()
|
return logger.debug.restore()
|
||||||
})
|
})
|
||||||
|
|
||||||
return describe('when joined to a doc', function () {
|
return describe('when joined to a doc', function () {
|
||||||
|
@ -177,7 +177,7 @@ describe('leaveDoc', function () {
|
||||||
|
|
||||||
return it('should trigger a low level message only', function () {
|
return it('should trigger a low level message only', function () {
|
||||||
return sinon.assert.calledWith(
|
return sinon.assert.calledWith(
|
||||||
logger.log,
|
logger.debug,
|
||||||
sinon.match.any,
|
sinon.match.any,
|
||||||
'ignoring request from client to leave room it is not in'
|
'ignoring request from client to leave room it is not in'
|
||||||
)
|
)
|
||||||
|
|
|
@ -42,7 +42,7 @@ module.exports = {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
this.running = true
|
this.running = true
|
||||||
logger.log('clsi running in dev mode')
|
logger.info('clsi running in dev mode')
|
||||||
|
|
||||||
return (() => {
|
return (() => {
|
||||||
const result = []
|
const result = []
|
||||||
|
|
|
@ -116,7 +116,7 @@ describe('DrainManager', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
return it('should log out that it reached the end', function () {
|
return it('should log out that it reached the end', function () {
|
||||||
return this.logger.log
|
return this.logger.info
|
||||||
.calledWith('All clients have been told to reconnectGracefully')
|
.calledWith('All clients have been told to reconnectGracefully')
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue