mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 16:20:11 -04:00
text-stats: Add JSON output mode in chrome://tracing format
This allows the whole trace to be captured and then loaded into chrome://tracing or https://ui.perfetto.dev
This commit is contained in:
parent
f6322d8c93
commit
fb7a2d7a13
@ -22,9 +22,10 @@
|
||||
*
|
||||
*/
|
||||
TextMonitor::
|
||||
TextMonitor(TextStats *server, std::ostream *outStream, bool show_raw_data ) : PStatMonitor(server) {
|
||||
_outStream = outStream; //[PECI]
|
||||
_show_raw_data = show_raw_data;
|
||||
TextMonitor(TextStats *server, std::ostream *outStream, bool show_raw_data, bool json) : PStatMonitor(server) {
|
||||
_outStream = outStream; //[PECI]
|
||||
_show_raw_data = show_raw_data;
|
||||
_json = json;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,6 +74,30 @@ got_bad_version(int client_major, int client_minor,
|
||||
<< server_major << "." << server_minor << ".\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever a new Thread definition is received from the client.
|
||||
* Generally, the client will send all of its threads over shortly after
|
||||
* connecting, but there's no guarantee that they will all be received before
|
||||
* the first frames are received. The monitor should be prepared to accept
|
||||
* new Thread definitions midstream.
|
||||
*/
|
||||
void TextMonitor::
|
||||
new_thread(int thread_index) {
|
||||
if (_json) {
|
||||
const PStatClientData *client_data = get_client_data();
|
||||
|
||||
int pid = get_client_pid();
|
||||
if (pid < 0) {
|
||||
pid = _dummy_pid;
|
||||
}
|
||||
|
||||
(*_outStream)
|
||||
<< "{\"name\":\"thread_name\",\"ph\":\"M\",\"pid\":" << pid
|
||||
<< ",\"tid\":" << thread_index << ",\"args\":{\"name\":\""
|
||||
<< client_data->get_thread_name(thread_index) << "\"}},\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called as each frame's data is made available. There is no gurantee the
|
||||
* frames will arrive in order, or that all of them will arrive at all. The
|
||||
@ -84,12 +109,29 @@ new_data(int thread_index, int frame_number) {
|
||||
PStatView &view = get_view(thread_index);
|
||||
const PStatThreadData *thread_data = view.get_thread_data();
|
||||
|
||||
if (frame_number == thread_data->get_latest_frame_number()) {
|
||||
view.set_to_frame(frame_number);
|
||||
view.set_to_frame(frame_number);
|
||||
|
||||
if (view.all_collectors_known()) {
|
||||
const PStatClientData *client_data = get_client_data();
|
||||
if (true) {
|
||||
const PStatClientData *client_data = get_client_data();
|
||||
|
||||
if (_json) {
|
||||
int pid = get_client_pid();
|
||||
if (pid < 0) {
|
||||
pid = _dummy_pid;
|
||||
}
|
||||
|
||||
const PStatFrameData &frame_data = thread_data->get_frame(frame_number);
|
||||
int num_events = frame_data.get_num_events();
|
||||
for (int i = 0; i < num_events; ++i) {
|
||||
int collector_index = frame_data.get_time_collector(i);
|
||||
(*_outStream)
|
||||
<< "{\"name\":\"" << client_data->get_collector_fullname(collector_index)
|
||||
<< "\",\"ts\":" << (uint64_t)(frame_data.get_time(i) * 1000000)
|
||||
<< ",\"ph\":\"" << (frame_data.is_start(i) ? 'B' : 'E') << "\""
|
||||
<< ",\"tid\":" << thread_index << ",\"pid\":" << pid << "},\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
(*_outStream) << "\rThread "
|
||||
<< client_data->get_thread_name(thread_index)
|
||||
<< " frame " << frame_number << ", "
|
||||
@ -149,6 +191,7 @@ new_data(int thread_index, int frame_number) {
|
||||
void TextMonitor::
|
||||
lost_connection() {
|
||||
nout << "Lost connection.\n";
|
||||
++_dummy_pid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,7 +29,7 @@ class TextStats;
|
||||
*/
|
||||
class TextMonitor : public PStatMonitor {
|
||||
public:
|
||||
TextMonitor(TextStats *server, std::ostream *outStream, bool show_raw_data);
|
||||
TextMonitor(TextStats *server, std::ostream *outStream, bool show_raw_data, bool json = false);
|
||||
TextStats *get_server();
|
||||
|
||||
virtual std::string get_monitor_name();
|
||||
@ -37,6 +37,7 @@ public:
|
||||
virtual void got_hello();
|
||||
virtual void got_bad_version(int client_major, int client_minor,
|
||||
int server_major, int server_minor);
|
||||
virtual void new_thread(int thread_index);
|
||||
virtual void new_data(int thread_index, int frame_number);
|
||||
virtual void lost_connection();
|
||||
virtual bool is_thread_safe();
|
||||
@ -47,6 +48,8 @@ public:
|
||||
private:
|
||||
std::ostream *_outStream; //[PECI]
|
||||
bool _show_raw_data;
|
||||
bool _json;
|
||||
int _dummy_pid = 0;
|
||||
};
|
||||
|
||||
#include "textMonitor.I"
|
||||
|
@ -50,6 +50,11 @@ TextStats() {
|
||||
"time per collector.",
|
||||
&TextStats::dispatch_none, &_show_raw_data, nullptr);
|
||||
|
||||
add_option
|
||||
("j", "", 0,
|
||||
"Output data in JSON format.",
|
||||
&TextStats::dispatch_none, &_json, nullptr);
|
||||
|
||||
add_option
|
||||
("o", "filename", 0,
|
||||
"Filename where to print. If not given then stderr is being used.",
|
||||
@ -66,7 +71,7 @@ TextStats() {
|
||||
PStatMonitor *TextStats::
|
||||
make_monitor() {
|
||||
|
||||
return new TextMonitor(this, _outFile, _show_raw_data);
|
||||
return new TextMonitor(this, _outFile, _show_raw_data, _json);
|
||||
}
|
||||
|
||||
|
||||
@ -87,13 +92,23 @@ run() {
|
||||
nout << "Listening for connections.\n";
|
||||
|
||||
if (_got_outputFileName) {
|
||||
_outFile = new std::ofstream(_outputFileName.c_str(), std::ios::out);
|
||||
_outFile = new std::ofstream(_outputFileName.c_str(), std::ios::out | std::ios::trunc);
|
||||
} else {
|
||||
_outFile = &(nout);
|
||||
}
|
||||
|
||||
if (_json) {
|
||||
(*_outFile) << "[\n";
|
||||
}
|
||||
|
||||
main_loop(&user_interrupted);
|
||||
nout << "Exiting.\n";
|
||||
|
||||
if (_json) {
|
||||
// Remove the last comma.
|
||||
_outFile->seekp(-3, std::ios::cur);
|
||||
(*_outFile) << "\n]\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
private:
|
||||
int _port;
|
||||
bool _show_raw_data;
|
||||
bool _json = false;
|
||||
|
||||
// [PECI]
|
||||
bool _got_outputFileName;
|
||||
|
Loading…
x
Reference in New Issue
Block a user