diff options
author | Jason Rassi <rassi@10gen.com> | 2014-10-03 19:36:28 -0400 |
---|---|---|
committer | Jason Rassi <rassi@10gen.com> | 2014-11-25 17:49:07 -0500 |
commit | cf8bb50e5a8a22205e344e0536646f1ca6bc81e4 (patch) | |
tree | 540b71000862c09ed608f7c2074c635f9c8cd4bc /src/mongo/db | |
parent | 8f0d423946be1873d0af5c6db488d2bee9629899 (diff) | |
download | mongo-cf8bb50e5a8a22205e344e0536646f1ca6bc81e4.tar.gz |
SERVER-6218 Profiler should only abbreviate query/updateobj
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/client.cpp | 80 | ||||
-rw-r--r-- | src/mongo/db/curop.h | 15 | ||||
-rw-r--r-- | src/mongo/db/introspect.cpp | 28 |
3 files changed, 45 insertions, 78 deletions
diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp index 947d545f8d6..21e25cd2266 100644 --- a/src/mongo/db/client.cpp +++ b/src/mongo/db/client.cpp @@ -495,54 +495,58 @@ namespace mongo { return s.str(); } -#define OPDEBUG_APPEND_NUMBER(x) if( x != -1 ) b.appendNumber( #x , (x) ) -#define OPDEBUG_APPEND_BOOL(x) if( x ) b.appendBool( #x , (x) ) - bool OpDebug::append(const CurOp& curop, BSONObjBuilder& b, size_t maxSize) const { - b.append( "op" , iscommand ? "command" : opToString( op ) ); - b.append( "ns" , ns.toString() ); - - int queryUpdateObjSize = 0; - if (!query.isEmpty()) { - queryUpdateObjSize += query.objsize(); - } - else if (!iscommand && curop.haveQuery()) { - queryUpdateObjSize += curop.query()["query"].size(); - } - - if (!updateobj.isEmpty()) { - queryUpdateObjSize += updateobj.objsize(); - } - - if (static_cast<size_t>(queryUpdateObjSize) > maxSize) { - if (!query.isEmpty()) { - // Use 60 since BSONObj::toString can truncate strings into 150 chars - // and we want to have enough room for both query and updateobj when - // the entire document is going to be serialized into a string - const string abbreviated(query.toString(false, false), 0, 60); - b.append(iscommand ? "command" : "query", abbreviated + "..."); + namespace { + /** + * Appends {name: obj} to the provided builder. If obj is greater than maxSize, appends a + * string summary of obj instead of the object itself. + */ + void appendAsObjOrString(const StringData& name, + const BSONObj& obj, + size_t maxSize, + BSONObjBuilder* builder) { + if (static_cast<size_t>(obj.objsize()) <= maxSize) { + builder->append(name, obj); } - else if (!iscommand && curop.haveQuery()) { - const string abbreviated(curop.query()["query"].toString(false, false), 0, 60); - b.append("query", abbreviated + "..."); + else { + // Generate an abbreviated serialization for the object, by passing false as the + // "full" argument to obj.toString(). + const bool isArray = false; + const bool full = false; + std::string objToString = obj.toString(isArray, full); + if (objToString.size() <= maxSize) { + builder->append(name, objToString); + } + else { + // objToString is still too long, so we append to the builder a truncated form + // of objToString concatenated with "...". Instead of creating a new string + // temporary, mutate objToString to do this (we know that we can mutate + // characters in objToString up to and including objToString[maxSize]). + objToString[maxSize - 3] = '.'; + objToString[maxSize - 2] = '.'; + objToString[maxSize - 1] = '.'; + builder->append(name, StringData(objToString).substr(0, maxSize)); + } } + } + } - if (!updateobj.isEmpty()) { - const string abbreviated(updateobj.toString(false, false), 0, 60); - b.append("updateobj", abbreviated + "..."); - } +#define OPDEBUG_APPEND_NUMBER(x) if( x != -1 ) b.appendNumber( #x , (x) ) +#define OPDEBUG_APPEND_BOOL(x) if( x ) b.appendBool( #x , (x) ) + void OpDebug::append(const CurOp& curop, BSONObjBuilder& b) const { + const size_t maxElementSize = 50 * 1024; - return false; - } + b.append( "op" , iscommand ? "command" : opToString( op ) ); + b.append( "ns" , ns.toString() ); if (!query.isEmpty()) { - b.append(iscommand ? "command" : "query", query); + appendAsObjOrString(iscommand ? "command" : "query", query, maxElementSize, &b); } else if (!iscommand && curop.haveQuery()) { - curop.appendQuery(b, "query"); + appendAsObjOrString("query", curop.query(), maxElementSize, &b); } if (!updateobj.isEmpty()) { - b.append("updateobj", updateobj); + appendAsObjOrString("updateobj", updateobj, maxElementSize, &b); } const bool moved = (nmoved >= 1); @@ -578,8 +582,6 @@ namespace mongo { b.append( "millis" , executionTime ); execStats.append(b, "execStats"); - - return true; } void saveGLEStats(const BSONObj& result, const std::string& conn) { diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h index 4e42f85cc93..7b781e7051a 100644 --- a/src/mongo/db/curop.h +++ b/src/mongo/db/curop.h @@ -129,19 +129,10 @@ namespace mongo { std::string report( const CurOp& curop ) const; /** - * Appends stored data and information from curop to the builder. - * - * @param curop information about the current operation which will be - * use to append data to the builder. - * @param builder the BSON builder to use for appending data. Data can - * still be appended even if this method returns false. - * @param maxSize the maximum allowed combined size for the query object - * and update object - * - * @return false if the sum of the sizes for the query object and update - * object exceeded maxSize + * Appends information about the current operation to "builder". "curop" must be a + * reference to the CurOp that owns this OpDebug. */ - bool append(const CurOp& curop, BSONObjBuilder& builder, size_t maxSize) const; + void append(const CurOp& curop, BSONObjBuilder& builder) const; // ------------------- diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp index 9218ad25774..6dd6c323a99 100644 --- a/src/mongo/db/introspect.cpp +++ b/src/mongo/db/introspect.cpp @@ -45,10 +45,6 @@ #include "mongo/util/goodies.h" #include "mongo/util/log.h" -namespace { - const size_t MAX_PROFILE_DOC_SIZE_BYTES = 100*1024; -} - namespace mongo { namespace { @@ -94,8 +90,7 @@ namespace { // build object BSONObjBuilder b(profileBufBuilder); - const bool isQueryObjTooBig = !currentOp.debug().append(currentOp, b, - MAX_PROFILE_DOC_SIZE_BYTES); + currentOp.debug().append(currentOp, b); b.appendDate("ts", jsTime()); b.append("client", c.clientAddress()); @@ -105,27 +100,6 @@ namespace { BSONObj p = b.done(); - if (static_cast<size_t>(p.objsize()) > MAX_PROFILE_DOC_SIZE_BYTES || isQueryObjTooBig) { - string small = p.toString(/*isArray*/false, /*full*/false); - - warning() << "can't add full line to system.profile: " << small << endl; - - // rebuild with limited info - BSONObjBuilder b(profileBufBuilder); - b.appendDate("ts", jsTime()); - b.append("client", c.clientAddress() ); - _appendUserInfo(currentOp, b, authSession); - - b.append("err", "profile line too large (max is 100KB)"); - - // should be much smaller but if not don't break anything - if (small.size() < MAX_PROFILE_DOC_SIZE_BYTES){ - b.append("abbreviated", small); - } - - p = b.done(); - } - WriteUnitOfWork wunit(txn); // write: not replicated |