span.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. // NOTE: RPC users are not supposed to include this file.
  18. #ifndef BRPC_SPAN_H
  19. #define BRPC_SPAN_H
  20. #include <stdint.h>
  21. #include <string>
  22. #include <deque>
  23. #include <ostream>
  24. #include "butil/macros.h"
  25. #include "butil/endpoint.h"
  26. #include "butil/string_splitter.h"
  27. #include "bvar/collector.h"
  28. #include "bthread/task_meta.h"
  29. #include "brpc/options.pb.h" // ProtocolType
  30. #include "brpc/span.pb.h"
  31. namespace bthread {
  32. extern thread_local bthread::LocalStorage tls_bls;
  33. }
  34. namespace brpc {
  35. DECLARE_bool(enable_rpcz);
  36. // Collect information required by /rpcz and tracing system whose idea is
  37. // described in http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36356.pdf
  38. class Span : public bvar::Collected {
  39. friend class SpanDB;
  40. struct Forbidden {};
  41. public:
  42. // Call CreateServerSpan/CreateClientSpan instead.
  43. Span(Forbidden) {}
  44. ~Span() {}
  45. // Create a span to track a request inside server.
  46. static Span* CreateServerSpan(
  47. const std::string& full_method_name,
  48. uint64_t trace_id, uint64_t span_id, uint64_t parent_span_id,
  49. int64_t base_real_us);
  50. // Create a span without name to track a request inside server.
  51. static Span* CreateServerSpan(
  52. uint64_t trace_id, uint64_t span_id, uint64_t parent_span_id,
  53. int64_t base_real_us);
  54. // Clear all annotations and reset name of the span.
  55. void ResetServerSpanName(const std::string& name);
  56. // Create a span to track a request inside channel.
  57. static Span* CreateClientSpan(const std::string& full_method_name,
  58. int64_t base_real_us);
  59. static void Submit(Span* span, int64_t cpuwide_time_us);
  60. // Set tls parent.
  61. void AsParent() {
  62. bthread::tls_bls.rpcz_parent_span = this;
  63. }
  64. // Add log with time.
  65. void Annotate(const char* fmt, ...);
  66. void Annotate(const char* fmt, va_list args);
  67. void Annotate(const std::string& info);
  68. // When length <= 0, use strlen instead.
  69. void AnnotateCStr(const char* cstr, size_t length);
  70. // #child spans, Not O(1)
  71. size_t CountClientSpans() const;
  72. int64_t GetStartRealTimeUs() const;
  73. int64_t GetEndRealTimeUs() const;
  74. void set_log_id(uint64_t cid) { _log_id = cid; }
  75. void set_base_cid(bthread_id_t id) { _base_cid = id; }
  76. void set_ending_cid(bthread_id_t id) { _ending_cid = id; }
  77. void set_remote_side(const butil::EndPoint& pt) { _remote_side = pt; }
  78. void set_protocol(ProtocolType p) { _protocol = p; }
  79. void set_error_code(int error_code) { _error_code = error_code; }
  80. void set_request_size(int size) { _request_size = size; }
  81. void set_response_size(int size) { _response_size = size; }
  82. void set_async(bool async) { _async = async; }
  83. void set_base_real_us(int64_t tm) { _base_real_us = tm; }
  84. void set_received_us(int64_t tm)
  85. { _received_real_us = tm + _base_real_us; }
  86. void set_start_parse_us(int64_t tm)
  87. { _start_parse_real_us = tm + _base_real_us; }
  88. void set_start_callback_us(int64_t tm)
  89. { _start_callback_real_us = tm + _base_real_us; }
  90. void set_start_send_us(int64_t tm)
  91. { _start_send_real_us = tm + _base_real_us; }
  92. void set_sent_us(int64_t tm)
  93. { _sent_real_us = tm + _base_real_us; }
  94. Span* local_parent() const { return _local_parent; }
  95. static Span* tls_parent() {
  96. return (Span*)bthread::tls_bls.rpcz_parent_span;
  97. }
  98. uint64_t trace_id() const { return _trace_id; }
  99. uint64_t parent_span_id() const { return _parent_span_id; }
  100. uint64_t span_id() const { return _span_id; }
  101. uint64_t log_id() const { return _log_id; }
  102. bthread_id_t base_cid() const { return _base_cid; }
  103. bthread_id_t ending_cid() const { return _ending_cid; }
  104. const butil::EndPoint& remote_side() const { return _remote_side; }
  105. SpanType type() const { return _type; }
  106. ProtocolType protocol() const { return _protocol; }
  107. int error_code() const { return _error_code; }
  108. int request_size() const { return _request_size; }
  109. int response_size() const { return _response_size; }
  110. int64_t received_real_us() const { return _received_real_us; }
  111. int64_t start_parse_real_us() const { return _start_parse_real_us; }
  112. int64_t start_callback_real_us() const { return _start_callback_real_us; }
  113. int64_t start_send_real_us() const { return _start_send_real_us; }
  114. int64_t sent_real_us() const { return _sent_real_us; }
  115. bool async() const { return _async; }
  116. const std::string& full_method_name() const { return _full_method_name; }
  117. const std::string& info() const { return _info; }
  118. private:
  119. DISALLOW_COPY_AND_ASSIGN(Span);
  120. void dump_and_destroy(size_t round_index);
  121. void destroy();
  122. bvar::CollectorSpeedLimit* speed_limit();
  123. bvar::CollectorPreprocessor* preprocessor();
  124. void EndAsParent() {
  125. if (this == (Span*)bthread::tls_bls.rpcz_parent_span) {
  126. bthread::tls_bls.rpcz_parent_span = NULL;
  127. }
  128. }
  129. uint64_t _trace_id;
  130. uint64_t _span_id;
  131. uint64_t _parent_span_id;
  132. uint64_t _log_id;
  133. bthread_id_t _base_cid;
  134. bthread_id_t _ending_cid;
  135. butil::EndPoint _remote_side;
  136. SpanType _type;
  137. bool _async;
  138. ProtocolType _protocol;
  139. int _error_code;
  140. int _request_size;
  141. int _response_size;
  142. int64_t _base_real_us;
  143. int64_t _received_real_us;
  144. int64_t _start_parse_real_us;
  145. int64_t _start_callback_real_us;
  146. int64_t _start_send_real_us;
  147. int64_t _sent_real_us;
  148. std::string _full_method_name;
  149. // Format:
  150. // time1_us \s annotation1 <SEP>
  151. // time2_us \s annotation2 <SEP>
  152. // ...
  153. std::string _info;
  154. Span* _local_parent;
  155. Span* _next_client;
  156. Span* _tls_next;
  157. };
  158. // Extract name and annotations from Span::info()
  159. class SpanInfoExtractor {
  160. public:
  161. SpanInfoExtractor(const char* info);
  162. bool PopAnnotation(int64_t before_this_time,
  163. int64_t* time, std::string* annotation);
  164. private:
  165. butil::StringSplitter _sp;
  166. };
  167. // These two functions can be used for composing TRACEPRINT as well as hiding
  168. // span implementations.
  169. bool CanAnnotateSpan();
  170. void AnnotateSpan(const char* fmt, ...);
  171. class SpanFilter {
  172. public:
  173. virtual bool Keep(const BriefSpan&) = 0;
  174. };
  175. class SpanDB;
  176. // Find a span by its trace_id and span_id, serialize it into `span'.
  177. int FindSpan(uint64_t trace_id, uint64_t span_id, RpczSpan* span);
  178. // Find spans by their trace_id, serialize them into `out'
  179. void FindSpans(uint64_t trace_id, std::deque<RpczSpan>* out);
  180. // Put at most `max_scan' spans before `before_this_time' into `out'.
  181. // If filter is not NULL, only push spans that make SpanFilter::Keep()
  182. // true.
  183. void ListSpans(int64_t before_this_time, size_t max_scan,
  184. std::deque<BriefSpan>* out, SpanFilter* filter);
  185. void DescribeSpanDB(std::ostream& os);
  186. SpanDB* LoadSpanDBFromFile(const char* filepath);
  187. int FindSpan(SpanDB* db, uint64_t trace_id, uint64_t span_id, RpczSpan* span);
  188. void FindSpans(SpanDB* db, uint64_t trace_id, std::deque<RpczSpan>* out);
  189. void ListSpans(SpanDB* db, int64_t before_this_time, size_t max_scan,
  190. std::deque<BriefSpan>* out, SpanFilter* filter);
  191. // Check this function first before creating a span.
  192. // If rpcz of upstream is enabled, local rpcz is enabled automatically.
  193. inline bool IsTraceable(bool is_upstream_traced) {
  194. extern bvar::CollectorSpeedLimit g_span_sl;
  195. return is_upstream_traced ||
  196. (FLAGS_enable_rpcz && bvar::is_collectable(&g_span_sl));
  197. }
  198. } // namespace brpc
  199. #endif // BRPC_SPAN_H