From d7514feafea74f00b3c98b60d07b7e71fdbb20cf Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Mon, 23 Feb 2026 11:18:27 +0100 Subject: [PATCH] [docstore] add metrics for writes to docs collection (#31741) * [docstore] add metrics for writes to docs collection Co-authored-by: Brian Gough * [docstore] fix import * [docstore] use counter metric * [docstore] add metric on lines delta Co-authored-by: Brian Gough --------- Co-authored-by: Brian Gough GitOrigin-RevId: 4662c5862315c800cb7b4d57bef60e08fbe7ba59 --- services/docstore/app/js/DocManager.js | 14 ++++++++++++++ services/docstore/app/js/MongoManager.js | 11 ++++++++++- services/docstore/app/js/mongodb.js | 3 ++- .../docstore/test/unit/js/MongoManager.test.js | 5 ++++- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index e1ca8b0579..56a3a7c90d 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -6,6 +6,7 @@ import DocArchive from './DocArchiveManager.js' import RangeManager from './RangeManager.js' import Settings from '@overleaf/settings' import { setTimeout } from 'node:timers/promises' +import Metrics from '@overleaf/metrics' /** * @import { Document } from 'mongodb' @@ -255,6 +256,19 @@ const DocManager = { }) } updateLines = !_.isEqual(doc.lines, lines) + if (doc.lines.length === lines.length) { + Metrics.inc('mongo_docs_update_delta', 1, { + status: 'same-line-length', + }) + } else if (doc.lines.length > lines.length) { + Metrics.inc('mongo_docs_update_delta', 1, { + status: 'smaller-line-length', + }) + } else if (doc.lines.length < lines.length) { + Metrics.inc('mongo_docs_update_delta', 1, { + status: 'larger-line-length', + }) + } updateVersion = doc.version !== version updateRanges = RangeManager.shouldUpdateRanges(doc.ranges, ranges) } diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 1725747b3c..5e4110dace 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -1,8 +1,9 @@ import mongodb from './mongodb.js' import Settings from '@overleaf/settings' import Errors from './Errors.js' +import Metrics from '@overleaf/metrics' -const { db, ObjectId } = mongodb +const { db, ObjectId, BSON } = mongodb const ARCHIVING_LOCK_DURATION_MS = Settings.archivingLockDurationMs @@ -98,6 +99,8 @@ async function upsertIntoDocCollection(projectId, docId, previousRev, updates) { if (updates.lines || updates.ranges) { update.$inc = { rev: 1 } } + const payloadSize = BSON.calculateObjectSize(update) + Metrics.count('mongo_docs_write', payloadSize, 1, { method: 'update' }) const result = await db.docs.updateOne( { _id: new ObjectId(docId), @@ -110,6 +113,8 @@ async function upsertIntoDocCollection(projectId, docId, previousRev, updates) { throw new Errors.DocRevValueError() } } else { + const payloadSize = BSON.calculateObjectSize(updates) + Metrics.count('mongo_docs_write', payloadSize, 1, { method: 'insert' }) try { await db.docs.insertOne({ _id: new ObjectId(docId), @@ -129,6 +134,8 @@ async function upsertIntoDocCollection(projectId, docId, previousRev, updates) { } async function patchDoc(projectId, docId, meta) { + const payloadSize = BSON.calculateObjectSize(meta) + Metrics.count('mongo_docs_write', payloadSize, 1, { method: 'patch' }) await db.docs.updateOne( { _id: new ObjectId(docId), @@ -195,6 +202,8 @@ async function restoreArchivedDoc(projectId, docId, archivedDoc) { inS3: true, }, } + const payloadSize = BSON.calculateObjectSize(update) + Metrics.count('mongo_docs_write', payloadSize, 1, { method: 'restore' }) const result = await db.docs.updateOne(query, update) if (result.matchedCount === 0) { diff --git a/services/docstore/app/js/mongodb.js b/services/docstore/app/js/mongodb.js index 6ddb183588..9bd0388f81 100644 --- a/services/docstore/app/js/mongodb.js +++ b/services/docstore/app/js/mongodb.js @@ -6,7 +6,7 @@ import Settings from '@overleaf/settings' import MongoUtils from '@overleaf/mongo-utils' import mongodb from 'mongodb-legacy' -const { MongoClient, ObjectId } = mongodb +const { MongoClient, ObjectId, BSON } = mongodb const mongoClient = new MongoClient(Settings.mongo.url, Settings.mongo.options) const mongoDb = mongoClient.db() @@ -25,5 +25,6 @@ export default { db, mongoClient, ObjectId, + BSON, cleanupTestDatabase, } diff --git a/services/docstore/test/unit/js/MongoManager.test.js b/services/docstore/test/unit/js/MongoManager.test.js index a6d2359127..df6bb8a8d3 100644 --- a/services/docstore/test/unit/js/MongoManager.test.js +++ b/services/docstore/test/unit/js/MongoManager.test.js @@ -1,9 +1,11 @@ import sinon from 'sinon' -import { ObjectId } from 'mongodb-legacy' +import mongodb from 'mongodb-legacy' import path from 'node:path' import { assert, beforeEach, describe, expect, it, vi } from 'vitest' import Errors from '../../../app/js/Errors.js' +const { ObjectId, BSON } = mongodb + const modulePath = path.join( import.meta.dirname, '../../../app/js/MongoManager' @@ -22,6 +24,7 @@ describe('MongoManager', () => { default: { db: ctx.db, ObjectId, + BSON, }, }))