tracer_provider_test.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include <gtest/gtest.h>
  4. #include <algorithm>
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include "opentelemetry/common/macros.h"
  9. #include "opentelemetry/nostd/shared_ptr.h"
  10. #include "opentelemetry/nostd/string_view.h"
  11. #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
  12. #include "opentelemetry/sdk/resource/resource.h"
  13. #include "opentelemetry/sdk/trace/exporter.h"
  14. #include "opentelemetry/sdk/trace/id_generator.h"
  15. #include "opentelemetry/sdk/trace/processor.h"
  16. #include "opentelemetry/sdk/trace/random_id_generator.h"
  17. #include "opentelemetry/sdk/trace/sampler.h"
  18. #include "opentelemetry/sdk/trace/samplers/always_off.h"
  19. #include "opentelemetry/sdk/trace/simple_processor.h"
  20. #include "opentelemetry/sdk/trace/simple_processor_factory.h"
  21. #include "opentelemetry/sdk/trace/tracer.h"
  22. #include "opentelemetry/sdk/trace/tracer_context.h"
  23. #include "opentelemetry/sdk/trace/tracer_provider.h"
  24. #include "opentelemetry/sdk/trace/tracer_provider_factory.h"
  25. #include "opentelemetry/trace/tracer.h"
  26. using namespace opentelemetry::sdk::trace;
  27. using namespace opentelemetry::sdk::resource;
  28. TEST(TracerProvider, GetTracer)
  29. {
  30. std::unique_ptr<SpanProcessor> processor(new SimpleSpanProcessor(nullptr));
  31. std::vector<std::unique_ptr<SpanProcessor>> processors;
  32. processors.push_back(std::move(processor));
  33. std::unique_ptr<TracerContext> context1(
  34. new TracerContext(std::move(processors), Resource::Create({})));
  35. TracerProvider tp1(std::move(context1));
  36. auto t1 = tp1.GetTracer("test");
  37. auto t2 = tp1.GetTracer("test");
  38. auto t3 = tp1.GetTracer("different", "1.0.0");
  39. auto t4 = tp1.GetTracer("");
  40. auto t5 = tp1.GetTracer(opentelemetry::nostd::string_view{});
  41. auto t6 = tp1.GetTracer("different", "1.0.0", "https://opentelemetry.io/schemas/1.2.0");
  42. ASSERT_NE(nullptr, t1);
  43. ASSERT_NE(nullptr, t2);
  44. ASSERT_NE(nullptr, t3);
  45. ASSERT_NE(nullptr, t6);
  46. // Should return the same instance each time.
  47. ASSERT_EQ(t1, t2);
  48. ASSERT_NE(t1, t3);
  49. ASSERT_EQ(t4, t5);
  50. ASSERT_NE(t3, t6);
  51. // Should be an sdk::trace::Tracer with the processor attached.
  52. #ifdef OPENTELEMETRY_RTTI_ENABLED
  53. auto sdkTracer1 = dynamic_cast<Tracer *>(t1.get());
  54. #else
  55. auto sdkTracer1 = static_cast<Tracer *>(t1.get());
  56. #endif
  57. ASSERT_NE(nullptr, sdkTracer1);
  58. ASSERT_EQ("AlwaysOnSampler", sdkTracer1->GetSampler().GetDescription());
  59. std::unique_ptr<SpanProcessor> processor2(new SimpleSpanProcessor(nullptr));
  60. std::vector<std::unique_ptr<SpanProcessor>> processors2;
  61. processors2.push_back(std::move(processor2));
  62. std::unique_ptr<TracerContext> context2(
  63. new TracerContext(std::move(processors2), Resource::Create({}),
  64. std::unique_ptr<Sampler>(new AlwaysOffSampler()),
  65. std::unique_ptr<IdGenerator>(new RandomIdGenerator)));
  66. TracerProvider tp2(std::move(context2));
  67. #ifdef OPENTELEMETRY_RTTI_ENABLED
  68. auto sdkTracer2 = dynamic_cast<Tracer *>(tp2.GetTracer("test").get());
  69. #else
  70. auto sdkTracer2 = static_cast<Tracer *>(tp2.GetTracer("test").get());
  71. #endif
  72. ASSERT_EQ("AlwaysOffSampler", sdkTracer2->GetSampler().GetDescription());
  73. auto instrumentation_scope1 = sdkTracer1->GetInstrumentationScope();
  74. ASSERT_EQ(instrumentation_scope1.GetName(), "test");
  75. ASSERT_EQ(instrumentation_scope1.GetVersion(), "");
  76. // Should be an sdk::trace::Tracer with the processor attached.
  77. #ifdef OPENTELEMETRY_RTTI_ENABLED
  78. auto sdkTracer3 = dynamic_cast<Tracer *>(t3.get());
  79. #else
  80. auto sdkTracer3 = static_cast<Tracer *>(t3.get());
  81. #endif
  82. auto instrumentation_scope3 = sdkTracer3->GetInstrumentationScope();
  83. ASSERT_EQ(instrumentation_scope3.GetName(), "different");
  84. ASSERT_EQ(instrumentation_scope3.GetVersion(), "1.0.0");
  85. }
  86. TEST(TracerProvider, GetTracerEqualityCheck)
  87. {
  88. auto processor = SimpleSpanProcessorFactory::Create(nullptr);
  89. auto provider = TracerProviderFactory::Create(std::move(processor));
  90. // providing the same scope names should return the same tracer
  91. auto tracer_1a = provider->GetTracer("library_name");
  92. auto tracer_1b = provider->GetTracer("library_name");
  93. EXPECT_EQ(tracer_1a, tracer_1b);
  94. // providing the same scope name and version should return the same tracer
  95. auto tracer_version1a = provider->GetTracer("library_name", "v1.0");
  96. auto tracer_version1b = provider->GetTracer("library_name", "v1.0");
  97. EXPECT_EQ(tracer_version1a, tracer_version1b);
  98. // providing the same name, version, and schema urls should return the same tracer
  99. auto tracer_urla = provider->GetTracer("library_name", "v1.0", "url");
  100. auto tracer_urlb = provider->GetTracer("library_name", "v1.0", "url");
  101. EXPECT_EQ(tracer_urla, tracer_urlb);
  102. }
  103. TEST(TracerProvider, GetTracerInequalityCheck)
  104. {
  105. auto processor = SimpleSpanProcessorFactory::Create(nullptr);
  106. auto provider = TracerProviderFactory::Create(std::move(processor));
  107. auto tracer_library_1 = provider->GetTracer("library_1");
  108. auto tracer_library_2 = provider->GetTracer("library_2");
  109. auto tracer_version_1 = provider->GetTracer("library_1", "v1.0");
  110. auto tracer_version_2 = provider->GetTracer("library_1", "v2.0");
  111. auto tracer_url_1 = provider->GetTracer("library_1", "v1.0", "url_1");
  112. auto tracer_url_2 = provider->GetTracer("library_1", "v1.0", "url_2");
  113. // different scope names should return distinct tracers
  114. EXPECT_NE(tracer_library_1, tracer_library_2);
  115. // different scope versions should return distinct tracers
  116. EXPECT_NE(tracer_version_1, tracer_library_1);
  117. EXPECT_NE(tracer_version_1, tracer_version_2);
  118. // different scope schema urls should return distinct tracers
  119. EXPECT_NE(tracer_url_1, tracer_library_1);
  120. EXPECT_NE(tracer_url_1, tracer_version_1);
  121. EXPECT_NE(tracer_url_1, tracer_url_2);
  122. }
  123. #if OPENTELEMETRY_ABI_VERSION_NO >= 2
  124. TEST(TracerProvider, GetTracerEqualityCheckAbiv2)
  125. {
  126. auto processor = SimpleSpanProcessorFactory::Create(nullptr);
  127. auto provider = TracerProviderFactory::Create(std::move(processor));
  128. auto tracer_attribute1a = provider->GetTracer("library_name", "v1.0", "url", {{"key", "one"}});
  129. auto tracer_attribute1b = provider->GetTracer("library_name", "v1.0", "url", {{"key", "one"}});
  130. // providing the same name, version, schema url and attributes should return the same tracer
  131. EXPECT_EQ(tracer_attribute1a, tracer_attribute1b);
  132. }
  133. TEST(TracerProvider, GetTracerInequalityCheckAbiv2)
  134. {
  135. auto processor = SimpleSpanProcessorFactory::Create(nullptr);
  136. auto provider = TracerProviderFactory::Create(std::move(processor));
  137. auto tracer_1 = provider->GetTracer("library_name", "v1.0", "url");
  138. auto tracer_attribute1 = provider->GetTracer("library_name", "v1.0", "url", {{"key", "one"}});
  139. auto tracer_attribute2 = provider->GetTracer("library_name", "v1.0", "url", {{"key", "two"}});
  140. // different scope attributes should return distinct tracers
  141. EXPECT_NE(tracer_attribute1, tracer_1);
  142. EXPECT_NE(tracer_attribute1, tracer_attribute2);
  143. }
  144. TEST(TracerProvider, GetTracerAbiv2)
  145. {
  146. std::unique_ptr<SpanProcessor> processor(new SimpleSpanProcessor(nullptr));
  147. std::vector<std::unique_ptr<SpanProcessor>> processors;
  148. processors.push_back(std::move(processor));
  149. std::unique_ptr<TracerContext> context1(
  150. new TracerContext(std::move(processors), Resource::Create({})));
  151. TracerProvider tp(std::move(context1));
  152. auto t1 = tp.GetTracer("name1", "version1", "url1");
  153. ASSERT_NE(nullptr, t1);
  154. auto t2 = tp.GetTracer("name2", "version2", "url2", nullptr);
  155. ASSERT_NE(nullptr, t2);
  156. auto t3 = tp.GetTracer("name3", "version3", "url3", {{"accept_single_attr", true}});
  157. ASSERT_NE(nullptr, t3);
  158. {
  159. auto tracer = static_cast<opentelemetry::sdk::trace::Tracer *>(t3.get());
  160. auto scope = tracer->GetInstrumentationScope();
  161. auto attrs = scope.GetAttributes();
  162. ASSERT_EQ(attrs.size(), 1);
  163. auto attr = attrs.find("accept_single_attr");
  164. ASSERT_FALSE(attr == attrs.end());
  165. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<bool>(attr->second));
  166. EXPECT_EQ(opentelemetry::nostd::get<bool>(attr->second), true);
  167. }
  168. std::pair<opentelemetry::nostd::string_view, opentelemetry::common::AttributeValue> attr4 = {
  169. "accept_single_attr", true};
  170. auto t4 = tp.GetTracer("name4", "version4", "url4", {attr4});
  171. ASSERT_NE(nullptr, t4);
  172. {
  173. auto tracer = static_cast<opentelemetry::sdk::trace::Tracer *>(t4.get());
  174. auto scope = tracer->GetInstrumentationScope();
  175. auto attrs = scope.GetAttributes();
  176. ASSERT_EQ(attrs.size(), 1);
  177. auto attr = attrs.find("accept_single_attr");
  178. ASSERT_FALSE(attr == attrs.end());
  179. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<bool>(attr->second));
  180. EXPECT_EQ(opentelemetry::nostd::get<bool>(attr->second), true);
  181. }
  182. auto t5 = tp.GetTracer("name5", "version5", "url5", {{"foo", "1"}, {"bar", "2"}});
  183. ASSERT_NE(nullptr, t5);
  184. {
  185. auto tracer = static_cast<opentelemetry::sdk::trace::Tracer *>(t5.get());
  186. auto scope = tracer->GetInstrumentationScope();
  187. auto attrs = scope.GetAttributes();
  188. ASSERT_EQ(attrs.size(), 2);
  189. auto attr = attrs.find("bar");
  190. ASSERT_FALSE(attr == attrs.end());
  191. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::string>(attr->second));
  192. EXPECT_EQ(opentelemetry::nostd::get<std::string>(attr->second), "2");
  193. }
  194. std::initializer_list<
  195. std::pair<opentelemetry::nostd::string_view, opentelemetry::common::AttributeValue>>
  196. attrs6 = {{"foo", "1"}, {"bar", 42}};
  197. auto t6 = tp.GetTracer("name6", "version6", "url6", attrs6);
  198. ASSERT_NE(nullptr, t6);
  199. {
  200. auto tracer = static_cast<opentelemetry::sdk::trace::Tracer *>(t6.get());
  201. auto scope = tracer->GetInstrumentationScope();
  202. auto attrs = scope.GetAttributes();
  203. ASSERT_EQ(attrs.size(), 2);
  204. auto attr = attrs.find("bar");
  205. ASSERT_FALSE(attr == attrs.end());
  206. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<int>(attr->second));
  207. EXPECT_EQ(opentelemetry::nostd::get<int>(attr->second), 42);
  208. }
  209. typedef std::pair<opentelemetry::nostd::string_view, opentelemetry::common::AttributeValue> KV;
  210. std::initializer_list<KV> attrs7 = {{"foo", 3.14}, {"bar", "2"}};
  211. auto t7 = tp.GetTracer("name7", "version7", "url7", attrs7);
  212. ASSERT_NE(nullptr, t7);
  213. {
  214. auto tracer = static_cast<opentelemetry::sdk::trace::Tracer *>(t7.get());
  215. auto scope = tracer->GetInstrumentationScope();
  216. auto attrs = scope.GetAttributes();
  217. ASSERT_EQ(attrs.size(), 2);
  218. auto attr = attrs.find("foo");
  219. ASSERT_FALSE(attr == attrs.end());
  220. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<double>(attr->second));
  221. EXPECT_EQ(opentelemetry::nostd::get<double>(attr->second), 3.14);
  222. }
  223. auto t8 = tp.GetTracer("name8", "version8", "url8",
  224. {{"a", "string"},
  225. {"b", false},
  226. {"c", 314159},
  227. {"d", static_cast<unsigned int>(314159)},
  228. {"e", static_cast<int32_t>(-20)},
  229. {"f", static_cast<uint32_t>(20)},
  230. {"g", static_cast<int64_t>(-20)},
  231. {"h", static_cast<uint64_t>(20)},
  232. {"i", 3.1},
  233. {"j", "string"}});
  234. ASSERT_NE(nullptr, t8);
  235. {
  236. auto tracer = static_cast<opentelemetry::sdk::trace::Tracer *>(t8.get());
  237. auto scope = tracer->GetInstrumentationScope();
  238. auto attrs = scope.GetAttributes();
  239. ASSERT_EQ(attrs.size(), 10);
  240. auto attr = attrs.find("e");
  241. ASSERT_FALSE(attr == attrs.end());
  242. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<int32_t>(attr->second));
  243. EXPECT_EQ(opentelemetry::nostd::get<int32_t>(attr->second), -20);
  244. }
  245. std::map<std::string, opentelemetry::common::AttributeValue> attr9{
  246. {"a", "string"},
  247. {"b", false},
  248. {"c", 314159},
  249. {"d", static_cast<unsigned int>(314159)},
  250. {"e", static_cast<int32_t>(-20)},
  251. {"f", static_cast<uint32_t>(20)},
  252. {"g", static_cast<int64_t>(-20)},
  253. {"h", static_cast<uint64_t>(20)},
  254. {"i", 3.1},
  255. {"j", "string"}};
  256. auto t9 = tp.GetTracer("name9", "version9", "url9", attr9);
  257. ASSERT_NE(nullptr, t9);
  258. {
  259. auto tracer = static_cast<opentelemetry::sdk::trace::Tracer *>(t9.get());
  260. auto scope = tracer->GetInstrumentationScope();
  261. auto attrs = scope.GetAttributes();
  262. ASSERT_EQ(attrs.size(), 10);
  263. auto attr = attrs.find("h");
  264. ASSERT_FALSE(attr == attrs.end());
  265. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<uint64_t>(attr->second));
  266. EXPECT_EQ(opentelemetry::nostd::get<uint64_t>(attr->second), 20);
  267. }
  268. // cleanup properly without crash
  269. tp.ForceFlush();
  270. tp.Shutdown();
  271. }
  272. #endif /* OPENTELEMETRY_ABI_VERSION_NO >= 2 */
  273. TEST(TracerProvider, Shutdown)
  274. {
  275. std::unique_ptr<SpanProcessor> processor(new SimpleSpanProcessor(nullptr));
  276. std::vector<std::unique_ptr<SpanProcessor>> processors;
  277. processors.push_back(std::move(processor));
  278. std::unique_ptr<TracerContext> context1(new TracerContext(std::move(processors)));
  279. TracerProvider tp1(std::move(context1));
  280. EXPECT_TRUE(tp1.Shutdown());
  281. // It's safe to shutdown again
  282. EXPECT_TRUE(tp1.Shutdown());
  283. }
  284. TEST(TracerProvider, ForceFlush)
  285. {
  286. std::unique_ptr<SpanProcessor> processor1(new SimpleSpanProcessor(nullptr));
  287. TracerProvider tp1(std::move(processor1));
  288. EXPECT_TRUE(tp1.ForceFlush());
  289. }