http_instrumented_main.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include <chrono>
  4. #include <iostream>
  5. #include <memory>
  6. #include <mutex> // IWYU pragma: keep
  7. #include <string>
  8. #include <utility>
  9. #include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h"
  10. #include "opentelemetry/exporters/otlp/otlp_http_exporter_options.h"
  11. #include "opentelemetry/exporters/otlp/otlp_http_exporter_runtime_options.h"
  12. #include "opentelemetry/exporters/otlp/otlp_http_log_record_exporter_factory.h"
  13. #include "opentelemetry/exporters/otlp/otlp_http_log_record_exporter_options.h"
  14. #include "opentelemetry/exporters/otlp/otlp_http_log_record_exporter_runtime_options.h"
  15. #include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_factory.h"
  16. #include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h"
  17. #include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_runtime_options.h"
  18. #include "opentelemetry/logs/logger_provider.h"
  19. #include "opentelemetry/metrics/meter_provider.h"
  20. #include "opentelemetry/sdk/logs/batch_log_record_processor_factory.h"
  21. #include "opentelemetry/sdk/logs/batch_log_record_processor_options.h"
  22. #include "opentelemetry/sdk/logs/batch_log_record_processor_runtime_options.h"
  23. #include "opentelemetry/sdk/logs/exporter.h"
  24. #include "opentelemetry/sdk/logs/logger_provider.h"
  25. #include "opentelemetry/sdk/logs/logger_provider_factory.h"
  26. #include "opentelemetry/sdk/logs/processor.h"
  27. #include "opentelemetry/sdk/logs/provider.h"
  28. #include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_factory.h"
  29. #include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_options.h"
  30. #include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_runtime_options.h"
  31. #include "opentelemetry/sdk/metrics/meter_context.h"
  32. #include "opentelemetry/sdk/metrics/meter_context_factory.h"
  33. #include "opentelemetry/sdk/metrics/meter_provider.h"
  34. #include "opentelemetry/sdk/metrics/meter_provider_factory.h"
  35. #include "opentelemetry/sdk/metrics/metric_reader.h"
  36. #include "opentelemetry/sdk/metrics/provider.h"
  37. #include "opentelemetry/sdk/metrics/push_metric_exporter.h"
  38. #include "opentelemetry/sdk/trace/batch_span_processor_factory.h"
  39. #include "opentelemetry/sdk/trace/batch_span_processor_options.h"
  40. #include "opentelemetry/sdk/trace/batch_span_processor_runtime_options.h"
  41. #include "opentelemetry/sdk/trace/exporter.h"
  42. #include "opentelemetry/sdk/trace/processor.h"
  43. #include "opentelemetry/sdk/trace/provider.h"
  44. #include "opentelemetry/sdk/trace/tracer_provider.h"
  45. #include "opentelemetry/sdk/trace/tracer_provider_factory.h"
  46. #include "opentelemetry/trace/tracer_provider.h"
  47. #ifdef BAZEL_BUILD
  48. # include "examples/common/logs_foo_library/foo_library.h"
  49. # include "examples/common/metrics_foo_library/foo_library.h"
  50. #else
  51. # include "logs_foo_library/foo_library.h"
  52. # include "metrics_foo_library/foo_library.h"
  53. #endif
  54. namespace
  55. {
  56. #ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
  57. std::mutex serialize;
  58. /**
  59. The purpose of MyThreadInstrumentation is to demonstrate
  60. how notifications are delivered to the application.
  61. Printing to std::cout is useful for debugging,
  62. to understand the overall thread execution in the library.
  63. In production, a real application would instead:
  64. - set thread priorities / CPU affinity
  65. - set thread local storage keys
  66. - set a thread name to the operating system
  67. - set network namespaces
  68. in the OnXXX() code here.
  69. */
  70. class MyThreadInstrumentation : public opentelemetry::sdk::common::ThreadInstrumentation
  71. {
  72. public:
  73. MyThreadInstrumentation(const std::string &thread_name,
  74. const std::string &network_name,
  75. const std::string &priority)
  76. : thread_name_(thread_name), network_name_(network_name), priority_(priority)
  77. {}
  78. ~MyThreadInstrumentation() override = default;
  79. void OnStart() override
  80. {
  81. std::lock_guard<std::mutex> lock_guard(serialize);
  82. std::cout << "OnStart() thread " << thread_name_ << ", id " << std::this_thread::get_id();
  83. if (!network_name_.empty())
  84. {
  85. std::cout << ", network_name " << network_name_;
  86. }
  87. if (!priority_.empty())
  88. {
  89. std::cout << ", priority " << priority_;
  90. }
  91. std::cout << std::endl << std::flush;
  92. }
  93. void OnEnd() override
  94. {
  95. std::lock_guard<std::mutex> lock_guard(serialize);
  96. std::cout << "OnEnd() thread " << thread_name_ << ", id " << std::this_thread::get_id()
  97. << std::endl
  98. << std::flush;
  99. }
  100. void BeforeWait() override
  101. {
  102. std::lock_guard<std::mutex> lock_guard(serialize);
  103. std::cout << "BeforeWait() thread " << thread_name_ << ", id " << std::this_thread::get_id()
  104. << ", waiting" << std::endl
  105. << std::flush;
  106. }
  107. void AfterWait() override
  108. {
  109. std::lock_guard<std::mutex> lock_guard(serialize);
  110. std::cout << "AfterWait() thread " << thread_name_ << ", id " << std::this_thread::get_id()
  111. << ", done waiting" << std::endl
  112. << std::flush;
  113. }
  114. void BeforeLoad() override
  115. {
  116. std::lock_guard<std::mutex> lock_guard(serialize);
  117. std::cout << "BeforeLoad() thread " << thread_name_ << ", id " << std::this_thread::get_id()
  118. << ", about to work" << std::endl
  119. << std::flush;
  120. }
  121. void AfterLoad() override
  122. {
  123. std::lock_guard<std::mutex> lock_guard(serialize);
  124. std::cout << "AfterLoad() thread " << thread_name_ << ", id " << std::this_thread::get_id()
  125. << ", done working" << std::endl
  126. << std::flush;
  127. }
  128. private:
  129. std::string thread_name_;
  130. std::string network_name_;
  131. std::string priority_;
  132. };
  133. #endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
  134. opentelemetry::exporter::otlp::OtlpHttpExporterOptions tracer_opts;
  135. opentelemetry::exporter::otlp::OtlpHttpMetricExporterOptions meter_opts;
  136. opentelemetry::exporter::otlp::OtlpHttpLogRecordExporterOptions logger_opts;
  137. std::shared_ptr<opentelemetry::sdk::trace::TracerProvider> tracer_provider;
  138. std::shared_ptr<opentelemetry::sdk::metrics::MeterProvider> meter_provider;
  139. std::shared_ptr<opentelemetry::sdk::logs::LoggerProvider> logger_provider;
  140. void InitTracer()
  141. {
  142. // Create OTLP exporter instance
  143. opentelemetry::exporter::otlp::OtlpHttpExporterRuntimeOptions exp_rt_opts;
  144. #ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
  145. auto exp_instr = std::shared_ptr<opentelemetry::sdk::common::ThreadInstrumentation>(
  146. new MyThreadInstrumentation("OtlpHttpExporter", "trace-net", "high"));
  147. exp_rt_opts.thread_instrumentation = exp_instr;
  148. #endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
  149. auto exporter =
  150. opentelemetry::exporter::otlp::OtlpHttpExporterFactory::Create(tracer_opts, exp_rt_opts);
  151. // Create Processor instance
  152. opentelemetry::sdk::trace::BatchSpanProcessorOptions pro_opts;
  153. opentelemetry::sdk::trace::BatchSpanProcessorRuntimeOptions pro_rt_opts;
  154. #ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
  155. auto pro_instr = std::shared_ptr<opentelemetry::sdk::common::ThreadInstrumentation>(
  156. new MyThreadInstrumentation("BatchSpanProcessor", "", "high"));
  157. pro_rt_opts.thread_instrumentation = pro_instr;
  158. #endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
  159. auto processor = opentelemetry::sdk::trace::BatchSpanProcessorFactory::Create(
  160. std::move(exporter), pro_opts, pro_rt_opts);
  161. // Create Provider instance
  162. tracer_provider = opentelemetry::sdk::trace::TracerProviderFactory::Create(std::move(processor));
  163. // Set the global trace provider
  164. std::shared_ptr<opentelemetry::trace::TracerProvider> api_provider = tracer_provider;
  165. opentelemetry::sdk::trace::Provider::SetTracerProvider(api_provider);
  166. }
  167. void CleanupTracer()
  168. {
  169. // We call ForceFlush to prevent to cancel running exportings, It's optional.
  170. if (tracer_provider)
  171. {
  172. tracer_provider->ForceFlush();
  173. tracer_provider->Shutdown();
  174. }
  175. tracer_provider.reset();
  176. std::shared_ptr<opentelemetry::trace::TracerProvider> none;
  177. opentelemetry::sdk::trace::Provider::SetTracerProvider(none);
  178. }
  179. void InitMetrics()
  180. {
  181. // Create OTLP exporter instance
  182. opentelemetry::exporter::otlp::OtlpHttpMetricExporterRuntimeOptions exp_rt_opts;
  183. #ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
  184. auto exp_instr = std::shared_ptr<opentelemetry::sdk::common::ThreadInstrumentation>(
  185. new MyThreadInstrumentation("OtlpHttpMetricExporter", "metric-net", "medium"));
  186. exp_rt_opts.thread_instrumentation = exp_instr;
  187. #endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
  188. auto exporter =
  189. opentelemetry::exporter::otlp::OtlpHttpMetricExporterFactory::Create(meter_opts, exp_rt_opts);
  190. std::string version{"1.2.0"};
  191. std::string schema{"https://opentelemetry.io/schemas/1.2.0"};
  192. // Initialize and set the global MeterProvider
  193. opentelemetry::sdk::metrics::PeriodicExportingMetricReaderOptions reader_options;
  194. reader_options.export_interval_millis = std::chrono::milliseconds(1000);
  195. reader_options.export_timeout_millis = std::chrono::milliseconds(500);
  196. opentelemetry::sdk::metrics::PeriodicExportingMetricReaderRuntimeOptions reader_rt_opts;
  197. #ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
  198. auto reader_periodic_instr = std::shared_ptr<opentelemetry::sdk::common::ThreadInstrumentation>(
  199. new MyThreadInstrumentation("PeriodicExportingMetricReader(periodic)", "", "medium"));
  200. auto reader_collect_instr = std::shared_ptr<opentelemetry::sdk::common::ThreadInstrumentation>(
  201. new MyThreadInstrumentation("PeriodicExportingMetricReader(collect)", "", "medium"));
  202. reader_rt_opts.periodic_thread_instrumentation = reader_periodic_instr;
  203. reader_rt_opts.collect_thread_instrumentation = reader_collect_instr;
  204. #endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
  205. auto reader = opentelemetry::sdk::metrics::PeriodicExportingMetricReaderFactory::Create(
  206. std::move(exporter), reader_options, reader_rt_opts);
  207. auto context = opentelemetry::sdk::metrics::MeterContextFactory::Create();
  208. context->AddMetricReader(std::move(reader));
  209. meter_provider = opentelemetry::sdk::metrics::MeterProviderFactory::Create(std::move(context));
  210. std::shared_ptr<opentelemetry::metrics::MeterProvider> api_provider = meter_provider;
  211. opentelemetry::sdk::metrics::Provider::SetMeterProvider(api_provider);
  212. }
  213. void CleanupMetrics()
  214. {
  215. // We call ForceFlush to prevent to cancel running exportings, It's optional.
  216. if (meter_provider)
  217. {
  218. meter_provider->ForceFlush();
  219. meter_provider->Shutdown();
  220. }
  221. meter_provider.reset();
  222. std::shared_ptr<opentelemetry::metrics::MeterProvider> none;
  223. opentelemetry::sdk::metrics::Provider::SetMeterProvider(none);
  224. }
  225. void InitLogger()
  226. {
  227. // Create OTLP exporter instance
  228. opentelemetry::exporter::otlp::OtlpHttpLogRecordExporterRuntimeOptions exp_rt_opts;
  229. #ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
  230. auto exp_instr = std::shared_ptr<opentelemetry::sdk::common::ThreadInstrumentation>(
  231. new MyThreadInstrumentation("OtlpHttpLogRecordExporter", "log-net", "low"));
  232. exp_rt_opts.thread_instrumentation = exp_instr;
  233. #endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
  234. auto exporter = opentelemetry::exporter::otlp::OtlpHttpLogRecordExporterFactory::Create(
  235. logger_opts, exp_rt_opts);
  236. // Create Processor instance
  237. opentelemetry::sdk::logs::BatchLogRecordProcessorOptions pro_opts;
  238. opentelemetry::sdk::logs::BatchLogRecordProcessorRuntimeOptions pro_rt_opts;
  239. #ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
  240. auto pro_instr = std::shared_ptr<opentelemetry::sdk::common::ThreadInstrumentation>(
  241. new MyThreadInstrumentation("BatchLogRecordProcessor", "", "low"));
  242. pro_rt_opts.thread_instrumentation = pro_instr;
  243. #endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
  244. auto processor = opentelemetry::sdk::logs::BatchLogRecordProcessorFactory::Create(
  245. std::move(exporter), pro_opts, pro_rt_opts);
  246. logger_provider = opentelemetry::sdk::logs::LoggerProviderFactory::Create(std::move(processor));
  247. std::shared_ptr<opentelemetry::logs::LoggerProvider> api_provider = logger_provider;
  248. opentelemetry::sdk::logs::Provider::SetLoggerProvider(api_provider);
  249. }
  250. void CleanupLogger()
  251. {
  252. // We call ForceFlush to prevent to cancel running exportings, It's optional.
  253. if (logger_provider)
  254. {
  255. logger_provider->ForceFlush();
  256. logger_provider->Shutdown();
  257. }
  258. logger_provider.reset();
  259. std::shared_ptr<opentelemetry::logs::LoggerProvider> none;
  260. opentelemetry::sdk::logs::Provider::SetLoggerProvider(none);
  261. }
  262. } // namespace
  263. /*
  264. Usage:
  265. - example_otlp_instrumented_http
  266. - example_otlp_instrumented_http <TRACE_URL> <METRIC_URL> <LOG_URL>
  267. */
  268. int main(int argc, char *argv[])
  269. {
  270. if (argc > 1)
  271. {
  272. tracer_opts.url = argv[1];
  273. }
  274. else
  275. {
  276. tracer_opts.url = "http://localhost:4318/v1/traces";
  277. }
  278. if (argc > 2)
  279. {
  280. meter_opts.url = argv[2];
  281. }
  282. else
  283. {
  284. meter_opts.url = "http://localhost:4318/v1/metrics";
  285. }
  286. if (argc > 3)
  287. {
  288. logger_opts.url = argv[3];
  289. }
  290. else
  291. {
  292. logger_opts.url = "http://localhost:4318/v1/logs";
  293. }
  294. std::cout << "Initializing opentelemetry-cpp" << std::endl << std::flush;
  295. InitTracer();
  296. InitMetrics();
  297. InitLogger();
  298. std::cout << "Application payload" << std::endl << std::flush;
  299. foo_library();
  300. std::string name{"otlp_http_metric_example"};
  301. foo_library::observable_counter_example(name);
  302. std::cout << "Shutting down opentelemetry-cpp" << std::endl << std::flush;
  303. CleanupLogger();
  304. CleanupMetrics();
  305. CleanupTracer();
  306. std::cout << "Done" << std::endl << std::flush;
  307. return 0;
  308. }