solarwinds_apm 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }