Skip to content

Commit 5228100

Browse files
authored
Standardize Logs Collection for Consistent Querying (#2226)
* chore: fix log type into lower case * chore: revert changes for make the logs working * chore: add logs migration route * chore: add migration model function * chore: add tests for migration api * chore: update route name * chore: update route name
1 parent 46bc908 commit 5228100

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

controllers/logs.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,19 @@ const fetchAllLogs = async (req, res) => {
7272
}
7373
};
7474

75+
const updateLogs = async (req, res) => {
76+
try {
77+
const response = await logsQuery.updateLogs();
78+
return res.json({
79+
response,
80+
});
81+
} catch (error) {
82+
return res.boom.serverUnavailable(SOMETHING_WENT_WRONG);
83+
}
84+
};
85+
7586
module.exports = {
7687
fetchLogs,
7788
fetchAllLogs,
89+
updateLogs,
7890
};

models/logs.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,72 @@ const fetchAllLogs = async (query) => {
250250
}
251251
};
252252

253+
const updateLogs = async () => {
254+
const batchSize = 500;
255+
let lastDoc = null;
256+
let isCompleted = false;
257+
258+
const summary = {
259+
totalLogsProcessed: 0,
260+
totalLogsUpdated: 0,
261+
totalOperationsFailed: 0,
262+
failedLogDetails: [],
263+
};
264+
265+
try {
266+
while (!isCompleted) {
267+
let query = logsModel.orderBy("timestamp").limit(batchSize);
268+
if (lastDoc) {
269+
query = query.startAfter(lastDoc);
270+
}
271+
const snapshot = await query.get();
272+
273+
if (snapshot.empty) {
274+
isCompleted = true;
275+
continue;
276+
}
277+
278+
const batch = firestore.batch();
279+
snapshot.forEach((doc) => {
280+
const data = doc.data();
281+
if (data.meta && data.meta.createdBy) {
282+
const updatedMeta = {
283+
...data.meta,
284+
userId: data.meta.createdBy,
285+
};
286+
delete updatedMeta.createdBy;
287+
288+
batch.update(doc.ref, { meta: updatedMeta });
289+
summary.totalLogsUpdated++;
290+
}
291+
summary.totalLogsProcessed++;
292+
});
293+
294+
try {
295+
await batch.commit();
296+
} catch (err) {
297+
logger.error("Batch update failed for logs collection:", err);
298+
summary.totalOperationsFailed += snapshot.docs.length;
299+
summary.failedLogDetails.push(...snapshot.docs.map((doc) => doc.id));
300+
}
301+
302+
lastDoc = snapshot.docs[snapshot.docs.length - 1];
303+
isCompleted = snapshot.docs.length < batchSize;
304+
}
305+
306+
logger.info("Migration completed:", summary);
307+
return summary;
308+
} catch (error) {
309+
logger.error("Error during logs migration:", error);
310+
throw error;
311+
}
312+
};
313+
253314
module.exports = {
254315
addLog,
255316
fetchLogs,
256317
fetchCacheLogs,
257318
fetchLastAddedCacheLog,
258319
fetchAllLogs,
320+
updateLogs,
259321
};

routes/logs.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ const { SUPERUSER } = require("../constants/roles");
77

88
router.get("/:type", authenticate, authorizeRoles([SUPERUSER]), logs.fetchLogs);
99
router.get("/", authenticate, authorizeRoles([SUPERUSER]), logs.fetchAllLogs);
10+
router.post("/migrate", authenticate, authorizeRoles([SUPERUSER]), logs.updateLogs);
1011

1112
module.exports = router;

test/integration/logs.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,36 @@ describe("/logs", function () {
203203
});
204204
});
205205

206+
describe("Update logs", function () {
207+
it("should run the migration and update logs successfully", async function () {
208+
const res = await chai.request(app).post("/logs/migrate").set("cookie", `${cookieName}=${superUserToken}`).send();
209+
210+
expect(res).to.have.status(200);
211+
expect(res.body).to.be.an("object");
212+
expect(res.body.response).to.have.property("totalLogsProcessed").that.is.a("number");
213+
expect(res.body.response).to.have.property("totalLogsUpdated").that.is.a("number");
214+
expect(res.body.response).to.have.property("totalOperationsFailed").that.is.a("number");
215+
expect(res.body.response).to.have.property("failedLogDetails").that.is.an("array");
216+
217+
expect(res.body.response.totalLogsProcessed).to.be.at.least(0);
218+
expect(res.body.response.totalLogsUpdated).to.be.lessThanOrEqual(res.body.response.totalLogsProcessed);
219+
220+
expect(res.body.response).to.have.all.keys(
221+
"totalLogsProcessed",
222+
"totalLogsUpdated",
223+
"totalOperationsFailed",
224+
"failedLogDetails"
225+
);
226+
});
227+
228+
it("should return error if unauthorized user tries to run migration", async function () {
229+
const res = await chai.request(app).post("/logs/migrate").set("cookie", `${cookieName}=invalidToken`).send();
230+
231+
expect(res).to.have.status(401);
232+
expect(res.body).to.have.property("error").that.is.a("string");
233+
});
234+
});
235+
206236
describe("Add logs when user doc is update", function () {
207237
let jwt;
208238
let userId;

0 commit comments

Comments
 (0)