| 38 | |
| 39 | |
| 40 | std::string TextFormatter::Format(const Entry& e) const |
| 41 | { |
| 42 | try { |
| 43 | std::ostringstream oss; |
| 44 | oss << std::format("[@{}] <{}:{}> {{{}}}", |
| 45 | GetLevelName(e.level_), |
| 46 | MakeProc_(e), |
| 47 | MakeThread_(e), |
| 48 | std::chrono::zoned_time{ std::chrono::current_zone(), e.timestamp_ } |
| 49 | ); |
| 50 | if (!e.note_.empty()) { |
| 51 | oss << "\n " << e.note_; |
| 52 | } |
| 53 | if (e.errorCode_) { |
| 54 | auto& ec = e.errorCode_; |
| 55 | if (ec.IsResolvedNontrivial()) { |
| 56 | auto pStrings = ec.GetStrings(); |
| 57 | oss << std::format("\n !{} [{}] ({}): {} => {}", pStrings->type, ec.AsHex(), pStrings->symbol, pStrings->name, pStrings->description); |
| 58 | } |
| 59 | else { |
| 60 | oss << std::format("\n !UNKNOWN [{}]", ec.AsHex()); |
| 61 | } |
| 62 | } |
| 63 | // display of source line info could be controlled here |
| 64 | // if so, hitcount would need to be separately handled |
| 65 | if (true) { |
| 66 | std::visit([&](auto& strings) { |
| 67 | oss << std::format("\n >> at {} {}\n {}({})\n", |
| 68 | strings.functionName_, |
| 69 | [&] { return e.hitCount_ == -1 ? std::string{} : std::format("[Hits: {}]", e.hitCount_); }(), |
| 70 | strings.file_, |
| 71 | e.sourceLine_ |
| 72 | ); |
| 73 | }, e.sourceStrings_); |
| 74 | } |
| 75 | if (e.pTrace_) { |
| 76 | try { |
| 77 | oss << " ====== STACK TRACE (newest on top) ======\n"; |
| 78 | oss << e.pTrace_->ToString(); |
| 79 | oss << " =========================================\n"; |
| 80 | } |
| 81 | catch (...) { |
| 82 | pmlog_panic_("Failed printing stack trace in TextFormatter::Format"); |
| 83 | } |
| 84 | } |
| 85 | return oss.str(); |
| 86 | } |
| 87 | catch (...) { |
| 88 | pmlog_panic_("Exception in TextFormatter::Format"); |
| 89 | return {}; |
| 90 | } |
| 91 | } |
| 92 | } |
no test coverage detected