| 130 | } |
| 131 | |
| 132 | void Trace::Dump(std::ostream* out, int flags) const { |
| 133 | // Gather a copy of the list of entries under the lock. This is fast |
| 134 | // enough that we aren't worried about stalling concurrent tracers |
| 135 | // (whereas doing the logging itself while holding the lock might be |
| 136 | // too slow, if the output stream is a file, for example). |
| 137 | vector<TraceEntry*> entries; |
| 138 | vector<pair<StringPiece, scoped_refptr<Trace>>> child_traces; |
| 139 | { |
| 140 | std::lock_guard<simple_spinlock> l(lock_); |
| 141 | for (TraceEntry* cur = entries_head_; |
| 142 | cur != nullptr; |
| 143 | cur = cur->next) { |
| 144 | entries.push_back(cur); |
| 145 | } |
| 146 | |
| 147 | child_traces = child_traces_; |
| 148 | } |
| 149 | |
| 150 | // Save original flags. |
| 151 | std::ios::fmtflags save_flags(out->flags()); |
| 152 | |
| 153 | int64_t prev_usecs = 0; |
| 154 | for (TraceEntry* e : entries) { |
| 155 | // Log format borrowed from glog/logging.cc |
| 156 | int64_t usecs_since_prev = 0; |
| 157 | if (prev_usecs != 0) { |
| 158 | usecs_since_prev = e->timestamp_micros - prev_usecs; |
| 159 | } |
| 160 | prev_usecs = e->timestamp_micros; |
| 161 | |
| 162 | using std::setw; |
| 163 | *out << FormatTimestampForLog(e->timestamp_micros); |
| 164 | *out << ' '; |
| 165 | if (flags & INCLUDE_TIME_DELTAS) { |
| 166 | out->fill(' '); |
| 167 | *out << "(+" << setw(6) << usecs_since_prev << "us) "; |
| 168 | } |
| 169 | *out << const_basename(e->file_path) << ':' << e->line_number |
| 170 | << "] "; |
| 171 | out->write(reinterpret_cast<char*>(e) + sizeof(TraceEntry), |
| 172 | e->message_len); |
| 173 | *out << std::endl; |
| 174 | } |
| 175 | |
| 176 | for (const auto& entry : child_traces) { |
| 177 | const auto& t = entry.second; |
| 178 | *out << "Related trace '" << entry.first << "':" << std::endl; |
| 179 | *out << t->DumpToString(flags & (~INCLUDE_METRICS)); |
| 180 | } |
| 181 | |
| 182 | if (flags & INCLUDE_METRICS) { |
| 183 | *out << "Metrics: " << MetricsAsJSON(); |
| 184 | } |
| 185 | |
| 186 | // Restore stream flags. |
| 187 | out->flags(save_flags); |
| 188 | } |
| 189 | |