1 |
|
|
#ifndef SRC_TRACING_NODE_TRACE_WRITER_H_ |
2 |
|
|
#define SRC_TRACING_NODE_TRACE_WRITER_H_ |
3 |
|
|
|
4 |
|
|
#include <sstream> |
5 |
|
|
#include <queue> |
6 |
|
|
|
7 |
|
|
#include "libplatform/v8-tracing.h" |
8 |
|
|
#include "tracing/agent.h" |
9 |
|
|
#include "uv.h" |
10 |
|
|
|
11 |
|
|
namespace node { |
12 |
|
|
namespace tracing { |
13 |
|
|
|
14 |
|
|
using v8::platform::tracing::TraceObject; |
15 |
|
|
using v8::platform::tracing::TraceWriter; |
16 |
|
|
|
17 |
|
|
class NodeTraceWriter : public AsyncTraceWriter { |
18 |
|
|
public: |
19 |
|
|
explicit NodeTraceWriter(const std::string& log_file_pattern); |
20 |
|
|
~NodeTraceWriter() override; |
21 |
|
|
|
22 |
|
|
void InitializeOnThread(uv_loop_t* loop) override; |
23 |
|
|
void AppendTraceEvent(TraceObject* trace_event) override; |
24 |
|
|
void Flush(bool blocking) override; |
25 |
|
|
|
26 |
|
|
static const int kTracesPerFile = 1 << 19; |
27 |
|
|
|
28 |
|
|
private: |
29 |
|
939 |
struct WriteRequest { |
30 |
|
|
std::string str; |
31 |
|
|
int highest_request_id; |
32 |
|
|
}; |
33 |
|
|
|
34 |
|
|
void AfterWrite(); |
35 |
|
|
void StartWrite(uv_buf_t buf); |
36 |
|
|
void OpenNewFileForStreaming(); |
37 |
|
|
void WriteToFile(std::string&& str, int highest_request_id); |
38 |
|
|
void WriteSuffix(); |
39 |
|
|
void FlushPrivate(); |
40 |
|
|
static void ExitSignalCb(uv_async_t* signal); |
41 |
|
|
|
42 |
|
|
uv_loop_t* tracing_loop_ = nullptr; |
43 |
|
|
// Triggers callback to initiate writing the contents of stream_ to disk. |
44 |
|
|
uv_async_t flush_signal_; |
45 |
|
|
// Triggers callback to close async objects, ending the tracing thread. |
46 |
|
|
uv_async_t exit_signal_; |
47 |
|
|
// Prevents concurrent R/W on state related to serialized trace data |
48 |
|
|
// before it's written to disk, namely stream_ and total_traces_ |
49 |
|
|
// as well as json_trace_writer_. |
50 |
|
|
Mutex stream_mutex_; |
51 |
|
|
// Prevents concurrent R/W on state related to write requests. |
52 |
|
|
// If both mutexes are locked, request_mutex_ has to be locked first. |
53 |
|
|
Mutex request_mutex_; |
54 |
|
|
// Allows blocking calls to Flush() to wait on a condition for |
55 |
|
|
// trace events to be written to disk. |
56 |
|
|
ConditionVariable request_cond_; |
57 |
|
|
// Used to wait until async handles have been closed. |
58 |
|
|
ConditionVariable exit_cond_; |
59 |
|
|
int fd_ = -1; |
60 |
|
|
uv_fs_t write_req_; |
61 |
|
|
std::queue<WriteRequest> write_req_queue_; |
62 |
|
|
int num_write_requests_ = 0; |
63 |
|
|
int highest_request_id_completed_ = 0; |
64 |
|
|
int total_traces_ = 0; |
65 |
|
|
int file_num_ = 0; |
66 |
|
|
std::string log_file_pattern_; |
67 |
|
|
std::ostringstream stream_; |
68 |
|
|
std::unique_ptr<TraceWriter> json_trace_writer_; |
69 |
|
|
bool exited_ = false; |
70 |
|
|
}; |
71 |
|
|
|
72 |
|
|
} // namespace tracing |
73 |
|
|
} // namespace node |
74 |
|
|
|
75 |
|
|
#endif // SRC_TRACING_NODE_TRACE_WRITER_H_ |