2
0

main.cc 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. // Include common Trace Provider API and processor
  4. #include "opentelemetry/sdk/trace/simple_processor.h"
  5. #include "opentelemetry/sdk/trace/tracer_provider.h"
  6. #include "opentelemetry/trace/provider.h"
  7. #include "opentelemetry/exporters/etw/etw_tracer_exporter.h"
  8. #include <iostream>
  9. #include <thread>
  10. #include <cstdio>
  11. #ifndef LOG_DEBUG
  12. # include <mutex>
  13. /**
  14. * @brief Thread-safe logger routine.
  15. * @param format
  16. * @param args
  17. * @return
  18. */
  19. static inline int log_vprintf(const char *format, va_list args)
  20. {
  21. static std::mutex cout_mutex;
  22. std::lock_guard<std::mutex> lk(cout_mutex);
  23. return vprintf(format, args);
  24. };
  25. /**
  26. * @brief Thread-safe logger routine.
  27. * @param format
  28. * @param
  29. * @return
  30. */
  31. static inline int log_printf(const char *format, ...)
  32. {
  33. int result;
  34. va_list ap;
  35. va_start(ap, format);
  36. result = log_vprintf(format, ap);
  37. va_end(ap);
  38. return result;
  39. };
  40. // Debug macros
  41. # define LOG_DEBUG(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
  42. # define LOG_TRACE(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
  43. # define LOG_INFO(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
  44. # define LOG_WARN(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
  45. # define LOG_ERROR(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
  46. #endif
  47. using namespace OPENTELEMETRY_NAMESPACE;
  48. using namespace opentelemetry::exporter::etw;
  49. // Specify destination ETW Provider Name or GUID.
  50. //
  51. // In Visual Studio:
  52. // - View -> Other Windows -> Diagnostic Events...
  53. // - Click Configure (gear on top).
  54. // - Specify "OpenTelemetry-ETW-TLD" in the list of providers.
  55. //
  56. // Event view shows event flow in realtime.
  57. const char *kGlobalProviderName = "OpenTelemetry-ETW-TLD";
  58. std::string providerName = kGlobalProviderName;
  59. // One provider can be used to associate with different destinations.
  60. exporter::etw::TracerProvider provider;
  61. // Code below is generic and may be reused with any other TracerProvider.
  62. // In ETW provider case - instrumentation name must match destination
  63. // ETW provider name.
  64. nostd::shared_ptr<trace::Tracer> tracer = provider.GetTracer(providerName, "1.0");
  65. // Obtain numeric thread id
  66. static inline uint64_t gettid()
  67. {
  68. std::stringstream ss;
  69. ss << std::this_thread::get_id();
  70. uint64_t id = std::stoull(ss.str());
  71. return id;
  72. }
  73. // bop gets called by beep.
  74. void bop()
  75. {
  76. LOG_TRACE("bop worker tid=%u", gettid());
  77. auto span = tracer->StartSpan("bop");
  78. span->AddEvent("BopEvent", {{"tid", gettid()}});
  79. span->SetAttribute("attrib", 2);
  80. span->End();
  81. }
  82. // beep gets called in its own thread.
  83. // It is running in a thread pool, invoked via lambda by dispatcher.
  84. void beep()
  85. {
  86. LOG_TRACE("beep worker tid=%u", gettid());
  87. auto span = tracer->StartSpan("beep");
  88. span->AddEvent("BeepEvent", {{"tid", gettid()}});
  89. span->SetAttribute("attrib", 1);
  90. {
  91. auto bopScope = tracer->WithActiveSpan(span);
  92. bop();
  93. }
  94. span->End();
  95. }
  96. // Max number of threads to spawn
  97. constexpr int kMaxThreads = 10;
  98. int main(int /*arc*/, char ** /*argv*/)
  99. {
  100. std::thread pool[kMaxThreads];
  101. // Main dispatcher span: parent of all child thread spans.
  102. auto mainSpan = tracer->StartSpan("beep_bop");
  103. mainSpan->SetAttribute("attrib", 0);
  104. // Start several threads to perform beep-bop actions.
  105. LOG_TRACE("beep-boop dispatcher tid=%u", gettid());
  106. for (auto i = 0; i < kMaxThreads; i++)
  107. {
  108. pool[i] = std::thread([&]() {
  109. // This code runs in its own worker thread.
  110. auto beepScope = tracer->WithActiveSpan(mainSpan);
  111. // call beep -> bop
  112. beep();
  113. });
  114. };
  115. // Join all worker threads in the pool
  116. for (auto &th : pool)
  117. {
  118. try
  119. {
  120. if (th.joinable())
  121. th.join();
  122. }
  123. catch (...)
  124. {
  125. // thread might have been gracefully terminated already
  126. }
  127. }
  128. // End span
  129. mainSpan->End();
  130. return 0;
  131. }