N|Solid
nsolid.h
Go to the documentation of this file.
1 #ifndef SRC_NSOLID_H_
2 #define SRC_NSOLID_H_
3 
4 #include "node.h"
5 #include "uv.h"
6 
7 #include <memory>
8 #include <string>
9 
20 namespace node {
25 namespace nsolid {
26 
27 #define NSOLID_PROCESS_METRICS_STRINGS(V) \
28  V(std::string, title, title, EOther) \
29  V(std::string, user, user, EOther)
30 
31 #define NSOLID_PROCESS_METRICS_NUMBERS(V) \
32  V(uint64_t, timestamp, timestamp, ECounter) \
33  V(uint64_t, uptime, uptime, ECounter) \
34  V(uint64_t, system_uptime, systemUptime, ECounter) \
35  V(uint64_t, free_mem, freeMem, EGauge) \
36  V(uint64_t, block_input_op_count, blockInputOpCount, ECounter) \
37  V(uint64_t, block_output_op_count, blockOutputOpCount, ECounter) \
38  V(uint64_t, ctx_switch_involuntary_count, \
39  ctxSwitchInvoluntaryCount, \
40  ECounter) \
41  V(uint64_t, ctx_switch_voluntary_count, ctxSwitchVoluntaryCount, ECounter) \
42  V(uint64_t, ipc_received_count, ipcReceivedCount, ECounter) \
43  V(uint64_t, ipc_sent_count, ipcSentCount, ECounter) \
44  V(uint64_t, page_fault_hard_count, pageFaultHardCount, ECounter) \
45  V(uint64_t, page_fault_soft_count, pageFaultSoftCount, ECounter) \
46  V(uint64_t, signal_count, signalCount, ECounter) \
47  V(uint64_t, swap_count, swapCount, ECounter) \
48  V(uint64_t, rss, rss, EGauge) \
49  V(double, load_1m, load1m, EGauge) \
50  V(double, load_5m, load5m, EGauge) \
51  V(double, load_15m, load15m, EGauge) \
52  V(double, cpu_user_percent, cpuUserPercent, EGauge) \
53  V(double, cpu_system_percent, cpuSystemPercent, EGauge) \
54  V(double, cpu_percent, cpuPercent, EGauge)
55 
56 #define NSOLID_PROCESS_METRICS(V) \
57  NSOLID_PROCESS_METRICS_STRINGS(V) \
58  NSOLID_PROCESS_METRICS_NUMBERS(V)
59 
60 #define NSOLID_ENV_METRICS(V) \
61  V(uint64_t, thread_id, threadId, EOther) \
62  V(uint64_t, timestamp, timestamp, ECounter) \
63  V(uint64_t, active_handles, activeHandles, EGauge) \
64  V(uint64_t, active_requests, activeRequests, EGauge) \
65  V(uint64_t, total_heap_size, heapTotal, EGauge) \
66  V(uint64_t, total_heap_size_executable, totalHeapSizeExecutable, EGauge) \
67  V(uint64_t, total_physical_size, totalPhysicalSize, EGauge) \
68  V(uint64_t, total_available_size, totalAvailableSize, EGauge) \
69  V(uint64_t, used_heap_size, heapUsed, EGauge) \
70  V(uint64_t, heap_size_limit, heapSizeLimit, EGauge) \
71  V(uint64_t, malloced_memory, mallocedMemory, EGauge) \
72  V(uint64_t, external_memory, externalMem, EGauge) \
73  V(uint64_t, peak_malloced_memory, peakMallocedMemory, EGauge) \
74  V(uint64_t, number_of_native_contexts, numberOfNativeContexts, EGauge) \
75  V(uint64_t, number_of_detached_contexts, numberOfDetachedContexts, EGauge) \
76  V(uint64_t, gc_count, gcCount, ECounter) \
77  V(uint64_t, gc_forced_count, gcForcedCount, ECounter) \
78  V(uint64_t, gc_full_count, gcFullCount, ECounter) \
79  V(uint64_t, gc_major_count, gcMajorCount, ECounter) \
80  V(double, gc_dur_us99_ptile, gcDurUs99Ptile, ESeries) \
81  V(double, gc_dur_us_median, gcDurUsMedian, ESeries) \
82  V(uint64_t, dns_count, dnsCount, ECounter) \
83  V(uint64_t, http_client_abort_count, httpClientAbortCount, ECounter) \
84  V(uint64_t, http_client_count, httpClientCount, ECounter) \
85  V(uint64_t, http_server_abort_count, httpServerAbortCount, ECounter) \
86  V(uint64_t, http_server_count, httpServerCount, ECounter) \
87  V(double, dns99_ptile, dns99Ptile, ESeries) \
88  V(double, dns_median, dnsMedian, ESeries) \
89  V(double, http_client99_ptile, httpClient99Ptile, ESeries) \
90  V(double, http_client_median, httpClientMedian, ESeries) \
91  V(double, http_server99_ptile, httpServer99Ptile, ESeries) \
92  V(double, http_server_median, httpServerMedian, ESeries) \
93  V(uint64_t, loop_idle_time, loopIdleTime, EGauge) \
94  V(uint64_t, loop_iterations, loopIterations, ECounter) \
95  V(uint64_t, loop_iter_with_events, loopIterWithEvents, ECounter) \
96  V(uint64_t, events_processed, eventsProcessed, ECounter) \
97  V(uint64_t, events_waiting, eventsWaiting, EGauge) \
98  V(uint64_t, provider_delay, providerDelay, EGauge) \
99  V(uint64_t, processing_delay, processingDelay, EGauge) \
100  V(double, loop_utilization, loopUtilization, EGauge) \
101  V(double, res_5s, res5s, EGauge) \
102  V(double, res_1m, res1m, EGauge) \
103  V(double, res_5m, res5m, EGauge) \
104  V(double, res_15m, res15m, EGauge) \
105  V(uint64_t, loop_total_count, loopTotalCount, ECounter) \
106  V(double, loop_avg_tasks, loopAvgTasks, EGauge) \
107  V(double, loop_estimated_lag, loopEstimatedLag, EGauge) \
108  V(double, loop_idle_percent, loopIdlePercent, EGauge)
109 
110 #define NSOLID_ERRORS(V) \
111  V(SUCCESS, 0, "Success") \
112  V(NOT_LICENSED, 1, "N|Solid Runtime is not Licensed")
113 
117 enum NSolidErr {
118 #define V(Type, Value, Msg) \
119  NSOLID_E_##Type = Value,
120  NSOLID_ERRORS(V)
121 #undef V
122 #define X(Type, Msg) \
123  NSOLID_E_UV_ ## Type = UV_ ## Type,
124  UV_ERRNO_MAP(X)
125 #undef X
126 };
127 
128 
129 class ProcessMetrics;
130 class ThreadMetrics;
131 
133 namespace internal {
134 
135 using on_block_loop_hook_proxy_sig = void(*)(uint64_t, std::string, void*);
136 using on_unblock_loop_hook_proxy_sig = on_block_loop_hook_proxy_sig;
137 using thread_added_hook_proxy_sig = void(*)(uint64_t, void*);
138 using thread_removed_hook_proxy_sig = thread_added_hook_proxy_sig;
139 using on_license_proxy_sig = void(*)(bool, uint64_t, void*);
140 using deleter_sig = void(*)(void*);
141 
142 template <typename G>
143 void on_block_loop_hook_proxy_(uint64_t, std::string, void*);
144 template <typename G>
145 void on_unblock_loop_hook_proxy_(uint64_t, std::string, void*);
146 template <typename G>
147 void thread_added_hook_proxy_(uint64_t thread_id, void* data);
148 template <typename G>
149 void thread_removed_hook_proxy_(uint64_t thread_id, void* data);
150 template <typename G>
151 void license_hook_proxy_(bool licensed, uint64_t expiration, void* g);
152 template <typename G>
153 void delete_proxy_(void* g);
154 
155 
156 int on_block_loop_hook_(uint64_t,
157  void*,
158  on_block_loop_hook_proxy_sig,
159  deleter_sig);
160 int on_unblock_loop_hook_(void*, on_unblock_loop_hook_proxy_sig, deleter_sig);
161 int thread_added_hook_(void*, thread_added_hook_proxy_sig, deleter_sig);
162 int thread_removed_hook_(void*,
163  thread_removed_hook_proxy_sig,
164  deleter_sig);
165 void SetOnLicenseHook(on_license_proxy_sig, void*, deleter_sig);
166 
167 } // namespace internal
168 
176 enum class NODE_EXTERN MetricsType: unsigned int {
177  ECounter,
178  EGauge,
179  ESeries,
180  EOther
181 };
182 
183 
188 class NODE_EXTERN ProcessMetrics {
189  public:
194  ProcessMetrics();
199  ~ProcessMetrics() = default;
200 
205  struct MetricsStor {
206 #define PM1(Type, CName, JSName, MType) Type CName;
207  NSOLID_PROCESS_METRICS_STRINGS(PM1)
208 #undef PM1
209 #define PM2(Type, CName, JSName, MType) Type CName = 0;
210  NSOLID_PROCESS_METRICS_NUMBERS(PM2)
211 #undef PM2
212  // This is a duplicate of cpuPercent, for backwards compatibility.
213  double cpu = 0;
214  };
215 
221  std::string toJSON();
230  int Get(MetricsStor* stor);
237  int Update();
238 
239  private:
240  MetricsStor stor_;
241  uint64_t cpu_prev_[3];
242  uint64_t cpu_prev_time_;
243 };
244 
245 
250 class NODE_EXTERN ThreadMetrics {
251  public:
252  struct MetricsStor;
253  using thread_metrics_proxy_sig = void(*)(ThreadMetrics*);
254 
259  struct MetricsStor {
260 #define EM(Type, CName, JSName, MType) Type CName = 0;
261  NSOLID_ENV_METRICS(EM)
262 #undef EM
263  };
264 
271  explicit ThreadMetrics(uint64_t thread_id);
272  ThreadMetrics() = delete;
277  ~ThreadMetrics();
278 
279  // All these calls are thread-safe.
285  std::string toJSON();
294  int Get(MetricsStor* stor);
295  // The callback is called from the NSolid thread.
296  // signature: cb(ThreadMetrics*, ...Data)
307  template <typename Cb, typename... Data>
308  int Update(Cb&& cb, Data&&... data);
309 
310  private:
311  int get_thread_metrics_();
312  static void get_general_metrics_(void* inst, ThreadMetrics* tm);
313  static void get_heap_stats_(void* inst, ThreadMetrics* tm);
314  static void get_event_loop_stats_(void* inst, ThreadMetrics* tm);
315  static void get_http_dns_stats_(void* inst, ThreadMetrics* tm);
316  static void get_gc_stats_(void* inst, ThreadMetrics* tm);
317 
318  template <typename G>
319  static void thread_metrics_proxy_(ThreadMetrics* tm);
320 
321  uint64_t thread_id_ = 0xFFFFFFFFFFFFFFFF;
322  uint64_t prev_idle_time_ = 0;
323  uint64_t prev_call_time_;
324  uint64_t current_hrtime_;
325  void* user_data_ = nullptr;
326  thread_metrics_proxy_sig proxy_;
327 
328  uv_mutex_t stor_lock_;
329  MetricsStor stor_;
330 };
331 
332 
343 class NODE_EXTERN MetricsStream {
344  public:
351  enum class Type: uint32_t {
352  kRawDns = 1 << 0,
353  kRawHttpClient = 1 << 1,
354  kRawHttpServer = 1 << 2,
355  kRawGcRegular = 1 << 3,
356  kRawGcForced = 1 << 4,
357  kRawGcFull = 1 << 5,
358  kRawGcMajor = 1 << 6,
359  kRawGc = 120
360  };
361 
362  using metrics_stream_bucket = std::vector<std::tuple<Type, double>>;
363  using metrics_stream_proxy_sig = void(*)(MetricsStream*,
364  metrics_stream_bucket,
365  void*);
366 
373  explicit MetricsStream(uint64_t thread_id);
374  MetricsStream() = delete;
379  ~MetricsStream();
380 
381  // The callback is called from the NSolid thread.
382  // signature: cb(MetricsStream*, metrics_stream_bucket, ...Data)
402  template <typename Cb, typename... Data>
403  int Start(uint32_t flags,
404  uint64_t timeout,
405  uint32_t max_items,
406  Cb&& cb,
407  Data&&... data);
414  int Stop();
420  uint64_t ThreadId();
421 
422  private:
423  template <typename G>
424  static void metrics_stream_proxy_(MetricsStream*,
425  metrics_stream_bucket,
426  void*);
427  template <typename G>
428  static void deleter_(void*);
429 
430  int DoStart(uint32_t flags,
431  uint64_t timeout,
432  uint32_t max_items,
433  metrics_stream_proxy_sig,
434  void(*)(void*),
435  void* cb);
436 
437  class Impl;
438  std::unique_ptr<Impl> impl_;
439 };
440 
441 
446 class NODE_EXTERN CpuProfiler {
447  public:
448  using cpu_profiler_proxy_sig = void(*)(int, std::string, void*);
449 
463  template <typename Cb, typename... Data>
464  static int TakeProfile(uint64_t thread_id,
465  uint64_t duration,
466  Cb&& cb,
467  Data&&... data);
475  static int StopProfile(uint64_t thread_id);
476 
477  private:
478  static int get_cpu_profile_(uint64_t thread_id,
479  uint64_t duration,
480  cpu_profiler_proxy_sig proxy,
481  void* data);
482  template <typename G>
483  static void cpu_profiler_proxy_(int status, std::string json, void* data);
484 };
485 
486 
491 class NODE_EXTERN Snapshot {
492  public:
493  using snapshot_proxy_sig = void(*)(int, std::string, void*);
494 
506  template <typename Cb, typename... Data>
507  int TakeSnapshot(uint64_t thread_id, Cb&& cb, Data&&... data);
508 
509  private:
510  int get_snapshot_(uint64_t thread_id,
511  snapshot_proxy_sig proxy,
512  void* data);
513  template <typename G>
514  static void snapshot_proxy_(int status, std::string profile, void* data);
515 };
516 
517 
525 NODE_EXTERN int ModuleInfo(uint64_t thread_id, std::string* json);
534 NODE_EXTERN int ProcessInfo(std::string* json);
535 
536 
549 template <typename Cb, typename... Data>
550 NODE_EXTERN int OnBlockedLoopHook(uint64_t threshold, Cb&& cb, Data&&... data);
561 template <typename Cb, typename... Data>
562 NODE_EXTERN int OnUnblockedLoopHook(Cb&& cb, Data&&... data);
563 
564 
575 template <typename Cb, typename... Data>
576 NODE_EXTERN int ThreadAddedHook(Cb&& cb, Data&&... data);
588 template <typename Cb, typename... Data>
589 NODE_EXTERN int ThreadRemovedHook(Cb&& cb, Data&&... data);
590 
591 
602 template <typename Cb, typename... Data>
603 NODE_EXTERN int OnLicenseHook(Cb&& cb, Data&&... data);
609 NODE_EXTERN void License(std::string token);
615 NODE_EXTERN bool IsLicensed();
621 NODE_EXTERN uint64_t LicenseExpiration();
622 
629 NODE_EXTERN uint64_t ThreadId(v8::Local<v8::Context> context);
630 
631 
632 
633 // DEFINITIONS //
635 template <typename Cb, typename... Data>
636 int ThreadMetrics::Update(Cb&& cb, Data&&... data) {
637  // NOLINTNEXTLINE(build/namespaces)
638  using namespace std::placeholders;
639  using UserData = decltype(std::bind(
640  std::forward<Cb>(cb), _1, std::forward<Data>(data)...));
641 
642  // _1 - ThreadMetrics*
643  std::unique_ptr<UserData> user_data = std::make_unique<UserData>(std::bind(
644  std::forward<Cb>(cb), _1, std::forward<Data>(data)...));
645 
646  user_data_ = static_cast<void*>(user_data.get());
647  proxy_ = thread_metrics_proxy_<UserData>;
648  stor_.thread_id = thread_id_;
649 
650  int er = get_thread_metrics_();
651  if (!er)
652  user_data.release();
653  return er;
654 }
655 
656 
657 template <typename G>
658 void ThreadMetrics::thread_metrics_proxy_(ThreadMetrics* tm) {
659  G* g = static_cast<G*>(tm->user_data_);
660  tm->user_data_ = nullptr;
661  tm->proxy_ = nullptr;
662  (*g)(tm);
663  delete g;
664 }
665 
666 
667 template <typename Cb, typename... Data>
668 int MetricsStream::Start(uint32_t flags,
669  uint64_t timeout,
670  uint32_t max_items,
671  Cb&& cb,
672  Data&&... data) {
673  // NOLINTNEXTLINE(build/namespaces)
674  using namespace std::placeholders;
675  using UserData = decltype(std::bind(
676  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
677  // _1 - MetricsStream* metrics_stream
678  // _2 - metrics_stream_bucket bucket
679  UserData* user_data = new UserData(std::bind(
680  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
681  int err = DoStart(flags,
682  timeout,
683  max_items,
684  metrics_stream_proxy_<UserData>,
685  internal::delete_proxy_<UserData>,
686  static_cast<void*>(user_data));
687  if (err) {
688  delete user_data;
689  }
690 
691  return err;
692 }
693 
694 
695 template <typename G>
696 void MetricsStream::metrics_stream_proxy_(
697  MetricsStream* ms, metrics_stream_bucket bucket, void* g) {
698  (*static_cast<G*>(g))(ms, bucket);
699 }
700 
701 
702 template <typename Cb, typename... Data>
703 int CpuProfiler::TakeProfile(uint64_t thread_id,
704  uint64_t duration,
705  Cb&& cb,
706  Data&&... data) {
707  // NOLINTNEXTLINE(build/namespaces)
708  using namespace std::placeholders;
709  using UserData = decltype(std::bind(
710  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
711 
712  // _1 - int status
713  // _2 - std::string json
714  std::unique_ptr<UserData> user_data = std::make_unique<UserData>(std::bind(
715  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
716 
717  int er = get_cpu_profile_(thread_id,
718  duration,
719  cpu_profiler_proxy_<UserData>,
720  user_data.get());
721  if (!er)
722  user_data.release();
723  return er;
724 }
725 
726 
727 template <typename G>
728 void CpuProfiler::cpu_profiler_proxy_(int status,
729  std::string json,
730  void* data) {
731  (*static_cast<G*>(data))(status, json);
732  delete static_cast<G*>(data);
733 }
734 
735 
736 template <typename Cb, typename... Data>
737 int Snapshot::TakeSnapshot(uint64_t thread_id,
738  Cb&& cb,
739  Data&&... data) {
740  // NOLINTNEXTLINE(build/namespaces)
741  using namespace std::placeholders;
742  using UserData = decltype(std::bind(
743  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
744 
745  // _1 - int status
746  // _2 - std::string json
747  std::unique_ptr<UserData> user_data = std::make_unique<UserData>(std::bind(
748  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
749 
750  int er = get_snapshot_(thread_id,
751  snapshot_proxy_<UserData>,
752  user_data.get());
753  if (!er)
754  user_data.release();
755  return er;
756 }
757 
758 
759 template <typename G>
760 void Snapshot::snapshot_proxy_(int status, std::string profile, void* data) {
761  (*static_cast<G*>(data))(status, profile);
762  delete static_cast<G*>(data);
763 }
764 
765 
766 template <typename Cb, typename... Data>
767 int OnBlockedLoopHook(uint64_t threshold, Cb&& cb, Data&&... data) {
768  // NOLINTNEXTLINE(build/namespaces)
769  using namespace std::placeholders;
770  using UserData = decltype(std::bind(
771  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
772 
773  // _1 - uint64_t thread_id
774  // _2 - std::string info
775  std::unique_ptr<UserData> user_data = std::make_unique<UserData>(std::bind(
776  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
777 
778  int er = internal::on_block_loop_hook_(
779  threshold,
780  user_data.get(),
781  internal::on_block_loop_hook_proxy_<UserData>,
782  internal::delete_proxy_<UserData>);
783  if (!er)
784  user_data.release();
785  return er;
786 }
787 
788 
789 template <typename Cb, typename... Data>
790 int OnUnblockedLoopHook(Cb&& cb, Data&&... data) {
791  // NOLINTNEXTLINE(build/namespaces)
792  using namespace std::placeholders;
793  using UserData = decltype(std::bind(
794  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
795 
796  // _1 - uint64_t thread_id
797  // _2 - std::string info
798  std::unique_ptr<UserData> user_data = std::make_unique<UserData>(std::bind(
799  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
800 
801  int er = internal::on_unblock_loop_hook_(
802  user_data.get(),
803  internal::on_unblock_loop_hook_proxy_<UserData>,
804  internal::delete_proxy_<UserData>);
805  if (!er)
806  user_data.release();
807  return er;
808 }
809 
810 
811 template <typename Cb, typename... Data>
812 int ThreadAddedHook(Cb&& cb, Data&&... data) {
813  // NOLINTNEXTLINE(build/namespaces)
814  using namespace std::placeholders;
815  using UserData = decltype(std::bind(
816  std::forward<Cb>(cb), _1, std::forward<Data>(data)...));
817 
818  if (!IsLicensed())
819  return NSOLID_E_NOT_LICENSED;
820 
821  // _1 - uint64_t thread_id
822  std::unique_ptr<UserData> user_data = std::make_unique<UserData>(std::bind(
823  std::forward<Cb>(cb), _1, std::forward<Data>(data)...));
824 
825  int er = internal::thread_added_hook_(
826  user_data.get(),
827  internal::thread_added_hook_proxy_<UserData>,
828  internal::delete_proxy_<UserData>);
829  if (!er)
830  user_data.release();
831  return er;
832 }
833 
834 
835 template <typename Cb, typename... Data>
836 int ThreadRemovedHook(Cb&& cb, Data&&... data) {
837  // NOLINTNEXTLINE(build/namespaces)
838  using namespace std::placeholders;
839  using UserData = decltype(std::bind(
840  std::forward<Cb>(cb), _1, std::forward<Data>(data)...));
841 
842  if (!IsLicensed())
843  return NSOLID_E_NOT_LICENSED;
844 
845  // _1 - uint64_t thread_id
846  std::unique_ptr<UserData> user_data = std::make_unique<UserData>(std::bind(
847  std::forward<Cb>(cb), _1, std::forward<Data>(data)...));
848 
849  int er = internal::thread_removed_hook_(
850  user_data.get(),
851  internal::thread_removed_hook_proxy_<UserData>,
852  internal::delete_proxy_<UserData>);
853  if (!er)
854  user_data.release();
855  return er;
856 }
857 
858 
859 template <typename Cb, typename... Data>
860 int OnLicenseHook(Cb&& cb, Data&&... data) {
861  // NOLINTNEXTLINE(build/namespaces)
862  using namespace std::placeholders;
863  using UserData = decltype(std::bind(
864  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
865 
866  // _1 - bool licensed
867  // _2 - uint64_t expiration
868  UserData* user_data = new UserData(std::bind(
869  std::forward<Cb>(cb), _1, _2, std::forward<Data>(data)...));
870 
871  internal::SetOnLicenseHook(internal::license_hook_proxy_<UserData>,
872  user_data,
873  internal::delete_proxy_<UserData>);
874  return 0;
875 }
876 
877 
878 namespace internal {
879 
880 template <typename G>
881 void on_block_loop_hook_proxy_(uint64_t thread_id,
882  std::string info,
883  void* data) {
884  (*static_cast<G*>(data))(thread_id, info);
885 }
886 
887 template <typename G>
888 void on_unblock_loop_hook_proxy_(uint64_t thread_id,
889  std::string info,
890  void* data) {
891  (*static_cast<G*>(data))(thread_id, info);
892 }
893 
894 template <typename G>
895 void thread_added_hook_proxy_(uint64_t thread_id, void* data) {
896  (*static_cast<G*>(data))(thread_id);
897 }
898 
899 template <typename G>
900 void thread_removed_hook_proxy_(uint64_t thread_id, void* data) {
901  (*static_cast<G*>(data))(thread_id);
902 }
903 
904 template <typename G>
905 void license_hook_proxy_(bool licensed, uint64_t expiration, void* g) {
906  (*static_cast<G*>(g))(licensed, expiration);
907 }
908 
909 template <typename G>
910 void delete_proxy_(void* g) {
911  delete static_cast<G*>(g);
912 }
913 
914 } // namespace internal
917 } // namespace nsolid
918 } // namespace node
919 
920 #endif // SRC_NSOLID_H_
node::nsolid::NSolidErr
NSolidErr
List of errors returned by N|Solid C++ API.
Definition: nsolid.h:117
node::nsolid::IsLicensed
bool IsLicensed()
node::nsolid::CpuProfiler::TakeProfile
static int TakeProfile(uint64_t thread_id, uint64_t duration, Cb &&cb, Data &&... data)
allows taking a CPU profile from a specific JS thread for a period of time. Only 1 concurrent profile...
node::nsolid::ProcessInfo
int ProcessInfo(std::string *json)
returns relevant information about the running process and platform is running on.
node::nsolid::ThreadMetrics::Update
int Update(Cb &&cb, Data &&... data)
Calculates and stores the N|Solid JS thread metrics. A callback is called when the retrieval has comp...
node::nsolid::LicenseExpiration
uint64_t LicenseExpiration()
returns the expiration of the license in milliseconds since unix epoch or zero in case the runtime is...
node::nsolid::OnUnblockedLoopHook
int OnUnblockedLoopHook(Cb &&cb, Data &&... data)
Register a hook(function) to be called when the event loop moves from the blocked-loop state to not b...
node::nsolid::CpuProfiler
class that allows to take CPU profiles from a specific JS thread.
Definition: nsolid.h:441
node::nsolid::MetricsStream::Start
int Start(uint32_t flags, uint64_t timeout, uint32_t max_items, Cb &&cb, Data &&... data)
start collecting specific metrics.
node::nsolid::ModuleInfo
int ModuleInfo(uint64_t thread_id, std::string *json)
to retrieve the list of packages used by the process
node::nsolid::License
void License(std::string token)
configures a license in the N|Solid runtime
node::nsolid::ThreadId
uint64_t ThreadId(v8::Local< v8::Context > context)
returns the thread id from a specific v8::Context
node::nsolid::Snapshot::TakeSnapshot
int TakeSnapshot(uint64_t thread_id, Cb &&cb, Data &&... data)
allows taking a heap snapshot from a specific JS thread. Only 1 concurrent snapshot per thread can be...
node
node namespace
Definition: nsolid.h:20
node::nsolid::OnLicenseHook
int OnLicenseHook(Cb &&cb, Data &&... data)
Register a hook(function) to be called any time a license is set up in the N|Solid runtime.
node::nsolid::ThreadRemovedHook
int ThreadRemovedHook(Cb &&cb, Data &&... data)
Register a hook(function) to be called any time a JS thread is destroyed.
node::nsolid::OnBlockedLoopHook
int OnBlockedLoopHook(uint64_t threshold, Cb &&cb, Data &&... data)
Register a hook(function) to be called when the event loop of any of the active JS threads is blocked...
node::nsolid::ThreadAddedHook
int ThreadAddedHook(Cb &&cb, Data &&... data)
Register a hook(function) to be called any time a JS thread is created.
node::nsolid::MetricsType
MetricsType
Defines the types of metrics supported.
Definition: nsolid.h:174
node::nsolid::Snapshot
class that allows taking heap snapshots from a specific JS thread.
Definition: nsolid.h:486