appoptics_apm 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (226) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +43 -0
  3. data/.dockerignore +5 -0
  4. data/.gitignore +23 -0
  5. data/.rubocop.yml +5 -0
  6. data/.travis.yml +82 -0
  7. data/CHANGELOG.md +769 -0
  8. data/CONFIG.md +33 -0
  9. data/Dockerfile +41 -0
  10. data/Dockerfile_test +66 -0
  11. data/Gemfile +41 -0
  12. data/LICENSE +193 -0
  13. data/README.md +351 -0
  14. data/Rakefile +202 -0
  15. data/Vagrantfile +67 -0
  16. data/appoptics_apm.gemspec +55 -0
  17. data/build_gems.sh +15 -0
  18. data/docker-compose.yml +73 -0
  19. data/examples/DNT.md +35 -0
  20. data/examples/carrying_context.rb +220 -0
  21. data/examples/instrumenting_metal_controller.rb +8 -0
  22. data/examples/puma_on_heroku_config.rb +17 -0
  23. data/examples/tracing_async_threads.rb +124 -0
  24. data/examples/tracing_background_jobs.rb +53 -0
  25. data/examples/tracing_forked_processes.rb +99 -0
  26. data/examples/unicorn_on_heroku_config.rb +28 -0
  27. data/ext/oboe_metal/extconf.rb +54 -0
  28. data/ext/oboe_metal/lib/.keep +0 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0.so.0.0.0 +0 -0
  30. data/ext/oboe_metal/noop/noop.c +7 -0
  31. data/ext/oboe_metal/src/VERSION +1 -0
  32. data/ext/oboe_metal/src/bson/bson.h +221 -0
  33. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  34. data/ext/oboe_metal/src/oboe.h +883 -0
  35. data/ext/oboe_metal/src/oboe.hpp +793 -0
  36. data/ext/oboe_metal/src/oboe_debug.h +50 -0
  37. data/ext/oboe_metal/src/oboe_wrap.cxx +6088 -0
  38. data/ext/oboe_metal/tests/test.rb +11 -0
  39. data/gemfiles/delayed_job.gemfile +36 -0
  40. data/gemfiles/frameworks.gemfile +44 -0
  41. data/gemfiles/instrumentation_mocked.gemfile +29 -0
  42. data/gemfiles/libraries.gemfile +85 -0
  43. data/gemfiles/rails23.gemfile +39 -0
  44. data/gemfiles/rails30.gemfile +42 -0
  45. data/gemfiles/rails31.gemfile +44 -0
  46. data/gemfiles/rails32.gemfile +54 -0
  47. data/gemfiles/rails40.gemfile +27 -0
  48. data/gemfiles/rails41.gemfile +27 -0
  49. data/gemfiles/rails42.gemfile +35 -0
  50. data/gemfiles/rails50.gemfile +44 -0
  51. data/gemfiles/rails51.gemfile +44 -0
  52. data/get_version.rb +5 -0
  53. data/init.rb +4 -0
  54. data/lib/appoptics_apm/api/layerinit.rb +39 -0
  55. data/lib/appoptics_apm/api/logging.rb +359 -0
  56. data/lib/appoptics_apm/api/memcache.rb +34 -0
  57. data/lib/appoptics_apm/api/profiling.rb +201 -0
  58. data/lib/appoptics_apm/api/tracing.rb +152 -0
  59. data/lib/appoptics_apm/api/util.rb +128 -0
  60. data/lib/appoptics_apm/api.rb +18 -0
  61. data/lib/appoptics_apm/base.rb +252 -0
  62. data/lib/appoptics_apm/config.rb +281 -0
  63. data/lib/appoptics_apm/frameworks/grape.rb +93 -0
  64. data/lib/appoptics_apm/frameworks/padrino/templates.rb +58 -0
  65. data/lib/appoptics_apm/frameworks/padrino.rb +52 -0
  66. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +106 -0
  67. data/lib/appoptics_apm/frameworks/rails/inst/action_controller2.rb +61 -0
  68. data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +58 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_view_2x.rb +56 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
  75. data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
  76. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  77. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +120 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +101 -0
  81. data/lib/appoptics_apm/frameworks/rails.rb +116 -0
  82. data/lib/appoptics_apm/frameworks/sinatra/templates.rb +56 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +71 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +92 -0
  86. data/lib/appoptics_apm/inst/curb.rb +329 -0
  87. data/lib/appoptics_apm/inst/dalli.rb +85 -0
  88. data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
  89. data/lib/appoptics_apm/inst/em-http-request.rb +105 -0
  90. data/lib/appoptics_apm/inst/excon.rb +130 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +77 -0
  92. data/lib/appoptics_apm/inst/http.rb +83 -0
  93. data/lib/appoptics_apm/inst/httpclient.rb +176 -0
  94. data/lib/appoptics_apm/inst/memcache.rb +102 -0
  95. data/lib/appoptics_apm/inst/memcached.rb +94 -0
  96. data/lib/appoptics_apm/inst/mongo.rb +242 -0
  97. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  98. data/lib/appoptics_apm/inst/moped.rb +466 -0
  99. data/lib/appoptics_apm/inst/rack.rb +146 -0
  100. data/lib/appoptics_apm/inst/redis.rb +275 -0
  101. data/lib/appoptics_apm/inst/resque.rb +151 -0
  102. data/lib/appoptics_apm/inst/rest-client.rb +50 -0
  103. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  104. data/lib/appoptics_apm/inst/sidekiq-client.rb +53 -0
  105. data/lib/appoptics_apm/inst/sidekiq-worker.rb +67 -0
  106. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  107. data/lib/appoptics_apm/inst/typhoeus.rb +113 -0
  108. data/lib/appoptics_apm/instrumentation.rb +22 -0
  109. data/lib/appoptics_apm/legacy_method_profiling.rb +97 -0
  110. data/lib/appoptics_apm/loading.rb +66 -0
  111. data/lib/appoptics_apm/logger.rb +41 -0
  112. data/lib/appoptics_apm/method_profiling.rb +33 -0
  113. data/lib/appoptics_apm/ruby.rb +35 -0
  114. data/lib/appoptics_apm/support.rb +135 -0
  115. data/lib/appoptics_apm/test.rb +94 -0
  116. data/lib/appoptics_apm/thread_local.rb +26 -0
  117. data/lib/appoptics_apm/util.rb +312 -0
  118. data/lib/appoptics_apm/version.rb +15 -0
  119. data/lib/appoptics_apm/xtrace.rb +103 -0
  120. data/lib/appoptics_apm.rb +72 -0
  121. data/lib/joboe_metal.rb +214 -0
  122. data/lib/oboe/README +2 -0
  123. data/lib/oboe/backward_compatibility.rb +80 -0
  124. data/lib/oboe/inst/rack.rb +11 -0
  125. data/lib/oboe.rb +7 -0
  126. data/lib/oboe_metal.rb +187 -0
  127. data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
  128. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +222 -0
  129. data/ruby_setup.sh +47 -0
  130. data/run_docker_build_gem_upload_to_packagecloud.sh +20 -0
  131. data/run_tests_docker.rb +32 -0
  132. data/test/benchmark/README.md +65 -0
  133. data/test/benchmark/logging_bench.rb +54 -0
  134. data/test/benchmark/with_libraries_gemfile/bunny_bench.rb +69 -0
  135. data/test/benchmark/with_rails5x_gemfile/action_controller5x_bench.rb +43 -0
  136. data/test/frameworks/apps/grape_nested.rb +33 -0
  137. data/test/frameworks/apps/grape_simple.rb +80 -0
  138. data/test/frameworks/apps/padrino_simple.rb +80 -0
  139. data/test/frameworks/apps/sinatra_simple.rb +55 -0
  140. data/test/frameworks/grape_test.rb +286 -0
  141. data/test/frameworks/padrino_test.rb +222 -0
  142. data/test/frameworks/rails3x_test.rb +554 -0
  143. data/test/frameworks/rails4x_test.rb +570 -0
  144. data/test/frameworks/rails5x_api_test.rb +210 -0
  145. data/test/frameworks/rails5x_test.rb +376 -0
  146. data/test/frameworks/rails_shared_tests.rb +172 -0
  147. data/test/frameworks/sinatra_test.rb +140 -0
  148. data/test/instrumentation/bunny_client_test.rb +276 -0
  149. data/test/instrumentation/bunny_consumer_test.rb +204 -0
  150. data/test/instrumentation/curb_test.rb +398 -0
  151. data/test/instrumentation/dalli_test.rb +177 -0
  152. data/test/instrumentation/em_http_request_test.rb +89 -0
  153. data/test/instrumentation/excon_test.rb +231 -0
  154. data/test/instrumentation/faraday_test.rb +228 -0
  155. data/test/instrumentation/http_test.rb +143 -0
  156. data/test/instrumentation/httpclient_test.rb +320 -0
  157. data/test/instrumentation/memcache_test.rb +260 -0
  158. data/test/instrumentation/memcached_test.rb +229 -0
  159. data/test/instrumentation/mongo_v1_test.rb +479 -0
  160. data/test/instrumentation/mongo_v2_index_test.rb +124 -0
  161. data/test/instrumentation/mongo_v2_test.rb +584 -0
  162. data/test/instrumentation/mongo_v2_view_test.rb +435 -0
  163. data/test/instrumentation/moped_test.rb +517 -0
  164. data/test/instrumentation/rack_test.rb +165 -0
  165. data/test/instrumentation/redis_hashes_test.rb +268 -0
  166. data/test/instrumentation/redis_keys_test.rb +321 -0
  167. data/test/instrumentation/redis_lists_test.rb +310 -0
  168. data/test/instrumentation/redis_misc_test.rb +163 -0
  169. data/test/instrumentation/redis_sets_test.rb +296 -0
  170. data/test/instrumentation/redis_sortedsets_test.rb +328 -0
  171. data/test/instrumentation/redis_strings_test.rb +349 -0
  172. data/test/instrumentation/resque_test.rb +185 -0
  173. data/test/instrumentation/rest-client_test.rb +288 -0
  174. data/test/instrumentation/sequel_mysql2_test.rb +353 -0
  175. data/test/instrumentation/sequel_mysql_test.rb +334 -0
  176. data/test/instrumentation/sequel_pg_test.rb +336 -0
  177. data/test/instrumentation/sidekiq-client_test.rb +159 -0
  178. data/test/instrumentation/sidekiq-worker_test.rb +180 -0
  179. data/test/instrumentation/twitter-cassandra_test.rb +424 -0
  180. data/test/instrumentation/typhoeus_test.rb +284 -0
  181. data/test/jobs/delayed_job/db_worker_job.rb +29 -0
  182. data/test/jobs/delayed_job/error_worker_job.rb +10 -0
  183. data/test/jobs/delayed_job/remote_call_worker_job.rb +20 -0
  184. data/test/jobs/resque/db_worker_job.rb +29 -0
  185. data/test/jobs/resque/error_worker_job.rb +10 -0
  186. data/test/jobs/resque/remote_call_worker_job.rb +20 -0
  187. data/test/jobs/sidekiq/db_worker_job.rb +29 -0
  188. data/test/jobs/sidekiq/error_worker_job.rb +10 -0
  189. data/test/jobs/sidekiq/remote_call_worker_job.rb +20 -0
  190. data/test/minitest_helper.rb +276 -0
  191. data/test/mocked/curb_mocked_test.rb +311 -0
  192. data/test/mocked/excon_mocked_test.rb +166 -0
  193. data/test/mocked/faraday_mocked_test.rb +93 -0
  194. data/test/mocked/http_mocked_test.rb +129 -0
  195. data/test/mocked/httpclient_mocked_test.rb +245 -0
  196. data/test/mocked/rest_client_mocked_test.rb +103 -0
  197. data/test/mocked/typhoeus_mocked_test.rb +192 -0
  198. data/test/models/widget.rb +36 -0
  199. data/test/profiling/legacy_method_profiling_test.rb +201 -0
  200. data/test/profiling/method_profiling_test.rb +631 -0
  201. data/test/queues/delayed_job-client_test.rb +95 -0
  202. data/test/queues/delayed_job-worker_test.rb +91 -0
  203. data/test/reporter/reporter_test.rb +14 -0
  204. data/test/servers/delayed_job.rb +107 -0
  205. data/test/servers/rackapp_8101.rb +29 -0
  206. data/test/servers/rails3x_8140.rb +96 -0
  207. data/test/servers/rails4x_8140.rb +96 -0
  208. data/test/servers/rails5x_8140.rb +95 -0
  209. data/test/servers/rails5x_api_8150.rb +78 -0
  210. data/test/servers/sidekiq.rb +29 -0
  211. data/test/servers/sidekiq.yml +7 -0
  212. data/test/servers/sidekiq_initializer.rb +25 -0
  213. data/test/settings +0 -0
  214. data/test/support/auto_tracing_test.rb +50 -0
  215. data/test/support/backcompat_test.rb +276 -0
  216. data/test/support/config_test.rb +149 -0
  217. data/test/support/dnt_test.rb +98 -0
  218. data/test/support/init_report_test.rb +25 -0
  219. data/test/support/liboboe_settings_test.rb +110 -0
  220. data/test/support/logging_test.rb +130 -0
  221. data/test/support/noop_test.rb +88 -0
  222. data/test/support/sql_sanitize_test.rb +55 -0
  223. data/test/support/tracing_mode_test.rb +33 -0
  224. data/test/support/tvalias_test.rb +15 -0
  225. data/test/support/xtrace_test.rb +41 -0
  226. metadata +475 -0
