appoptics_apm-zearn 4.13.1

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 (145) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +5 -0
  3. data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
  4. data/.github/workflows/build_and_release_gem.yml +103 -0
  5. data/.github/workflows/build_for_packagecloud.yml +70 -0
  6. data/.github/workflows/docker-images.yml +47 -0
  7. data/.github/workflows/run_cpluplus_tests.yml +73 -0
  8. data/.github/workflows/run_tests.yml +168 -0
  9. data/.github/workflows/scripts/test_install.rb +23 -0
  10. data/.github/workflows/swig/swig-v4.0.2.tar.gz +0 -0
  11. data/.github/workflows/test_on_4_linux.yml +159 -0
  12. data/.gitignore +36 -0
  13. data/.rubocop.yml +29 -0
  14. data/.travis.yml +130 -0
  15. data/.yardopts +6 -0
  16. data/CHANGELOG.md +769 -0
  17. data/CONFIG.md +33 -0
  18. data/Gemfile +14 -0
  19. data/LICENSE +202 -0
  20. data/README.md +393 -0
  21. data/appoptics_apm.gemspec +70 -0
  22. data/bin/appoptics_apm_config +15 -0
  23. data/examples/prepend.rb +13 -0
  24. data/examples/sdk_examples.rb +158 -0
  25. data/ext/oboe_metal/README.md +69 -0
  26. data/ext/oboe_metal/extconf.rb +151 -0
  27. data/ext/oboe_metal/lib/.keep +0 -0
  28. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -0
  30. data/ext/oboe_metal/noop/noop.c +8 -0
  31. data/ext/oboe_metal/src/README.md +6 -0
  32. data/ext/oboe_metal/src/VERSION +2 -0
  33. data/ext/oboe_metal/src/bson/bson.h +220 -0
  34. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  35. data/ext/oboe_metal/src/frames.cc +246 -0
  36. data/ext/oboe_metal/src/frames.h +40 -0
  37. data/ext/oboe_metal/src/init_appoptics_apm.cc +21 -0
  38. data/ext/oboe_metal/src/logging.cc +95 -0
  39. data/ext/oboe_metal/src/logging.h +35 -0
  40. data/ext/oboe_metal/src/oboe.h +1156 -0
  41. data/ext/oboe_metal/src/oboe_api.cpp +652 -0
  42. data/ext/oboe_metal/src/oboe_api.hpp +431 -0
  43. data/ext/oboe_metal/src/oboe_debug.h +59 -0
  44. data/ext/oboe_metal/src/oboe_swig_wrap.cc +7329 -0
  45. data/ext/oboe_metal/src/profiling.cc +435 -0
  46. data/ext/oboe_metal/src/profiling.h +78 -0
  47. data/ext/oboe_metal/test/CMakeLists.txt +53 -0
  48. data/ext/oboe_metal/test/FindGMock.cmake +43 -0
  49. data/ext/oboe_metal/test/README.md +56 -0
  50. data/ext/oboe_metal/test/frames_test.cc +164 -0
  51. data/ext/oboe_metal/test/profiling_test.cc +93 -0
  52. data/ext/oboe_metal/test/ruby_inc_dir.rb +8 -0
  53. data/ext/oboe_metal/test/ruby_prefix.rb +8 -0
  54. data/ext/oboe_metal/test/ruby_test_helper.rb +67 -0
  55. data/ext/oboe_metal/test/test.h +11 -0
  56. data/ext/oboe_metal/test/test_main.cc +32 -0
  57. data/init.rb +4 -0
  58. data/lib/appoptics_apm/api/layerinit.rb +41 -0
  59. data/lib/appoptics_apm/api/logging.rb +381 -0
  60. data/lib/appoptics_apm/api/memcache.rb +37 -0
  61. data/lib/appoptics_apm/api/metrics.rb +63 -0
  62. data/lib/appoptics_apm/api/tracing.rb +57 -0
  63. data/lib/appoptics_apm/api/util.rb +120 -0
  64. data/lib/appoptics_apm/api.rb +21 -0
  65. data/lib/appoptics_apm/base.rb +231 -0
  66. data/lib/appoptics_apm/config.rb +299 -0
  67. data/lib/appoptics_apm/frameworks/grape.rb +98 -0
  68. data/lib/appoptics_apm/frameworks/padrino.rb +78 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_controller6.rb +50 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +88 -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 +29 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +114 -0
  81. data/lib/appoptics_apm/frameworks/rails/inst/logger_formatters.rb +27 -0
  82. data/lib/appoptics_apm/frameworks/rails.rb +100 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +96 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
  86. data/lib/appoptics_apm/inst/curb.rb +332 -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 +101 -0
  90. data/lib/appoptics_apm/inst/excon.rb +125 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +106 -0
  92. data/lib/appoptics_apm/inst/graphql.rb +240 -0
  93. data/lib/appoptics_apm/inst/grpc_client.rb +159 -0
  94. data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
  95. data/lib/appoptics_apm/inst/http.rb +81 -0
  96. data/lib/appoptics_apm/inst/httpclient.rb +174 -0
  97. data/lib/appoptics_apm/inst/logger_formatter.rb +50 -0
  98. data/lib/appoptics_apm/inst/logging_log_event.rb +28 -0
  99. data/lib/appoptics_apm/inst/lumberjack_formatter.rb +13 -0
  100. data/lib/appoptics_apm/inst/memcached.rb +86 -0
  101. data/lib/appoptics_apm/inst/mongo.rb +246 -0
  102. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  103. data/lib/appoptics_apm/inst/moped.rb +466 -0
  104. data/lib/appoptics_apm/inst/rack.rb +182 -0
  105. data/lib/appoptics_apm/inst/rack_cache.rb +35 -0
  106. data/lib/appoptics_apm/inst/redis.rb +274 -0
  107. data/lib/appoptics_apm/inst/resque.rb +151 -0
  108. data/lib/appoptics_apm/inst/rest-client.rb +48 -0
  109. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  110. data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
  111. data/lib/appoptics_apm/inst/sidekiq-worker.rb +66 -0
  112. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  113. data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
  114. data/lib/appoptics_apm/instrumentation.rb +22 -0
  115. data/lib/appoptics_apm/loading.rb +65 -0
  116. data/lib/appoptics_apm/logger.rb +14 -0
  117. data/lib/appoptics_apm/noop/README.md +9 -0
  118. data/lib/appoptics_apm/noop/context.rb +27 -0
  119. data/lib/appoptics_apm/noop/metadata.rb +25 -0
  120. data/lib/appoptics_apm/noop/profiling.rb +21 -0
  121. data/lib/appoptics_apm/oboe_init_options.rb +211 -0
  122. data/lib/appoptics_apm/ruby.rb +35 -0
  123. data/lib/appoptics_apm/sdk/current_trace.rb +77 -0
  124. data/lib/appoptics_apm/sdk/custom_metrics.rb +94 -0
  125. data/lib/appoptics_apm/sdk/logging.rb +37 -0
  126. data/lib/appoptics_apm/sdk/tracing.rb +434 -0
  127. data/lib/appoptics_apm/support/profiling.rb +18 -0
  128. data/lib/appoptics_apm/support/transaction_metrics.rb +67 -0
  129. data/lib/appoptics_apm/support/transaction_settings.rb +219 -0
  130. data/lib/appoptics_apm/support/x_trace_options.rb +110 -0
  131. data/lib/appoptics_apm/support_report.rb +119 -0
  132. data/lib/appoptics_apm/test.rb +95 -0
  133. data/lib/appoptics_apm/thread_local.rb +26 -0
  134. data/lib/appoptics_apm/util.rb +326 -0
  135. data/lib/appoptics_apm/version.rb +16 -0
  136. data/lib/appoptics_apm/xtrace.rb +115 -0
  137. data/lib/appoptics_apm.rb +77 -0
  138. data/lib/joboe_metal.rb +212 -0
  139. data/lib/oboe.rb +7 -0
  140. data/lib/oboe_metal.rb +172 -0
  141. data/lib/rails/generators/appoptics_apm/install_generator.rb +47 -0
  142. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +425 -0
  143. data/log/.keep +0 -0
  144. data/yardoc_frontpage.md +26 -0
  145. metadata +231 -0
