oboe-heroku 0.8.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,635 @@
1
+ /**
2
+ * @file oboe.hpp - C++ liboboe wrapper primarily for generating SWIG interfaces
3
+ *
4
+ * This API should follow https://github.com/tracelytics/tracelons/wiki/Instrumentation-API
5
+ */
6
+
7
+ #ifndef OBOE_HPP
8
+ #define OBOE_HPP
9
+
10
+ #include <string>
11
+ #include <oboe.h>
12
+
13
+
14
+ class Event;
15
+ class Reporter;
16
+ class Context;
17
+
18
+ /**
19
+ * Metadata is the X-Trace identifier and the information needed to work with it.
20
+ */
21
+ class Metadata : private oboe_metadata_t {
22
+ friend class Reporter;
23
+ friend class SslReporter;
24
+ friend class UdpReporter;
25
+ friend class FileReporter;
26
+ friend class Context;
27
+
28
+ public:
29
+ Metadata(oboe_metadata_t *md) {
30
+ oboe_metadata_copy(this, md);
31
+ }
32
+
33
+ ~Metadata() {
34
+ oboe_metadata_destroy(this);
35
+ }
36
+
37
+ static Metadata* fromString(std::string s) {
38
+ oboe_metadata_t md;
39
+ oboe_metadata_fromstr(&md, s.data(), s.size());
40
+ return new Metadata(&md); // copies md
41
+ }
42
+
43
+ // these new objects are managed by SWIG %newobject
44
+ Event *createEvent();
45
+
46
+ static Metadata *makeRandom() {
47
+ oboe_metadata_t md;
48
+ oboe_metadata_init(&md);
49
+ oboe_metadata_random(&md);
50
+ return new Metadata(&md); // copies md
51
+ }
52
+
53
+ Metadata *copy() {
54
+ return new Metadata(this);
55
+ }
56
+
57
+ bool isValid() {
58
+ return oboe_metadata_is_valid(this);
59
+ }
60
+
61
+ #ifdef SWIGJAVA
62
+ std::string toStr() {
63
+ #else
64
+ std::string toString() {
65
+ #endif
66
+ char buf[OBOE_MAX_METADATA_PACK_LEN];
67
+
68
+ int rc = oboe_metadata_tostr(this, buf, sizeof(buf) - 1);
69
+ if (rc == 0) {
70
+ return std::string(buf);
71
+ } else {
72
+ return std::string(); // throw exception?
73
+ }
74
+ }
75
+
76
+ };
77
+
78
+ /**
79
+ * The Context class manages the metadata and the settings configuration.
80
+ *
81
+ * The metadata includes the X-Trace identifier fields and the information work working with it.
82
+ * The metadata is needed before any trace messages can be sent and must either be generated for
83
+ * new traces or derived from the X-Trace header of an existing trace.
84
+ *
85
+ * The settings information is used primarily to determine when a new request should be traced.
86
+ * The information begins with configuration values for tracing_mode and sample_rate and then
87
+ * updates are received periodically from the collector to adjust the rate at which traces
88
+ * are generated.
89
+ */
90
+ class Context {
91
+ public:
92
+ /**
93
+ * Set the tracing mode.
94
+ *
95
+ * @param newMode One of
96
+ * - OBOE_TRACE_NEVER(0) to disable tracing,
97
+ * - OBOE_TRACE_ALWAYS(1) to start a new trace if needed, or
98
+ * - OBOE_TRACE_THROUGH(2) to only add to an existing trace.
99
+ */
100
+ static void setTracingMode(int newMode) {
101
+ oboe_settings_cfg_tracing_mode_set(newMode);
102
+ }
103
+
104
+ /**
105
+ * Set the default sample rate.
106
+ *
107
+ * This rate is used until overridden by the TraceView servers. If not set then the
108
+ * value 300,000 will be used (ie. 30%).
109
+ *
110
+ * The rate is interpreted as a ratio out of OBOE_SAMPLE_RESOLUTION (currently 1,000,000).
111
+ *
112
+ * @param newRate A number between 0 (none) and OBOE_SAMPLE_RESOLUTION (a million)
113
+ */
114
+ static void setDefaultSampleRate(int newRate) {
115
+ oboe_settings_cfg_sample_rate_set(newRate);
116
+ }
117
+
118
+ /**
119
+ * Check if the current request should be sampled based on settings.
120
+ *
121
+ * If in_xtrace is empty, then sampling will be considered as a new trace.
122
+ * Otherwise sampling will be considered as adding to the current trace.
123
+ * Different layers may have special rules.
124
+ *
125
+ * If a valid X-TV-Meta identifier is provided and AppView Web sample
126
+ * always is enabled then return true independent of the other conditions.
127
+ *
128
+ * @param layer Name of the layer being considered for tracing
129
+ * @param in_xtrace Incoming X-Trace ID (NULL or empty string if not present)
130
+ * @param in_tv_meta AppView Web ID from X-TV-Meta HTTP header or higher layer (NULL or empty string if not present).
131
+ * @return True if we should trace; otherwise false.
132
+ */
133
+ static bool sampleRequest(
134
+ std::string layer,
135
+ std::string in_xtrace,
136
+ std::string in_tv_meta)
137
+ {
138
+ return (oboe_sample_layer(layer.c_str(), in_xtrace.c_str(), in_tv_meta.c_str(), NULL, NULL));
139
+ }
140
+
141
+ /**
142
+ * Get a pointer to the current context (from thread-local storage)
143
+ */
144
+ static oboe_metadata_t *get() {
145
+ return oboe_context_get();
146
+ }
147
+
148
+ /**
149
+ * Get the current context as a printable string.
150
+ */
151
+ #ifdef SWIGJAVA
152
+ static std::string toStr() {
153
+ #else
154
+ static std::string toString() {
155
+ #endif
156
+ char buf[OBOE_MAX_METADATA_PACK_LEN];
157
+
158
+ oboe_metadata_t *md = Context::get();
159
+ int rc = oboe_metadata_tostr(md, buf, sizeof(buf) - 1);
160
+ if (rc == 0) {
161
+ return std::string(buf);
162
+ } else {
163
+ return std::string(); // throw exception?
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Set the current context (this updates thread-local storage).
169
+ */
170
+ static void set(oboe_metadata_t *md) {
171
+ oboe_context_set(md);
172
+ }
173
+
174
+ /**
175
+ * Set the current context from a string.
176
+ */
177
+ static void fromString(std::string s) {
178
+ oboe_context_set_fromstr(s.data(), s.size());
179
+ }
180
+
181
+ // this new object is managed by SWIG %newobject
182
+ static Metadata *copy() {
183
+ return new Metadata(Context::get());
184
+ }
185
+
186
+ static void clear() {
187
+ oboe_context_clear();
188
+ }
189
+
190
+ static bool isValid() {
191
+ return oboe_context_is_valid();
192
+ }
193
+
194
+ /**
195
+ * Initialize the Oboe library.
196
+ */
197
+ static void init() {
198
+ oboe_init();
199
+ }
200
+
201
+ /**
202
+ * Disconnect or shut down the Oboe reporter, but allow it to be reconnect()ed.
203
+ *
204
+ * We don't make this a Reporter method in case there is other housework to do.
205
+ *
206
+ * @param rep Pointer to the active reporter object.
207
+ */
208
+ static void disconnect(Reporter *rep);
209
+
210
+ /**
211
+ * Reconnect or restart the Oboe reporter.
212
+ *
213
+ * We don't make this a Reporter method in case there is other housework to do.
214
+ *
215
+ * @param rep Pointer to the active reporter object.
216
+ */
217
+ static void reconnect(Reporter *rep);
218
+
219
+ /**
220
+ * Shut down the Oboe library.
221
+ *
222
+ * This releases any resources held by the library which may include terminating
223
+ * child threads.
224
+ */
225
+ static void shutdown() {
226
+ oboe_shutdown();
227
+ }
228
+
229
+ // these new objects are managed by SWIG %newobject
230
+ static Event *createEvent();
231
+ static Event *startTrace();
232
+
233
+ private:
234
+
235
+ };
236
+
237
+ class Event : private oboe_event_t {
238
+ friend class Reporter;
239
+ friend class SslReporter;
240
+ friend class UdpReporter;
241
+ friend class FileReporter;
242
+ friend class Context;
243
+ friend class Metadata;
244
+
245
+ private:
246
+ Event() {
247
+ oboe_event_init(this, Context::get());
248
+ }
249
+
250
+ Event(const oboe_metadata_t *md, bool addEdge=true) {
251
+ // both methods copy metadata from md -> this
252
+ if (addEdge) {
253
+ // create_event automatically adds edge in event to md
254
+ oboe_metadata_create_event(md, this);
255
+ } else {
256
+ // initializes new Event with this md's task_id & new random op_id; no edges set
257
+ oboe_event_init(this, md);
258
+ }
259
+ }
260
+
261
+ public:
262
+ ~Event() {
263
+ oboe_event_destroy(this);
264
+ }
265
+
266
+ // called e.g. from Python e.addInfo("Key", None) & Ruby e.addInfo("Key", nil)
267
+ bool addInfo(char *key, void* val) {
268
+ (void)key;
269
+ (void)val;
270
+
271
+ // oboe_event_add_info(evt, key, NULL) does nothing
272
+ (void) key;
273
+ (void) val;
274
+ return true;
275
+ }
276
+
277
+ bool addInfo(char *key, const std::string& val) {
278
+ if (memchr(val.data(), '\0', val.size())) {
279
+ return oboe_event_add_info_binary(this, key, val.data(), val.size()) == 0;
280
+ } else {
281
+ return oboe_event_add_info(this, key, val.data()) == 0;
282
+ }
283
+ }
284
+
285
+ bool addInfo(char *key, long val) {
286
+ int64_t val_ = val;
287
+ return oboe_event_add_info_int64(this, key, val_) == 0;
288
+ }
289
+
290
+ bool addInfo(char *key, double val) {
291
+ return oboe_event_add_info_double(this, key, val) == 0;
292
+ }
293
+
294
+ bool addEdge(oboe_metadata_t *md) {
295
+ return oboe_event_add_edge(this, md) == 0;
296
+ }
297
+
298
+ bool addEdgeStr(const std::string& val) {
299
+ return oboe_event_add_edge_fromstr(this, val.c_str(), val.size()) == 0;
300
+ }
301
+
302
+ Metadata* getMetadata() {
303
+ return new Metadata(&this->metadata);
304
+ }
305
+
306
+ std::string metadataString() {
307
+ char buf[OBOE_MAX_METADATA_PACK_LEN];
308
+
309
+ int rc = oboe_metadata_tostr(&this->metadata, buf, sizeof(buf) - 1);
310
+ if (rc == 0) {
311
+ return std::string(buf);
312
+ } else {
313
+ return std::string(); // throw exception?
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Report this event.
319
+ *
320
+ * This sends the event using the default reporter.
321
+ *
322
+ * @return True on success; otherwise an error message is logged.
323
+ */
324
+ bool send() {
325
+ return (oboe_event_send(this, Context::get()) >= 0);
326
+ }
327
+
328
+ static Event* startTrace(const oboe_metadata_t *md);
329
+
330
+ };
331
+
332
+ Event *Context::createEvent() {
333
+ return new Event(Context::get());
334
+ }
335
+
336
+ Event *Metadata::createEvent() {
337
+ return new Event(this);
338
+ }
339
+
340
+ Event *Context::startTrace() {
341
+ oboe_metadata_t *md = Context::get();
342
+ oboe_metadata_random(md);
343
+ return new Event();
344
+ }
345
+
346
+ Event *Event::startTrace(const oboe_metadata_t *md) {
347
+ return new Event(md, false);
348
+ }
349
+
350
+ class Reporter : private oboe_reporter_t {
351
+ friend class Context; // Access to the private oboe_reporter_t base structure.
352
+ public:
353
+ /**
354
+ * Initialize a reporter structure for use with the specified protocol.
355
+ *
356
+ * @param protocol One of "file", "udp", or "ssl".
357
+ * @param args A configuration string for the specified protocol (protocol dependent syntax).
358
+ */
359
+ Reporter(const char *protocol, const char *args) {
360
+ oboe_reporter_init(this, protocol, args);
361
+ }
362
+
363
+ ~Reporter() {
364
+ oboe_reporter_destroy(this);
365
+ }
366
+
367
+ bool sendReport(Event *evt) {
368
+ return oboe_reporter_send(this, Context::get(), evt) >= 0;
369
+ }
370
+
371
+ bool sendReport(Event *evt, oboe_metadata_t *md) {
372
+ return oboe_reporter_send(this, md, evt) >= 0;
373
+ }
374
+ };
375
+
376
+ class SslReporter : private oboe_reporter_t {
377
+ public:
378
+ SslReporter(const char *config) {
379
+ oboe_reporter_ssl_init(this, config);
380
+ }
381
+
382
+ ~SslReporter() {
383
+ oboe_reporter_destroy(this);
384
+ }
385
+
386
+ bool sendReport(Event *evt) {
387
+ return oboe_reporter_send(this, Context::get(), evt) >= 0;
388
+ }
389
+
390
+ bool sendReport(Event *evt, oboe_metadata_t *md) {
391
+ return oboe_reporter_send(this, md, evt) >= 0;
392
+ }
393
+ };
394
+
395
+ class UdpReporter : private oboe_reporter_t {
396
+ public:
397
+ UdpReporter(const char *addr, const char *port=NULL) {
398
+ if (port == NULL)
399
+ port = "7831";
400
+
401
+ oboe_reporter_udp_init(this, addr, port);
402
+ }
403
+
404
+ ~UdpReporter() {
405
+ oboe_reporter_destroy(this);
406
+ }
407
+
408
+ bool sendReport(Event *evt) {
409
+ return oboe_reporter_send(this, Context::get(), evt) >= 0;
410
+ }
411
+
412
+ bool sendReport(Event *evt, oboe_metadata_t *md) {
413
+ return oboe_reporter_send(this, md, evt) >= 0;
414
+ }
415
+ };
416
+
417
+ class FileReporter : private oboe_reporter_t {
418
+ public:
419
+ FileReporter(const char *file) {
420
+ oboe_reporter_file_init(this, file);
421
+ }
422
+
423
+ ~FileReporter() {
424
+ oboe_reporter_destroy(this);
425
+ }
426
+
427
+ bool sendReport(Event *evt) {
428
+ return oboe_reporter_send(this, Context::get(), evt) >= 0;
429
+ }
430
+
431
+ bool sendReport(Event *evt, oboe_metadata_t *md) {
432
+ return oboe_reporter_send(this, md, evt) >= 0;
433
+ }
434
+ };
435
+
436
+
437
+ /**
438
+ * Base class for a diagnostic log message handler.
439
+ */
440
+ class DebugLogger {
441
+ public:
442
+ virtual void log(int module, int level, const char *source_name, int source_lineno, const char *msg) = 0;
443
+ };
444
+
445
+ /**
446
+ * "C" language wrapper for DebugLogger classes.
447
+ *
448
+ * A logging function that can be added to the logger chain using
449
+ * DebugLog::addDebugLogger().
450
+ *
451
+ * @param context The context pointer that was registered in the call to
452
+ * DebugLog::addDebugLogger(). Use it to pass the pointer-to-self for
453
+ * objects (ie. "this" in C++) or just a structure in C, May be
454
+ * NULL.
455
+ * @param module The module identifier as passed to oboe_debug_logger().
456
+ * @param level The diagnostic detail level as passed to oboe_debug_logger().
457
+ * @param source_name Name of the source file as passed to oboe_debug_logger().
458
+ * @param source_lineno Number of the line in the source file where message is
459
+ * logged from as passed to oboe_debug_logger().
460
+ * @param msg The formatted message produced from the format string and its
461
+ * arguments as passed to oboe_debug_logger().
462
+ */
463
+ extern "C" void oboe_debug_log_handler(void *context, int module, int level, const char *source_name, int source_lineno, const char *msg) {
464
+ ((DebugLogger *)context)->log(module, level, source_name, source_lineno, msg);
465
+ }
466
+
467
+ class DebugLog {
468
+ public:
469
+ /**
470
+ * Get a printable name for a diagnostics logging level.
471
+ *
472
+ * @param level A detail level in the range 0 to 6 (OBOE_DEBUG_FATAL to OBOE_DEBUG_HIGH).
473
+ */
474
+ static std::string getLevelName(int level) {
475
+ return std::string(oboe_debug_log_level_name(level));
476
+ }
477
+
478
+ /**
479
+ * Get a printable name for a diagnostics logging module identifier.
480
+ *
481
+ * @param module One of the OBOE_MODULE_* values.
482
+ */
483
+ static std::string getModuleName(int module) {
484
+ return std::string(oboe_debug_module_name(module));
485
+ }
486
+
487
+ /**
488
+ * Get the maximum logging detail level for a module or for all modules.
489
+ *
490
+ * This level applies to the default logger only. Added loggers get all messages
491
+ * below their registed detail level and need to do their own module-specific
492
+ * filtering.
493
+ *
494
+ * @param module One of the OBOE_MODULE_* values. Use OBOE_MODULE_ALL (-1) to
495
+ * get the overall maximum detail level.
496
+ * @return Maximum detail level value for module (or overall) where zero is the
497
+ * lowest and higher values generate more detailed log messages.
498
+ */
499
+ static int getLevel(int module) {
500
+ return oboe_debug_log_level_get(module);
501
+ }
502
+
503
+ /**
504
+ * Set the maximum logging detail level for a module or for all modules.
505
+ *
506
+ * This level applies to the default logger only. Added loggers get all messages
507
+ * below their registered detail level and need to do their own module-specific
508
+ * filtering.
509
+ *
510
+ * @param module One of the OBOE_MODULE_* values. Use OBOE_MODULE_ALL to set
511
+ * the overall maximum detail level.
512
+ * @param newLevel Maximum detail level value where zero is the lowest and higher
513
+ * values generate more detailed log messages.
514
+ */
515
+ static void setLevel(int module, int newLevel) {
516
+ oboe_debug_log_level_set(module, newLevel);
517
+ }
518
+
519
+ /**
520
+ * Set the output stream for the default logger.
521
+ *
522
+ * @param newStream A valid, open FILE* stream or NULL to disable the default logger.
523
+ * @return Zero on success; otherwise an error code (normally from errno).
524
+ */
525
+ static int setOutputStream(FILE *newStream) {
526
+ return oboe_debug_log_to_stream(newStream);
527
+ }
528
+
529
+ /**
530
+ * Set the default logger to write to the specified file.
531
+ *
532
+ * A NULL or empty path name will disable the default logger.
533
+ *
534
+ * If the file exists then it will be opened in append mode.
535
+ *
536
+ * @param pathname The path name of the
537
+ * @return Zero on success; otherwise an error code (normally from errno).
538
+ */
539
+ static int setOutputFile(const char *pathname) {
540
+ return oboe_debug_log_to_file(pathname);
541
+ }
542
+
543
+ /**
544
+ * Add a logger that takes messages up to a given logging detail level.
545
+ *
546
+ * This adds the logger to a chain in order of the logging level. Log messages
547
+ * are passed to each logger down the chain until the remaining loggers only
548
+ * accept messages of a lower detail level.
549
+ *
550
+ * @return Zero on success, one if re-registered with the new logging level, and
551
+ * otherwise a negative value to indicate an error.
552
+ */
553
+ static int addDebugLogger(DebugLogger *newLogger, int logLevel) {
554
+ return oboe_debug_log_add(oboe_debug_log_handler, newLogger, logLevel);
555
+ }
556
+
557
+ /**
558
+ * Remove a logger.
559
+ *
560
+ * Remove the logger from the message handling chain.
561
+ *
562
+ * @return Zero on success, one if it was not found, and otherwise a negative
563
+ * value to indicate an error.
564
+ */
565
+ static int removeDebugLogger(DebugLogger *oldLogger) {
566
+ return oboe_debug_log_remove(oboe_debug_log_handler, oldLogger);
567
+ }
568
+
569
+ /**
570
+ * Low-level diagnostics logging function.
571
+ *
572
+ * Use this to pass
573
+ * @param module One of the numeric module identifiers defined in debug.h - used to control logging detail by module.
574
+ * @param level Diagnostic detail level of this message - used to control logging volume by detail level.
575
+ * @param source_name Name of the source file, if available, or another useful name, or NULL.
576
+ * @param source_lineno Number of the line in the source file where message is logged from, if available, or zero.
577
+ * @param format A C language printf format specification string.
578
+ * @param args A variable argument list in VA_ARG format containing arguments for each argument specifier in the format.
579
+ */
580
+ static void logMessage(int module, int level, const char *source_name, int source_lineno, const char *msg) {
581
+ oboe_debug_logger(module, level, source_name, source_lineno, "%s", msg);
582
+ }
583
+ };
584
+
585
+ class Config {
586
+ public:
587
+ /**
588
+ * Check if the Oboe library is compatible with a given version.revision.
589
+ *
590
+ * This will succeed if the library is at least as recent as specified and if no
591
+ * definitions have been removed since that revision.
592
+ *
593
+ * @param version The library's version number which increments every time the API changes.
594
+ * @param revision The revision of the current version of the library.
595
+ * @return Non-zero if the Oboe library is considered compatible with the specified revision.
596
+ */
597
+ static bool checkVersion(int version, int revision) {
598
+ return (oboe_config_check_version(version, revision) != 0);
599
+ }
600
+
601
+ /**
602
+ * Get the Oboe library version number.
603
+ *
604
+ * This number increments whenever an incompatible change to the API/ABI is made.
605
+ *
606
+ * @return The library's version number or -1 if the version is not known.
607
+ */
608
+ static int getVersion() {
609
+ return oboe_config_get_version();
610
+ }
611
+
612
+ /**
613
+ * Get the Oboe library revision number.
614
+ *
615
+ * This number increments whenever a compatible change is made to the
616
+ * API/ABI (ie. an addition).
617
+ *
618
+ * @return The library's revision number or -1 if not known.
619
+ */
620
+ static int getRevision() {
621
+ return oboe_config_get_revision();
622
+ }
623
+ };
624
+
625
+
626
+ void Context::disconnect(Reporter *rep) {
627
+ oboe_disconnect(rep);
628
+ }
629
+
630
+ void Context::reconnect(Reporter *rep) {
631
+ oboe_reconnect(rep);
632
+ }
633
+
634
+
635
+ #endif // OBOE_HPP
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @file: debug.h - Diagnostic logging functions for liboboe.
3
+ *
4
+ * Most of the diagnostics logging interface is defined in oboe.h but we
5
+ * separate some of it out here for special handling when generating
6
+ * SWIG interfaces.
7
+ */
8
+
9
+ #ifndef _OBOE_DEBUG_H
10
+ #define _OBOE_DEBUG_H
11
+
12
+ #ifdef __cplusplus
13
+ extern "C" {
14
+ #endif
15
+
16
+ /**
17
+ * Defined diagnostic log detail levels.
18
+ */
19
+ enum OBOE_DEBUG_LOG_LEVEL {
20
+ OBOE_DEBUG_FATAL = 0,
21
+ OBOE_DEBUG_ERROR = 1,
22
+ OBOE_DEBUG_WARNING = 2,
23
+ OBOE_DEBUG_INFO = 3,
24
+ OBOE_DEBUG_LOW = 4,
25
+ OBOE_DEBUG_MEDIUM = 5,
26
+ OBOE_DEBUG_HIGH = 6
27
+ };
28
+
29
+ /**
30
+ * Defined modules that do diagnostic logging.
31
+ */
32
+ enum OBOE_DEBUG_MODULE {
33
+ OBOE_MODULE_ALL = -1, /*!< Pseudo module to refer to ALL modules - used for configuring generic settings */
34
+ OBOE_MODULE_UNDEF = 0, /*!< Generic (undefined) module */
35
+ OBOE_MODULE_LIBOBOE, /*!< The core Oboe library */
36
+ OBOE_MODULE_SETTINGS, /*!< The Oboe settings functionality */
37
+ OBOE_MODULE_REPORTER_FILE, /*!< File reporter */
38
+ OBOE_MODULE_REPORTER_UDP, /*!< UDP (Tracelyzer) reporter */
39
+ OBOE_MODULE_REPORTER_SSL /*!< SSL reporter */
40
+ };
41
+
42
+ #ifdef __cplusplus
43
+ } // extern "C"
44
+ #endif
45
+
46
+ #endif // _OBOE_DEBUG_H