summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/core/opcounters_write_cmd.js81
-rw-r--r--jstests/gle/opcounters_legacy.js43
-rw-r--r--src/mongo/db/commands.cpp9
-rw-r--r--src/mongo/db/commands.h14
-rw-r--r--src/mongo/db/dbcommands.cpp7
-rw-r--r--src/mongo/s/commands_public.cpp1
-rw-r--r--src/mongo/s/s_only.cpp6
7 files changed, 116 insertions, 45 deletions
diff --git a/jstests/core/opcounters_write_cmd.js b/jstests/core/opcounters_write_cmd.js
index 88a5c65b4c3..b8fb30e8738 100644
--- a/jstests/core/opcounters_write_cmd.js
+++ b/jstests/core/opcounters_write_cmd.js
@@ -2,7 +2,7 @@
// Legacy write mode test also available at jstests/gle.
var mongo = new Mongo(db.getMongo().host);
-mongo.forceWriteMode("commands");
+
var newdb = mongo.getDB(db.toString());
var t = newdb.opcounters;
@@ -10,8 +10,6 @@ var isMongos = ("isdbgrid" == newdb.runCommand("ismaster").msg);
var opCounters;
var res;
-assert(t.getDB().getMongo().useWriteCommands(), "test is not running with write commands")
-
//
// Count ops attempted in write commands in mongod and mongos
//
@@ -40,25 +38,28 @@ res = t.insert([{_id:1},{_id:2}])
assert.writeOK(res);
assert.eq(opCounters.insert + 2, newdb.serverStatus().opcounters.insert);
-// Single insert, with error.
-opCounters = newdb.serverStatus().opcounters;
-res = t.insert({_id:0})
-assert.writeError(res);
-assert.eq(opCounters.insert + 1, newdb.serverStatus().opcounters.insert);
-
-// Bulk insert, with error, ordered.
-opCounters = newdb.serverStatus().opcounters;
-res = t.insert([{_id:3},{_id:3},{_id:4}])
-assert.writeError(res);
-assert.eq(opCounters.insert + 2, newdb.serverStatus().opcounters.insert);
-
-// Bulk insert, with error, unordered.
-var continueOnErrorFlag = 1;
-opCounters = newdb.serverStatus().opcounters;
-res = t.insert([{_id:5},{_id:5},{_id:6}], continueOnErrorFlag)
-assert.writeError(res);
-assert.eq(opCounters.insert + 3, newdb.serverStatus().opcounters.insert);
+// Test is not run when in compatibility mode as errors are not counted
+if (t.getMongo().writeMode() != "compatibility"){
+ // Single insert, with error.
+ opCounters = newdb.serverStatus().opcounters;
+ res = t.insert({_id:0})
+ assert.writeError(res);
+ assert.eq(opCounters.insert + 1, newdb.serverStatus().opcounters.insert);
+
+ // Bulk insert, with error, ordered.
+ opCounters = newdb.serverStatus().opcounters;
+ res = t.insert([{_id:3},{_id:3},{_id:4}])
+ assert.writeError(res);
+ assert.eq(opCounters.insert + 2, newdb.serverStatus().opcounters.insert);
+
+ // Bulk insert, with error, unordered.
+ var continueOnErrorFlag = 1;
+ opCounters = newdb.serverStatus().opcounters;
+ res = t.insert([{_id:5},{_id:5},{_id:6}], continueOnErrorFlag)
+ assert.writeError(res);
+ assert.eq(opCounters.insert + 3, newdb.serverStatus().opcounters.insert);
+}
//
// 2. Update.
//
@@ -146,22 +147,38 @@ t.drop();
t.insert({_id:0})
// Command, recognized, no error.
-opCounters = newdb.serverStatus().opcounters;
+serverStatus = newdb.serverStatus();
+opCounters = serverStatus.opcounters
+metricsObj = serverStatus.metrics.commands
assert.eq(opCounters.command + 1, newdb.serverStatus().opcounters.command); // "serverStatus" counted
+// Count this and the last run of "serverStatus"
+assert.eq(metricsObj.serverStatus.total + 2,
+ newdb.serverStatus().metrics.commands.serverStatus.total,
+ "total ServerStatus command counter did not increment"); // "serverStatus" counted
+assert.eq(metricsObj.serverStatus.failed,
+ newdb.serverStatus().metrics.commands.serverStatus.failed,
+ "failed ServerStatus command counter incremented!"); // "serverStatus" counted
// Command, recognized, with error.
-opCounters = newdb.serverStatus().opcounters;
-res = t.runCommand("count", {query:{$invalidOp:1}});
+countVal = { "total" : 0, "failed" : 0 };
+if (metricsObj.count != null) {
+ countVal = metricsObj.count
+}
+res = t.runCommand("count", {query:{$invalidOp:1}}); // "count command" counted
assert.eq(0, res.ok);
-assert.eq(opCounters.command + 2,
+assert.eq(opCounters.command + 5,
newdb.serverStatus().opcounters.command); // "serverStatus", "count" counted
+assert.eq(countVal.total +1,
+ newdb.serverStatus().metrics.commands.count.total,
+ "total count command counter did not incremented"); // "serverStatus", "count" counted
+assert.eq(countVal.failed + 1,
+ newdb.serverStatus().metrics.commands.count.failed,
+ "failed count command counter did not increment"); // "serverStatus", "count" counted
+
// Command, unrecognized.
-opCounters = newdb.serverStatus().opcounters;
-res = t.runCommand("command that doesn't exist");
+res = t.runCommand("invalid"); // "invalid" command only counted on MongoS
assert.eq(0, res.ok);
-//assert.eq(opCounters.command + 1, newdb.serverStatus().opcounters.command); // "serverStatus" counted
-// TODO Replace below with above when SERVER-9038 is resolved (mongos counts unrecognized commands)
-assert.eq(opCounters.command + (isMongos ? 2 : 1), newdb.serverStatus().opcounters.command);
-
-// Command, recognized, counting suppressed (TODO implement when SERVER-9038 is resolved).
+assert.eq(opCounters.command + (isMongos ? 9 : 8), newdb.serverStatus().opcounters.command); // "serverStatus" counted
+assert.eq(null, newdb.serverStatus().metrics.commands.invalid);
+assert.eq(metricsObj['<UNKNOWN>'] + 1, newdb.serverStatus().metrics.commands['<UNKNOWN>']);
diff --git a/jstests/gle/opcounters_legacy.js b/jstests/gle/opcounters_legacy.js
index 52e18c48643..a3435719eac 100644
--- a/jstests/gle/opcounters_legacy.js
+++ b/jstests/gle/opcounters_legacy.js
@@ -150,25 +150,44 @@ t.drop();
t.insert({_id:0})
// Command, recognized, no error.
-opCounters = db.serverStatus().opcounters;
+serverStatus = db.serverStatus();
+opCounters = serverStatus.opcounters
+metricsObj = serverStatus.metrics.commands
assert.eq(opCounters.command + 1, db.serverStatus().opcounters.command); // "serverStatus" counted
+// Count this and the last run of "serverStatus"
+assert.eq( metricsObj.serverStatus.total + 2,
+ db.serverStatus().metrics.commands.serverStatus.total,
+ "total ServerStatus command counter did not increment" )
+assert.eq( metricsObj.serverStatus.failed,
+ db.serverStatus().metrics.commands.serverStatus.failed,
+ "failed ServerStatus command counter incremented!" )
// Command, recognized, with error.
-opCounters = db.serverStatus().opcounters;
+serverStatus = db.serverStatus();
+opCounters = serverStatus.opcounters
+metricsObj = serverStatus.metrics.commands
+var countVal = { "total" : 0, "failed" : 0 };
+if (metricsObj.count != null){
+ countVal = metricsObj.count
+}
res = t.runCommand("count", {query:{$invalidOp:1}});
assert.eq(0, res.ok);
assert.eq(opCounters.command + 2,
db.serverStatus().opcounters.command); // "serverStatus", "count" counted
+assert.eq( countVal.total +1,
+ db.serverStatus().metrics.commands.count.total,
+ "total count command counter did not incremented" )
+assert.eq( countVal.failed + 1,
+ db.serverStatus().metrics.commands.count.failed,
+ "failed count command counter did not increment" )
+
// Command, unrecognized.
-opCounters = db.serverStatus().opcounters;
-res = t.runCommand("command that doesn't exist");
+serverStatus = db.serverStatus();
+opCounters = serverStatus.opcounters
+metricsObj = serverStatus.metrics.commands
+res = t.runCommand("invalid");
assert.eq(0, res.ok);
-//assert.eq(opCounters.command + 1, db.serverStatus().opcounters.command); // "serverStatus" counted
-// TODO Replace below with above when SERVER-9038 is resolved (mongos counts unrecognized commands)
-assert.eq(opCounters.command + (isMongos ? 2 : 1), db.serverStatus().opcounters.command);
-
-// Command, recognized, counting suppressed (TODO implement when SERVER-9038 is resolved).
-
-// Restore 'db' var
-db = lastDB;
+assert.eq(opCounters.command + 1, db.serverStatus().opcounters.command); // "serverStatus" counted
+assert.eq(null, db.serverStatus().metrics.commands.invalid);
+assert.eq(metricsObj['<UNKNOWN>'] +1, db.serverStatus().metrics.commands['<UNKNOWN>']); \ No newline at end of file
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index 2ef8db5085a..72508f89de5 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -62,6 +62,10 @@ namespace mongo {
int Command::testCommandsEnabled = 0;
+ Counter64 Command::unknownCommands;
+ static ServerStatusMetricField<Counter64> displayUnknownCommands( "commands.<UNKNOWN>",
+ &Command::unknownCommands );
+
namespace {
ExportedServerParameter<int> testCommandsParameter(ServerParameterSet::getGlobal(),
"enableTestCommands",
@@ -176,7 +180,10 @@ namespace mongo {
ss << "</tr>\n";
}
- Command::Command(StringData _name, bool web, StringData oldName) : name(_name.toString()) {
+ Command::Command(StringData _name, bool web, StringData oldName) :
+ name(_name.toString()),
+ _commandsExecutedMetric("commands."+ _name.toString()+".total", &_commandsExecuted),
+ _commandsFailedMetric("commands."+ _name.toString()+".failed", &_commandsFailed) {
// register ourself.
if ( _commands == 0 )
_commands = new map<string,Command*>;
diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h
index ac56a808d01..73952e547ad 100644
--- a/src/mongo/db/commands.h
+++ b/src/mongo/db/commands.h
@@ -32,10 +32,12 @@
#include <string>
#include <vector>
+#include "mongo/base/counter.h"
#include "mongo/base/status.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/auth/resource_pattern.h"
#include "mongo/db/client_basic.h"
+#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/query/explain.h"
@@ -217,6 +219,14 @@ namespace mutablebson {
static std::map<std::string,Command*> * _commandsByBestName;
static std::map<std::string,Command*> * _webCommands;
+ // Counters for how many times this command has been executed and failed
+ Counter64 _commandsExecuted;
+ Counter64 _commandsFailed;
+
+ // Pointers to hold the metrics tree references
+ ServerStatusMetricField<Counter64> _commandsExecutedMetric;
+ ServerStatusMetricField<Counter64> _commandsFailedMetric;
+
public:
// Stops all index builds required to run this command and returns index builds killed.
virtual std::vector<BSONObj> stopIndexBuilds(OperationContext* opCtx,
@@ -225,6 +235,10 @@ namespace mutablebson {
static const std::map<std::string,Command*>* commandsByBestName() { return _commandsByBestName; }
static const std::map<std::string,Command*>* webCommands() { return _webCommands; }
+
+ // Counter for unknown commands
+ static Counter64 unknownCommands;
+
/** @return if command was found */
static void runAgainstRegistered(const char *ns,
BSONObj& jsobj,
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp
index a2cce53daba..2cd9cc893f5 100644
--- a/src/mongo/db/dbcommands.cpp
+++ b/src/mongo/db/dbcommands.cpp
@@ -1378,8 +1378,14 @@ namespace mongo {
txn->getCurOp()->ensureStarted();
+ c->_commandsExecuted.increment();
+
retval = _execCommand(txn, c, dbname, cmdObj, queryOptions, errmsg, result, fromRepl);
+ if ( !retval ){
+ c->_commandsFailed.increment();
+ }
+
appendCommandStatus(result, retval, errmsg);
// For commands from mongos, append some info to help getLastError(w) work.
@@ -1458,6 +1464,7 @@ namespace mongo {
str::stream() << "no such cmd: " << e.fieldName());
anObjBuilder.append("code", ErrorCodes::CommandNotFound);
anObjBuilder.append("bad cmd" , _cmdobj );
+ Command::unknownCommands.increment();
}
BSONObj x = anObjBuilder.done();
diff --git a/src/mongo/s/commands_public.cpp b/src/mongo/s/commands_public.cpp
index bb45370eb4c..2b8aadab8d2 100644
--- a/src/mongo/s/commands_public.cpp
+++ b/src/mongo/s/commands_public.cpp
@@ -2588,6 +2588,7 @@ namespace mongo {
false,
str::stream() << "no such cmd: " << commandName);
anObjBuilder.append("code", ErrorCodes::CommandNotFound);
+ Command::unknownCommands.increment();
return;
}
ClientInfo *client = ClientInfo::get();
diff --git a/src/mongo/s/s_only.cpp b/src/mongo/s/s_only.cpp
index 3db331d2dbf..9c17e2d2d8c 100644
--- a/src/mongo/s/s_only.cpp
+++ b/src/mongo/s/s_only.cpp
@@ -137,6 +137,8 @@ namespace mongo {
return;
}
+ c->_commandsExecuted.increment();
+
std::string errmsg;
bool ok;
try {
@@ -155,6 +157,10 @@ namespace mongo {
result.append( "code" , code );
}
+ if ( !ok ) {
+ c->_commandsFailed.increment();
+ }
+
appendCommandStatus(result, ok, errmsg);
}
}