summaryrefslogtreecommitdiff
path: root/src/tracing/agent.cc
diff options
context:
space:
mode:
authorJames M Snell <jasnell@gmail.com>2018-04-03 18:05:33 -0700
committerJames M Snell <jasnell@gmail.com>2018-04-17 08:30:20 -0700
commit5c27e44488aa1c00248297204ff3484c24ff3ae7 (patch)
tree4c061d36122bcb91028eb9d0457dfa15bc84604a /src/tracing/agent.cc
parent95fafc0254f6636b7c7546ac63599c79a7182fd9 (diff)
downloadandroid-node-v8-5c27e44488aa1c00248297204ff3484c24ff3ae7.tar.gz
android-node-v8-5c27e44488aa1c00248297204ff3484c24ff3ae7.tar.bz2
android-node-v8-5c27e44488aa1c00248297204ff3484c24ff3ae7.zip
trace_events: adds a new trace_events api
Removes the requirement to use `--trace-events-enabled` to enable trace events. Tracing is enabled automatically if there are any enabled categories. Adds a new `trace_events` module with an API for enabling/disabling trace events at runtime without a command line flag. ```js const trace_events = require('trace_events'); const categories = [ 'node.perf', 'node.async_hooks' ]; const tracing = trace_events.createTracing({ categories }); tracing.enable(); // do stuff tracing.disable(); ``` Multiple `Tracing` objects may exist and be enabled at any point in time. The enabled trace event categories is the union of all enabled `Tracing` objects and the `--trace-event-categories` flag. PR-URL: https://github.com/nodejs/node/pull/19803 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Diffstat (limited to 'src/tracing/agent.cc')
-rw-r--r--src/tracing/agent.cc113
1 files changed, 83 insertions, 30 deletions
diff --git a/src/tracing/agent.cc b/src/tracing/agent.cc
index 71e53e787a..cd4c3c0df9 100644
--- a/src/tracing/agent.cc
+++ b/src/tracing/agent.cc
@@ -5,55 +5,40 @@
#include "tracing/node_trace_buffer.h"
#include "tracing/node_trace_writer.h"
-#include "env-inl.h"
-
namespace node {
namespace tracing {
using v8::platform::tracing::TraceConfig;
using std::string;
-Agent::Agent(const std::string& log_file_pattern) {
- int err = uv_loop_init(&tracing_loop_);
- CHECK_EQ(err, 0);
+Agent::Agent(const std::string& log_file_pattern)
+ : log_file_pattern_(log_file_pattern) {
+ tracing_controller_ = new TracingController();
+ tracing_controller_->Initialize(nullptr);
+}
+
+void Agent::Start() {
+ if (started_)
+ return;
- NodeTraceWriter* trace_writer = new NodeTraceWriter(
- log_file_pattern, &tracing_loop_);
+ CHECK_EQ(uv_loop_init(&tracing_loop_), 0);
+
+ NodeTraceWriter* trace_writer =
+ new NodeTraceWriter(log_file_pattern_, &tracing_loop_);
TraceBuffer* trace_buffer = new NodeTraceBuffer(
NodeTraceBuffer::kBufferChunks, trace_writer, &tracing_loop_);
- tracing_controller_ = new TracingController();
tracing_controller_->Initialize(trace_buffer);
-}
-
-void Agent::Start(const string& enabled_categories) {
- TraceConfig* trace_config = new TraceConfig();
- if (!enabled_categories.empty()) {
- std::stringstream category_list(enabled_categories);
- while (category_list.good()) {
- std::string category;
- getline(category_list, category, ',');
- trace_config->AddIncludedCategory(category.c_str());
- }
- } else {
- trace_config->AddIncludedCategory("v8");
- trace_config->AddIncludedCategory("node");
- trace_config->AddIncludedCategory("node.async_hooks");
- }
// This thread should be created *after* async handles are created
// (within NodeTraceWriter and NodeTraceBuffer constructors).
// Otherwise the thread could shut down prematurely.
- int err = uv_thread_create(&thread_, ThreadCb, this);
- CHECK_EQ(err, 0);
-
- tracing_controller_->StartTracing(trace_config);
+ CHECK_EQ(0, uv_thread_create(&thread_, ThreadCb, this));
started_ = true;
}
void Agent::Stop() {
- if (!started_) {
+ if (!started_)
return;
- }
// Perform final Flush on TraceBuffer. We don't want the tracing controller
// to flush the buffer again on destruction of the V8::Platform.
tracing_controller_->StopTracing();
@@ -70,5 +55,73 @@ void Agent::ThreadCb(void* arg) {
uv_run(&agent->tracing_loop_, UV_RUN_DEFAULT);
}
+void Agent::Enable(const std::string& categories) {
+ if (!categories.empty()) {
+ std::stringstream category_list(categories);
+ while (category_list.good()) {
+ std::string category;
+ getline(category_list, category, ',');
+ categories_.insert(category.c_str());
+ }
+ RestartTracing();
+ }
+}
+
+void Agent::Enable(const std::set<std::string>& categories) {
+ if (!categories.empty()) {
+ categories_.insert(categories.begin(), categories.end());
+ RestartTracing();
+ }
+}
+
+void Agent::Disable(const std::set<std::string>& categories) {
+ if (!categories.empty()) {
+ for (auto category : categories) {
+ auto pos = categories_.lower_bound(category);
+ if (pos != categories_.end())
+ categories_.erase(pos);
+ }
+ RestartTracing();
+ }
+}
+
+void Agent::RestartTracing() {
+ static bool warned;
+ if (!warned) {
+ warned = true;
+ fprintf(stderr, "Warning: Trace event is an experimental feature "
+ "and could change at any time.\n");
+ }
+ Start(); // Start the agent if it hasn't already been started
+ tracing_controller_->StopTracing();
+ auto config = CreateTraceConfig();
+ if (config != nullptr)
+ tracing_controller_->StartTracing(config);
+}
+
+TraceConfig* Agent::CreateTraceConfig() {
+ if (categories_.empty())
+ return nullptr;
+ TraceConfig* trace_config = new TraceConfig();
+ for (auto category = categories_.begin();
+ category != categories_.end();
+ category = categories_.upper_bound(*category)) {
+ trace_config->AddIncludedCategory(category->c_str());
+ }
+ return trace_config;
+}
+
+std::string Agent::GetEnabledCategories() {
+ std::string categories;
+ for (auto category = categories_.begin();
+ category != categories_.end();
+ category = categories_.upper_bound(*category)) {
+ if (!categories.empty())
+ categories += ',';
+ categories += *category;
+ }
+ return categories;
+}
+
} // namespace tracing
} // namespace node