TEST(StringPiece, SuffixEmpty) { StringPiece a; EXPECT_TRUE(a.endsWith("")); EXPECT_FALSE(a.endsWith("a")); EXPECT_FALSE(a.endsWith('a')); EXPECT_TRUE(a.removeSuffix("")); EXPECT_EQ("", a); EXPECT_FALSE(a.removeSuffix("a")); EXPECT_EQ("", a); EXPECT_FALSE(a.removeSuffix('a')); EXPECT_EQ("", a); }
void parseMessage(StringPiece msg, size_t* threadID, size_t* messageIndex) { // Validate and strip off the message prefix and suffix constexpr StringPiece prefix{"thread "}; if (!msg.startsWith(prefix)) { throw std::runtime_error("bad message prefix"); } msg.advance(prefix.size()); if (!msg.endsWith(kMsgSuffix)) { throw std::runtime_error("bad message suffix"); } msg.subtract(kMsgSuffix.size()); // Parse then strip off the thread index auto threadIDEnd = msg.find(' '); if (threadIDEnd == StringPiece::npos) { throw std::runtime_error("no middle found"); } *threadID = folly::to<size_t>(msg.subpiece(0, threadIDEnd)); msg.advance(threadIDEnd); // Validate that the middle of the message is what we expect, // then strip it off constexpr StringPiece middle{" message "}; if (!msg.startsWith(middle)) { throw std::runtime_error("bad message middle"); } msg.advance(middle.size()); // Parse the message index *messageIndex = folly::to<size_t>(msg); }
void messageReceived(StringPiece msg) { if (msg.endsWith(" log messages discarded: " "logging faster than we can write")) { auto discardCount = folly::to<size_t>(msg.subpiece(0, msg.find(' '))); XLOG(DBG3, "received discard notification: ", discardCount); numDiscarded_ += discardCount; ++discardEventsSeen_; return; } size_t threadID = 0; size_t messageIndex = 0; try { parseMessage(msg, &threadID, &messageIndex); } catch (const std::exception& ex) { ++numUnableToParse_; XLOG(ERR, "unable to parse log message: ", msg); return; } auto& data = perThreadReadData_[threadID]; data.numMessagesRead++; if (messageIndex > data.lastId) { data.lastId = messageIndex; } else { ++numOutOfOrder_; XLOG(ERR) << "received out-of-order messages from writer " << threadID << ": " << messageIndex << " received after " << data.lastId; } }