feat(usage-use-cases.js): Added functions for persisting usage data to database

This commit is contained in:
Chris Troutner
2025-06-04 12:26:03 -07:00
parent 28e012feb6
commit fcb4acb11d
3 changed files with 76 additions and 0 deletions
+2
View File
@@ -4,11 +4,13 @@
// Load Mongoose models.
import Users from './models/users.js'
import Usage from './models/usage.js'
class LocalDB {
constructor () {
// Encapsulate dependencies
this.Users = Users
this.Usage = Usage
}
}
+15
View File
@@ -0,0 +1,15 @@
/*
Usage data model
*/
// Global npm libraries
import mongoose from 'mongoose'
const Usage = new mongoose.Schema({
ip: { type: String },
url: { type: String },
method: { type: String },
timestamp: { type: Date }
})
export default mongoose.model('usage', Usage)
+59
View File
@@ -3,6 +3,10 @@
for tracking the usage of REST API and JSON RPC calls. This library is used
by admins to keep an eye on how many API calls were made in a 24-hour and
1-hour time period.
Usage stats are held in memory. But they are periodically backed up to the
Mongo database. On startup, the usage stats are loaded from the database.
This allows the usage stats to be persisted across restarts.
*/
// This global variable is used to share data between the REST middleware and
@@ -24,6 +28,9 @@ class UsageUseCases {
this.getRestSummary = this.getRestSummary.bind(this)
this.getTopIps = this.getTopIps.bind(this)
this.getTopEndpoints = this.getTopEndpoints.bind(this)
this.clearUsage = this.clearUsage.bind(this)
this.saveUsage = this.saveUsage.bind(this)
this.loadUsage = this.loadUsage.bind(this)
// State
}
@@ -108,6 +115,58 @@ class UsageUseCases {
throw err
}
}
// Clear the usage database data
async clearUsage () {
try {
await this.adapters.Usage.deleteMany({})
// Debugging: verify the database is empty
// Delete this code after debugging
const usage = await this.adapters.Usage.find({})
console.log('usage: ', usage)
} catch (err) {
console.error('Error in usage-use-cases.js/clearUsage()')
throw err
}
}
// Save the usage data to the database
async saveUsage (inObj = {}) {
try {
for (let i = 0; i < restCalls.length; i++) {
const thisRestCall = restCalls[i]
// Debugging: delete this code after debugging
if (i === 5) {
console.log('saveUsage() thisRestCall: ', thisRestCall)
}
const usage = new this.UsageModel(thisRestCall)
await usage.save()
}
} catch (err) {
console.error('Error in usage-use-cases.js/saveUsage()')
throw err
}
}
// Load usage data from the database
async loadUsage () {
try {
const usage = await this.adapters.Usage.find({})
// console.log('usage: ', usage)
if (usage[5]) {
console.log('loadUsage() usage[5]: ', usage[5])
}
restCalls = usage
} catch (err) {
console.error('Error in usage-use-cases.js/loadUsage()')
throw err
}
}
}
// This Koa middleware is called any time there is a REST API. It logs the