1
1
#include " tracing/agent.h"
2
2
3
- #include < sstream>
4
3
#include < string>
5
4
#include " tracing/node_trace_buffer.h"
6
- #include " tracing/node_trace_writer.h"
7
5
8
6
namespace node {
9
7
namespace tracing {
10
8
11
- namespace {
12
-
13
- class ScopedSuspendTracing {
9
+ class Agent ::ScopedSuspendTracing {
14
10
public:
15
- ScopedSuspendTracing (TracingController* controller, Agent* agent)
16
- : controller_(controller), agent_(agent) {
17
- controller->StopTracing ();
11
+ ScopedSuspendTracing (TracingController* controller, Agent* agent,
12
+ bool do_suspend = true )
13
+ : controller_(controller), agent_(do_suspend ? agent : nullptr ) {
14
+ if (do_suspend) {
15
+ CHECK (agent_->started_ );
16
+ controller->StopTracing ();
17
+ }
18
18
}
19
19
20
20
~ScopedSuspendTracing () {
21
+ if (agent_ == nullptr ) return ;
21
22
TraceConfig* config = agent_->CreateTraceConfig ();
22
23
if (config != nullptr ) {
23
24
controller_->StartTracing (config);
@@ -29,8 +30,10 @@ class ScopedSuspendTracing {
29
30
Agent* agent_;
30
31
};
31
32
33
+ namespace {
34
+
32
35
std::set<std::string> flatten (
33
- const std::unordered_map<int , std::set <std::string>>& map) {
36
+ const std::unordered_map<int , std::multiset <std::string>>& map) {
34
37
std::set<std::string> result;
35
38
for (const auto & id_value : map)
36
39
result.insert (id_value.second .begin (), id_value.second .end ());
@@ -43,18 +46,17 @@ using v8::platform::tracing::TraceConfig;
43
46
using v8::platform::tracing::TraceWriter;
44
47
using std::string;
45
48
46
- Agent::Agent (const std::string& log_file_pattern)
47
- : log_file_pattern_(log_file_pattern) {
49
+ Agent::Agent () {
48
50
tracing_controller_ = new TracingController ();
49
51
tracing_controller_->Initialize (nullptr );
52
+
53
+ CHECK_EQ (uv_loop_init (&tracing_loop_), 0 );
50
54
}
51
55
52
56
void Agent::Start () {
53
57
if (started_)
54
58
return ;
55
59
56
- CHECK_EQ (uv_loop_init (&tracing_loop_), 0 );
57
-
58
60
NodeTraceBuffer* trace_buffer_ = new NodeTraceBuffer (
59
61
NodeTraceBuffer::kBufferChunks , this , &tracing_loop_);
60
62
tracing_controller_->Initialize (trace_buffer_);
@@ -71,18 +73,30 @@ void Agent::Start() {
71
73
72
74
AgentWriterHandle Agent::AddClient (
73
75
const std::set<std::string>& categories,
74
- std::unique_ptr<AsyncTraceWriter> writer) {
76
+ std::unique_ptr<AsyncTraceWriter> writer,
77
+ enum UseDefaultCategoryMode mode) {
75
78
Start ();
79
+
80
+ const std::set<std::string>* use_categories = &categories;
81
+
82
+ std::set<std::string> categories_with_default;
83
+ if (mode == kUseDefaultCategories ) {
84
+ categories_with_default.insert (categories.begin (), categories.end ());
85
+ categories_with_default.insert (categories_[kDefaultHandleId ].begin (),
86
+ categories_[kDefaultHandleId ].end ());
87
+ use_categories = &categories_with_default;
88
+ }
89
+
76
90
ScopedSuspendTracing suspend (tracing_controller_, this );
77
91
int id = next_writer_id_++;
78
92
writers_[id] = std::move (writer);
79
- categories_[id] = categories ;
93
+ categories_[id] = { use_categories-> begin (), use_categories-> end () } ;
80
94
81
95
return AgentWriterHandle (this , id);
82
96
}
83
97
84
- void Agent::Stop () {
85
- file_writer_. reset ( );
98
+ AgentWriterHandle Agent::DefaultHandle () {
99
+ return AgentWriterHandle ( this , kDefaultHandleId );
86
100
}
87
101
88
102
void Agent::StopTracing () {
@@ -99,54 +113,30 @@ void Agent::StopTracing() {
99
113
}
100
114
101
115
void Agent::Disconnect (int client) {
116
+ if (client == kDefaultHandleId ) return ;
102
117
ScopedSuspendTracing suspend (tracing_controller_, this );
103
118
writers_.erase (client);
104
119
categories_.erase (client);
105
120
}
106
121
107
- void Agent::Enable (const std::string& categories) {
122
+ void Agent::Enable (int id, const std::set<std:: string> & categories) {
108
123
if (categories.empty ())
109
124
return ;
110
- std::set<std::string> categories_set;
111
- std::istringstream category_list (categories);
112
- while (category_list.good ()) {
113
- std::string category;
114
- getline (category_list, category, ' ,' );
115
- categories_set.emplace (std::move (category));
116
- }
117
- Enable (categories_set);
118
- }
119
125
120
- void Agent::Enable (const std::set<std::string>& categories) {
121
- if (categories.empty ())
122
- return ;
123
-
124
- file_writer_categories_.insert (categories.begin (), categories.end ());
125
- std::set<std::string> full_list (file_writer_categories_.begin (),
126
- file_writer_categories_.end ());
127
- if (file_writer_.empty ()) {
128
- // Ensure background thread is running
129
- Start ();
130
- std::unique_ptr<NodeTraceWriter> writer (
131
- new NodeTraceWriter (log_file_pattern_, &tracing_loop_));
132
- file_writer_ = AddClient (full_list, std::move (writer));
133
- } else {
134
- ScopedSuspendTracing suspend (tracing_controller_, this );
135
- categories_[file_writer_.id_ ] = full_list;
136
- }
126
+ ScopedSuspendTracing suspend (tracing_controller_, this ,
127
+ id != kDefaultHandleId );
128
+ categories_[id].insert (categories.begin (), categories.end ());
137
129
}
138
130
139
- void Agent::Disable (const std::set<std::string>& categories) {
131
+ void Agent::Disable (int id, const std::set<std::string>& categories) {
132
+ ScopedSuspendTracing suspend (tracing_controller_, this ,
133
+ id != kDefaultHandleId );
134
+ std::multiset<std::string>& writer_categories = categories_[id];
140
135
for (const std::string& category : categories) {
141
- auto it = file_writer_categories_ .find (category);
142
- if (it != file_writer_categories_ .end ())
143
- file_writer_categories_ .erase (it);
136
+ auto it = writer_categories .find (category);
137
+ if (it != writer_categories .end ())
138
+ writer_categories .erase (it);
144
139
}
145
- if (file_writer_.empty ())
146
- return ;
147
- ScopedSuspendTracing suspend (tracing_controller_, this );
148
- categories_[file_writer_.id_ ] = { file_writer_categories_.begin (),
149
- file_writer_categories_.end () };
150
140
}
151
141
152
142
TraceConfig* Agent::CreateTraceConfig () const {
@@ -178,5 +168,6 @@ void Agent::Flush(bool blocking) {
178
168
for (const auto & id_writer : writers_)
179
169
id_writer.second ->Flush (blocking);
180
170
}
171
+
181
172
} // namespace tracing
182
173
} // namespace node
0 commit comments