in mcrouter/tools/mcpiper/MessagePrinter-inl.h [138:332]
folly::Optional<StyledString> MessagePrinter::filterAndBuildOutput(
uint64_t msgId,
const Message& message,
const std::string& key,
carbon::Result result,
const folly::SocketAddress& from,
const folly::SocketAddress& to,
mc_protocol_t protocol,
int64_t latencyUs,
const ServerLoad& serverLoad) {
++stats_.totalMessages;
if (!matchAddress(from, to)) {
return folly::none;
}
if (filter_.protocol.hasValue() && filter_.protocol.value() != protocol) {
return folly::none;
}
auto value = carbon::valueRangeSlow(const_cast<Message&>(message));
if (value.size() < filter_.valueMinSize ||
value.size() > filter_.valueMaxSize) {
return folly::none;
}
// if latency is 0 and the filter is not set, we let it pass through
if (latencyUs < filter_.minLatencyUs) {
return folly::none;
}
StyledString out;
out.append("\n");
if (options_.script) {
out.append("{\n", format_.dataOpColor);
/* always present, makes comma accounting simpler */
out.append(folly::sformat(" \"reqid\": {}", msgId));
}
if (options_.printTimeFn) {
timeval ts;
gettimeofday(&ts, nullptr);
if (options_.script) {
out.append(
folly::sformat(",\n \"ts\": \"{}\"", options_.printTimeFn(ts)));
} else {
out.append(options_.printTimeFn(ts));
out.append(" ");
}
}
out.append(serializeConnectionDetails(from, to, protocol));
if (!options_.script) {
out.append("\n{\n", format_.dataOpColor);
}
auto msgHeader =
serializeMessageHeader(detail::getName<Message>(), result, key);
if (!msgHeader.empty()) {
if (options_.script) {
out.append(",\n ");
} else {
out.append(" ");
}
out.append(std::move(msgHeader), format_.headerColor);
}
// Msg attributes
if (!options_.script) {
/* Rendered above for script mode */
out.append("\n reqid: ", format_.msgAttrColor);
out.append(folly::sformat("0x{:x}", msgId), format_.dataValueColor);
}
if (latencyUs > 0) { // it is 0 only for requests
if (options_.script) {
out.append(",\n \"rtt_us\": ");
} else {
out.append("\n request/response latency (us): ", format_.msgAttrColor);
}
out.append(folly::to<std::string>(latencyUs), format_.dataValueColor);
}
if (!serverLoad.isZero()) {
if (options_.script) {
out.append(",\n \"server_load_percent\": ");
} else {
out.append("\n server load: ", format_.msgAttrColor);
}
out.append(
folly::sformat("{:.2f}%", serverLoad.percentLoad()),
format_.dataValueColor);
}
if (options_.script) {
out.append(",\n \"flags\": ");
out.append(folly::to<std::string>(getFlagsIfExist(message)));
} else {
out.append("\n flags: ", format_.msgAttrColor);
out.append(
folly::sformat("0x{:x}", getFlagsIfExist(message)),
format_.dataValueColor);
}
if (!options_.script && getFlagsIfExist(message)) {
auto flagDesc = describeFlags(getFlagsIfExist(message));
if (!flagDesc.empty()) {
out.pushAppendColor(format_.attrColor);
out.append(" [");
bool first = true;
for (auto& s : flagDesc) {
if (!first) {
out.append(", ");
}
first = false;
out.append(s);
}
out.pushBack(']');
out.popAppendColor();
}
}
auto typeSpecificAttr = getTypeSpecificAttributes(message);
if (options_.script && !typeSpecificAttr.empty()) {
out.pushBack(',');
}
out.append(typeSpecificAttr);
if (!value.empty()) {
size_t uncompressedSize;
auto formattedValue = valueFormatter_->uncompressAndFormat(
value,
getFlagsIfExist(message),
format_,
options_.script,
uncompressedSize);
if (options_.script) {
out.append(folly::sformat(",\n \"value_wire_bytes\": {}", value.size()));
out.append(folly::sformat(
",\n \"value_uncompressed_bytes\": {}", uncompressedSize));
} else {
out.append("\n value size: ", format_.msgAttrColor);
if (uncompressedSize != value.size()) {
out.append(
folly::sformat(
"{} uncompressed, {} compressed, {:.2f}% savings",
uncompressedSize,
value.size(),
100.0 - 100.0 * value.size() / uncompressedSize),
format_.dataValueColor);
} else {
out.append(
folly::to<std::string>(value.size()), format_.dataValueColor);
}
}
if (!options_.quiet) {
if (options_.script) {
out.append(",\n \"value\": ");
} else {
out.append("\n value: ", format_.msgAttrColor);
}
out.append(formattedValue);
}
}
if (options_.script) {
out.append("\n},\n");
} else {
out.append("\n}\n", format_.dataOpColor);
}
// Match pattern
if (filter_.pattern) {
auto matches = matchAll(out.text(), *filter_.pattern);
auto success = matches.empty() == filter_.invertMatch;
if (!success && afterMatchCount_ == 0) {
return folly::none;
}
if (!filter_.invertMatch) {
for (auto& m : matches) {
out.setFg(m.first, m.second, format_.matchColor);
}
}
// Reset after match
if (success && options_.numAfterMatch > 0) {
afterMatchCount_ = options_.numAfterMatch + 1;
}
}
return out;
}