appoptics_apm 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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