| 757 | } |
| 758 | |
| 759 | void TraceEvent::AppendAsJSON(std::string* out) const { |
| 760 | int64_t time_int64 = timestamp_; |
| 761 | int process_id = TraceLog::GetInstance()->process_id(); |
| 762 | // Category group checked at category creation time. |
| 763 | DCHECK(!strchr(name_, '"')); |
| 764 | StringAppendF(out, |
| 765 | "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 "," |
| 766 | "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{", |
| 767 | TraceLog::GetCategoryGroupName(category_group_enabled_), |
| 768 | process_id, |
| 769 | thread_id_, |
| 770 | time_int64, |
| 771 | phase_, |
| 772 | name_); |
| 773 | |
| 774 | // Output argument names and values, stop at first NULL argument name. |
| 775 | for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { |
| 776 | if (i > 0) |
| 777 | *out += ","; |
| 778 | *out += "\""; |
| 779 | *out += arg_names_[i]; |
| 780 | *out += "\":"; |
| 781 | |
| 782 | if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) |
| 783 | convertable_values_[i]->AppendAsTraceFormat(out); |
| 784 | else |
| 785 | AppendValueAsJSON(arg_types_[i], arg_values_[i], out); |
| 786 | } |
| 787 | *out += "}"; |
| 788 | |
| 789 | if (phase_ == TRACE_EVENT_PHASE_COMPLETE) { |
| 790 | int64_t duration = duration_; |
| 791 | if (duration != -1) |
| 792 | StringAppendF(out, ",\"dur\":%" PRId64, duration); |
| 793 | if (thread_timestamp_ >= 0) { |
| 794 | int64_t thread_duration = thread_duration_; |
| 795 | if (thread_duration != -1) |
| 796 | StringAppendF(out, ",\"tdur\":%" PRId64, thread_duration); |
| 797 | } |
| 798 | } |
| 799 | |
| 800 | // Output tts if thread_timestamp is valid. |
| 801 | if (thread_timestamp_ >= 0) { |
| 802 | int64_t thread_time_int64 = thread_timestamp_; |
| 803 | StringAppendF(out, ",\"tts\":%" PRId64, thread_time_int64); |
| 804 | } |
| 805 | |
| 806 | // If id_ is set, print it out as a hex string so we don't loose any |
| 807 | // bits (it might be a 64-bit pointer). |
| 808 | if (flags_ & TRACE_EVENT_FLAG_HAS_ID) |
| 809 | StringAppendF(out, ",\"id\":\"0x%" PRIx64 "\"", static_cast<uint64_t>(id_)); |
| 810 | |
| 811 | // Instant events also output their scope. |
| 812 | if (phase_ == TRACE_EVENT_PHASE_INSTANT) { |
| 813 | char scope = '?'; |
| 814 | switch (flags_ & TRACE_EVENT_FLAG_SCOPE_MASK) { |
| 815 | case TRACE_EVENT_SCOPE_GLOBAL: |
| 816 | scope = TRACE_EVENT_SCOPE_NAME_GLOBAL; |
no test coverage detected