@@ -0,0 +1,793 @@
1
+ /**
2
+ * @file oboe.hpp - C++ liboboe wrapper primarily for generating SWIG interfaces
3
+ *
4
+ * This API should follow https://github.com/tracelytics/tracelons/wiki/Instrumentation-API
5
+ */
6
+
7
+ #ifndef OBOE_HPP
8
+ #define OBOE_HPP
9
+
10
+ #include <string>
11
+ #include <oboe.h>
12
+
13
+
14
+ class Event;
15
+ class Reporter;
16
+ class Context;
17
+
18
+ /**
19
+ * Metadata is the X-Trace identifier and the information needed to work with it.
20
+ */
21
+ class Metadata : private oboe_metadata_t {
22
+ friend class Reporter;
23
+ friend class SslReporter;
24
+ friend class UdpReporter;
25
+ friend class FileReporter;
26
+ friend class Context;
27
+
28
+ public:
29
+ Metadata(oboe_metadata_t *md) {
30
+ oboe_metadata_copy(this, md);
31
+ }
32
+
33
+ ~Metadata() {
34
+ oboe_metadata_destroy(this);
35
+ }
36
+
37
+ static Metadata* fromString(std::string s) {
38
+ oboe_metadata_t md;
39
+ oboe_metadata_fromstr(&md, s.data(), s.size());
40
+ return new Metadata(&md); // copies md
41
+ }
42
+
43
+ // these new objects are managed by SWIG %newobject
44
+ Event *createEvent();
45
+
46
+ static Metadata *makeRandom(bool sampled=true) {
47
+ oboe_metadata_t md;
48
+ oboe_metadata_init(&md);
49
+ oboe_metadata_random(&md);
50
+
51
+ if (sampled) {
52
+ md.flags |= XTR_FLAGS_SAMPLED;
53
+ }
54
+
55
+ return new Metadata(&md); // copies md
56
+ }
57
+
58
+ Metadata *copy() {
59
+ return new Metadata(this);
60
+ }
61
+
62
+ bool isValid() {
63
+ return oboe_metadata_is_valid(this);
64
+ }
65
+
66
+ bool isSampled() {
67
+ return oboe_metadata_is_sampled(this);
68
+ }
69
+
70
+ #ifdef SWIGJAVA
71
+ std::string toStr() {
72
+ #else
73
+ std::string toString() {
74
+ #endif
75
+ char buf[OBOE_MAX_METADATA_PACK_LEN];
76
+
77
+ int rc = oboe_metadata_tostr(this, buf, sizeof(buf) - 1);
78
+ if (rc == 0) {
79
+ return std::string(buf);
80
+ } else {
81
+ return std::string(); // throw exception?
82
+ }
83
+ }
84
+
85
+ };
86
+
87
+ /**
88
+ * The Context class manages the metadata and the settings configuration.
89
+ *
90
+ * The metadata includes the X-Trace identifier fields and the information work working with it.
91
+ * The metadata is needed before any trace messages can be sent and must either be generated for
92
+ * new traces or derived from the X-Trace header of an existing trace.
93
+ *
94
+ * The settings information is used primarily to determine when a new request should be traced.
95
+ * The information begins with configuration values for tracing_mode and sample_rate and then
96
+ * updates are received periodically from the collector to adjust the rate at which traces
97
+ * are generated.
98
+ */
99
+ class Context {
100
+ public:
101
+ /**
102
+ * Set the tracing mode.
103
+ *
104
+ * @param newMode One of
105
+ * - OBOE_TRACE_NEVER(0) to disable tracing,
106
+ * - OBOE_TRACE_ALWAYS(1) to start a new trace if needed, or
107
+ * - OBOE_TRACE_THROUGH(2) to only add to an existing trace.
108
+ */
109
+ static void setTracingMode(int newMode) {
110
+ oboe_settings_mode_set(newMode);
111
+ }
112
+
113
+ /**
114
+ * Set the default sample rate.
115
+ *
116
+ * This rate is used until overridden by the AppOptics servers. If not set then the
117
+ * value comes from settings records downloaded from AppOptics.
118
+ *
119
+ * The rate is interpreted as a ratio out of OBOE_SAMPLE_RESOLUTION (currently 1,000,000).
120
+ *
121
+ * @param newRate A number between 0 (none) and OBOE_SAMPLE_RESOLUTION (a million)
122
+ */
123
+ static void setDefaultSampleRate(int newRate) {
124
+ oboe_settings_rate_set(newRate);
125
+ }
126
+
127
+ /**
128
+ * Check if the current request should be traced based on the current settings.
129
+ *
130
+ * If in_xtrace is empty, or if it is identified as a foreign (ie. cross customer)
131
+ * trace, then sampling will be considered as a new trace.
132
+ * Otherwise sampling will be considered as adding to the current trace.
133
+ * Different layers may have special rules. Also special rules for AppView
134
+ * Web synthetic traces apply if in_tv_meta is given a non-empty string.
135
+ *
136
+ * This is designed to be called once per layer per request.
137
+ *
138
+ * @param layer Name of the layer being considered for tracing
139
+ * @param in_xtrace Incoming X-Trace ID (NULL or empty string if not present)
140
+ * @return Zero to not trace; otherwise return the sample rate used in the low order
141
+ * bytes 0 to 2 and the sample source in the higher-order byte 3.
142
+ */
143
+ static int sampleRequest(
144
+ std::string layer,
145
+ std::string in_xtrace)
146
+ {
147
+ int sample_rate = 0;
148
+ int sample_source = 0;
149
+ int rc = (oboe_sample_layer(layer.c_str(), in_xtrace.c_str(), &sample_rate, &sample_source));
150
+
151
+ return (rc == 0 ? 0 : (((sample_source & 0xFF) << 24) | (sample_rate & 0xFFFFFF)));
152
+ }
153
+
154
+ /**
155
+ * Get a pointer to the current context (from thread-local storage)
156
+ */
157
+ static oboe_metadata_t *get() {
158
+ return oboe_context_get();
159
+ }
160
+
161
+ /**
162
+ * Get the current context as a printable string.
163
+ */
164
+ #ifdef SWIGJAVA
165
+ static std::string toStr() {
166
+ #else
167
+ static std::string toString() {
168
+ #endif
169
+ char buf[OBOE_MAX_METADATA_PACK_LEN];
170
+
171
+ oboe_metadata_t *md = Context::get();
172
+ int rc = oboe_metadata_tostr(md, buf, sizeof(buf) - 1);
173
+ if (rc == 0) {
174
+ return std::string(buf);
175
+ } else {
176
+ return std::string(); // throw exception?
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Set the current context (this updates thread-local storage).
182
+ */
183
+ static void set(oboe_metadata_t *md) {
184
+ oboe_context_set(md);
185
+ }
186
+
187
+ /**
188
+ * Set the current context from a string.
189
+ */
190
+ static void fromString(std::string s) {
191
+ oboe_context_set_fromstr(s.data(), s.size());
192
+ }
193
+
194
+ // this new object is managed by SWIG %newobject
195
+ static Metadata *copy() {
196
+ return new Metadata(Context::get());
197
+ }
198
+
199
+ static void setSampledFlag() {
200
+ oboe_metadata_t *md = Context::get();
201
+ md->flags |= XTR_FLAGS_SAMPLED;
202
+ }
203
+
204
+ static void clear() {
205
+ oboe_context_clear();
206
+ }
207
+
208
+ static bool isValid() {
209
+ return oboe_context_is_valid();
210
+ }
211
+
212
+ static bool isSampled() {
213
+ return oboe_context_is_sampled();
214
+ }
215
+
216
+ /**
217
+ * Initialize the Oboe subsystems.
218
+ *
219
+ * This should be called before any other oboe_* functions. However, in order
220
+ * to make the library easier to work with, checks are in place so that it
221
+ * will be called by any of the other functions that depend on it.
222
+ *
223
+ * Besides initializing the oboe library, this will also initialize a
224
+ * reporter based on the values of environment variables, configuration
225
+ * file options.
226
+ */
227
+ static void init(std::string access_key, std::string hostname_alias) {
228
+ oboe_init(access_key.c_str(), hostname_alias.c_str());
229
+ }
230
+
231
+ /**
232
+ * Initialize the Oboe subsytems using a specific reporter configuration.
233
+ *
234
+ * This should be called before any other oboe_* functions butm may also be
235
+ * used to change or re-initialize the current reporter. To reconnect the
236
+ * reporter use oboe_disconnect() and oboe_reconnect() instead.
237
+ *
238
+ * @param protocol One of OBOE_REPORTER_PROTOCOL_FILE, OBOE_REPORTER_PROTOCOL_UDP,
239
+ * or OBOE_REPORTER_PROTOCOL_SSL.
240
+ * @param args A configuration string for the specified protocol (protocol dependent syntax).
241
+ * @return Zero on success; otherwise an error code.
242
+ */
243
+ static int init_reporter(const char *protocol, const char *args) {
244
+ return oboe_init_reporter(protocol, args);
245
+ }
246
+
247
+ /**
248
+ * Disconnect or shut down the Oboe reporter, but allow it to be reconnect()ed.
249
+ *
250
+ * We don't make this a Reporter method in case there is other housework to do.
251
+ *
252
+ * @param rep Pointer to the active reporter object.
253
+ */
254
+ static void disconnect(Reporter *rep);
255
+
256
+ /**
257
+ * Reconnect or restart the Oboe reporter.
258
+ *
259
+ * We don't make this a Reporter method in case there is other housework to do.
260
+ *
261
+ * @param rep Pointer to the active reporter object.
262
+ */
263
+ static void reconnect(Reporter *rep);
264
+
265
+ /**
266
+ * Shut down the Oboe library.
267
+ *
268
+ * This releases any resources held by the library which may include terminating
269
+ * child threads.
270
+ */
271
+ static void shutdown() {
272
+ oboe_shutdown();
273
+ }
274
+
275
+ // these new objects are managed by SWIG %newobject
276
+ static Event *createEvent();
277
+ static Event *startTrace();
278
+
279
+ private:
280
+
281
+ };
282
+
283
+ class Event : private oboe_event_t {
284
+ friend class Reporter;
285
+ friend class SslReporter;
286
+ friend class UdpReporter;
287
+ friend class FileReporter;
288
+ friend class Context;
289
+ friend class Metadata;
290
+
291
+ private:
292
+ Event() {
293
+ oboe_event_init(this, Context::get());
294
+ }
295
+
296
+ Event(const oboe_metadata_t *md, bool addEdge=true) {
297
+ // both methods copy metadata from md -> this
298
+ if (addEdge) {
299
+ // create_event automatically adds edge in event to md
300
+ oboe_metadata_create_event(md, this);
301
+ } else {
302
+ // initializes new Event with this md's task_id & new random op_id; no edges set
303
+ oboe_event_init(this, md);
304
+ }
305
+ }
306
+
307
+ public:
308
+ ~Event() {
309
+ oboe_event_destroy(this);
310
+ }
311
+
312
+ // called e.g. from Python e.addInfo("Key", None) & Ruby e.addInfo("Key", nil)
313
+ bool addInfo(char *key, void* val) {
314
+ // oboe_event_add_info(evt, key, NULL) does nothing
315
+ (void) key;
316
+ (void) val;
317
+ return true;
318
+ }
319
+
320
+ bool addInfo(char *key, const std::string& val) {
321
+ if (memchr(val.data(), '\0', val.size())) {
322
+ return oboe_event_add_info_binary(this, key, val.data(), val.size()) == 0;
323
+ } else {
324
+ return oboe_event_add_info(this, key, val.data()) == 0;
325
+ }
326
+ }
327
+
328
+ bool addInfo(char *key, long val) {
329
+ int64_t val_ = val;
330
+ return oboe_event_add_info_int64(this, key, val_) == 0;
331
+ }
332
+
333
+ bool addInfo(char *key, double val) {
334
+ return oboe_event_add_info_double(this, key, val) == 0;
335
+ }
336
+
337
+ bool addEdge(oboe_metadata_t *md) {
338
+ return oboe_event_add_edge(this, md) == 0;
339
+ }
340
+
341
+ bool addEdgeStr(const std::string& val) {
342
+ return oboe_event_add_edge_fromstr(this, val.c_str(), val.size()) == 0;
343
+ }
344
+
345
+ /**
346
+ * Get a new copy of this metadata.
347
+ *
348
+ * NOTE: The returned object must be "delete"d.
349
+ */
350
+ Metadata* getMetadata() {
351
+ return new Metadata(&this->metadata);
352
+ }
353
+
354
+ std::string metadataString() {
355
+ char buf[OBOE_MAX_METADATA_PACK_LEN];
356
+
357
+ int rc = oboe_metadata_tostr(&this->metadata, buf, sizeof(buf) - 1);
358
+ if (rc == 0) {
359
+ return std::string(buf);
360
+ } else {
361
+ return std::string(); // throw exception?
362
+ }
363
+ }
364
+
365
+ /**
366
+ * Report this event.
367
+ *
368
+ * This sends the event using the default reporter.
369
+ *
370
+ * @return True on success; otherwise an error message is logged.
371
+ */
372
+ bool send() {
373
+ return (oboe_event_send(OBOE_SEND_EVENT, this, Context::get()) >= 0);
374
+ }
375
+
376
+ static Event* startTrace(const oboe_metadata_t *md);
377
+
378
+ };
379
+
380
+ class Span {
381
+ public:
382
+ static void createHttpSpan(const char *transaction, const char *url, const int64_t duration,
383
+ const int status, const char *method, const int has_error);
384
+ };
385
+
386
+ void Span::createHttpSpan(const char *transaction, const char *url, const int64_t duration,
387
+ const int status, const char *method, const int has_error) {
388
+ oboe_http_span(transaction, url, duration, status, method, has_error);
389
+ }
390
+
391
+ class MetricTags {
392
+ friend class CustomMetrics;
393
+ public:
394
+ MetricTags(size_t count) {
395
+ tags = new oboe_metric_tag_t[count];
396
+ size = count;
397
+ }
398
+ ~MetricTags() {
399
+ delete[] tags;
400
+ }
401
+ bool add(size_t index, char *k, char *v) {
402
+ if (index < size) {
403
+ tags[index].key = k;
404
+ tags[index].value = v;
405
+ return true;
406
+ }
407
+ return false;
408
+ }
409
+ private:
410
+ oboe_metric_tag_t* get() const {
411
+ return tags;
412
+ }
413
+
414
+ oboe_metric_tag_t *tags;
415
+ size_t size;
416
+ };
417
+
418
+ class CustomMetrics {
419
+ public:
420
+ static int summary(const char *name, const double value, const int count, const int host_tag,
421
+ const MetricTags *tags, const size_t tags_count) {
422
+ return oboe_custom_metric_summary(name, value, count, host_tag, tags->get(), tags_count);
423
+ }
424
+
425
+ static int increment(const char *name, const int count, const int host_tag,
426
+ const MetricTags *tags, const size_t tags_count) {
427
+ return oboe_custom_metric_increment(name, count, host_tag, tags->get(), tags_count);
428
+ }
429
+ };
430
+
431
+ /**
432
+ * Create a new event object using the thread's context.
433
+ *
434
+ * NOTE: The returned object must be "delete"d.
435
+ */
436
+ Event *Context::createEvent() {
437
+ return new Event(Context::get());
438
+ }
439
+
440
+ /**
441
+ * Create a new event object using this Metadata's context.
442
+ *
443
+ * NOTE: The returned object must be "delete"d.
444
+ */
445
+ Event *Metadata::createEvent() {
446
+ return new Event(this);
447
+ }
448
+
449
+ /**
450
+ * Create a new event object with a new trace context.
451
+ *
452
+ * NOTE: The returned object must be "delete"d.
453
+ */
454
+ Event *Context::startTrace() {
455
+ oboe_metadata_t *md = Context::get();
456
+ oboe_metadata_random(md);
457
+ return new Event();
458
+ }
459
+
460
+ /**
461
+ * Create a new event object using the given metadata context.
462
+ *
463
+ * NOTE: The metadata context must be unique to the new trace.
464
+ *
465
+ * NOTE: The returned object must be "delete"d.
466
+ *
467
+ * @param md The metadata object to use when creating the new event.
468
+ */
469
+ Event *Event::startTrace(const oboe_metadata_t *md) {
470
+ return new Event(md, false);
471
+ }
472
+
473
+ class Reporter : private oboe_reporter_t {
474
+ friend class Context; // Access to the private oboe_reporter_t base structure.
475
+ public:
476
+ /**
477
+ * Initialize a reporter structure for use with the specified protocol.
478
+ *
479
+ * @param protocol One of "file", "udp", or "ssl".
480
+ * @param args A configuration string for the specified protocol (protocol dependent syntax).
481
+ */
482
+ Reporter(const char *protocol, const char *args) {
483
+ oboe_init_reporter(protocol, args);
484
+ }
485
+
486
+ ~Reporter() {
487
+ oboe_reporter_destroy(this);
488
+ }
489
+
490
+ bool sendReport(Event *evt) {
491
+ return oboe_event_send(OBOE_SEND_EVENT, evt, Context::get()) >= 0;
492
+ }
493
+
494
+ bool sendReport(Event *evt, oboe_metadata_t *md) {
495
+ return oboe_event_send(OBOE_SEND_EVENT, evt, md) >= 0;
496
+ }
497
+
498
+ bool sendStatus(Event *evt) {
499
+ return oboe_event_send(OBOE_SEND_STATUS, evt, Context::get()) >= 0;
500
+ }
501
+
502
+ bool sendStatus(Event *evt, oboe_metadata_t *md) {
503
+ return oboe_event_send(OBOE_SEND_STATUS, evt, md) >= 0;
504
+ }
505
+ };
506
+
507
+
508
+ class SslReporter : private oboe_reporter_t {
509
+ public:
510
+ SslReporter(const char *config) {
511
+ oboe_reporter_ssl_init(this, config);
512
+ }
513
+
514
+ ~SslReporter() {
515
+ oboe_reporter_destroy(this);
516
+ }
517
+
518
+ bool sendReport(Event *evt) {
519
+ return oboe_event_send(OBOE_SEND_EVENT, evt, Context::get()) >= 0;
520
+ }
521
+
522
+ bool sendReport(Event *evt, oboe_metadata_t *md) {
523
+ return oboe_event_send(OBOE_SEND_EVENT, evt, md) >= 0;
524
+ }
525
+
526
+ bool sendStatus(Event *evt) {
527
+ return oboe_event_send(OBOE_SEND_STATUS, evt, Context::get()) >= 0;
528
+ }
529
+
530
+ bool sendStatus(Event *evt, oboe_metadata_t *md) {
531
+ return oboe_event_send(OBOE_SEND_STATUS, evt, md) >= 0;
532
+ }
533
+ };
534
+
535
+
536
+ class UdpReporter : private oboe_reporter_t {
537
+ public:
538
+ UdpReporter(const char *addr, const char *port=NULL) {
539
+ if (port == NULL)
540
+ port = "7831";
541
+
542
+ oboe_reporter_udp_init(this, addr, port);
543
+ }
544
+
545
+ ~UdpReporter() {
546
+ oboe_reporter_destroy(this);
547
+ }
548
+
549
+ bool sendReport(Event *evt) {
550
+ return oboe_event_send(OBOE_SEND_EVENT, evt, Context::get()) >= 0;
551
+ }
552
+
553
+ bool sendReport(Event *evt, oboe_metadata_t *md) {
554
+ return oboe_event_send(OBOE_SEND_EVENT, evt, md) >= 0;
555
+ }
556
+
557
+ bool sendStatus(Event *evt) {
558
+ return oboe_event_send(OBOE_SEND_STATUS, evt, Context::get()) >= 0;
559
+ }
560
+
561
+ bool sendStatus(Event *evt, oboe_metadata_t *md) {
562
+ return oboe_event_send(OBOE_SEND_STATUS, evt, md) >= 0;
563
+ }
564
+ };
565
+
566
+ class FileReporter : private oboe_reporter_t {
567
+ public:
568
+ FileReporter(const char *file) {
569
+ oboe_reporter_file_init(this, file);
570
+ }
571
+
572
+ ~FileReporter() {
573
+ oboe_reporter_destroy(this);
574
+ }
575
+
576
+ bool sendReport(Event *evt) {
577
+ return oboe_event_send(OBOE_SEND_EVENT, evt, Context::get()) >= 0;
578
+ }
579
+
580
+ bool sendReport(Event *evt, oboe_metadata_t *md) {
581
+ return oboe_event_send(OBOE_SEND_EVENT, evt, md) >= 0;
582
+ }
583
+
584
+ bool sendStatus(Event *evt) {
585
+ return oboe_event_send(OBOE_SEND_STATUS, evt, Context::get()) >= 0;
586
+ }
587
+
588
+ bool sendStatus(Event *evt, oboe_metadata_t *md) {
589
+ return oboe_event_send(OBOE_SEND_STATUS, evt, md) >= 0;
590
+ }
591
+ };
592
+
593
+
594
+ /**
595
+ * Base class for a diagnostic log message handler.
596
+ */
597
+ class DebugLogger {
598
+ public:
599
+ virtual ~DebugLogger() {}
600
+ virtual void log(int module, int level, const char *source_name, int source_lineno, const char *msg) = 0;
601
+ };
602
+
603
+ /**
604
+ * "C" language wrapper for DebugLogger classes.
605
+ *
606
+ * A logging function that can be added to the logger chain using
607
+ * DebugLog::addDebugLogger().
608
+ *
609
+ * @param context The context pointer that was registered in the call to
610
+ * DebugLog::addDebugLogger(). Use it to pass the pointer-to-self for
611
+ * objects (ie. "this" in C++) or just a structure in C, May be
612
+ * NULL.
613
+ * @param module The module identifier as passed to oboe_debug_logger().
614
+ * @param level The diagnostic detail level as passed to oboe_debug_logger().
615
+ * @param source_name Name of the source file as passed to oboe_debug_logger().
616
+ * @param source_lineno Number of the line in the source file where message is
617
+ * logged from as passed to oboe_debug_logger().
618
+ * @param msg The formatted message produced from the format string and its
619
+ * arguments as passed to oboe_debug_logger().
620
+ */
621
+ extern "C" void oboe_debug_log_handler(void *context, int module, int level, const char *source_name, int source_lineno, const char *msg) {
622
+ ((DebugLogger *)context)->log(module, level, source_name, source_lineno, msg);
623
+ }
624
+
625
+ class DebugLog {
626
+ public:
627
+ /**
628
+ * Get a printable name for a diagnostics logging level.
629
+ *
630
+ * @param level A detail level in the range 0 to 6 (OBOE_DEBUG_FATAL to OBOE_DEBUG_HIGH).
631
+ */
632
+ static std::string getLevelName(int level) {
633
+ return std::string(oboe_debug_log_level_name(level));
634
+ }
635
+
636
+ /**
637
+ * Get a printable name for a diagnostics logging module identifier.
638
+ *
639
+ * @param module One of the OBOE_MODULE_* values.
640
+ */
641
+ static std::string getModuleName(int module) {
642
+ return std::string(oboe_debug_module_name(module));
643
+ }
644
+
645
+ /**
646
+ * Get the maximum logging detail level for a module or for all modules.
647
+ *
648
+ * This level applies to the default logger only. Added loggers get all messages
649
+ * below their registed detail level and need to do their own module-specific
650
+ * filtering.
651
+ *
652
+ * @param module One of the OBOE_MODULE_* values. Use OBOE_MODULE_ALL (-1) to
653
+ * get the overall maximum detail level.
654
+ * @return Maximum detail level value for module (or overall) where zero is the
655
+ * lowest and higher values generate more detailed log messages.
656
+ */
657
+ static int getLevel(int module) {
658
+ return oboe_debug_log_level_get(module);
659
+ }
660
+
661
+ /**
662
+ * Set the maximum logging detail level for a module or for all modules.
663
+ *
664
+ * This level applies to the default logger only. Added loggers get all messages
665
+ * below their registered detail level and need to do their own module-specific
666
+ * filtering.
667
+ *
668
+ * @param module One of the OBOE_MODULE_* values. Use OBOE_MODULE_ALL to set
669
+ * the overall maximum detail level.
670
+ * @param newLevel Maximum detail level value where zero is the lowest and higher
671
+ * values generate more detailed log messages.
672
+ */
673
+ static void setLevel(int module, int newLevel) {
674
+ oboe_debug_log_level_set(module, newLevel);
675
+ }
676
+
677
+ /**
678
+ * Set the output stream for the default logger.
679
+ *
680
+ * @param newStream A valid, open FILE* stream or NULL to disable the default logger.
681
+ * @return Zero on success; otherwise an error code (normally from errno).
682
+ */
683
+ static int setOutputStream(FILE *newStream) {
684
+ return oboe_debug_log_to_stream(newStream);
685
+ }
686
+
687
+ /**
688
+ * Set the default logger to write to the specified file.
689
+ *
690
+ * A NULL or empty path name will disable the default logger.
691
+ *
692
+ * If the file exists then it will be opened in append mode.
693
+ *
694
+ * @param pathname The path name of the
695
+ * @return Zero on success; otherwise an error code (normally from errno).
696
+ */
697
+ static int setOutputFile(const char *pathname) {
698
+ return oboe_debug_log_to_file(pathname);
699
+ }
700
+
701
+ /**
702
+ * Add a logger that takes messages up to a given logging detail level.
703
+ *
704
+ * This adds the logger to a chain in order of the logging level. Log messages
705
+ * are passed to each logger down the chain until the remaining loggers only
706
+ * accept messages of a lower detail level.
707
+ *
708
+ * @return Zero on success, one if re-registered with the new logging level, and
709
+ * otherwise a negative value to indicate an error.
710
+ */
711
+ static int addDebugLogger(DebugLogger *newLogger, int logLevel) {
712
+ return oboe_debug_log_add(oboe_debug_log_handler, newLogger, logLevel);
713
+ }
714
+
715
+ /**
716
+ * Remove a logger.
717
+ *
718
+ * Remove the logger from the message handling chain.
719
+ *
720
+ * @return Zero on success, one if it was not found, and otherwise a negative
721
+ * value to indicate an error.
722
+ */
723
+ static int removeDebugLogger(DebugLogger *oldLogger) {
724
+ return oboe_debug_log_remove(oboe_debug_log_handler, oldLogger);
725
+ }
726
+
727
+ /**
728
+ * Low-level diagnostics logging function.
729
+ *
730
+ * Use this to pass
731
+ * @param module One of the numeric module identifiers defined in debug.h - used to control logging detail by module.
732
+ * @param level Diagnostic detail level of this message - used to control logging volume by detail level.
733
+ * @param source_name Name of the source file, if available, or another useful name, or NULL.
734
+ * @param source_lineno Number of the line in the source file where message is logged from, if available, or zero.
735
+ * @param format A C language printf format specification string.
736
+ * @param args A variable argument list in VA_ARG format containing arguments for each argument specifier in the format.
737
+ */
738
+ static void logMessage(int module, int level, const char *source_name, int source_lineno, const char *msg) {
739
+ oboe_debug_logger(module, level, source_name, source_lineno, "%s", msg);
740
+ }
741
+ };
742
+
743
+ class Config {
744
+ public:
745
+ /**
746
+ * Check if the Oboe library is compatible with a given version.revision.
747
+ *
748
+ * This will succeed if the library is at least as recent as specified and if no
749
+ * definitions have been removed since that revision.
750
+ *
751
+ * @param version The library's version number which increments every time the API changes.
752
+ * @param revision The revision of the current version of the library.
753
+ * @return Non-zero if the Oboe library is considered compatible with the specified revision.
754
+ */
755
+ static bool checkVersion(int version, int revision) {
756
+ return (oboe_config_check_version(version, revision) != 0);
757
+ }
758
+
759
+ /**
760
+ * Get the Oboe library version number.
761
+ *
762
+ * This number increments whenever an incompatible change to the API/ABI is made.
763
+ *
764
+ * @return The library's version number or -1 if the version is not known.
765
+ */
766
+ static int getVersion() {
767
+ return oboe_config_get_version();
768
+ }
769
+
770
+ /**
771
+ * Get the Oboe library revision number.
772
+ *
773
+ * This number increments whenever a compatible change is made to the
774
+ * API/ABI (ie. an addition).
775
+ *
776
+ * @return The library's revision number or -1 if not known.
777
+ */
778
+ static int getRevision() {
779
+ return oboe_config_get_revision();
780
+ }
781
+ };
782
+
783
+
784
+ void Context::disconnect(Reporter *rep) {
785
+ oboe_disconnect(rep);
786
+ }
787
+
788
+ void Context::reconnect(Reporter *rep) {
789
+ oboe_reconnect(rep);
790
+ }
791
+
792
+
793
+ #endif // OBOE_HPP