solarwinds_apm 6.1.2 → 7.0.0.prev1

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -2
  3. data/lib/solarwinds_apm/api/current_trace_info.rb +10 -6
  4. data/lib/solarwinds_apm/api/custom_metrics.rb +8 -25
  5. data/lib/solarwinds_apm/api/tracing.rb +12 -27
  6. data/lib/solarwinds_apm/api/transaction_name.rb +6 -10
  7. data/lib/solarwinds_apm/config.rb +1 -1
  8. data/lib/solarwinds_apm/constants.rb +1 -0
  9. data/lib/solarwinds_apm/noop/api.rb +5 -2
  10. data/lib/solarwinds_apm/noop.rb +0 -24
  11. data/lib/solarwinds_apm/opentelemetry/otlp_processor.rb +90 -69
  12. data/lib/solarwinds_apm/opentelemetry/solarwinds_propagator.rb +0 -2
  13. data/lib/solarwinds_apm/opentelemetry/solarwinds_response_propagator.rb +5 -4
  14. data/lib/solarwinds_apm/opentelemetry.rb +5 -7
  15. data/lib/solarwinds_apm/otel_native_config.rb +177 -0
  16. data/lib/solarwinds_apm/patch/README.md +15 -0
  17. data/lib/solarwinds_apm/{noop/metadata.rb → sampling/dice.rb} +19 -17
  18. data/lib/solarwinds_apm/sampling/http_sampler.rb +87 -0
  19. data/lib/solarwinds_apm/sampling/json_sampler.rb +52 -0
  20. data/lib/solarwinds_apm/sampling/metrics.rb +38 -0
  21. data/lib/solarwinds_apm/sampling/oboe_sampler.rb +348 -0
  22. data/lib/solarwinds_apm/sampling/sampler.rb +197 -0
  23. data/lib/solarwinds_apm/sampling/sampling_constants.rb +127 -0
  24. data/lib/solarwinds_apm/sampling/sampling_patch.rb +49 -0
  25. data/lib/solarwinds_apm/sampling/setting_example.txt +1 -0
  26. data/lib/solarwinds_apm/{noop/context.rb → sampling/settings.rb} +14 -25
  27. data/lib/solarwinds_apm/sampling/token_bucket.rb +126 -0
  28. data/lib/solarwinds_apm/sampling/trace_options.rb +100 -0
  29. data/lib/solarwinds_apm/{patch.rb → sampling.rb} +20 -4
  30. data/lib/solarwinds_apm/{noop/span.rb → support/aws_resource_detector.rb} +5 -18
  31. data/lib/solarwinds_apm/support/logger_formatter.rb +1 -1
  32. data/lib/solarwinds_apm/support/logging_log_event.rb +1 -1
  33. data/lib/solarwinds_apm/support/lumberjack_formatter.rb +1 -1
  34. data/lib/solarwinds_apm/support/otlp_endpoint.rb +99 -0
  35. data/lib/solarwinds_apm/support/resource_detector/aws/beanstalk.rb +51 -0
  36. data/lib/solarwinds_apm/support/resource_detector/aws/ec2.rb +145 -0
  37. data/lib/solarwinds_apm/support/resource_detector/aws/ecs.rb +173 -0
  38. data/lib/solarwinds_apm/support/resource_detector/aws/eks.rb +174 -0
  39. data/lib/solarwinds_apm/support/resource_detector/aws/lambda.rb +66 -0
  40. data/lib/solarwinds_apm/support/resource_detector.rb +192 -0
  41. data/lib/solarwinds_apm/support/service_key_checker.rb +12 -6
  42. data/lib/solarwinds_apm/support/transaction_settings.rb +6 -0
  43. data/lib/solarwinds_apm/support/txn_name_manager.rb +54 -9
  44. data/lib/solarwinds_apm/support/utils.rb +9 -0
  45. data/lib/solarwinds_apm/support.rb +3 -4
  46. data/lib/solarwinds_apm/version.rb +4 -4
  47. data/lib/solarwinds_apm.rb +27 -73
  48. metadata +99 -40
  49. data/ext/oboe_metal/extconf.rb +0 -168
  50. data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.sha256 +0 -1
  51. data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.sha256 +0 -1
  52. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.sha256 +0 -1
  53. data/ext/oboe_metal/lib/liboboe-1.0-lambda-aarch64.so.sha256 +0 -1
  54. data/ext/oboe_metal/lib/liboboe-1.0-lambda-x86_64.so.sha256 +0 -1
  55. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.sha256 +0 -1
  56. data/ext/oboe_metal/src/VERSION +0 -1
  57. data/ext/oboe_metal/src/bson/bson.h +0 -220
  58. data/ext/oboe_metal/src/bson/platform_hacks.h +0 -91
  59. data/ext/oboe_metal/src/init_solarwinds_apm.cc +0 -18
  60. data/ext/oboe_metal/src/oboe.h +0 -930
  61. data/ext/oboe_metal/src/oboe_api.cpp +0 -793
  62. data/ext/oboe_metal/src/oboe_api.h +0 -621
  63. data/ext/oboe_metal/src/oboe_debug.h +0 -17
  64. data/ext/oboe_metal/src/oboe_swig_wrap.cc +0 -11045
  65. data/lib/oboe_metal.rb +0 -187
  66. data/lib/solarwinds_apm/cert/star.appoptics.com.issuer.crt +0 -24
  67. data/lib/solarwinds_apm/oboe_init_options.rb +0 -222
  68. data/lib/solarwinds_apm/opentelemetry/solarwinds_exporter.rb +0 -239
  69. data/lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb +0 -174
  70. data/lib/solarwinds_apm/opentelemetry/solarwinds_sampler.rb +0 -333
  71. data/lib/solarwinds_apm/otel_config.rb +0 -174
  72. data/lib/solarwinds_apm/otel_lambda_config.rb +0 -56
  73. data/lib/solarwinds_apm/patch/dummy_patch.rb +0 -12
  74. data/lib/solarwinds_apm/support/oboe_tracing_mode.rb +0 -33
  75. data/lib/solarwinds_apm/support/support_report.rb +0 -99
  76. data/lib/solarwinds_apm/support/transaction_cache.rb +0 -57
  77. data/lib/solarwinds_apm/support/x_trace_options.rb +0 -138
