diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e5f88f9c4..04157b40b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Increment the: ## [Unreleased] +* [API/SDK] Logger: Support for Instrumentation library ([#1128](https://github.com/open-telemetry/opentelemetry-cpp/pull/1128)) * [EXPORTER] Bugfix: Jaeger exporter: extend supported attributes types ([#1106](https://github.com/open-telemetry/opentelemetry-cpp/pull/1106)) * [EXPORTER] Fix otlp generates null span ids ([#1106](https://github.com/open-telemetry/opentelemetry-cpp/pull/1106)) diff --git a/api/include/opentelemetry/logs/logger_provider.h b/api/include/opentelemetry/logs/logger_provider.h index 93ba683f94..5f1795c8ea 100644 --- a/api/include/opentelemetry/logs/logger_provider.h +++ b/api/include/opentelemetry/logs/logger_provider.h @@ -31,10 +31,16 @@ class LoggerProvider */ virtual nostd::shared_ptr GetLogger(nostd::string_view logger_name, - nostd::string_view options = "") = 0; + nostd::string_view options, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") = 0; virtual nostd::shared_ptr GetLogger(nostd::string_view logger_name, - nostd::span args) = 0; + nostd::span args, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") = 0; }; } // namespace logs OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/logs/noop.h b/api/include/opentelemetry/logs/noop.h index a61507093c..6c5c24d671 100644 --- a/api/include/opentelemetry/logs/noop.h +++ b/api/include/opentelemetry/logs/noop.h @@ -65,13 +65,19 @@ class NoopLoggerProvider final : public opentelemetry::logs::LoggerProvider {} nostd::shared_ptr GetLogger(nostd::string_view logger_name, - nostd::string_view options) override + nostd::string_view options, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") override { return logger_; } nostd::shared_ptr GetLogger(nostd::string_view logger_name, - nostd::span args) override + nostd::span args, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") override { return logger_; } diff --git a/api/test/logs/logger_test.cc b/api/test/logs/logger_test.cc index 99c7474280..6809568e47 100644 --- a/api/test/logs/logger_test.cc +++ b/api/test/logs/logger_test.cc @@ -25,8 +25,9 @@ namespace trace = opentelemetry::trace; // Check that the default logger is a noop logger instance TEST(Logger, GetLoggerDefault) { - auto lp = Provider::GetLoggerProvider(); - auto logger = lp->GetLogger("TestLogger"); + auto lp = Provider::GetLoggerProvider(); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = lp->GetLogger("TestLogger", "", "library_name", "", schema_url); auto name = logger->GetName(); EXPECT_NE(nullptr, logger); EXPECT_EQ(name, "noop logger"); @@ -40,17 +41,19 @@ TEST(Logger, GetNoopLoggerNameWithArgs) // GetLogger(name, list(args)) std::array sv{"string"}; span args{sv}; - lp->GetLogger("NoopLoggerWithArgs", args); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + lp->GetLogger("NoopLoggerWithArgs", args, "library_name", "", schema_url); // GetLogger(name, string options) - lp->GetLogger("NoopLoggerWithOptions", "options"); + lp->GetLogger("NoopLoggerWithOptions", "options", "lib_name", "", schema_url); } // Test the Log() overloads TEST(Logger, LogMethodOverloads) { - auto lp = Provider::GetLoggerProvider(); - auto logger = lp->GetLogger("TestLogger"); + auto lp = Provider::GetLoggerProvider(); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = lp->GetLogger("TestLogger", "", "library_name", "", schema_url); // Create a map to test the logs with std::map m = {{"key1", "value1"}}; @@ -92,12 +95,20 @@ class TestLogger : public Logger // Define a basic LoggerProvider class that returns an instance of the logger class defined above class TestProvider : public LoggerProvider { - shared_ptr GetLogger(string_view library_name, string_view options = "") override + nostd::shared_ptr GetLogger(nostd::string_view logger_name, + nostd::string_view options, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") override { return shared_ptr(new TestLogger()); } - shared_ptr GetLogger(string_view library_name, span args) override + nostd::shared_ptr GetLogger(nostd::string_view logger_name, + nostd::span args, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") override { return shared_ptr(new TestLogger()); } @@ -112,7 +123,8 @@ TEST(Logger, PushLoggerImplementation) auto lp = Provider::GetLoggerProvider(); // Check that the implementation was pushed by calling TestLogger's GetName() - auto logger = lp->GetLogger("TestLogger"); + nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = lp->GetLogger("TestLogger", "", "library_name", "", schema_url); ASSERT_EQ("test logger", logger->GetName()); } #endif diff --git a/api/test/logs/provider_test.cc b/api/test/logs/provider_test.cc index c9eb7bddc7..5c1095e3bb 100644 --- a/api/test/logs/provider_test.cc +++ b/api/test/logs/provider_test.cc @@ -8,24 +8,29 @@ # include "opentelemetry/logs/provider.h" # include "opentelemetry/nostd/shared_ptr.h" -# include "opentelemetry/nostd/span.h" -# include "opentelemetry/nostd/string_view.h" using opentelemetry::logs::Logger; using opentelemetry::logs::LoggerProvider; using opentelemetry::logs::Provider; using opentelemetry::nostd::shared_ptr; -using opentelemetry::nostd::span; -using opentelemetry::nostd::string_view; +namespace nostd = opentelemetry::nostd; class TestProvider : public LoggerProvider { - shared_ptr GetLogger(string_view library_name, string_view options) override + nostd::shared_ptr GetLogger(nostd::string_view logger_name, + nostd::string_view options, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") override { return shared_ptr(nullptr); } - shared_ptr GetLogger(string_view library_name, span args) override + nostd::shared_ptr GetLogger(nostd::string_view logger_name, + nostd::span args, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") override { return shared_ptr(nullptr); } @@ -57,15 +62,9 @@ TEST(Provider, MultipleLoggerProviders) TEST(Provider, GetLogger) { auto tf = shared_ptr(new TestProvider()); - // tests GetLogger(name, options) - auto logger = tf->GetLogger("logger1"); + // tests GetLogger(name, version, schema) + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = tf->GetLogger("logger1", "", "library_name", "", schema_url); EXPECT_EQ(nullptr, logger); - - // tests GetLogger(name, arguments) - - std::array sv{"string"}; - span args{sv}; - auto logger2 = tf->GetLogger("logger2", args); - EXPECT_EQ(nullptr, logger2); } #endif diff --git a/examples/common/logs_foo_library/foo_library.cc b/examples/common/logs_foo_library/foo_library.cc index a5b8d9ae98..ebd3101b73 100644 --- a/examples/common/logs_foo_library/foo_library.cc +++ b/examples/common/logs_foo_library/foo_library.cc @@ -22,7 +22,7 @@ nostd::shared_ptr get_tracer() nostd::shared_ptr get_logger() { auto provider = logs::Provider::GetLoggerProvider(); - return provider->GetLogger("foo_library_logger"); + return provider->GetLogger("foo_library_logger", "", "foo_library"); } } // namespace diff --git a/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h b/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h old mode 100644 new mode 100755 index 8a928d829e..fcd5e9fd1e --- a/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h +++ b/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h @@ -157,7 +157,29 @@ class ElasticSearchRecordable final : public sdk::logs::Recordable /** * Returns a JSON object contain the log information */ - nlohmann::json GetJSON() noexcept { return json_; }; + nlohmann::json GetJSON() noexcept { return json_; } + + /** + * Set instrumentation_library for this log. + * @param instrumentation_library the instrumentation library to set + */ + void SetInstrumentationLibrary( + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + &instrumentation_library) noexcept + { + instrumentation_library_ = &instrumentation_library; + } + + /** Returns the associated instruementation library */ + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary & + GetInstrumentationLibrary() const noexcept + { + return *instrumentation_library_; + } + +private: + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + *instrumentation_library_ = nullptr; }; } // namespace logs } // namespace exporter diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h index 3420b3f5db..0237362d08 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h @@ -215,27 +215,39 @@ class LoggerProvider : public opentelemetry::logs::LoggerProvider * @brief Obtain ETW Tracer. * @param name ProviderId (instrumentation name) - Name or GUID * - * @param args Additional arguments that controls `codec` of the provider. - * Possible values are: - * - "ETW" - 'classic' Trace Logging Dynamic manifest ETW events. - * - "MSGPACK" - MessagePack-encoded binary payload ETW events. - * - "XML" - XML events (reserved for future use) + * @param version Library version * @return */ - nostd::shared_ptr GetLogger(nostd::string_view name, - nostd::string_view args = "") override + nostd::shared_ptr GetLogger( + nostd::string_view logger_name, + nostd::string_view options, + nostd::string_view library_name, + nostd::string_view version = "", + nostd::string_view schema_url = "") override { - UNREFERENCED_PARAMETER(args); + UNREFERENCED_PARAMETER(options); + UNREFERENCED_PARAMETER(library_name); + UNREFERENCED_PARAMETER(version); + UNREFERENCED_PARAMETER(schema_url); ETWProvider::EventFormat evtFmt = config_.encoding; - return nostd::shared_ptr{new (std::nothrow) - etw::Logger(*this, name, evtFmt)}; + return nostd::shared_ptr{ + new (std::nothrow) etw::Logger(*this, logger_name, evtFmt)}; } nostd::shared_ptr GetLogger( - nostd::string_view name, - nostd::span args) override + nostd::string_view logger_name, + nostd::span args, + nostd::string_view library_name, + nostd::string_view version = "", + nostd::string_view schema_url = "") override { - return GetLogger(name, args[0]); + UNREFERENCED_PARAMETER(args); + UNREFERENCED_PARAMETER(library_name); + UNREFERENCED_PARAMETER(version); + UNREFERENCED_PARAMETER(schema_url); + ETWProvider::EventFormat evtFmt = config_.encoding; + return nostd::shared_ptr{ + new (std::nothrow) etw::Logger(*this, logger_name, evtFmt)}; } }; diff --git a/exporters/etw/test/etw_logger_test.cc b/exporters/etw/test/etw_logger_test.cc index 419e4ad0da..e4cf53ee34 100644 --- a/exporters/etw/test/etw_logger_test.cc +++ b/exporters/etw/test/etw_logger_test.cc @@ -48,7 +48,8 @@ TEST(ETWLogger, LoggerCheckWithBody) std::string providerName = kGlobalProviderName; // supply unique instrumentation name here exporter::etw::LoggerProvider lp; - auto logger = lp.GetLogger(providerName); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = lp.GetLogger(providerName, "", schema_url); Properties attribs = {{"attrib1", 1}, {"attrib2", 2}}; EXPECT_NO_THROW( logger->Log(opentelemetry::logs::Severity::kDebug, "My Log", "This is test log body")); @@ -90,7 +91,8 @@ TEST(ETWLogger, LoggerCheckWithAttributes) std::string providerName = kGlobalProviderName; // supply unique instrumentation name here exporter::etw::LoggerProvider lp; - auto logger = lp.GetLogger(providerName); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = lp.GetLogger(providerName, "", schema_url); // Log attributes Properties attribs = {{"attrib1", 1}, {"attrib2", 2}}; EXPECT_NO_THROW(logger->Log(opentelemetry::logs::Severity::kDebug, "My Log", attribs)); diff --git a/exporters/ostream/test/ostream_log_test.cc b/exporters/ostream/test/ostream_log_test.cc index a21be32f29..c53d233c0b 100644 --- a/exporters/ostream/test/ostream_log_test.cc +++ b/exporters/ostream/test/ostream_log_test.cc @@ -249,7 +249,9 @@ TEST(OStreamLogExporter, IntegrationTest) auto apiProvider = nostd::shared_ptr(sdkProvider); auto provider = nostd::shared_ptr(apiProvider); logs_api::Provider::SetLoggerProvider(provider); - auto logger = logs_api::Provider::GetLoggerProvider()->GetLogger("Logger"); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = + logs_api::Provider::GetLoggerProvider()->GetLogger("Logger", "", "lib_name", "", schema_url); // Back up cout's streambuf std::streambuf *original = std::cout.rdbuf(); diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h index 368505ca2a..6b1d1eb0f2 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h @@ -9,6 +9,7 @@ # include "opentelemetry/proto/logs/v1/logs.pb.h" # include "opentelemetry/proto/resource/v1/resource.pb.h" +# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" # include "opentelemetry/exporters/otlp/protobuf_include_suffix.h" // clang-format on @@ -94,14 +95,25 @@ class OtlpLogRecordable final : public opentelemetry::sdk::logs::Recordable */ virtual void SetTraceFlags(opentelemetry::trace::TraceFlags trace_flags) noexcept override; + /** + * Set instrumentation_library for this log. + * @param instrumentation_library the instrumentation library to set + */ + void SetInstrumentationLibrary( + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + &instrumentation_library) noexcept override; + + /** Returns the associated instruementation library */ + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary & + GetInstrumentationLibrary() const noexcept; + private: proto::logs::v1::LogRecord log_record_; opentelemetry::sdk::common::AttributeMap resource_attributes_; // TODO shared resource // const opentelemetry::sdk::resource::Resource *resource_ = nullptr; - // TODO InstrumentationLibrary - // const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary - // *instrumentation_library_ = nullptr; + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + *instrumentation_library_ = nullptr; }; } // namespace otlp diff --git a/exporters/otlp/src/otlp_log_recordable.cc b/exporters/otlp/src/otlp_log_recordable.cc index 5276b62690..edc6f28623 100644 --- a/exporters/otlp/src/otlp_log_recordable.cc +++ b/exporters/otlp/src/otlp_log_recordable.cc @@ -199,6 +199,18 @@ void OtlpLogRecordable::SetTraceFlags(opentelemetry::trace::TraceFlags trace_fla log_record_.set_flags(trace_flags.flags()); } +void OtlpLogRecordable::SetInstrumentationLibrary( + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + &instrumentation_library) noexcept +{ + instrumentation_library_ = &instrumentation_library; +} + +const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary & +OtlpLogRecordable::GetInstrumentationLibrary() const noexcept +{ + return *instrumentation_library_; +} } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/otlp/test/otlp_grpc_log_exporter_test.cc b/exporters/otlp/test/otlp_grpc_log_exporter_test.cc index 0f28e46c24..feb97f3b65 100644 --- a/exporters/otlp/test/otlp_grpc_log_exporter_test.cc +++ b/exporters/otlp/test/otlp_grpc_log_exporter_test.cc @@ -137,7 +137,8 @@ TEST_F(OtlpGrpcLogExporterTestPeer, ExportIntegrationTest) '3', '2', '1', '0'}; opentelemetry::trace::SpanId span_id{span_id_bin}; - auto logger = provider->GetLogger("test"); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = provider->GetLogger("test", "", "lib_name", "", schema_url); logger->Log(opentelemetry::logs::Severity::kInfo, "Log name", "Log message", {{"service.name", "unit_test_service"}, {"tenant.id", "test_user"}, diff --git a/exporters/otlp/test/otlp_http_log_exporter_test.cc b/exporters/otlp/test/otlp_http_log_exporter_test.cc index 536636033e..7996b7c06f 100755 --- a/exporters/otlp/test/otlp_http_log_exporter_test.cc +++ b/exporters/otlp/test/otlp_http_log_exporter_test.cc @@ -223,7 +223,8 @@ TEST_F(OtlpHttpLogExporterTestPeer, ExportJsonIntegrationTest) char span_id_hex[2 * opentelemetry::trace::SpanId::kSize] = {0}; opentelemetry::trace::SpanId span_id{span_id_bin}; - auto logger = provider->GetLogger("test"); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = provider->GetLogger("test", "", "lib_name", "", schema_url); logger->Log(opentelemetry::logs::Severity::kInfo, "Log name", "Log message", {{"service.name", "unit_test_service"}, {"tenant.id", "test_user"}, @@ -314,7 +315,8 @@ TEST_F(OtlpHttpLogExporterTestPeer, ExportBinaryIntegrationTest) '3', '2', '1', '0'}; opentelemetry::trace::SpanId span_id{span_id_bin}; - auto logger = provider->GetLogger("test"); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = provider->GetLogger("test", "", "lib_name", "", schema_url); logger->Log(opentelemetry::logs::Severity::kInfo, "Log name", "Log message", {{"service.name", "unit_test_service"}, {"tenant.id", "test_user"}, diff --git a/exporters/otlp/test/otlp_log_recordable_test.cc b/exporters/otlp/test/otlp_log_recordable_test.cc index 808d04fafe..b7b8acc293 100644 --- a/exporters/otlp/test/otlp_log_recordable_test.cc +++ b/exporters/otlp/test/otlp_log_recordable_test.cc @@ -188,6 +188,15 @@ TEST(OtlpLogRecordable, SetArrayAttribute) } } +TEST(OtlpLogRecordable, SetInstrumentationLibrary) +{ + OtlpLogRecordable rec; + auto inst_lib = + opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary::Create("test", "v1"); + rec.SetInstrumentationLibrary(*inst_lib); + EXPECT_EQ(rec.GetInstrumentationLibrary(), *inst_lib); +} + /** * AttributeValue can contain different int types, such as int, int64_t, * unsigned int, and uint64_t. To avoid writing test cases for each, we can diff --git a/sdk/include/opentelemetry/sdk/logs/log_record.h b/sdk/include/opentelemetry/sdk/logs/log_record.h index 34ef5befb0..290ac26b41 100644 --- a/sdk/include/opentelemetry/sdk/logs/log_record.h +++ b/sdk/include/opentelemetry/sdk/logs/log_record.h @@ -181,6 +181,21 @@ class LogRecord final : public Recordable * @return the timestamp for this log */ opentelemetry::common::SystemTimestamp GetTimestamp() const noexcept { return timestamp_; } + + /** + * Set instrumentation_library for this log. + * @param instrumentation_library the instrumentation library to set + */ + void SetInstrumentationLibrary( + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + &instrumentation_library) noexcept + { + instrumentation_library_ = &instrumentation_library; + } + +private: + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + *instrumentation_library_ = nullptr; }; } // namespace logs } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/logs/logger.h b/sdk/include/opentelemetry/sdk/logs/logger.h index 4fd1ed89ed..3f505fb95a 100644 --- a/sdk/include/opentelemetry/sdk/logs/logger.h +++ b/sdk/include/opentelemetry/sdk/logs/logger.h @@ -5,6 +5,7 @@ #ifdef ENABLE_LOGS_PREVIEW # include "opentelemetry/logs/logger.h" +# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" # include "opentelemetry/sdk/logs/logger_provider.h" # include "opentelemetry/sdk/logs/processor.h" @@ -25,8 +26,11 @@ class Logger final : public opentelemetry::logs::Logger * @param name The name of this logger instance * @param logger_provider The logger provider that owns this logger. */ - explicit Logger(opentelemetry::nostd::string_view name, - std::shared_ptr logger_provider) noexcept; + explicit Logger( + opentelemetry::nostd::string_view name, + std::shared_ptr logger_provider, + std::unique_ptr instrumentation_library = + instrumentationlibrary::InstrumentationLibrary::Create("")) noexcept; /** * Returns the name of this logger. @@ -57,6 +61,10 @@ class Logger final : public opentelemetry::logs::Logger opentelemetry::trace::TraceFlags trace_flags, opentelemetry::common::SystemTimestamp timestamp) noexcept override; + /** Returns the associated instruementation library */ + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary & + GetInstrumentationLibrary() const noexcept; + private: // The name of this logger std::string logger_name_; @@ -64,6 +72,7 @@ class Logger final : public opentelemetry::logs::Logger // The logger provider of this Logger. Uses a weak_ptr to avoid cyclic dependency issues the with // logger provider std::weak_ptr logger_provider_; + std::shared_ptr instrumentation_library_; }; } // namespace logs diff --git a/sdk/include/opentelemetry/sdk/logs/logger_provider.h b/sdk/include/opentelemetry/sdk/logs/logger_provider.h old mode 100644 new mode 100755 index db07ba5f66..c983d0c7ce --- a/sdk/include/opentelemetry/sdk/logs/logger_provider.h +++ b/sdk/include/opentelemetry/sdk/logs/logger_provider.h @@ -7,7 +7,6 @@ # include # include # include -# include # include # include "opentelemetry/logs/logger_provider.h" @@ -41,24 +40,29 @@ class LoggerProvider final : public opentelemetry::logs::LoggerProvider, /** * Creates a logger with the given name, and returns a shared pointer to it. * If a logger with that name already exists, return a shared pointer to it - * @param name The name of the logger to be created. - * @param options (OPTIONAL) The options for the logger. TODO: Once the logging spec defines it, - * give a list of options that the logger supports. + * @param logger_name The name of the logger to be created. + * @param options The version of the library. + * @param library_name The version of the library. + * @param version The version of the library. */ - opentelemetry::nostd::shared_ptr GetLogger( - opentelemetry::nostd::string_view name, - opentelemetry::nostd::string_view options = "") noexcept override; - + nostd::shared_ptr GetLogger( + nostd::string_view logger_name, + nostd::string_view options, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") noexcept override; /** * Creates a logger with the given name, and returns a shared pointer to it. * If a logger with that name already exists, return a shared pointer to it * @param name The name of the logger to be created. - * @param args (OPTIONAL) The arguments for the logger. TODO: Once the logging spec defines it, - * give a list of arguments that the logger supports. + * @param version The version of the library. */ - opentelemetry::nostd::shared_ptr GetLogger( - opentelemetry::nostd::string_view name, - nostd::span args) noexcept override; + nostd::shared_ptr GetLogger( + nostd::string_view logger_name, + nostd::span args, + nostd::string_view library_name, + nostd::string_view library_version = "", + nostd::string_view schema_url = "") noexcept override; /** * Returns a shared pointer to the processor currently stored in the @@ -79,8 +83,7 @@ class LoggerProvider final : public opentelemetry::logs::LoggerProvider, opentelemetry::sdk::common::AtomicSharedPtr processor_; // A vector of pointers to all the loggers that have been created - std::unordered_map> - loggers_; + std::vector> loggers_; // A mutex that ensures only one thread is using the map of loggers std::mutex mu_; diff --git a/sdk/include/opentelemetry/sdk/logs/recordable.h b/sdk/include/opentelemetry/sdk/logs/recordable.h index db730752d2..d570d2aeee 100644 --- a/sdk/include/opentelemetry/sdk/logs/recordable.h +++ b/sdk/include/opentelemetry/sdk/logs/recordable.h @@ -92,6 +92,14 @@ class Recordable * @param trace_flags the trace flags to set */ virtual void SetTraceFlags(opentelemetry::trace::TraceFlags trace_flags) noexcept = 0; + + /** + * Set instrumentation_library for this log. + * @param instrumentation_library the instrumentation library to set + */ + virtual void SetInstrumentationLibrary( + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + &instrumentation_library) noexcept = 0; }; } // namespace logs } // namespace sdk diff --git a/sdk/src/logs/logger.cc b/sdk/src/logs/logger.cc index 735b527b80..d1439f7f82 100644 --- a/sdk/src/logs/logger.cc +++ b/sdk/src/logs/logger.cc @@ -16,8 +16,13 @@ namespace trace_api = opentelemetry::trace; namespace nostd = opentelemetry::nostd; namespace common = opentelemetry::common; -Logger::Logger(nostd::string_view name, std::shared_ptr logger_provider) noexcept - : logger_name_(std::string(name)), logger_provider_(logger_provider) +Logger::Logger(nostd::string_view name, + std::shared_ptr logger_provider, + std::unique_ptr + instrumentation_library) noexcept + : logger_name_(std::string(name)), + logger_provider_(logger_provider), + instrumentation_library_{std::move(instrumentation_library)} {} const nostd::string_view Logger::GetName() noexcept @@ -114,6 +119,12 @@ void Logger::Log(opentelemetry::logs::Severity severity, processor->OnReceive(std::move(recordable)); } +const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary & +Logger::GetInstrumentationLibrary() const noexcept +{ + return *instrumentation_library_; +} + } // namespace logs } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/logs/logger_provider.cc b/sdk/src/logs/logger_provider.cc index 58e6a75ea4..061a1b849d 100644 --- a/sdk/src/logs/logger_provider.cc +++ b/sdk/src/logs/logger_provider.cc @@ -16,17 +16,24 @@ namespace logs_api = opentelemetry::logs; LoggerProvider::LoggerProvider() noexcept : processor_{nullptr} {} -nostd::shared_ptr LoggerProvider::GetLogger(nostd::string_view name, - nostd::string_view options) noexcept +nostd::shared_ptr LoggerProvider::GetLogger( + nostd::string_view logger_name, + nostd::string_view options, + nostd::string_view library_name, + nostd::string_view library_version, + nostd::string_view schema_url) noexcept { // Ensure only one thread can read/write from the map of loggers std::lock_guard lock_guard{mu_}; - // If a logger with a name "name" already exists, return it - auto loggerkv = loggers_.find(name.data()); - if (loggerkv != loggers_.end()) + // If a logger with a name "logger_name" already exists, return it + for (auto &logger : loggers_) { - return nostd::shared_ptr(loggerkv->second); + auto& logger_lib = logger->GetInstrumentationLibrary(); + if (logger->GetName() == logger_name && logger_lib.equal(library_name, library_version, schema_url)) + { + return nostd::shared_ptr{logger}; + } } // Check if creating a new logger would exceed the max number of loggers @@ -44,17 +51,21 @@ nostd::shared_ptr LoggerProvider::GetLogger(nostd::string_view // If no logger with that name exists yet, create it and add it to the map of loggers - nostd::shared_ptr logger(new Logger(name, this->shared_from_this())); - loggers_[name.data()] = logger; - return logger; + auto lib = instrumentationlibrary::InstrumentationLibrary::Create(library_name, library_version, + schema_url); + loggers_.push_back(std::shared_ptr( + new Logger(logger_name, this->shared_from_this(), std::move(lib)))); + return nostd::shared_ptr{loggers_.back()}; } -nostd::shared_ptr LoggerProvider::GetLogger( - nostd::string_view name, - nostd::span args) noexcept +nostd::shared_ptr LoggerProvider::GetLogger( + nostd::string_view logger_name, + nostd::span args, + nostd::string_view library_name, + nostd::string_view library_version, + nostd::string_view schema_url) noexcept { - // Currently, no args support - return GetLogger(name); + return GetLogger(logger_name, "", library_name, library_version, schema_url); } std::shared_ptr LoggerProvider::GetProcessor() noexcept diff --git a/sdk/test/logs/logger_provider_sdk_test.cc b/sdk/test/logs/logger_provider_sdk_test.cc index 5c0be6fb94..c01eb9b934 100644 --- a/sdk/test/logs/logger_provider_sdk_test.cc +++ b/sdk/test/logs/logger_provider_sdk_test.cc @@ -31,34 +31,32 @@ TEST(LoggerProviderSDK, LoggerProviderGetLoggerSimple) { auto lp = std::shared_ptr(new LoggerProvider()); - auto logger1 = lp->GetLogger("logger1"); - auto logger2 = lp->GetLogger("logger2"); + nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger1 = lp->GetLogger("logger1", "", "lib_name", "", schema_url); + auto logger2 = lp->GetLogger("logger2", "", "lib_name", "", schema_url); // Check that the logger is not nullptr ASSERT_NE(logger1, nullptr); ASSERT_NE(logger2, nullptr); + auto sdk_logger1 = static_cast(logger1.get()); + auto sdk_logger2 = static_cast(logger2.get()); + ASSERT_EQ(sdk_logger1->GetInstrumentationLibrary().GetName(), "lib_name"); + ASSERT_EQ(sdk_logger1->GetInstrumentationLibrary().GetVersion(), ""); + ASSERT_EQ(sdk_logger1->GetInstrumentationLibrary().GetSchemaURL(), schema_url); + + ASSERT_EQ(sdk_logger2->GetInstrumentationLibrary().GetName(), "lib_name"); + ASSERT_EQ(sdk_logger2->GetInstrumentationLibrary().GetVersion(), ""); + ASSERT_EQ(sdk_logger2->GetInstrumentationLibrary().GetSchemaURL(), schema_url); + // Check that two loggers with different names aren't the same instance ASSERT_NE(logger1, logger2); // Check that two loggers with the same name are the same instance - auto logger3 = lp->GetLogger("logger1"); + auto logger3 = lp->GetLogger("logger1", "", "lib_name", "", schema_url); ASSERT_EQ(logger1, logger3); -} - -TEST(LoggerProviderSDK, LoggerProviderLoggerArguments) -{ - // Currently, arguments are not supported by the loggers. - // TODO: Once the logging spec defines what arguments are allowed, add more - // detail to this test - auto lp = std::shared_ptr(new LoggerProvider()); - - auto logger1 = lp->GetLogger("logger1", ""); - - // Check GetLogger(logger_name, args) - std::array sv{"string"}; - nostd::span args{sv}; - auto logger2 = lp->GetLogger("logger2", args); + auto sdk_logger3 = static_cast(logger3.get()); + ASSERT_EQ(sdk_logger3->GetInstrumentationLibrary(), sdk_logger1->GetInstrumentationLibrary()); } class DummyProcessor : public LogProcessor diff --git a/sdk/test/logs/logger_sdk_test.cc b/sdk/test/logs/logger_sdk_test.cc index 26632f1f91..b754b30bed 100644 --- a/sdk/test/logs/logger_sdk_test.cc +++ b/sdk/test/logs/logger_sdk_test.cc @@ -17,9 +17,14 @@ TEST(LoggerSDK, LogToNullProcessor) // even when there is no processor set // since it calls Processor::OnReceive() - auto lp = std::shared_ptr(new LoggerProvider()); - auto logger = lp->GetLogger("logger"); - + auto lp = std::shared_ptr(new LoggerProvider()); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = lp->GetLogger("logger", "", "lib_name", "", schema_url); + + auto sdk_logger = static_cast(logger.get()); + ASSERT_EQ(sdk_logger->GetInstrumentationLibrary().GetName(), "lib_name"); + ASSERT_EQ(sdk_logger->GetInstrumentationLibrary().GetVersion(), ""); + ASSERT_EQ(sdk_logger->GetInstrumentationLibrary().GetSchemaURL(), schema_url); // Log a sample log record to a nullptr processor logger->Debug("Test log"); } @@ -66,15 +71,20 @@ TEST(LoggerSDK, LogToAProcessor) { // Create an API LoggerProvider and logger auto api_lp = std::shared_ptr(new LoggerProvider()); - auto logger = api_lp->GetLogger("logger"); + const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + auto logger = api_lp->GetLogger("logger", "", "lib_name", "", schema_url); // Cast the API LoggerProvider to an SDK Logger Provider and assert that it is still the same // LoggerProvider by checking that getting a logger with the same name as the previously defined // logger is the same instance auto lp = static_cast(api_lp.get()); - auto logger2 = lp->GetLogger("logger"); + auto logger2 = lp->GetLogger("logger", "", "lib_name", "", schema_url); ASSERT_EQ(logger, logger2); + auto sdk_logger = static_cast(logger.get()); + ASSERT_EQ(sdk_logger->GetInstrumentationLibrary().GetName(), "lib_name"); + ASSERT_EQ(sdk_logger->GetInstrumentationLibrary().GetVersion(), ""); + ASSERT_EQ(sdk_logger->GetInstrumentationLibrary().GetSchemaURL(), schema_url); // Set a processor for the LoggerProvider auto shared_recordable = std::shared_ptr(new LogRecord()); auto processor = std::shared_ptr(new MockProcessor(shared_recordable));