all.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #pragma once
  2. #include "control.h"
  3. #include "event.h"
  4. #include "preprocessor.h"
  5. #include "probe.h"
  6. #include "start.h"
  7. //
  8. // Full documentation: https://wiki.yandex-team.ru/development/poisk/arcadia/library/lwtrace/
  9. //
  10. // Short usage instruction:
  11. //
  12. // 1. Declare probes provider in header file 'probes.h':
  13. // #include <yweb/robot/kiwi/lwtrace/all.h>
  14. // #define MY_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \ // name of your provider
  15. // PROBE(MyProbe, GROUPS("MyGroup1", "MyGroup2"), TYPES(), NAMES()) \ // probe specification w/o argiments
  16. // PROBE(MyAnotherProbe, GROUPS("MyGroup2"), TYPES(int, TString), NAMES("arg1", "arg2")) \ // another probe with arguments
  17. // PROBE(MyScopedProbe, GROUPS(), TYPES(ui64, int), NAMES("duration", "stage")) \ // scoped probe with argument
  18. // /**/
  19. // LWTRACE_DECLARE_PROVIDER(MY_PROVIDER)
  20. //
  21. // 2. Define provider in source file 'provider.cpp':
  22. // #include "probes.h"
  23. // LWTRACE_DEFINE_PROVIDER(MY_PROVIDER)
  24. //
  25. // 3. Call probes from provider in your code:
  26. // #include "probes.h"
  27. // int main() {
  28. // GLOBAL_LWPROBE(MY_PROVIDER, MyProbe);
  29. // GLOBAL_LWPROBE(MY_PROVIDER, MyAnotherProbe, 123, stroka);
  30. // ... or ...
  31. // LWTRACE_USING(MY_PROVIDER); // expands into using namespace
  32. // LWPROBE(MyProbe);
  33. // LWPROBE(MyAnotherProbe, 123, stroka);
  34. // }
  35. //
  36. // 4. Attach provider to your monitoring service:
  37. // #include <yweb/robot/kiwi/util/monservice.h>
  38. // #include "probes.h"
  39. // class TMyMonSrvc: public NKiwi::TMonService {
  40. // TMyMonSrvc(TProbeRegistry& probes)
  41. // {
  42. // THolder<NKiwi::TTraceMonPage> tr(new NKiwi::TTraceMonPage());
  43. // tr->GetProbes().AddProbesList(LWTRACE_GET_PROBES(MY_PROVIDER));
  44. // Register(tr.Release());
  45. // }
  46. // };
  47. //
  48. // 5. Compile and run application
  49. //
  50. // 6. Create file 'mysuper.tr' with trace query:
  51. // Blocks { # Log all calls to probes from MyGroup1
  52. // ProbeDesc { Group: "MyGroup1" }
  53. // Action {
  54. // LogAction { LogTimestamp: true }
  55. // }
  56. // }
  57. // Blocks { # Log first 10 calls to MyAnother with arg1 > 1000
  58. // ProbeDesc { Name: "MyAnotherProbe"; Provider: "MY_PROVIDER" }
  59. // Predicate {
  60. // Operators { Type: OT_GT; Param: "arg1"; Value: "1000" }
  61. // }
  62. // Action {
  63. // LogAction { MaxRecords: 10 }
  64. // }
  65. // }
  66. // Blocks { # Start following executon of all 4 blocks each time MyAnotherProbe was called with arg2 == "start"
  67. // ProbeDesc { Name: "MyAnotherProbe"; Provider: "MY_PROVIDER" }
  68. // Predicate {
  69. // Operators { Type: OT_EQ; Param: "arg2"; Value: "start" }
  70. // }
  71. // Action { StartAction {} }
  72. // }
  73. // Blocks { # Stop following executon of all 4 blocks each time MyAnotherProbe was called with arg2 == "stop"
  74. // ProbeDesc { Name: "MyAnotherProbe"; Provider: "MY_PROVIDER" }
  75. // Predicate {
  76. // Operators { Type: OT_EQ; Param: "arg2"; Value: "stop" }
  77. // }
  78. // Action { StopAction {} }
  79. // }
  80. //
  81. // 7. Send trace query to the server with HTTP POST:
  82. // yweb/robot/kiwi/scripts/trace.sh new uniq-id-for-my-trace hostname:monport < mysuper.tr
  83. //
  84. // 8. With browser go to: http://hostname:monport/trace
  85. //
  86. // 9. Delete query from server:
  87. // yweb/robot/kiwi/scripts/trace.sh delete uniq-id-for-my-trace hostname:monport
  88. //
  89. //
  90. // CONFIGURATION AND SUPPORT:
  91. // 1. Turning off all calls to probes.
  92. // Add to project's CMakeLists.txt: add_definitions(-DLWTRACE_DISABLE_PROBES)
  93. //
  94. // 2. Turning off all calls to events.
  95. // Add to project's CMakeLists.txt: add_definitions(-DLWTRACE_DISABLE_EVENTS)
  96. //
  97. // 3. Increasing maximum number of probe parameters:
  98. // Add more lines in FOREACH_PARAMNUM macro definition in preprocessor.h
  99. //
  100. //
  101. // ISSUES
  102. // 1. Note that executors for different blocks are attached in order of their declaration in trace script.
  103. // Executor can be called by a program as soon as it is attached, therefore there is no guarantee that
  104. // all blocks are started simultaneously
  105. //
  106. #ifndef LWTRACE_DISABLE
  107. // Declare user provider (see USAGE INSTRUCTION)
  108. #define LWTRACE_DECLARE_PROVIDER(provider) LWTRACE_DECLARE_PROVIDER_I(provider)
  109. // Define user provider (see USAGE INSTRUCTION)
  110. #define LWTRACE_DEFINE_PROVIDER(provider) LWTRACE_DEFINE_PROVIDER_I(provider)
  111. // Import names from provider
  112. #define LWTRACE_USING(provider) using namespace LWTRACE_GET_NAMESPACE(provider);
  113. // Probes and events list accessor
  114. #define LWTRACE_GET_PROBES(provider) LWTRACE_GET_PROBES_I(provider)
  115. #define LWTRACE_GET_EVENTS(provider) LWTRACE_GET_EVENTS_I(provider)
  116. #ifndef LWTRACE_DISABLE_PROBES
  117. // Call a probe
  118. // NOTE: LWPROBE() should be used in source files only with previous call to LWTRACE_USING(MY_PROVIDER)
  119. // NOTE: in header files GLOBAL_LWPROBE() should be used instead
  120. // NOTE: if lots of calls needed in header file, it's convenient to define/undef the following macro:
  121. // NOTE: #define MY_PROBE(name, ...) GLOBAL_LWPROBE(MY_PROVIDER, name, ## __VA_ARGS__)
  122. #define GLOBAL_LWPROBE(provider, probe, ...) LWPROBE_I(LWTRACE_GET_NAMESPACE(provider)::LWTRACE_GET_NAME(probe), ##__VA_ARGS__)
  123. #define LWPROBE(probe, ...) LWPROBE_I(LWTRACE_GET_NAME(probe), ##__VA_ARGS__)
  124. #define GLOBAL_LWPROBE_ENABLED(provider, probe) LWPROBE_ENABLED_I(LWTRACE_GET_NAMESPACE(provider)::LWTRACE_GET_NAME(probe))
  125. #define LWPROBE_ENABLED(probe) LWPROBE_ENABLED_I(LWTRACE_GET_NAME(probe))
  126. #define LWPROBE_OBJ(probe, ...) LWPROBE_I(probe, ##__VA_ARGS__)
  127. // Calls a probe when scope is beeing left
  128. // NOTE: arguments are passed by value and stored until scope exit
  129. // NOTE: probe should be declared with first params of type ui64, argument for which is automaticaly generated (duration in microseconds)
  130. // NOTE: *_DURATION() macros take through "..." all arguments except the first one
  131. #define GLOBAL_LWPROBE_DURATION(provider, probe, ...) LWPROBE_DURATION_I(LWTRACE_GET_NAMESPACE(provider)::LWTRACE_GET_TYPE(probe), lwtrace_scoped_##provider##probe, LWTRACE_GET_NAMESPACE(provider)::LWTRACE_GET_NAME(probe), ##__VA_ARGS__)
  132. #define LWPROBE_DURATION(probe, ...) LWPROBE_DURATION_I(LWTRACE_GET_TYPE(probe), lwtrace_scoped_##probe, LWTRACE_GET_NAME(probe), ##__VA_ARGS__)
  133. // Probe with orbit support
  134. #define GLOBAL_LWTRACK(provider, probe, orbit, ...) LWTRACK_I(LWTRACE_GET_NAMESPACE(provider)::LWTRACE_GET_NAME(probe), orbit, ##__VA_ARGS__)
  135. #define LWTRACK(probe, orbit, ...) LWTRACK_I(LWTRACE_GET_NAME(probe), orbit, ##__VA_ARGS__)
  136. #define LWTRACK_OBJ(probe, orbit, ...) LWTRACK_I(probe, orbit, ##__VA_ARGS__)
  137. #else
  138. #define GLOBAL_LWPROBE(provider, probe, ...)
  139. #define LWPROBE(probe, ...)
  140. #define GLOBAL_LWPROBE_ENABLED(provider, probe) false
  141. #define LWPROBE_ENABLED(probe) false
  142. #define LWPROBE_OBJ(probe, ...) Y_UNUSED(probe)
  143. #define GLOBAL_LWPROBE_DURATION(provider, probe, ...)
  144. #define LWPROBE_DURATION(probe, ...)
  145. #define GLOBAL_LWTRACK(provider, probe, orbit, ...)
  146. #define LWTRACK(probe, orbit, ...)
  147. #define LWTRACK_OBJ(probe, orbit, ...) Y_UNUSED(probe)
  148. #endif
  149. #ifndef LWTRACE_DISABLE_EVENTS
  150. // Call an event
  151. // NOTE: LWEVENT() should be used in source files only with previous call to LWTRACE_USING(MY_PROVIDER)
  152. // NOTE: in header files GLOBAL_LWEVENT() should be used instead
  153. // NOTE: if lots of calls needed in header file, it's convenient to define/undef the following macro:
  154. // NOTE: #define MY_EVENT(name, ...) GLOBAL_LWEVENT(MY_PROVIDER, name, ## __VA_ARGS__)
  155. #define GLOBAL_LWEVENT(provider, event, ...) LWEVENT_I(LWTRACE_GET_NAMESPACE(provider)::LWTRACE_GET_NAME(event), ##__VA_ARGS__)
  156. #define LWEVENT(event, ...) LWEVENT_I(LWTRACE_GET_NAME(event), ##__VA_ARGS__)
  157. #else
  158. #define GLOBAL_LWEVENT(provider, event, ...)
  159. #define LWEVENT(event, ...)
  160. #endif
  161. #else
  162. #define LWTRACE_DECLARE_PROVIDER(provider)
  163. #define LWTRACE_DEFINE_PROVIDER(provider)
  164. #define LWTRACE_USING(provider)
  165. #define LWTRACE_GET_PROBES(provider) NULL
  166. #define LWTRACE_GET_EVENTS(provider) NULL
  167. #define GLOBAL_LWPROBE(provider, probe, ...)
  168. #define LWPROBE(probe, ...)
  169. #define GLOBAL_LWPROBE_ENABLED(provider, probe) false
  170. #define LWPROBE_ENABLED(probe) false
  171. #define GLOBAL_LWPROBE_DURATION(provider, probe, ...)
  172. #define LWPROBE_DURATION(probe, ...)
  173. #define GLOBAL_LWTRACK(provider, probe, orbit, ...)
  174. #define LWTRACK(probe, orbit, ...)
  175. #define GLOBAL_LWEVENT(provider, event, ...)
  176. #define LWEVENT(event, ...)
  177. #endif