tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

mongodbのdb.serverStatus()、db.stats()、db.collection.stats()、db.collection.totalSize()を出力するのをスクリプトにしておくテスト

はじめに

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