solarwinds_apm 5.0.0

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