logger_provider_sdk_test.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include <gtest/gtest.h>
  4. #include <stdint.h>
  5. #include <chrono>
  6. #include <string>
  7. #include <unordered_map>
  8. #include <utility>
  9. #include <vector>
  10. #include "opentelemetry/common/attribute_value.h"
  11. #include "opentelemetry/common/timestamp.h"
  12. #include "opentelemetry/logs/logger_provider.h"
  13. #include "opentelemetry/logs/provider.h"
  14. #include "opentelemetry/logs/severity.h"
  15. #include "opentelemetry/nostd/shared_ptr.h"
  16. #include "opentelemetry/nostd/string_view.h"
  17. #include "opentelemetry/nostd/variant.h"
  18. #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
  19. #include "opentelemetry/sdk/logs/event_logger_provider.h"
  20. #include "opentelemetry/sdk/logs/event_logger_provider_factory.h"
  21. #include "opentelemetry/sdk/logs/exporter.h"
  22. #include "opentelemetry/sdk/logs/logger.h"
  23. #include "opentelemetry/sdk/logs/logger_context.h"
  24. #include "opentelemetry/sdk/logs/logger_provider.h"
  25. #include "opentelemetry/sdk/logs/processor.h"
  26. #include "opentelemetry/sdk/logs/provider.h"
  27. #include "opentelemetry/sdk/logs/recordable.h"
  28. #include "opentelemetry/sdk/logs/simple_log_record_processor.h"
  29. #include "opentelemetry/sdk/resource/resource.h"
  30. #include "opentelemetry/trace/span_id.h"
  31. #include "opentelemetry/trace/trace_flags.h"
  32. #include "opentelemetry/trace/trace_id.h"
  33. using namespace opentelemetry::sdk::logs;
  34. namespace logs_api = opentelemetry::logs;
  35. namespace logs_sdk = opentelemetry::sdk::logs;
  36. namespace nostd = opentelemetry::nostd;
  37. TEST(LoggerProviderSDK, PushToAPI)
  38. {
  39. auto lp =
  40. nostd::shared_ptr<logs_api::LoggerProvider>(new opentelemetry::sdk::logs::LoggerProvider());
  41. logs_sdk::Provider::SetLoggerProvider(lp);
  42. // Check that the loggerprovider was correctly pushed into the API
  43. ASSERT_EQ(lp, logs_api::Provider::GetLoggerProvider());
  44. }
  45. TEST(LoggerProviderSDK, LoggerProviderGetLoggerSimple)
  46. {
  47. auto lp = std::shared_ptr<logs_api::LoggerProvider>(new LoggerProvider());
  48. nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.11.0"};
  49. auto logger1 = lp->GetLogger("logger1", "opentelelemtry_library", "", schema_url);
  50. auto logger2 = lp->GetLogger("logger2", "", "", schema_url);
  51. // Check that the logger is not nullptr
  52. ASSERT_NE(logger1, nullptr);
  53. ASSERT_NE(logger2, nullptr);
  54. auto sdk_logger1 = static_cast<opentelemetry::sdk::logs::Logger *>(logger1.get());
  55. auto sdk_logger2 = static_cast<opentelemetry::sdk::logs::Logger *>(logger2.get());
  56. ASSERT_EQ(sdk_logger1->GetInstrumentationScope().GetName(), "opentelelemtry_library");
  57. ASSERT_EQ(sdk_logger1->GetInstrumentationScope().GetVersion(), "");
  58. ASSERT_EQ(sdk_logger1->GetInstrumentationScope().GetSchemaURL(), schema_url);
  59. ASSERT_EQ(sdk_logger2->GetInstrumentationScope().GetName(), "logger2");
  60. ASSERT_EQ(sdk_logger2->GetInstrumentationScope().GetVersion(), "");
  61. ASSERT_EQ(sdk_logger2->GetInstrumentationScope().GetSchemaURL(), schema_url);
  62. // Check that two loggers with different names aren't the same instance
  63. ASSERT_NE(logger1, logger2);
  64. // Check that two loggers with the same name are the same instance
  65. auto logger3 = lp->GetLogger("logger1", "opentelelemtry_library", "", schema_url);
  66. ASSERT_EQ(logger1, logger3);
  67. auto sdk_logger3 = static_cast<opentelemetry::sdk::logs::Logger *>(logger3.get());
  68. ASSERT_EQ(sdk_logger3->GetInstrumentationScope(), sdk_logger1->GetInstrumentationScope());
  69. }
  70. TEST(LoggerProviderSDK, LoggerProviderLoggerArguments)
  71. {
  72. auto lp = std::shared_ptr<logs_api::LoggerProvider>(new LoggerProvider());
  73. nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.11.0"};
  74. auto logger1 = lp->GetLogger("logger1", "opentelelemtry_library", "", schema_url);
  75. auto logger2 = lp->GetLogger("logger2", "opentelelemtry_library", "", schema_url);
  76. auto sdk_logger1 = static_cast<opentelemetry::sdk::logs::Logger *>(logger1.get());
  77. auto sdk_logger2 = static_cast<opentelemetry::sdk::logs::Logger *>(logger2.get());
  78. ASSERT_EQ(sdk_logger2->GetInstrumentationScope(), sdk_logger1->GetInstrumentationScope());
  79. auto logger3 = lp->GetLogger("logger3", "opentelelemtry_library", "", schema_url,
  80. {{"scope_key1", "scope_value"}, {"scope_key2", 2}});
  81. auto sdk_logger3 = static_cast<opentelemetry::sdk::logs::Logger *>(logger3.get());
  82. EXPECT_EQ(sdk_logger3->GetInstrumentationScope().GetAttributes().size(), 2);
  83. {
  84. auto attibute = sdk_logger3->GetInstrumentationScope().GetAttributes().find("scope_key1");
  85. ASSERT_FALSE(attibute == sdk_logger3->GetInstrumentationScope().GetAttributes().end());
  86. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::string>(attibute->second));
  87. EXPECT_EQ(opentelemetry::nostd::get<std::string>(attibute->second), "scope_value");
  88. }
  89. std::unordered_map<std::string, std::string> scope_attributes = {{"scope_key", "scope_value"}};
  90. auto logger4 =
  91. lp->GetLogger("logger4", "opentelelemtry_library", "", schema_url, scope_attributes);
  92. auto sdk_logger4 = static_cast<opentelemetry::sdk::logs::Logger *>(logger4.get());
  93. EXPECT_EQ(sdk_logger4->GetInstrumentationScope().GetAttributes().size(), 1);
  94. {
  95. auto attibute = sdk_logger4->GetInstrumentationScope().GetAttributes().find("scope_key");
  96. ASSERT_FALSE(attibute == sdk_logger4->GetInstrumentationScope().GetAttributes().end());
  97. ASSERT_TRUE(opentelemetry::nostd::holds_alternative<std::string>(attibute->second));
  98. EXPECT_EQ(opentelemetry::nostd::get<std::string>(attibute->second), "scope_value");
  99. }
  100. }
  101. #if OPENTELEMETRY_ABI_VERSION_NO < 2
  102. TEST(LoggerProviderSDK, EventLoggerProviderFactory)
  103. {
  104. auto elp = opentelemetry::sdk::logs::EventLoggerProviderFactory::Create();
  105. auto lp = std::shared_ptr<logs_api::LoggerProvider>(new LoggerProvider());
  106. nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.11.0"};
  107. auto logger1 = lp->GetLogger("logger1", "opentelelemtry_library", "", schema_url);
  108. auto event_logger = elp->CreateEventLogger(logger1, "otel-cpp.test");
  109. }
  110. #endif
  111. TEST(LoggerProviderSDK, LoggerEqualityCheck)
  112. {
  113. auto lp = std::shared_ptr<logs_api::LoggerProvider>(new LoggerProvider());
  114. nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.11.0"};
  115. auto logger1 = lp->GetLogger("logger1", "opentelelemtry_library", "", schema_url);
  116. auto logger2 = lp->GetLogger("logger1", "opentelelemtry_library", "", schema_url);
  117. EXPECT_EQ(logger1, logger2);
  118. auto logger3 = lp->GetLogger("logger3");
  119. auto another_logger3 = lp->GetLogger("logger3");
  120. EXPECT_EQ(logger3, another_logger3);
  121. auto logger4 = lp->GetLogger("logger4", "opentelelemtry_library", "1.0.0", schema_url);
  122. auto another_logger4 = lp->GetLogger("logger4", "opentelelemtry_library", "1.0.0", schema_url);
  123. EXPECT_EQ(logger4, another_logger4);
  124. auto logger5 =
  125. lp->GetLogger("logger5", "opentelelemtry_library", "1.0.0", schema_url, {{"key", "value"}});
  126. auto another_logger5 =
  127. lp->GetLogger("logger5", "opentelelemtry_library", "1.0.0", schema_url, {{"key", "value"}});
  128. EXPECT_EQ(logger5, another_logger5);
  129. }
  130. TEST(LoggerProviderSDK, GetLoggerInequalityCheck)
  131. {
  132. auto lp = std::shared_ptr<logs_api::LoggerProvider>(new LoggerProvider());
  133. auto logger_library_1 = lp->GetLogger("logger1", "library_1");
  134. auto logger_library_2 = lp->GetLogger("logger1", "library_2");
  135. auto logger_version_1 = lp->GetLogger("logger1", "library_1", "1.0.0");
  136. auto logger_version_2 = lp->GetLogger("logger1", "library_1", "2.0.0");
  137. auto logger_url_1 = lp->GetLogger("logger1", "library_1", "1.0.0", "url_1");
  138. auto logger_url_2 = lp->GetLogger("logger1", "library_1", "1.0.0", "url_2");
  139. auto logger_attribute_1 =
  140. lp->GetLogger("logger1", "library_1", "1.0.0", "url_1", {{"key", "one"}});
  141. auto logger_attribute_2 =
  142. lp->GetLogger("logger1", "library_1", "1.0.0", "url_1", {{"key", "two"}});
  143. // different scope names should return distinct loggers
  144. EXPECT_NE(logger_library_1, logger_library_2);
  145. // different scope versions should return distinct loggers
  146. EXPECT_NE(logger_version_1, logger_library_1);
  147. EXPECT_NE(logger_version_1, logger_version_2);
  148. // different scope schema urls should return distinct loggers
  149. EXPECT_NE(logger_url_1, logger_library_1);
  150. EXPECT_NE(logger_url_1, logger_version_1);
  151. EXPECT_NE(logger_url_1, logger_url_2);
  152. // different scope attributes should return distinct loggers
  153. EXPECT_NE(logger_attribute_1, logger_library_1);
  154. EXPECT_NE(logger_attribute_1, logger_url_1);
  155. EXPECT_NE(logger_attribute_1, logger_attribute_2);
  156. }
  157. class DummyLogRecordable final : public opentelemetry::sdk::logs::Recordable
  158. {
  159. public:
  160. void SetTimestamp(opentelemetry::common::SystemTimestamp) noexcept override {}
  161. void SetObservedTimestamp(opentelemetry::common::SystemTimestamp) noexcept override {}
  162. void SetSeverity(opentelemetry::logs::Severity) noexcept override {}
  163. void SetBody(const opentelemetry::common::AttributeValue &) noexcept override {}
  164. void SetEventId(int64_t, nostd::string_view) noexcept override {}
  165. void SetTraceId(const opentelemetry::trace::TraceId &) noexcept override {}
  166. void SetSpanId(const opentelemetry::trace::SpanId &) noexcept override {}
  167. void SetTraceFlags(const opentelemetry::trace::TraceFlags &) noexcept override {}
  168. void SetAttribute(nostd::string_view,
  169. const opentelemetry::common::AttributeValue &) noexcept override
  170. {}
  171. void SetResource(const opentelemetry::sdk::resource::Resource &) noexcept override {}
  172. void SetInstrumentationScope(
  173. const opentelemetry::sdk::instrumentationscope::InstrumentationScope &) noexcept override
  174. {}
  175. };
  176. class DummyProcessor : public LogRecordProcessor
  177. {
  178. std::unique_ptr<Recordable> MakeRecordable() noexcept override
  179. {
  180. return std::unique_ptr<Recordable>(new DummyLogRecordable());
  181. }
  182. void OnEmit(std::unique_ptr<Recordable> && /* record */) noexcept override {}
  183. bool ForceFlush(std::chrono::microseconds /* timeout */) noexcept override { return true; }
  184. bool Shutdown(std::chrono::microseconds /* timeout */) noexcept override { return true; }
  185. };
  186. TEST(LoggerProviderSDK, GetResource)
  187. {
  188. // Create a LoggerProvider without a processor
  189. auto resource = opentelemetry::sdk::resource::Resource::Create({{"key", "value"}});
  190. LoggerProvider lp{nullptr, resource};
  191. ASSERT_EQ(nostd::get<std::string>(lp.GetResource().GetAttributes().at("key")), "value");
  192. }
  193. TEST(LoggerProviderSDK, Shutdown)
  194. {
  195. std::unique_ptr<SimpleLogRecordProcessor> processor(new SimpleLogRecordProcessor(nullptr));
  196. SimpleLogRecordProcessor *processor_ptr = processor.get();
  197. std::vector<std::unique_ptr<LogRecordProcessor>> processors;
  198. processors.push_back(std::move(processor));
  199. std::unique_ptr<LoggerContext> context(new LoggerContext(std::move(processors)));
  200. LoggerProvider lp(std::move(context));
  201. EXPECT_TRUE(lp.Shutdown());
  202. EXPECT_TRUE(processor_ptr->IsShutdown());
  203. // It's safe to shutdown again
  204. EXPECT_TRUE(lp.Shutdown());
  205. }
  206. TEST(LoggerProviderSDK, ForceFlush)
  207. {
  208. std::unique_ptr<SimpleLogRecordProcessor> processor(new SimpleLogRecordProcessor(nullptr));
  209. std::vector<std::unique_ptr<LogRecordProcessor>> processors;
  210. processors.push_back(std::move(processor));
  211. std::unique_ptr<LoggerContext> context(new LoggerContext(std::move(processors)));
  212. LoggerProvider lp(std::move(context));
  213. EXPECT_TRUE(lp.ForceFlush());
  214. }