A while ago, I was working on a project where I needed to implement an audit log for some important data.
The requirements were clear:
- Log every change to the data
- Capture the before and after values for each field
- Record who made the change
At first, I thought, “I’ll just manually log every data change.”
It seemed simple enough—just add some logging code wherever data was updated. I already implement something like this in different project.
But as the project grew, I realized this approach was getting messy and repetitive. Wouldn’t it be better if I could just plug in a solution and have audit logging work for any model, anywhere in the project? That’s when I decided to build a Mongoose plugin for audit logging.
Why a plugin?
- It’s easy to add audit logging to any model—just plug it into the schema.
- If I (or anyone else) need audit logs for other data in the future, it’s just a one-line change.
- Maintenance and future improvements become much simpler.
So, I started building the plugin to fit my project’s needs:
- Track changes at the field level (including arrays and nested fields)
- Log before/after values
- Record who made the change
- Support soft delete, batch operations, and contextual logging
Once the plugin was working and the project was running smoothly, I thought:
“Why not add more features and open source it? Maybe other developers need this too!”
That’s how mongoose-log-history was born—a plugin you can drop into any Mongoose project to get robust, flexible audit logging out of the box.
What Does mongoose-log-history Do?
- Automatically logs every create, update, delete, and soft delete on your Mongoose models
- Field-level change tracking (including arrays and nested fields)
-
Batch operation support (
insertMany
,updateMany
,deleteMany
) - Contextual logging: add user info, approval steps, or any custom context
- Pruning utility: clean up old logs by date or count
- Compression support: save space for large document snapshots
- Discriminator support: works with Mongoose inheritance
- Manual logging API: for advanced or custom scenarios
How Easy Is It to Use?
Just add the plugin to your schema:
const mongoose = require('mongoose');
const { changeLoggingPlugin } = require('mongoose-log-history');
const orderSchema = new mongoose.Schema({
status: String,
tags: [String],
items: [{ sku: String, qty: Number }],
created_by: { id: mongoose.Schema.Types.ObjectId, name: String, role: String },
});
orderSchema.plugin(changeLoggingPlugin, {
modelName: 'Order',
trackedFields: [
{ value: 'status' },
{ value: 'tags', arrayType: 'simple' },
{
value: 'items',
arrayType: 'custom-key',
arrayKey: 'sku',
trackedFields: [{ value: 'qty' }],
},
],
contextFields: ['created_by.name'],
singleCollection: true,
saveWholeDoc: true,
compressDocs: true,
});
const Order = mongoose.model('Order', orderSchema);
Now, every change to your Order
documents is logged automatically!
What Does the Log Look Like?
Each log entry includes:
- The model and document ID
- The type of change (
create
,update
,delete
) - An array of field-level changes (with before/after values)
- User/context info (if configured)
- Full document snapshots (if enabled)
- Timestamps
Example log:
{
"model": "Order",
"model_id": "60f7c2b8e1b1c8a1b8e1b1c8",
"change_type": "update",
"logs": [
{
"field_name": "status",
"from_value": "pending",
"to_value": "approved",
"change_type": "edit"
}
],
"created_by": { "id": "...", "name": "Alice", "role": "admin" },
"context": { "doc": { "created_by.name": "Alice" } },
"created_at": "2024-06-14T12:34:56.789Z"
}
Advanced Features
-
Soft delete support: log when a field (e.g.,
status: 'deleted'
) marks a doc as deleted. -
Manual logging API: use
getTrackedChanges
,buildLogEntry
, etc. for custom flows. -
Pruning: clean up old logs with
pruneLogHistory
. - Compression: store large document snapshots efficiently.
Get Started
- npm: https://www.npmjs.com/package/mongoose-log-history
- GitHub: https://github.com/granitebps/mongoose-log-history
- Docs: See the README for full usage, options, and examples.
Feedback and Contributions
I’d love to hear your feedback, suggestions, or feature requests!
Feel free to open an issue, submit a PR, or just ⭐️ the repo if you find it useful.
Happy coding! 🚀
Top comments (0)