summaryrefslogtreecommitdiff
path: root/src/mongo/db/introspect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/introspect.cpp')
-rw-r--r--src/mongo/db/introspect.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
new file mode 100644
index 00000000000..5680fa1481f
--- /dev/null
+++ b/src/mongo/db/introspect.cpp
@@ -0,0 +1,108 @@
+// introspect.cpp
+
+/**
+* Copyright (C) 2008 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "pch.h"
+#include "introspect.h"
+#include "../bson/util/builder.h"
+#include "../util/goodies.h"
+#include "pdfile.h"
+#include "jsobj.h"
+#include "pdfile.h"
+#include "curop.h"
+
+namespace mongo {
+
+ BufBuilder profileBufBuilder; // reused, instead of allocated every time - avoids a malloc/free cycle
+
+ void profile( const Client& c , CurOp& currentOp ) {
+ verify( Lock::somethingWriteLocked() );
+
+ Database *db = c.database();
+ DEV verify( db );
+ const char *ns = db->profileName.c_str();
+
+ // build object
+ profileBufBuilder.reset();
+ BSONObjBuilder b(profileBufBuilder);
+ b.appendDate("ts", jsTime());
+ currentOp.debug().append( currentOp , b );
+
+ b.append("client", c.clientAddress() );
+
+ if ( c.getAuthenticationInfo() )
+ b.append( "user" , c.getAuthenticationInfo()->getUser( nsToDatabase( ns ) ) );
+
+ BSONObj p = b.done();
+
+ if (p.objsize() > 100*1024){
+ string small = p.toString(/*isArray*/false, /*full*/false);
+
+ warning() << "can't add full line to system.profile: " << small;
+
+ // rebuild with limited info
+ BSONObjBuilder b(profileBufBuilder);
+ b.appendDate("ts", jsTime());
+ b.append("client", c.clientAddress() );
+ if ( c.getAuthenticationInfo() )
+ b.append( "user" , c.getAuthenticationInfo()->getUser( nsToDatabase( ns ) ) );
+
+ b.append("err", "profile line too large (max is 100KB)");
+ if (small.size() < 100*1024){ // should be much smaller but if not don't break anything
+ b.append("abbreviated", small);
+ }
+
+ p = b.done();
+ }
+
+ // write: not replicated
+ // get or create the profiling collection
+ NamespaceDetails *details = getOrCreateProfileCollection(db);
+ if (details) {
+ int len = p.objsize();
+ Record *r = theDataFileMgr.fast_oplog_insert(details, ns, len);
+ memcpy(getDur().writingPtr(r->data(), len), p.objdata(), len);
+ }
+ }
+
+ NamespaceDetails* getOrCreateProfileCollection(Database *db, bool force) {
+ fassert(16372, db);
+ const char* profileName = db->profileName.c_str();
+ NamespaceDetails* details = db->namespaceIndex.details(profileName);
+ if (!details && (cmdLine.defaultProfile || force)) {
+ // system.profile namespace doesn't exist; create it
+ log() << "creating profile collection: " << profileName << endl;
+ string errmsg;
+ if (!userCreateNS(db->profileName.c_str(),
+ BSON("capped" << true << "size" << 1024 * 1024), errmsg , false)) {
+ log() << "could not create ns " << db->profileName << ": " << errmsg << endl;
+ return NULL;
+ }
+ details = db->namespaceIndex.details(profileName);
+ }
+ if (!details) {
+ // failed to get or create profile collection
+ static time_t last = time(0) - 10; // warn the first time
+ if( time(0) > last+10 ) {
+ log() << "profile: warning ns " << profileName << " does not exist" << endl;
+ last = time(0);
+ }
+ }
+ return details;
+ }
+
+} // namespace mongo