mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -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::
|
||||||
TextMonitor(TextStats *server, std::ostream *outStream, bool show_raw_data ) : PStatMonitor(server) {
|
TextMonitor(TextStats *server, std::ostream *outStream, bool show_raw_data, bool json) : PStatMonitor(server) {
|
||||||
_outStream = outStream; //[PECI]
|
_outStream = outStream; //[PECI]
|
||||||
_show_raw_data = show_raw_data;
|
_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";
|
<< 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
|
* 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
|
* 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);
|
PStatView &view = get_view(thread_index);
|
||||||
const PStatThreadData *thread_data = view.get_thread_data();
|
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()) {
|
if (true) {
|
||||||
const PStatClientData *client_data = get_client_data();
|
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 "
|
(*_outStream) << "\rThread "
|
||||||
<< client_data->get_thread_name(thread_index)
|
<< client_data->get_thread_name(thread_index)
|
||||||
<< " frame " << frame_number << ", "
|
<< " frame " << frame_number << ", "
|
||||||
@ -149,6 +191,7 @@ new_data(int thread_index, int frame_number) {
|
|||||||
void TextMonitor::
|
void TextMonitor::
|
||||||
lost_connection() {
|
lost_connection() {
|
||||||
nout << "Lost connection.\n";
|
nout << "Lost connection.\n";
|
||||||
|
++_dummy_pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +29,7 @@ class TextStats;
|
|||||||
*/
|
*/
|
||||||
class TextMonitor : public PStatMonitor {
|
class TextMonitor : public PStatMonitor {
|
||||||
public:
|
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();
|
TextStats *get_server();
|
||||||
|
|
||||||
virtual std::string get_monitor_name();
|
virtual std::string get_monitor_name();
|
||||||
@ -37,6 +37,7 @@ public:
|
|||||||
virtual void got_hello();
|
virtual void got_hello();
|
||||||
virtual void got_bad_version(int client_major, int client_minor,
|
virtual void got_bad_version(int client_major, int client_minor,
|
||||||
int server_major, int server_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 new_data(int thread_index, int frame_number);
|
||||||
virtual void lost_connection();
|
virtual void lost_connection();
|
||||||
virtual bool is_thread_safe();
|
virtual bool is_thread_safe();
|
||||||
@ -47,6 +48,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
std::ostream *_outStream; //[PECI]
|
std::ostream *_outStream; //[PECI]
|
||||||
bool _show_raw_data;
|
bool _show_raw_data;
|
||||||
|
bool _json;
|
||||||
|
int _dummy_pid = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "textMonitor.I"
|
#include "textMonitor.I"
|
||||||
|
@ -50,6 +50,11 @@ TextStats() {
|
|||||||
"time per collector.",
|
"time per collector.",
|
||||||
&TextStats::dispatch_none, &_show_raw_data, nullptr);
|
&TextStats::dispatch_none, &_show_raw_data, nullptr);
|
||||||
|
|
||||||
|
add_option
|
||||||
|
("j", "", 0,
|
||||||
|
"Output data in JSON format.",
|
||||||
|
&TextStats::dispatch_none, &_json, nullptr);
|
||||||
|
|
||||||
add_option
|
add_option
|
||||||
("o", "filename", 0,
|
("o", "filename", 0,
|
||||||
"Filename where to print. If not given then stderr is being used.",
|
"Filename where to print. If not given then stderr is being used.",
|
||||||
@ -66,7 +71,7 @@ TextStats() {
|
|||||||
PStatMonitor *TextStats::
|
PStatMonitor *TextStats::
|
||||||
make_monitor() {
|
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";
|
nout << "Listening for connections.\n";
|
||||||
|
|
||||||
if (_got_outputFileName) {
|
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 {
|
} else {
|
||||||
_outFile = &(nout);
|
_outFile = &(nout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_json) {
|
||||||
|
(*_outFile) << "[\n";
|
||||||
|
}
|
||||||
|
|
||||||
main_loop(&user_interrupted);
|
main_loop(&user_interrupted);
|
||||||
nout << "Exiting.\n";
|
nout << "Exiting.\n";
|
||||||
|
|
||||||
|
if (_json) {
|
||||||
|
// Remove the last comma.
|
||||||
|
_outFile->seekp(-3, std::ios::cur);
|
||||||
|
(*_outFile) << "\n]\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
int _port;
|
int _port;
|
||||||
bool _show_raw_data;
|
bool _show_raw_data;
|
||||||
|
bool _json = false;
|
||||||
|
|
||||||
// [PECI]
|
// [PECI]
|
||||||
bool _got_outputFileName;
|
bool _got_outputFileName;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user