Skip to content

Instantly share code, notes, and snippets.

@balthazar
Last active January 28, 2023 19:10
Show Gist options
  • Save balthazar/e2047bdc23cd077ed7c91310f44552f0 to your computer and use it in GitHub Desktop.
Save balthazar/e2047bdc23cd077ed7c91310f44552f0 to your computer and use it in GitHub Desktop.
// Utilitary script to get stats on all collections and indexes of a mongo cluster
//
// Usage:
// cat dbstats.js | mongosh MONGO_URI | sed -n 's/^>>:*//p'
// curl -L https://gist.githubusercontent.com/balthazar/e2047bdc23cd077ed7c91310f44552f0/raw | mongosh MONGO_URI | sed -n 's/^>>:*//p'
const mgo = db.getMongo()
const byteUnits = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
const RED = '\033[0;31m'
const BLUE = '\033[0;34m'
const GREEN = '\033[0;32m'
const YELLOW = '\033[0;33m'
const MAGENTA = '\033[0;35m'
const CYAN = '\033[0;36m'
const NC = '\033[0m'
function p(txt) {
txt.split('\n').map(t => print(`>>${t}`))
}
function humanSize(bytes) {
let i = -1
while (bytes > 1024) {
bytes = bytes / 1024
++i
}
return `${Math.max(bytes, 0.1).toLocaleString(undefined, { maximumFractionDigits: 2 })} ${
byteUnits[i] || 'B'
}`
}
function getStats(name) {
const db = mgo.getDB(name)
const stats = db
.getCollectionNames()
.map(n => db.getCollection(n).stats())
.sort((a, b) => a.size - b.size)
let total = 0
print(stats[0])
for (const stat of stats) {
const colName = stat.ns.replace(`${name}.`, '')
if (colName.startsWith('system.')) continue
p(`${GREEN}${colName} ${humanSize(stat.totalSize)}${NC}`)
p(`${MAGENTA}Data ${humanSize(stat.storageSize)}${NC}`)
p(`${BLUE}Indexes${NC} ${humanSize(stat.totalIndexSize)}`)
total += Number(stat.storageSize)
for (const index in stat.indexSizes) {
const iSize = stat.indexSizes[index]
p(`${BLUE}${index}${NC} ${humanSize(iSize)}`)
total += Number(iSize)
}
p(`${YELLOW}${stat.wiredTiger.uri.replace('statistics:table:', '')}${NC}`)
p('')
}
const { fsUsedSize } = db.stats()
const diffFs = fsUsedSize - total
const diffTxt = `${YELLOW}FS ${humanSize(fsUsedSize)}${NC} (${humanSize(diffFs)} diff)`
p(`${CYAN}${name}${NC}`)
p(`${RED}Total ${humanSize(total)}${NC}`)
if (diffFs) p(diffTxt)
}
;(() => {
const dbs = mgo.getDBNames().filter(n => !n.match(/^(config|local|admin)$/))
for (const name of dbs) {
p(name !== dbs[0] ? '\n\n=======\n' : '\n')
getStats(name)
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment