summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBernard Gorman <bernard.gorman@gmail.com>2017-03-22 08:21:15 +0000
committerBernard Gorman <bernard.gorman@gmail.com>2017-03-22 22:30:31 +0000
commit51d8b9c2f5eafc457f889d9786ebd68e4398ba64 (patch)
tree5f03f06ee26558803de1f8c7f40a6a6a7e5c09f7 /src
parent7b4770c1dbbc2a264a10f4fcfc87025ce832b680 (diff)
downloadmongo-51d8b9c2f5eafc457f889d9786ebd68e4398ba64.tar.gz
SERVER-27439 Large queries can omit comment in currentOp
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/curop.cpp67
1 files changed, 54 insertions, 13 deletions
diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp
index 2af0907170d..f4c028879c3 100644
--- a/src/mongo/db/curop.cpp
+++ b/src/mongo/db/curop.cpp
@@ -296,23 +296,30 @@ Command::ReadWriteType CurOp::getReadWriteType() const {
}
namespace {
+
+/**
+ * Used by callers of appendAsObjOrString to indicate whether a comment parameter may be present and
+ * should be retained upon truncation.
+ */
+enum class TruncationMode { kNoComment, kIncludeComment };
+
/**
- * Appends {name: obj} to the provided builder. If obj is greater than maxSize, appends a
- * string summary of obj instead of the object itself.
+ * Appends {<name>: obj} to the provided builder. If obj is greater than maxSize, appends a string
+ * summary of obj as { <name>: { $truncated: "obj" } }. If a comment parameter is present, add it to
+ * the truncation object.
*/
void appendAsObjOrString(StringData name,
const BSONObj& obj,
size_t maxSize,
- BSONObjBuilder* builder) {
+ BSONObjBuilder* builder,
+ TruncationMode truncateBehavior = TruncationMode::kNoComment) {
if (static_cast<size_t>(obj.objsize()) <= maxSize) {
builder->append(name, obj);
} else {
// Generate an abbreviated serialization for the object, by passing false as the
// "full" argument to obj.toString().
std::string objToString = obj.toString();
- if (objToString.size() <= maxSize) {
- builder->append(name, objToString);
- } else {
+ if (objToString.size() > maxSize) {
// 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
@@ -320,8 +327,22 @@ void appendAsObjOrString(StringData name,
objToString[maxSize - 3] = '.';
objToString[maxSize - 2] = '.';
objToString[maxSize - 1] = '.';
- builder->append(name, StringData(objToString).substr(0, maxSize));
}
+
+ StringData truncation = StringData(objToString).substr(0, maxSize);
+
+ // Append the truncated representation of the object to the builder. If this is an operation
+ // which supports a comment parameter and one is present, write it to the object alongside
+ // the truncated op. This object will appear as {$truncated: "{find: \"collection\", filter:
+ // {x: 1, ...", comment: "comment text" }
+ BSONObjBuilder truncatedBuilder(builder->subobjStart(name));
+ truncatedBuilder.append("$truncated", truncation);
+
+ if (truncateBehavior == TruncationMode::kIncludeComment && obj["comment"]) {
+ truncatedBuilder.append(obj["comment"]);
+ }
+
+ truncatedBuilder.doneFast();
}
}
} // namespace
@@ -354,9 +375,15 @@ void CurOp::reportState(BSONObjBuilder* builder) {
appendAsObjOrString("query",
upconvertQueryEntry(_query, NamespaceString(_ns), ntoreturn, ntoskip),
maxQuerySize,
- builder);
+ builder,
+ TruncationMode::kIncludeComment);
} else {
- appendAsObjOrString("query", _query, maxQuerySize, builder);
+ appendAsObjOrString(
+ "query",
+ _query,
+ maxQuerySize,
+ builder,
+ (_isCommand ? TruncationMode::kIncludeComment : TruncationMode::kNoComment));
}
if (!_collation.isEmpty()) {
@@ -364,7 +391,11 @@ void CurOp::reportState(BSONObjBuilder* builder) {
}
if (!_originatingCommand.isEmpty()) {
- appendAsObjOrString("originatingCommand", _originatingCommand, maxQuerySize, builder);
+ appendAsObjOrString("originatingCommand",
+ _originatingCommand,
+ maxQuerySize,
+ builder,
+ TruncationMode::kIncludeComment);
}
if (!_planSummary.empty()) {
@@ -557,15 +588,25 @@ void OpDebug::append(const CurOp& curop,
appendAsObjOrString("query",
upconvertQueryEntry(curop.query(), nss, ntoreturn, ntoskip),
maxElementSize,
- &b);
+ &b,
+ TruncationMode::kIncludeComment);
} else if (curop.haveQuery()) {
const char* fieldName = (logicalOp == LogicalOp::opCommand) ? "command" : "query";
- appendAsObjOrString(fieldName, curop.query(), maxElementSize, &b);
+ appendAsObjOrString(
+ fieldName,
+ curop.query(),
+ maxElementSize,
+ &b,
+ (iscommand ? TruncationMode::kIncludeComment : TruncationMode::kNoComment));
}
auto originatingCommand = curop.originatingCommand();
if (!originatingCommand.isEmpty()) {
- appendAsObjOrString("originatingCommand", originatingCommand, maxElementSize, &b);
+ appendAsObjOrString("originatingCommand",
+ originatingCommand,
+ maxElementSize,
+ &b,
+ TruncationMode::kIncludeComment);
}
if (!updateobj.isEmpty()) {