| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // Copyright The OpenTelemetry Authors
- // SPDX-License-Identifier: Apache-2.0
- // Include common Trace Provider API and processor
- #include "opentelemetry/sdk/trace/simple_processor.h"
- #include "opentelemetry/sdk/trace/tracer_provider.h"
- #include "opentelemetry/trace/provider.h"
- #include "opentelemetry/exporters/etw/etw_tracer_exporter.h"
- #include <iostream>
- #include <thread>
- #include <cstdio>
- #ifndef LOG_DEBUG
- # include <mutex>
- /**
- * @brief Thread-safe logger routine.
- * @param format
- * @param args
- * @return
- */
- static inline int log_vprintf(const char *format, va_list args)
- {
- static std::mutex cout_mutex;
- std::lock_guard<std::mutex> lk(cout_mutex);
- return vprintf(format, args);
- };
- /**
- * @brief Thread-safe logger routine.
- * @param format
- * @param
- * @return
- */
- static inline int log_printf(const char *format, ...)
- {
- int result;
- va_list ap;
- va_start(ap, format);
- result = log_vprintf(format, ap);
- va_end(ap);
- return result;
- };
- // Debug macros
- # define LOG_DEBUG(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
- # define LOG_TRACE(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
- # define LOG_INFO(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
- # define LOG_WARN(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
- # define LOG_ERROR(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
- #endif
- using namespace OPENTELEMETRY_NAMESPACE;
- using namespace opentelemetry::exporter::etw;
- // Specify destination ETW Provider Name or GUID.
- //
- // In Visual Studio:
- // - View -> Other Windows -> Diagnostic Events...
- // - Click Configure (gear on top).
- // - Specify "OpenTelemetry-ETW-TLD" in the list of providers.
- //
- // Event view shows event flow in realtime.
- const char *kGlobalProviderName = "OpenTelemetry-ETW-TLD";
- std::string providerName = kGlobalProviderName;
- // One provider can be used to associate with different destinations.
- exporter::etw::TracerProvider provider;
- // Code below is generic and may be reused with any other TracerProvider.
- // In ETW provider case - instrumentation name must match destination
- // ETW provider name.
- nostd::shared_ptr<trace::Tracer> tracer = provider.GetTracer(providerName, "1.0");
- // Obtain numeric thread id
- static inline uint64_t gettid()
- {
- std::stringstream ss;
- ss << std::this_thread::get_id();
- uint64_t id = std::stoull(ss.str());
- return id;
- }
- // bop gets called by beep.
- void bop()
- {
- LOG_TRACE("bop worker tid=%u", gettid());
- auto span = tracer->StartSpan("bop");
- span->AddEvent("BopEvent", {{"tid", gettid()}});
- span->SetAttribute("attrib", 2);
- span->End();
- }
- // beep gets called in its own thread.
- // It is running in a thread pool, invoked via lambda by dispatcher.
- void beep()
- {
- LOG_TRACE("beep worker tid=%u", gettid());
- auto span = tracer->StartSpan("beep");
- span->AddEvent("BeepEvent", {{"tid", gettid()}});
- span->SetAttribute("attrib", 1);
- {
- auto bopScope = tracer->WithActiveSpan(span);
- bop();
- }
- span->End();
- }
- // Max number of threads to spawn
- constexpr int kMaxThreads = 10;
- int main(int /*arc*/, char ** /*argv*/)
- {
- std::thread pool[kMaxThreads];
- // Main dispatcher span: parent of all child thread spans.
- auto mainSpan = tracer->StartSpan("beep_bop");
- mainSpan->SetAttribute("attrib", 0);
- // Start several threads to perform beep-bop actions.
- LOG_TRACE("beep-boop dispatcher tid=%u", gettid());
- for (auto i = 0; i < kMaxThreads; i++)
- {
- pool[i] = std::thread([&]() {
- // This code runs in its own worker thread.
- auto beepScope = tracer->WithActiveSpan(mainSpan);
- // call beep -> bop
- beep();
- });
- };
- // Join all worker threads in the pool
- for (auto &th : pool)
- {
- try
- {
- if (th.joinable())
- th.join();
- }
- catch (...)
- {
- // thread might have been gracefully terminated already
- }
- }
- // End span
- mainSpan->End();
- return 0;
- }
|