はじめに
mongodbで何か試してるときに、stats系やtotalSizeみたいとき多いですよね。
「いちいちmongoシェルに入るのめんどうだなー」
とか
「テキストに貼り付けるときjsonじゃないほうがいいなー」
とか思ってたのでstats系やtotalSizeを出力するやつを作りました
たいしたアレではないですが、
スクリプトをwatchコマンドやcron化したり、リダイレクトしてファイルに書きだせば一定間隔ごとも出せますね。
ってことで、スクリプト
説明(というか言い訳)
・serverStatus、dbStats、colStats、totalSizeで出力するかどうか切り替えられます
・8とか言うマジックナンバーが入ってますがタブのスペース数系の数値です(適当ですw)
・階層構造になってるやつは1階層分だけ表示できます。それ以上はまぁいいや、、と
・一番下のコメントは自分用ですw
スクリプト
mongo_stats_print.js
/* * print stats object */ var ObjPrint = function(obj){ this.tabStr = "\t"; if( typeof obj == 'object' ) this.prepare(obj); this.delimFormat = "________________# @str@ @dt@"; }; ObjPrint.prototype.noRecursive = function(bool){ this.norcrsv = bool; return this; }; ObjPrint.prototype.recursive = function(bool){ //if( typeof bool != "boolean" ) bool = false; this.rcrsv = bool; return this; }; ObjPrint.prototype.prepare = function(obj){ this.obj = obj; var maxKeyLen = 0; for(var key in obj) if(key.length > maxKeyLen) maxKeyLen = key.length; this.maxTabSize = parseInt(maxKeyLen / 8, 10) + 1; return this; }; ObjPrint.prototype.tabs = function(str){ var len = str.length; var co = parseInt(len / 8, 10); var tabCnt = this.maxTabSize - co; return Array(tabCnt + 1).join(this.tabStr); }; ObjPrint.prototype.datetime = function(str){ var d = new Date(); return this.zeroPadAndJoin([d.getFullYear(), (d.getMonth() + 1), d.getDate()], '-') + ' ' + this.zeroPadAndJoin([d.getHours(), d.getMinutes(), d.getSeconds()], ':') }; ObjPrint.prototype.zeroPadAndJoin = function(arr, delim){ if(!delim) delim = ' '; return arr.map(function(v){if((''+v).match(/\d{4}/)) return v; return ("0"+v).slice(-2);}).join(delim) }; ObjPrint.prototype.exec = function(finLine){ for(var key in this.obj){ // toStringとか出ないように if( !this.obj.hasOwnProperty(key) ) continue; // 前につける\t計算するのめんどいから1段階しか再帰しない if( !this.norcrsv && !this.rcrsv && typeof this.obj[key] == 'object'){ var op = new ObjPrint(); print(( this.rcrsv ? "\t" : "" ) + key + this.tabs(key)); op.recursive(true).prepare(this.obj[key]).exec(); continue; } print(( this.rcrsv ? "\t" : "" ) + key + this.tabs(key) + JSON.stringify(this.obj[key])); } if( finLine && (typeof finLine == "boolean") ) print("\n"); }; ObjPrint.prototype.delim = function(str){ print(this.delimFormat.replace('@str@', str).replace('@dt@', this.datetime())); return this; }; /* * main */ // create ObjPrint var statsProperty = { "dbStats" : true, "totalSize" : true, "colStats" : true, "serverStatus" : true, }; var op = new ObjPrint(); op.noRecursive(true); // serverStatus if( statsProperty.serverStatus ){ op.noRecursive(false); var ss = db.serverStatus(); op.delim('serverStatus').prepare(ss).exec(true); } // db stats if( statsProperty.dbStats ){ var dbStats = db.stats(); op.delim('dbStats').prepare(dbStats).exec(true); } // collections stats if( statsProperty.colStats ){ var cols = db.getCollectionNames(); var totalSize = {}; for(var idx in cols){ op.delim('colStats:'+cols[idx]).prepare(db[cols[idx]].stats()).exec(true); } } // totalSize; if( statsProperty.totalSize ){ var cols = db.getCollectionNames(); var totalSize = {}; for(var idx in cols){ totalSize[cols[idx]] = db[cols[idx]].totalSize(); } op.delim('totalSize').prepare(totalSize).exec(true); } /* print("a" + "\t" + "11"); print("bb" + "\t" + "11"); print("ccc" + "\t" + "11"); print("dddd" + "\t" + "11"); print("eeeee" + "\t" + "11"); print("ffffff" + "\t" + "11"); print("ggggggg" + "\t" + "11"); print("hhhhhhhh" + "\t" + "11"); print("iiiiiiiii" + "\t" + "11"); print("jjjjjjjjjj" + "\t" + "11"); print("kkkkkkkkkkk" + "\t" + "11"); print("llllllllllll" + "\t" + "11"); print("mmmmmmmmmmmmm" + "\t" + "11"); print("nnnnnnnnnnnnnn" + "\t" + "11"); print("ooooooooooooooo" + "\t" + "11"); print("pppppppppppppppp" + "\t" + "11"); print("qqqqqqqqqqqqqqqqq" + "\t" + "11"); */
使い方
認証とか入れてる場合はuなりpなりをつけます
db指定(今回はsample)はお忘れなく
# mongo sample mongo_stats_print.js
出力結果
# mongo sample mongo_stats_print.js MongoDB shell version: 2.4.8 connecting to: sample ________________# serverStatus 2014-03-26 20:20:16 host "hoge.co.jp" version "2.4.8" process "mongod" pid 31249 uptime 614088 uptimeMillis floatApprox 614088411 uptimeEstimate 608371 localTime asserts regular 0 warning 0 msg 0 user 0 rollovers 0 backgroundFlushing flushes 10234 total_ms 122906 average_ms 12.009575923392612 last_ms 0 last_finished "2014-03-26T11:19:29.273Z" connections current 1 available 19999 totalCreated {"floatApprox":438} cursors totalOpen 0 clientCursors_size 0 timedOut 4 dur commits 30 journaledMB 0 writeToDataFilesMB 0 compression 0 commitsInWriteLock 0 earlyCommits 0 timeMs {"dt":3068,"prepLogBuffer":0,"writeToJournal":0,"writeToDataFiles":0,"remapPrivateView":0} extra_info note "fields vary by platform" heap_usage_bytes 65868600 page_faults 47145 globalLock totalTime {"floatApprox":614088411000} lockTime {"floatApprox":19577337} currentQueue {"total":0,"readers":0,"writers":0} activeClients {"total":0,"readers":0,"writers":0} indexCounters accesses 418145884 hits 418145884 misses 0 resets 0 missRatio 0 locks . {"timeLockedMicros":{"R":{"floatApprox":23016229},"W":{"floatApprox":19577337}},"timeAcquiringMicros":{"R":{"floatApprox":1241239212},"W":{"floatApprox":140640786}}} admin {"timeLockedMicros":{},"timeAcquiringMicros":{}} local {"timeLockedMicros":{"r":{"floatApprox":1445540},"w":{"floatApprox":0}},"timeAcquiringMicros":{"r":{"floatApprox":752618},"w":{"floatApprox":0}}} sample {"timeLockedMicros":{"r":{"floatApprox":326040},"w":{"floatApprox":1384905089}},"timeAcquiringMicros":{"r":{"floatApprox":30236718},"w":{"floatApprox":6052307}}} test {"timeLockedMicros":{"r":{"floatApprox":350835},"w":{"floatApprox":15978330}},"timeAcquiringMicros":{"r":{"floatApprox":25508},"w":{"floatApprox":295868}}} asobi {"timeLockedMicros":{"r":{"floatApprox":915910},"w":{"floatApprox":1178918}},"timeAcquiringMicros":{"r":{"floatApprox":31829},"w":{"floatApprox":8159}}} network bytesIn 15807106614 bytesOut 1009271 numRequests 3090 opcounters insert 109843921 query 29334 update 16 delete 1 getmore 0 command 1513 opcountersRepl insert 0 query 0 update 0 delete 0 getmore 0 command 0 recordStats accessesNotInMemory 877 pageFaultExceptionsThrown 0 local {"accessesNotInMemory":0,"pageFaultExceptionsThrown":0} sample {"accessesNotInMemory":0,"pageFaultExceptionsThrown":0} test {"accessesNotInMemory":0,"pageFaultExceptionsThrown":0} writeBacksQueued false mem bits 64 resident 140 virtual 812 supported true mapped 288 mappedWithJournal 576 metrics document {"deleted":{"floatApprox":357490},"inserted":{"floatApprox":109843921},"returned":{"floatApprox":1458},"updated":{"floatApprox":6}} getLastError {"wtime":{"num":28,"totalMillis":0},"wtimeouts":{"floatApprox":0}} operation {"fastmod":{"floatApprox":0},"idhack":{"floatApprox":4},"scanAndOrder":{"floatApprox":0}} queryExecutor {"scanned":{"floatApprox":26043}} record {"moves":{"floatApprox":2}} repl {"apply":{"batches":{"num":0,"totalMillis":0},"ops":{"floatApprox":0}},"buffer":{"count":{"floatApprox":0},"maxSizeBytes":268435456,"sizeBytes":{"floatApprox":0}},"network":{"bytes":{"floatApprox":0},"getmores":{"num":0,"totalMillis":0},"ops":{"floatApprox":0},"readersCreated":{"floatApprox":0}},"oplog":{"insert":{"num":0,"totalMillis":0},"insertBytes":{"floatApprox":0}},"preload":{"docs":{"num":0,"totalMillis":0},"indexes":{"num":0,"totalMillis":0}}} ttl {"deletedDocuments":{"floatApprox":0},"passes":{"floatApprox":10234}} ok 1 ________________# dbStats 2014-03-26 20:20:16 db "sample" collections 3 objects 281171 avgObjSize 143.99876231901584 dataSize 40488276 storageSize 56709120 numExtents 10 indexes 1 indexSize 9140768 fileSize 469762048 nsSizeMB 16 dataFileVersion major 4 minor 5 ok 1 ________________# colStats:actlog 2014-03-26 20:20:16 ns "sample.actlog" count 281167 size 40488096 avgObjSize 144.00017071704715 storageSize 56700928 numExtents 8 nindexes 1 lastExtentSize 22937600 paddingFactor 1 systemFlags 1 userFlags 0 totalIndexSize 9140768 indexSizes _id_ 9140768 ok 1 ________________# colStats:system.indexes 2014-03-26 20:20:16 ns "sample.system.indexes" count 1 size 72 avgObjSize 72 storageSize 4096 numExtents 1 nindexes 0 lastExtentSize 4096 paddingFactor 1 systemFlags 0 userFlags 0 totalIndexSize 0 indexSizes ok 1 ________________# totalSize 2014-03-26 20:20:16 actlog 65841696 system.indexes 4096
watchで10秒ごとに結果をファイルに書き出してみる
db.stats()だけをcronで10秒ごとにファイルに書き出してみます
script変更
mongo_stats_print.jsの一部変更
// create ObjPrint var statsProperty = { "serverStatus" : true, "dbStats" : true, "colStats" : true, "totalSize" : true }; ↓いらないのはfalseに // create ObjPrint var statsProperty = { "serverStatus" : false, "dbStats" : true, "colStats" : false, "totalSize" : false };
watchで実行
# watch -n 10 "mongo sample mongo_stats_print.js | sed '1,2d' >> mongo_stats_print.txt"
結果
# less mongo_stats_print.txt ________________# dbStats 2014-03-26 20:37:06 db "sample" collections 3 objects 281171 avgObjSize 143.99876231901584 dataSize 40488276 storageSize 56709120 numExtents 10 indexes 1 indexSize 9140768 fileSize 469762048 nsSizeMB 16 dataFileVersion {"major":4,"minor":5} ok 1 ________________# dbStats 2014-03-26 20:46:16 db "sample" collections 3 objects 281171 avgObjSize 143.99876231901584 dataSize 40488276 storageSize 56709120 numExtents 10 indexes 1 indexSize 9140768 fileSize 469762048 nsSizeMB 16 dataFileVersion {"major":4,"minor":5} ok 1 ________________# dbStats 2014-03-26 20:46:26 db "sample" collections 3 objects 281171 avgObjSize 143.99876231901584 dataSize 40488276 storageSize 56709120 numExtents 10 indexes 1 indexSize 9140768 fileSize 469762048 nsSizeMB 16 dataFileVersion {"major":4,"minor":5} ok 1