| 304 | } |
| 305 | |
| 306 | Status ThreadMgr::StartInstrumentation(const scoped_refptr<MetricEntity>& metrics, |
| 307 | WebCallbackRegistry* web) const { |
| 308 | // Use function gauges here so that we can register a unique copy of these metrics in |
| 309 | // multiple tservers, even though the ThreadMgr is itself a singleton. |
| 310 | metrics->NeverRetire( |
| 311 | METRIC_threads_started.InstantiateFunctionGauge( |
| 312 | metrics, [this]() { return this->ReadThreadsStarted(); })); |
| 313 | metrics->NeverRetire( |
| 314 | METRIC_threads_running.InstantiateFunctionGauge( |
| 315 | metrics, [this]() { return this->ReadThreadsRunning(); })); |
| 316 | metrics->NeverRetire( |
| 317 | METRIC_cpu_utime.InstantiateFunctionGauge( |
| 318 | metrics, []() { return GetCpuUTime(); })); |
| 319 | metrics->NeverRetire( |
| 320 | METRIC_cpu_stime.InstantiateFunctionGauge( |
| 321 | metrics, []() { return GetCpuSTime(); })); |
| 322 | metrics->NeverRetire( |
| 323 | METRIC_voluntary_context_switches.InstantiateFunctionGauge( |
| 324 | metrics, []() { return GetVoluntaryContextSwitches(); })); |
| 325 | metrics->NeverRetire( |
| 326 | METRIC_involuntary_context_switches.InstantiateFunctionGauge( |
| 327 | metrics, []() { return GetInVoluntaryContextSwitches(); })); |
| 328 | metrics->NeverRetire( |
| 329 | METRIC_scheduling_priority.InstantiateFunctionGauge( |
| 330 | metrics, []() { return GetSchedulingPriority(); })); |
| 331 | |
| 332 | if (web) { |
| 333 | DCHECK_NOTNULL(web)->RegisterPathHandler( |
| 334 | "/threadz", "Threads", [this](const WebCallbackRegistry::WebRequest& req, |
| 335 | WebCallbackRegistry::WebResponse* resp) { |
| 336 | this->ThreadPathHandler(req, resp); |
| 337 | }, |
| 338 | /* is_styled= */ true, |
| 339 | /* is_on_nav_bar= */ true); |
| 340 | } |
| 341 | return Status::OK(); |
| 342 | } |
| 343 | |
| 344 | void ThreadMgr::AddThread(const pthread_t& pthread_id, const string& name, |
| 345 | const string& category, int64_t tid) { |
no test coverage detected