@@ -0,0 +1,652 @@
1
+ /**
2
+ * @file oboe_api.cpp - C++ liboboe wrapper primarily used via swig interfaces
3
+ * by the python and ruby agents
4
+ *
5
+ * TODO: This doc is outdated
6
+ * This API should follow https://github.com/tracelytics/tracelons/wiki/Instrumentation-API
7
+ **/
8
+
9
+ #include "oboe_api.hpp"
10
+
11
+ /////// Metatdata ///////
12
+
13
+ Metadata::Metadata(const oboe_metadata_t *md) {
14
+ oboe_metadata_copy(this, md);
15
+ }
16
+
17
+ Metadata::~Metadata() {
18
+ oboe_metadata_destroy(this);
19
+ }
20
+
21
+ Metadata *Metadata::makeRandom(bool sampled) {
22
+ oboe_metadata_t md;
23
+ oboe_metadata_init(&md);
24
+ oboe_metadata_random(&md);
25
+
26
+ if (sampled) md.flags |= XTR_FLAGS_SAMPLED;
27
+
28
+ return new Metadata(&md); // copies md
29
+ }
30
+
31
+ Metadata *Metadata::copy() {
32
+ return new Metadata(this);
33
+ }
34
+
35
+ bool Metadata::isValid() {
36
+ return oboe_metadata_is_valid(this);
37
+ }
38
+
39
+ bool Metadata::isSampled() {
40
+ return oboe_metadata_is_sampled(this);
41
+ }
42
+
43
+ Metadata *Metadata::fromString(std::string s) {
44
+ oboe_metadata_t md;
45
+ oboe_metadata_fromstr(&md, s.data(), s.size());
46
+ return new Metadata(&md); // copies md
47
+ }
48
+
49
+ oboe_metadata_t *Metadata::metadata() {
50
+ return this;
51
+ }
52
+
53
+ Event *Metadata::createEvent() {
54
+ return new Event(this);
55
+ }
56
+
57
+ #ifdef SWIGJAVA
58
+ std::string Metadata::toStr() {
59
+ #else
60
+ std::string Metadata::toString() {
61
+ #endif
62
+ char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
63
+
64
+ int rc = oboe_metadata_tostr(this, buf, sizeof(buf) - 1);
65
+ if (rc == 0) {
66
+ return std::string(buf);
67
+ } else {
68
+ return std::string(); // throw exception?
69
+ }
70
+ }
71
+
72
+ /////// Context ///////
73
+
74
+ void Context::setTracingMode(int newMode) {
75
+ oboe_settings_mode_set(newMode);
76
+ }
77
+
78
+ void Context::setDefaultSampleRate(int newRate) {
79
+ oboe_settings_rate_set(newRate);
80
+ }
81
+
82
+ void Context::getDecisions(
83
+ // this paramter list is too long, but other forms of sending info
84
+ // between python/ruby and c++ would require extra roudn trips
85
+ // and may be less efficient.
86
+ // TODO: benchmark this assumption
87
+
88
+ // output
89
+ int *do_metrics,
90
+ int *do_sample,
91
+ int *sample_rate,
92
+ int *sample_source,
93
+ double *bucket_rate,
94
+ double *bucket_cap,
95
+ int *type,
96
+ int *auth,
97
+ std::string *status_msg,
98
+ std::string *auth_msg,
99
+ int *status,
100
+
101
+ // input
102
+ const char *in_xtrace,
103
+ int custom_tracing_mode,
104
+ int custom_sample_rate,
105
+ int request_type,
106
+ int custom_trigger_mode,
107
+ const char *header_options,
108
+ const char *header_signature,
109
+ long header_timestamp
110
+ ) {
111
+ oboe_tracing_decisions_in_t tdi;
112
+ memset(&tdi, 0, sizeof(tdi));
113
+ tdi.custom_tracing_mode = custom_tracing_mode;
114
+ tdi.custom_sample_rate = custom_sample_rate;
115
+ tdi.custom_trigger_mode = custom_trigger_mode;
116
+ tdi.request_type = request_type;
117
+ tdi.version = 2;
118
+ tdi.in_xtrace = in_xtrace;
119
+ tdi.header_options = header_options;
120
+ tdi.header_signature = header_signature;
121
+ tdi.header_timestamp = header_timestamp;
122
+
123
+ oboe_tracing_decisions_out_t tdo;
124
+ memset(&tdo, 0, sizeof(tdo));
125
+ tdo.version = 3;
126
+
127
+ *status = oboe_tracing_decisions(&tdi, &tdo);
128
+
129
+ *do_sample = tdo.do_sample;
130
+ *do_metrics = tdo.do_metrics;
131
+ *sample_rate = tdo.sample_rate;
132
+ *sample_source = tdo.sample_source;
133
+ *bucket_rate = tdo.token_bucket_rate;
134
+ *bucket_cap = tdo.token_bucket_capacity;
135
+ *type = tdo.request_provisioned;
136
+ if (tdo.status_message && tdo.status_message[0] != '\0') {
137
+ *status_msg = tdo.status_message;
138
+ }
139
+ *auth = tdo.auth_status;
140
+ if (tdo.auth_message && tdo.auth_message[0] != '\0') {
141
+ *auth_msg = tdo.auth_message;
142
+ }
143
+ }
144
+
145
+ oboe_metadata_t *Context::get() {
146
+ return oboe_context_get();
147
+ }
148
+
149
+ #ifdef SWIGJAVA
150
+ std::string Context::toStr() {
151
+ #else
152
+ std::string Context::toString() {
153
+ #endif
154
+ char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
155
+
156
+ oboe_metadata_t *md = Context::get();
157
+ int rc = oboe_metadata_tostr(md, buf, sizeof(buf) - 1);
158
+ if (rc == 0) {
159
+ return std::string(buf);
160
+ } else {
161
+ return std::string(); // throw exception?
162
+ }
163
+ }
164
+
165
+ void Context::set(oboe_metadata_t *md) {
166
+ oboe_context_set(md);
167
+ }
168
+
169
+ void Context::fromString(std::string s) {
170
+ oboe_context_set_fromstr(s.data(), s.size());
171
+ }
172
+
173
+ // this new object is managed by SWIG %newobject
174
+ Metadata *Context::copy() {
175
+ return new Metadata(Context::get());
176
+ }
177
+
178
+ void Context::setSampledFlag() {
179
+ oboe_metadata_t *md = Context::get();
180
+ md->flags |= XTR_FLAGS_SAMPLED;
181
+ }
182
+
183
+ void Context::clear() {
184
+ oboe_context_clear();
185
+ }
186
+
187
+ bool Context::isValid() {
188
+ return oboe_context_is_valid();
189
+ }
190
+
191
+ bool Context::isSampled() {
192
+ return oboe_context_is_sampled();
193
+ }
194
+
195
+ std::string Context::validateTransformServiceName(std::string service_key) {
196
+ char service_key_cpy[71 + 1 + 256]; // Flawfinder: ignore, key=71, colon=1, name<=255
197
+ memset(service_key_cpy, 0, sizeof(service_key_cpy));
198
+ strncpy(service_key_cpy, service_key.c_str(), sizeof(service_key_cpy) - 1); // Flawfinder: ignore
199
+ int len = strlen(service_key_cpy); // Flawfinder: ignore
200
+ int ret = oboe_validate_transform_service_name(service_key_cpy, &len);
201
+
202
+ if (ret == -1) {
203
+ return "";
204
+ }
205
+
206
+ return std::string(service_key_cpy);
207
+ }
208
+
209
+ void Context::shutdown() {
210
+ oboe_shutdown();
211
+ }
212
+
213
+ int Context::isReady(unsigned int timeout) {
214
+ return oboe_is_ready(timeout);
215
+ }
216
+
217
+ bool Context::isLambda() {
218
+ return (bool) oboe_is_lambda();
219
+ }
220
+
221
+ /**
222
+ * Create a new event object that continues the trace context.
223
+ *
224
+ * NOTE: The returned object must be "delete"d.
225
+ */
226
+ Event *Context::createEvent() {
227
+ return new Event(Context::get());
228
+ }
229
+
230
+ /**
231
+ * Create a new event object with a new trace context.
232
+ *
233
+ * NOTE: The returned object must be "delete"d.
234
+ */
235
+ Event *Context::startTrace() {
236
+ oboe_metadata_t *md = Context::get();
237
+ oboe_metadata_random(md);
238
+ return new Event();
239
+ }
240
+
241
+ /////// Event ///////
242
+
243
+ Event::Event() {
244
+ oboe_event_init(this, Context::get(), NULL);
245
+ }
246
+
247
+ Event::Event(const oboe_metadata_t *md, bool addEdge) {
248
+ // both methods copy metadata from md -> this
249
+ if (addEdge) {
250
+ // create_event automatically adds edge in event to md
251
+ oboe_metadata_create_event(md, this);
252
+ } else {
253
+ // initializes new Event with this md's task_id & new random op_id; no edges set
254
+ oboe_event_init(this, md, NULL);
255
+ }
256
+ }
257
+
258
+ Event::~Event() {
259
+ oboe_event_destroy(this);
260
+ }
261
+
262
+ Event *Event::startTrace(const oboe_metadata_t *md) {
263
+ return new Event(md, false);
264
+ }
265
+
266
+ // called e.g. from Python e.addInfo("Key", None) & Ruby e.addInfo("Key", nil)
267
+ bool Event::addInfo(char *key, void *val) {
268
+ // oboe_event_add_info(evt, key, NULL) does nothing
269
+ (void)key;
270
+ (void)val;
271
+ return true;
272
+ }
273
+
274
+ bool Event::addInfo(char *key, const std::string &val) {
275
+ if (memchr(val.data(), '\0', val.size())) {
276
+ return oboe_event_add_info_binary(this, key, val.data(), val.size()) == 0;
277
+ } else {
278
+ return oboe_event_add_info(this, key, val.data()) == 0;
279
+ }
280
+ }
281
+
282
+ bool Event::addInfo(char *key, long val) {
283
+ int64_t val_ = val;
284
+ return oboe_event_add_info_int64(this, key, val_) == 0;
285
+ }
286
+
287
+ bool Event::addInfo(char *key, double val) {
288
+ return oboe_event_add_info_double(this, key, val) == 0;
289
+ }
290
+
291
+ bool Event::addInfo(char *key, bool val) {
292
+ return oboe_event_add_info_bool(this, key, val) == 0;
293
+ }
294
+
295
+ /*
296
+ * this function was added for profiling
297
+ * to report the timestamps of omitted snapshots
298
+ */
299
+ bool Event::addInfo(char *key, const long *vals, int num) {
300
+ oboe_bson_append_start_array(&(this->bbuf), key);
301
+ for (int i = 0; i < num; i++) {
302
+ // 5 is chosen so that indices upto 9999 can be stored
303
+ char index[5]; // Flawfinder: ignore
304
+ sprintf(index, "%d", i); // Flawfinder: ignore
305
+ oboe_bson_append_long(&(this->bbuf), index, (int64_t)vals[i]);
306
+ }
307
+ oboe_bson_append_finish_object(&(this->bbuf));
308
+ return true;
309
+ }
310
+
311
+ /*
312
+ * A profiling specific addInfo function
313
+ * to add the frames that make up a snapshot
314
+ */
315
+ bool Event::addInfo(char *key, const std::vector<FrameData> &vals) {
316
+ oboe_bson_append_start_array(&(this->bbuf), key);
317
+ int i = 0;
318
+ for (FrameData val : vals) {
319
+ // 5 is chosen so that indices upto 9999 can be stored
320
+ char index[5]; // Flawfinder: ignore
321
+ sprintf(index, "%d", i); // Flawfinder: ignore
322
+ i++;
323
+ oboe_bson_append_start_object(&(this->bbuf), index);
324
+
325
+ if (val.method != "")
326
+ oboe_bson_append_string(&(this->bbuf), "M", (val.method).c_str());
327
+ if (val.klass != "")
328
+ oboe_bson_append_string(&(this->bbuf), "C", (val.klass).c_str());
329
+ if (val.file != "")
330
+ oboe_bson_append_string(&(this->bbuf), "F", (val.file).c_str());
331
+ if (val.lineno > 0)
332
+ oboe_bson_append_long(&(this->bbuf), "L", (int64_t)val.lineno);
333
+
334
+ oboe_bson_append_finish_object(&(this->bbuf));
335
+ }
336
+ oboe_bson_append_finish_object(&(this->bbuf));
337
+ return true;
338
+ }
339
+
340
+ bool Event::addEdge(oboe_metadata_t *md) {
341
+ return oboe_event_add_edge(this, md) == 0;
342
+ }
343
+
344
+ bool Event::addEdgeStr(const std::string &val) {
345
+ return oboe_event_add_edge_fromstr(this, val.c_str(), val.size()) == 0;
346
+ }
347
+
348
+ bool Event::addHostname() {
349
+ static char oboe_hostname[HOST_NAME_MAX + 1] = {'\0'}; // Flawfinder: ignore
350
+
351
+ if (oboe_hostname[0] == '\0') {
352
+ (void)gethostname(oboe_hostname, sizeof(oboe_hostname) - 1);
353
+ if (oboe_hostname[0] == '\0') {
354
+ // Something is wrong but we don't want to to report this more than
355
+ // once so we'll set it to a minimal non-empty string.
356
+ OBOE_DEBUG_LOG_WARNING(OBOE_MODULE_LIBOBOE, "Failed to get hostname, setting it to '?'");
357
+ oboe_hostname[0] = '?';
358
+ oboe_hostname[1] = '\0';
359
+ }
360
+ }
361
+ return oboe_event_add_info(this, "Hostname", oboe_hostname) == 0;
362
+ }
363
+
364
+ bool Event::addContextOpId(const oboe_metadata_t *md) {
365
+ char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
366
+ oboe_metadata_tostr(md, buf, OBOE_MAX_METADATA_PACK_LEN);
367
+ buf[58] = '\0';
368
+
369
+ return oboe_event_add_info(this, "ContextOpId", &buf[42]);
370
+ }
371
+
372
+ bool Event::addSpanRef(const oboe_metadata_t *md) {
373
+ char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
374
+ oboe_metadata_tostr(md, buf, OBOE_MAX_METADATA_PACK_LEN);
375
+ buf[58] = '\0';
376
+
377
+ return oboe_event_add_info(this, "SpanRef", &buf[42]);
378
+ }
379
+
380
+ bool Event::addProfileEdge(std::string id) {
381
+ return oboe_event_add_info(this, "Edge", id.c_str());
382
+ }
383
+
384
+ /**
385
+ * Get a new copy of this metadata.
386
+ *
387
+ * NOTE: The returned object must be "delete"d.
388
+ */
389
+ Metadata *Event::getMetadata() {
390
+ return new Metadata(&this->metadata);
391
+ }
392
+
393
+ std::string Event::opIdString() {
394
+ char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
395
+ oboe_metadata_tostr(&this->metadata, buf, OBOE_MAX_METADATA_PACK_LEN);
396
+ buf[58] = '\0';
397
+ return std::string(&buf[42]);
398
+ }
399
+
400
+ std::string Event::metadataString() {
401
+ char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
402
+
403
+ int rc = oboe_metadata_tostr(&this->metadata, buf, sizeof(buf) - 1);
404
+ if (rc == 0) {
405
+ return std::string(buf);
406
+ } else {
407
+ return std::string(); // throw exception?
408
+ }
409
+ }
410
+
411
+ /**
412
+ * Report this event.
413
+ *
414
+ * This sends the event using the default reporter.
415
+ *
416
+ * @return True on success; otherwise an error message is logged.
417
+ */
418
+ bool Event::send() {
419
+ return (oboe_event_send(OBOE_SEND_EVENT, this, Context::get()) >= 0);
420
+ }
421
+
422
+ /**
423
+ * Report a Profiling Event
424
+ * needs to be sent raw, so that the timestamp doesn't get altered
425
+ */
426
+ bool Event::sendProfiling() {
427
+ int retval = -1;
428
+
429
+ this->bb_str = oboe_bson_buffer_finish(&this->bbuf);
430
+ if (!this->bb_str)
431
+ return -1;
432
+
433
+ size_t len = (size_t)(this->bbuf.cur - this->bbuf.buf);
434
+ retval = oboe_raw_send(OBOE_SEND_PROFILING, this->bb_str, len);
435
+
436
+ if (retval < 0)
437
+ OBOE_DEBUG_LOG_ERROR(OBOE_MODULE_LIBOBOE, "Raw send failed - reporter returned %d", retval);
438
+
439
+ return (retval >= 0);
440
+ }
441
+
442
+ /////// Span ///////
443
+
444
+ std::string Span::createSpan(const char *transaction, const char *domain, const int64_t duration, const int has_error, const char *service_name) {
445
+ oboe_span_params_t params;
446
+ memset(&params, 0, sizeof(oboe_span_params_t));
447
+ params.version = 1;
448
+ params.transaction = transaction;
449
+ params.domain = domain;
450
+ params.duration = duration;
451
+ params.has_error = has_error;
452
+ params.service = service_name;
453
+
454
+ char buffer[OBOE_TRANSACTION_NAME_MAX_LENGTH + 1]; // Flawfinder: ignore
455
+ int len = oboe_span(buffer, sizeof(buffer), &params);
456
+ if (len > 0) {
457
+ return std::string(buffer);
458
+ } else {
459
+ return "";
460
+ }
461
+ }
462
+
463
+ std::string Span::createHttpSpan(const char *transaction, const char *url, const char *domain, const int64_t duration,
464
+ const int status, const char *method, const int has_error, const char *service_name) {
465
+ oboe_span_params_t params;
466
+ memset(&params, 0, sizeof(oboe_span_params_t));
467
+ params.version = 1;
468
+ params.transaction = transaction;
469
+ params.url = url;
470
+ params.domain = domain;
471
+ params.duration = duration;
472
+ params.status = status;
473
+ params.method = method;
474
+ params.has_error = has_error;
475
+ params.service = service_name;
476
+
477
+ char buffer[OBOE_TRANSACTION_NAME_MAX_LENGTH + 1]; // Flawfinder: ignore
478
+ int len = oboe_http_span(buffer, sizeof(buffer), &params);
479
+ if (len > 0) {
480
+ return std::string(buffer);
481
+ } else {
482
+ return "";
483
+ }
484
+ }
485
+
486
+ /////// MetricTags ///////
487
+
488
+ MetricTags::MetricTags(size_t count) {
489
+ tags = new oboe_metric_tag_t[count];
490
+ for (size_t i = 0; i < count; i++) {
491
+ tags[i].key = nullptr;
492
+ tags[i].value = nullptr;
493
+ }
494
+ size = count;
495
+ }
496
+
497
+ MetricTags::~MetricTags() {
498
+ for (size_t i = 0; i < size; i++) {
499
+ delete tags[i].key; tags[i].key = nullptr;
500
+ delete tags[i].value; tags[i].value = nullptr;
501
+ }
502
+ delete[] tags;
503
+ }
504
+
505
+ bool MetricTags::add(size_t index, const char *k, const char *v) {
506
+ if (index < size) {
507
+ tags[index].key = strdup(k);
508
+ tags[index].value = strdup(v);
509
+ return (tags[index].key != nullptr && tags[index].value != nullptr);
510
+ }
511
+ return false;
512
+ }
513
+ oboe_metric_tag_t *MetricTags::get() const {
514
+ return tags;
515
+ }
516
+
517
+ /////// CustomMetrics ///////
518
+
519
+ int CustomMetrics::summary(const char *name, const double value, const int count, const int host_tag,
520
+ const char *service_name, const MetricTags *tags, size_t tags_count) {
521
+ if (tags->size < tags_count) {
522
+ tags_count = tags->size;
523
+ }
524
+ return oboe_custom_metric_summary(name, value, count, host_tag, service_name, tags->get(), tags_count);
525
+ }
526
+
527
+ int CustomMetrics::increment(const char *name, const int count, const int host_tag,
528
+ const char *service_name, const MetricTags *tags, size_t tags_count) {
529
+ if (tags->size < tags_count) {
530
+ tags_count = tags->size;
531
+ }
532
+ return oboe_custom_metric_increment(name, count, host_tag, service_name, tags->get(), tags_count);
533
+ }
534
+
535
+ /////// Profiling ///////
536
+
537
+ // adding this to have a proper interface, even though it just
538
+ // returns the return value of the oboe function
539
+ // 0 indicates not to profile, returns -1 if the collector hasn't sent anything
540
+ int OboeProfiling::get_interval() {
541
+ return oboe_get_profiling_interval();
542
+ }
543
+
544
+ /////// Reporter ///////
545
+
546
+ Reporter::Reporter(
547
+ std::string hostname_alias, // optional hostname alias
548
+ int log_level, // level at which log messages will be written to log file (0-6)
549
+ std::string log_file_path, // file name including path for log file
550
+
551
+ int max_transactions, // maximum number of transaction names to track
552
+ int max_flush_wait_time, // maximum wait time for flushing data before terminating in milli seconds
553
+ int events_flush_interval, // events flush timeout in seconds (threshold for batching messages before sending off)
554
+ int max_request_size_bytes, // events flush batch size in KB (threshold for batching messages before sending off)
555
+
556
+ std::string reporter, // the reporter to be used ("ssl", "upd", "file", "null")
557
+ std::string host, // collector endpoint (reporter=ssl), udp address (reporter=udp), or file path (reporter=file)
558
+ std::string service_key, // the service key (also known as access_key)
559
+ std::string trusted_path, // path to the SSL certificate (only for ssl)
560
+
561
+ int buffer_size, // size of the message buffer
562
+ int trace_metrics, // flag indicating if trace metrics reporting should be enabled (default) or disabled
563
+ int histogram_precision, // the histogram precision (only for ssl)
564
+ double token_bucket_capacity, // custom token bucket capacity
565
+ double token_bucket_rate, // custom token bucket rate
566
+ int file_single, // use single files in file reporter for each event
567
+
568
+ int ec2_metadata_timeout, // the timeout (milli seconds) for retrieving EC2 metadata
569
+ std::string grpc_proxy, // HTTP proxy address and port to be used for the gRPC connection
570
+ int stdout_clear_nonblocking, // flag indicating if the O_NONBLOCK flag on stdout should be cleared,
571
+ // only used in lambda reporter (off=0, on=1, default off)
572
+ int is_grpc_clean_hack_enabled // flag indicating if custom grpc clean hack enabled (default 0)
573
+ ) {
574
+ oboe_init_options_t options;
575
+ memset(&options, 0, sizeof(options));
576
+ options.version = 12;
577
+ oboe_init_options_set_defaults(&options);
578
+
579
+ if (hostname_alias != "") {
580
+ options.hostname_alias = hostname_alias.c_str();
581
+ }
582
+ options.log_level = log_level;
583
+ options.log_file_path = log_file_path.c_str();
584
+ options.max_transactions = max_transactions;
585
+ options.max_flush_wait_time = max_flush_wait_time;
586
+ options.events_flush_interval = events_flush_interval;
587
+ options.max_request_size_bytes = max_request_size_bytes;
588
+ if (reporter != "") {
589
+ options.reporter = reporter.c_str();
590
+ }
591
+ if (host != "") {
592
+ options.host = host.c_str();
593
+ }
594
+ if (service_key != "") {
595
+ options.service_key = service_key.c_str();
596
+ }
597
+ if (trusted_path != "") {
598
+ options.trusted_path = trusted_path.c_str();
599
+ }
600
+ options.buffer_size = buffer_size;
601
+ options.trace_metrics = trace_metrics;
602
+ options.histogram_precision = histogram_precision;
603
+ options.token_bucket_capacity = token_bucket_capacity;
604
+ options.token_bucket_rate = token_bucket_rate;
605
+ options.file_single = file_single;
606
+ options.ec2_metadata_timeout = ec2_metadata_timeout;
607
+ if (grpc_proxy != "") {
608
+ options.proxy = grpc_proxy.c_str();
609
+ }
610
+ options.stdout_clear_nonblocking = stdout_clear_nonblocking;
611
+ options.is_grpc_clean_hack_enabled = is_grpc_clean_hack_enabled;
612
+ init_status = oboe_init(&options);
613
+ }
614
+
615
+ Reporter::~Reporter() {
616
+ oboe_reporter_destroy(this);
617
+ }
618
+
619
+ bool Reporter::sendReport(Event *evt) {
620
+ return oboe_event_send(OBOE_SEND_EVENT, evt, Context::get()) >= 0;
621
+ }
622
+
623
+ bool Reporter::sendReport(Event *evt, oboe_metadata_t *md) {
624
+ return oboe_event_send(OBOE_SEND_EVENT, evt, md) >= 0;
625
+ }
626
+
627
+ bool Reporter::sendStatus(Event *evt) {
628
+ return oboe_event_send(OBOE_SEND_STATUS, evt, Context::get()) >= 0;
629
+ }
630
+
631
+ bool Reporter::sendStatus(Event *evt, oboe_metadata_t *md) {
632
+ return oboe_event_send(OBOE_SEND_STATUS, evt, md) >= 0;
633
+ }
634
+
635
+ void Reporter::flush() {
636
+ oboe_reporter_flush();
637
+ }
638
+
639
+ std::string Reporter::getType() {
640
+ const char* type = oboe_get_reporter_type();
641
+ return type ? std::string(type) : "";
642
+ }
643
+
644
+ /////// Config ///////
645
+
646
+ bool Config::checkVersion(int version, int revision) {
647
+ return (oboe_config_check_version(version, revision) != 0);
648
+ }
649
+
650
+ std::string Config::getVersionString() {
651
+ return oboe_config_get_version_string();
652
+ }