@@ -1,793 +0,0 @@
1
- /**
2
- * @file oboe_api.cpp - C++ liboboe wrapper primarily used via swig interfaces
3
- * by the python and ruby agents
4
- */
5
-
6
- #include "oboe_api.h"
7
- #include <algorithm>
8
-
9
- Metadata::Metadata(const oboe_metadata_t *md) {
10
- oboe_metadata_copy(this, md);
11
- }
12
-
13
- Metadata::~Metadata() {
14
- oboe_metadata_destroy(this);
15
- }
16
-
17
- Metadata *Metadata::makeRandom(bool sampled) {
18
- oboe_metadata_t md;
19
- oboe_metadata_init(&md);
20
- oboe_metadata_random(&md);
21
-
22
- if (sampled) md.flags |= XTR_FLAGS_SAMPLED;
23
-
24
- return new Metadata(&md); // copies md
25
- }
26
-
27
- Metadata *Metadata::copy() {
28
- return new Metadata(this);
29
- }
30
-
31
- bool Metadata::isValid() {
32
- return oboe_metadata_is_valid(this);
33
- }
34
-
35
- bool Metadata::isSampled() {
36
- return oboe_metadata_is_sampled(this);
37
- }
38
-
39
- Metadata *Metadata::fromString(const std::string& s) {
40
- oboe_metadata_t md;
41
- oboe_metadata_init(&md);
42
- oboe_metadata_fromstr(&md, s.data(), s.size());
43
- return new Metadata(&md); // copies md
44
- }
45
-
46
- oboe_metadata_t *Metadata::metadata() {
47
- return this;
48
- }
49
-
50
- Event *Metadata::createEvent() {
51
- return new Event(this);
52
- }
53
-
54
- #ifdef SWIGJAVA
55
- std::string Metadata::toStr() {
56
- #else
57
- std::string Metadata::toString() {
58
- #endif
59
- char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
60
-
61
- int rc = oboe_metadata_tostr(this, buf, sizeof(buf) - 1);
62
- if (rc == 0) {
63
- return std::string(buf);
64
- } else {
65
- return std::string(); // throw exception?
66
- }
67
- }
68
-
69
- /////// Context ///////
70
-
71
-
72
- void Context::setTracingMode(int newMode) {
73
- oboe_settings_mode_set(newMode);
74
- }
75
-
76
- void Context::setTriggerMode(int newMode) {
77
- oboe_settings_trigger_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(const 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(const std::string& service_key) {
201
- char service_key_cpy[71 + 1 + 256] = {0}; // Flawfinder: ignore, key=71, colon=1, name<=255
202
- std::copy_n(service_key.begin(), std::min(service_key.size(), sizeof(service_key_cpy)), std::begin(service_key_cpy));
203
- int len = strlen(service_key_cpy); // Flawfinder: ignore
204
- int ret = oboe_validate_transform_service_name(service_key_cpy, &len);
205
-
206
- if (ret == -1) {
207
- return "";
208
- }
209
-
210
- return std::string(service_key_cpy);
211
- }
212
-
213
- void Context::shutdown() {
214
- oboe_shutdown();
215
- }
216
-
217
- int Context::isReady(unsigned int timeout) {
218
- return oboe_is_ready(timeout);
219
- }
220
-
221
- bool Context::isLambda() {
222
- return (bool) oboe_is_lambda();
223
- }
224
-
225
- Event *Context::createEvent() {
226
- return new Event(Context::get());
227
- }
228
-
229
- Event *Context::startTrace() {
230
- oboe_metadata_t *md = Context::get();
231
- oboe_metadata_random(md);
232
- return new Event();
233
- }
234
-
235
- Event* Context::createEntry(const oboe_metadata_t *md, int64_t timestamp, const oboe_metadata_t *parent_md) {
236
- /**
237
- * As liboboe assumed to manage metadata, liboboe needs to make sure all events are from the same trace.
238
- * While Otel doesn't require liboboe to manage metadata,
239
- * we need to set the thread local metadata the same task id as input parameter md but a different op_id.
240
- */
241
- auto thread_local_md = Context::get();
242
- // set the thread_local_md to md to fulfill the same trace id requirement in Reporter::sendReport & oboe_event_send
243
- oboe_metadata_copy(thread_local_md, md);
244
- // reset op_id to zeros to fulfill the different op id requirement in Reporter::sendReport & oboe_event_send
245
- memset(thread_local_md->ids.op_id, 0, OBOE_MAX_OP_ID_LEN);
246
-
247
- auto event = new Event();
248
- oboe_event_destroy(event);
249
- oboe_event_init(event, md, md->ids.op_id);
250
-
251
- event->addInfo("Label", std::string("entry"));
252
- event->addInfo("Timestamp_u", timestamp);
253
- if(parent_md) {
254
- event->addEdge(const_cast<oboe_metadata*>(parent_md));
255
- }
256
- return event;
257
- }
258
-
259
- Event* Context::createEvent(int64_t timestamp) {
260
- auto event = new Event(Context::get());
261
- event->addInfo("Timestamp_u", timestamp);
262
- return event;
263
- }
264
-
265
- Event* Context::createExit(int64_t timestamp) {
266
- auto event = createEvent(timestamp);
267
- event->addInfo("Label", std::string("exit"));
268
- return event;
269
- }
270
-
271
- /////// Event ///////
272
- Event::Event() {
273
- oboe_event_init(this, Context::get(), NULL);
274
- }
275
-
276
- Event::Event(const oboe_metadata_t *md, bool addEdge) {
277
- // both methods copy metadata from md -> this
278
- if (addEdge) {
279
- // create_event automatically adds edge in event to md
280
- oboe_metadata_create_event(md, this);
281
- } else {
282
- // initializes new Event with this md's task_id & new random op_id; no edges set
283
- oboe_event_init(this, md, NULL);
284
- }
285
- }
286
-
287
- Event::~Event() {
288
- oboe_event_destroy(this);
289
- }
290
-
291
- Event *Event::startTrace(const oboe_metadata_t *md) {
292
- return new Event(md, false);
293
- }
294
-
295
- // called e.g. from Python e.addInfo("Key", None) & Ruby e.addInfo("Key", nil)
296
- bool Event::addInfo(const char *key, void *val) {
297
- // oboe_event_add_info(evt, key, NULL) does nothing
298
- (void)key;
299
- (void)val;
300
- return true;
301
- }
302
-
303
- bool Event::addInfo(const char *key, const std::string& val) {
304
- return oboe_event_add_info(this, key, val.c_str()) == 0;
305
- }
306
-
307
- bool Event::addInfo(const char *key, long val) {
308
- int64_t val_ = val;
309
- return oboe_event_add_info_int64(this, key, val_) == 0;
310
- }
311
-
312
- bool Event::addInfo(const char *key, double val) {
313
- return oboe_event_add_info_double(this, key, val) == 0;
314
- }
315
-
316
- bool Event::addInfo(const char *key, bool val) {
317
- return oboe_event_add_info_bool(this, key, val) == 0;
318
- }
319
-
320
- /*
321
- * this function was added for profiling
322
- * to report the timestamps of omitted snapshots
323
- */
324
- bool Event::addInfo(const char *key, const long *vals, int num) {
325
- oboe_bson_append_start_array(&(this->bbuf), key);
326
- for (int i = 0; i < num; i++) {
327
- oboe_bson_append_long(&(this->bbuf), std::to_string(i).c_str(), (int64_t)vals[i]);
328
- }
329
- oboe_bson_append_finish_object(&(this->bbuf));
330
- return true;
331
- }
332
-
333
- #ifndef SWIG
334
- /*
335
- * A profiling specific addInfo function
336
- * to add the frames that make up a snapshot
337
- */
338
- bool Event::addInfo(const char *key, const std::vector<FrameData> &vals) {
339
- oboe_bson_append_start_array(&(this->bbuf), key);
340
- int i = 0;
341
- for (FrameData val : vals) {
342
- oboe_bson_append_start_object(&(this->bbuf), std::to_string(i).c_str());
343
- i++;
344
-
345
- if (val.method != "")
346
- oboe_bson_append_string(&(this->bbuf), "M", (val.method).c_str());
347
- if (val.klass != "")
348
- oboe_bson_append_string(&(this->bbuf), "C", (val.klass).c_str());
349
- if (val.file != "")
350
- oboe_bson_append_string(&(this->bbuf), "F", (val.file).c_str());
351
- if (val.lineno > 0)
352
- oboe_bson_append_long(&(this->bbuf), "L", (int64_t)val.lineno);
353
-
354
- oboe_bson_append_finish_object(&(this->bbuf));
355
- }
356
- oboe_bson_append_finish_object(&(this->bbuf));
357
- return true;
358
- }
359
- #endif
360
-
361
- bool Event::addEdge(oboe_metadata_t *md) {
362
- return oboe_event_add_edge(this, md) == 0;
363
- }
364
-
365
- bool Event::addHostname() {
366
- char host[256] = {0};
367
- gethostname(host, sizeof(host)/sizeof(char));
368
- return oboe_event_add_info(this, "Hostname", host) == 0;
369
- }
370
-
371
- bool Event::addContextOpId(const oboe_metadata_t *md) {
372
- char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
373
- oboe_metadata_tostr(md, buf, OBOE_MAX_METADATA_PACK_LEN);
374
- buf[58] = '\0';
375
-
376
- return oboe_event_add_info(this, "ContextOpId", &buf[42]);
377
- }
378
-
379
- bool Event::addSpanRef(const oboe_metadata_t *md) {
380
- char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
381
- oboe_metadata_tostr(md, buf, OBOE_MAX_METADATA_PACK_LEN);
382
- buf[58] = '\0';
383
-
384
- return oboe_event_add_info(this, "SpanRef", &buf[42]);
385
- }
386
-
387
- bool Event::addProfileEdge(std::string id) {
388
- return oboe_event_add_info(this, "Edge", id.c_str());
389
- }
390
-
391
- /**
392
- * Get a new copy of this metadata.
393
- *
394
- * NOTE: The returned object must be "delete"d.
395
- */
396
- Metadata *Event::getMetadata() {
397
- return new Metadata(&this->metadata);
398
- }
399
-
400
- /**
401
- * used by Ruby profiling to manage edges separately from oboe
402
- */
403
- std::string Event::opIdString() {
404
- char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
405
- oboe_metadata_tostr(&this->metadata, buf, OBOE_MAX_METADATA_PACK_LEN);
406
- buf[52] = '\0';
407
- return std::string(&buf[36]);
408
- }
409
-
410
- std::string Event::metadataString() {
411
- char buf[OBOE_MAX_METADATA_PACK_LEN]; // Flawfinder: ignore
412
-
413
- int rc = oboe_metadata_tostr(&this->metadata, buf, sizeof(buf) - 1);
414
- if (rc == 0) {
415
- return std::string(buf);
416
- } else {
417
- return std::string(); // throw exception?
418
- }
419
- }
420
-
421
- /**
422
- * Report this event.
423
- *
424
- * This sends the event using the default reporter.
425
- *
426
- * @return True on success; otherwise an error message is logged.
427
- */
428
- bool Event::send(bool with_system_timestamp) {
429
- if (with_system_timestamp) {
430
- return (oboe_event_send(OBOE_SEND_EVENT, this, Context::get()) >= 0);
431
- } else {
432
- return (oboe_event_send_without_timestamp(OBOE_SEND_EVENT, this, Context::get()) >= 0);
433
- }
434
- }
435
-
436
- /**
437
- * Report a Profiling Event
438
- * needs to be sent raw, so that the timestamp doesn't get altered
439
- */
440
- bool Event::sendProfiling() {
441
- int retval = -1;
442
-
443
- this->bb_str = oboe_bson_buffer_finish(&this->bbuf);
444
- if (!this->bb_str)
445
- return -1;
446
-
447
- size_t len = (size_t)(this->bbuf.cur - this->bbuf.buf);
448
- retval = oboe_raw_send(OBOE_SEND_PROFILING, this->bb_str, len);
449
-
450
- return (retval >= 0);
451
- }
452
-
453
- /////// Span ///////
454
-
455
- std::string Span::createSpan(const char *transaction, const char *domain, const int64_t duration, const int has_error, const char *service_name) {
456
- oboe_span_params_t params;
457
- memset(&params, 0, sizeof(oboe_span_params_t));
458
- params.version = 1;
459
- params.transaction = transaction;
460
- params.domain = domain;
461
- params.duration = duration;
462
- params.has_error = has_error;
463
- params.service = service_name;
464
-
465
- char buffer[OBOE_TRANSACTION_NAME_MAX_LENGTH + 1]; // Flawfinder: ignore
466
- int len = oboe_span(buffer, sizeof(buffer), &params);
467
- if (len > 0) {
468
- return std::string(buffer);
469
- } else {
470
- return "";
471
- }
472
- }
473
-
474
- std::string Span::createHttpSpan(const char *transaction, const char *url, const char *domain, const int64_t duration,
475
- const int status, const char *method, const int has_error, const char *service_name) {
476
- oboe_span_params_t params;
477
- memset(&params, 0, sizeof(oboe_span_params_t));
478
- params.version = 1;
479
- params.transaction = transaction;
480
- params.url = url;
481
- params.domain = domain;
482
- params.duration = duration;
483
- params.status = status;
484
- params.method = method;
485
- params.has_error = has_error;
486
- params.service = service_name;
487
-
488
- char buffer[OBOE_TRANSACTION_NAME_MAX_LENGTH + 1]; // Flawfinder: ignore
489
- int len = oboe_http_span(buffer, sizeof(buffer), &params);
490
- if (len > 0) {
491
- return std::string(buffer);
492
- } else {
493
- return "";
494
- }
495
- }
496
-
497
- /////// MetricTags ///////
498
-
499
- MetricTags::MetricTags(size_t count) {
500
- tags = new oboe_metric_tag_t[count];
501
- for (size_t i = 0; i < count; i++) {
502
- tags[i].key = nullptr;
503
- tags[i].value = nullptr;
504
- }
505
- size = count;
506
- }
507
-
508
- MetricTags::~MetricTags() {
509
- for (size_t i = 0; i < size; i++) {
510
- if (tags[i].key) {
511
- free(tags[i].key);
512
- tags[i].key = nullptr;
513
- }
514
- if (tags[i].value) {
515
- free(tags[i].value);
516
- tags[i].value = nullptr;
517
- }
518
- }
519
- delete[] tags;
520
- }
521
-
522
- bool MetricTags::add(size_t index, const char *k, const char *v) {
523
- if (index < size) {
524
- tags[index].key = strdup(k);
525
- tags[index].value = strdup(v);
526
- return (tags[index].key != nullptr && tags[index].value != nullptr);
527
- }
528
- return false;
529
- }
530
- oboe_metric_tag_t *MetricTags::get() const {
531
- return tags;
532
- }
533
-
534
- /////// CustomMetrics ///////
535
-
536
- int CustomMetrics::summary(const char *name, const double value, const int count, const int host_tag,
537
- const char *service_name, const MetricTags *tags, size_t tags_count) {
538
- if (tags->size < tags_count) {
539
- tags_count = tags->size;
540
- }
541
- return oboe_custom_metric_summary(name, value, count, host_tag, service_name, tags->get(), tags_count);
542
- }
543
-
544
- int CustomMetrics::increment(const char *name, const int count, const int host_tag,
545
- const char *service_name, const MetricTags *tags, size_t tags_count) {
546
- if (tags->size < tags_count) {
547
- tags_count = tags->size;
548
- }
549
- return oboe_custom_metric_increment(name, count, host_tag, service_name, tags->get(), tags_count);
550
- }
551
-
552
- /////// Profiling ///////
553
-
554
- // adding this to have a proper interface, even though it just
555
- // returns the return value of the oboe function
556
- // 0 indicates not to profile, returns -1 if the collector hasn't sent anything
557
- int OboeProfiling::get_interval() {
558
- return oboe_get_profiling_interval();
559
- }
560
-
561
- /////// Reporter ///////
562
-
563
- Reporter::Reporter(
564
- std::string hostname_alias, // optional hostname alias
565
- int log_level, // level at which log messages will be written to log file (0-6)
566
- std::string log_file_path, // file name including path for log file
567
-
568
- int max_transactions, // maximum number of transaction names to track
569
- int max_flush_wait_time, // maximum wait time for flushing data before terminating in milli seconds
570
- int events_flush_interval, // events flush timeout in seconds (threshold for batching messages before sending off)
571
- int max_request_size_bytes, // events flush batch size in KB (threshold for batching messages before sending off)
572
-
573
- std::string reporter, // the reporter to be used ("ssl", "upd", "file", "null")
574
- std::string host, // collector endpoint (reporter=ssl), udp address (reporter=udp), or file path (reporter=file)
575
- std::string service_key, // the service key (also known as access_key)
576
- std::string certificates, // content of SSL certificates, passed to gRPC::SslCredentialsOptions() for collector connection verification
577
-
578
- int buffer_size, // size of the message buffer
579
- int trace_metrics, // flag indicating if trace metrics reporting should be enabled (default) or disabled
580
- int histogram_precision, // the histogram precision (only for ssl)
581
- double token_bucket_capacity, // custom token bucket capacity
582
- double token_bucket_rate, // custom token bucket rate
583
- int file_single, // use single files in file reporter for each event
584
-
585
- int ec2_metadata_timeout, // the timeout (milli seconds) for retrieving EC2 metadata
586
- std::string grpc_proxy, // HTTP proxy address and port to be used for the gRPC connection
587
- int stdout_clear_nonblocking, // flag indicating if the O_NONBLOCK flag on stdout should be cleared,
588
- // only used in lambda reporter (off=0, on=1, default off)
589
- int metric_format, // flag indicating the format of metric (0 = Both; 1 = TransactionResponseTime only; 2 = ResponseTime only; default = 0)
590
- int log_type, // log type (0 = stderr; 1 = stdout; 2 = file; 3 = null; 4 = disabled; default = 0)
591
- int defer_init // defer init (0 = disable; 1 = enabled, parent process will not init oboe but fork child process will init oboe; default = 0)
592
- ) {
593
- oboe_init_options_t options;
594
- memset(&options, 0, sizeof(options));
595
- options.version = 17;
596
- oboe_init_options_set_defaults(&options);
597
-
598
- if (hostname_alias != "") {
599
- options.hostname_alias = hostname_alias.c_str();
600
- }
601
- options.log_level = log_level;
602
- options.log_file_path = log_file_path.c_str();
603
- options.max_transactions = max_transactions;
604
- options.max_flush_wait_time = max_flush_wait_time;
605
- options.events_flush_interval = events_flush_interval;
606
- options.max_request_size_bytes = max_request_size_bytes;
607
- if (reporter != "") {
608
- options.reporter = reporter.c_str();
609
- }
610
- if (host != "") {
611
- options.host = host.c_str();
612
- }
613
- if (service_key != "") {
614
- options.service_key = service_key.c_str();
615
- }
616
- if (certificates != "") {
617
- options.certificates = certificates.c_str();
618
- }
619
- options.buffer_size = buffer_size;
620
- options.trace_metrics = trace_metrics;
621
- options.histogram_precision = histogram_precision;
622
- options.token_bucket_capacity = token_bucket_capacity;
623
- options.token_bucket_rate = token_bucket_rate;
624
- options.file_single = file_single;
625
- options.ec2_metadata_timeout = ec2_metadata_timeout;
626
- if (grpc_proxy != "") {
627
- options.proxy = grpc_proxy.c_str();
628
- }
629
- options.stdout_clear_nonblocking = stdout_clear_nonblocking;
630
- options.metric_format = metric_format;
631
- options.log_type = log_type;
632
- options.defer_init = defer_init;
633
- init_status = oboe_init(&options);
634
- }
635
-
636
- Reporter::~Reporter() {
637
- oboe_shutdown();
638
- }
639
-
640
- bool Reporter::sendReport(Event *evt, bool with_system_timestamp) {
641
- if (with_system_timestamp) {
642
- return oboe_event_send(OBOE_SEND_EVENT, evt, Context::get()) >= 0;
643
- } else {
644
- return oboe_event_send_without_timestamp(OBOE_SEND_EVENT, evt, Context::get()) >= 0;
645
- }
646
- }
647
-
648
- bool Reporter::sendReport(Event *evt, oboe_metadata_t *md, bool with_system_timestamp) {
649
- if (with_system_timestamp) {
650
- return oboe_event_send(OBOE_SEND_EVENT, evt, md) >= 0;
651
- } else {
652
- return oboe_event_send_without_timestamp(OBOE_SEND_EVENT, evt, md) >= 0;
653
- }
654
- }
655
-
656
- bool Reporter::sendStatus(Event *evt, bool with_system_timestamp) {
657
- if (with_system_timestamp) {
658
- return oboe_event_send(OBOE_SEND_STATUS, evt, Context::get()) >= 0;
659
- } else {
660
- return oboe_event_send_without_timestamp(OBOE_SEND_STATUS, evt, Context::get()) >= 0;
661
- }
662
- }
663
-
664
- bool Reporter::sendStatus(Event *evt, oboe_metadata_t *md, bool with_system_timestamp) {
665
- if (with_system_timestamp) {
666
- return oboe_event_send(OBOE_SEND_STATUS, evt, md) >= 0;
667
- } else {
668
- return oboe_event_send_without_timestamp(OBOE_SEND_STATUS, evt, md) >= 0;
669
- }
670
- }
671
-
672
- void Reporter::flush() {
673
- oboe_reporter_flush();
674
- }
675
-
676
- std::string Reporter::getType() {
677
- const char* type = oboe_get_reporter_type();
678
- return type ? std::string(type) : "";
679
- }
680
-
681
- /////// Config ///////
682
-
683
- bool Config::checkVersion(int version, int revision) {
684
- #ifndef _WIN32
685
- return (oboe_config_check_version(version, revision) != 0);
686
- #else
687
- return true;
688
- #endif
689
- }
690
-
691
- std::string Config::getVersionString() {
692
- return oboe_config_get_version_string();
693
- }
694
-
695
- // ===================================================================================================
696
- OboeAPI::OboeAPI(const OboeAPIOptions& options) {
697
- oboe_init_options_t oboe_options;
698
- memset(&oboe_options, 0, sizeof(oboe_options));
699
- oboe_options.version = 17;
700
- oboe_init_options_set_defaults(&oboe_options);
701
- oboe_options.log_level = options.logging_options.level;
702
- oboe_options.log_type = options.logging_options.type;
703
- oboe_init(&oboe_options);
704
- }
705
-
706
- OboeAPI::~OboeAPI() {
707
- oboe_shutdown();
708
- }
709
-
710
- void OboeAPI::getTracingDecision(
711
- // output
712
- int *do_metrics,
713
- int *do_sample,
714
- int *sample_rate,
715
- int *sample_source,
716
- double *bucket_rate,
717
- double *bucket_cap,
718
- int *type,
719
- int *auth,
720
- std::string *status_msg,
721
- std::string *auth_msg,
722
- int *status,
723
- // input
724
- const char *in_xtrace,
725
- const char *tracestate,
726
- int custom_tracing_mode,
727
- int custom_sample_rate,
728
- int request_type,
729
- int custom_trigger_mode,
730
- const char *header_options,
731
- const char *header_signature,
732
- long header_timestamp) {
733
- oboe_tracing_decisions_in_t tdi;
734
- memset(&tdi, 0, sizeof(tdi));
735
- tdi.version = 3;
736
-
737
- tdi.custom_tracing_mode = custom_tracing_mode;
738
- tdi.custom_sample_rate = custom_sample_rate;
739
- tdi.custom_trigger_mode = custom_trigger_mode;
740
- tdi.request_type = request_type;
741
-
742
- tdi.in_xtrace = in_xtrace;
743
- tdi.tracestate = tracestate; // value of sw member in tracestate, ignored when not in w3c mode
744
- tdi.header_options = header_options;
745
- tdi.header_signature = header_signature;
746
- tdi.header_timestamp = header_timestamp;
747
-
748
- oboe_tracing_decisions_out_t tdo;
749
- memset(&tdo, 0, sizeof(tdo));
750
- tdo.version = 3;
751
-
752
- *status = oboe_tracing_decisions(&tdi, &tdo);
753
-
754
- *do_sample = tdo.do_sample;
755
- *do_metrics = tdo.do_metrics;
756
- *sample_rate = tdo.sample_rate;
757
- *sample_source = tdo.sample_source;
758
- *bucket_rate = tdo.token_bucket_rate;
759
- *bucket_cap = tdo.token_bucket_capacity;
760
- *type = tdo.request_provisioned;
761
- if (tdo.status_message && tdo.status_message[0] != '\0') {
762
- *status_msg = tdo.status_message;
763
- }
764
- *auth = tdo.auth_status;
765
- if (tdo.auth_message && tdo.auth_message[0] != '\0') {
766
- *auth_msg = tdo.auth_message;
767
- }
768
- }
769
-
770
- bool OboeAPI::consumeRequestCount(unsigned int& counter) {
771
- return oboe_consume_request_count(&counter);
772
- }
773
- bool OboeAPI::consumeTokenBucketExhaustionCount(unsigned int& counter) {
774
- return oboe_consume_token_bucket_exhaustion_count(&counter);
775
- }
776
- bool OboeAPI::consumeTraceCount(unsigned int& counter) {
777
- return oboe_consume_trace_count(&counter);
778
- }
779
- bool OboeAPI::consumeSampleCount(unsigned int& counter) {
780
- return oboe_consume_sample_count(&counter);
781
- }
782
- bool OboeAPI::consumeThroughTraceCount(unsigned int& counter) {
783
- return oboe_consume_through_trace_count(&counter);
784
- }
785
- bool OboeAPI::consumeTriggeredTraceCount(unsigned int& counter) {
786
- return oboe_consume_triggered_trace_count(&counter);
787
- }
788
- bool OboeAPI::getLastUsedSampleRate(unsigned int& rate) {
789
- return oboe_get_last_used_sample_rate(&rate);
790
- }
791
- bool OboeAPI::getLastUsedSampleSource(unsigned int& source) {
792
- return oboe_get_last_used_sample_source(&source);
793
- }