Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/clang-tidy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ jobs:
matrix:
include:
- cmake_options: all-options-abiv1-preview
warning_limit: 418
warning_limit: 416
- cmake_options: all-options-abiv2-preview
warning_limit: 424
warning_limit: 422
env:
CC: /usr/bin/clang-22
CXX: /usr/bin/clang++-22
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/iwyu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ jobs:
matrix:
include:
- cmake_options: all-options-abiv1
warning_limit: 161
warning_limit: 160
- cmake_options: all-options-abiv1-preview
warning_limit: 190
warning_limit: 189
- cmake_options: all-options-abiv2-preview
warning_limit: 187
warning_limit: 186

steps:
- name: Harden the runner (Audit all outbound calls)
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ Increment the:

## [Unreleased]

* [API] `Logger::EmitLogRecord(...)` templates now short-circuit when the
supplied Severity is below the logger's minimum. Closes the second half of
#2667 so the `Trace`/`Debug`/`Info`/`Warn`/`Error`/`Fatal` helpers honor
the `Enabled()` flag transparently.
* [SDK] `Logger::EmitLogRecord(unique_ptr<LogRecord>)` now applies the
LoggerConfig trace-based filter using the current runtime context.
[#2667](https://github.com/open-telemetry/opentelemetry-cpp/issues/2667)

* [API] Fix `Logger::Enabled()`
[#2667](https://github.com/open-telemetry/opentelemetry-cpp/issues/2667)

Expand Down
6 changes: 6 additions & 0 deletions api/include/opentelemetry/logs/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ class Logger
return;
}

const Severity arg_severity = detail::FindSeverityInArgs(args...);
if (arg_severity != Severity::kInvalid && !Enabled(arg_severity))
{
return;
}

//
// Keep the parameter pack unpacking order from left to right because left
// ones are usually more important like severity and event_id than the
Expand Down
20 changes: 20 additions & 0 deletions api/include/opentelemetry/logs/logger_type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,26 @@ struct LogRecordHasType<ValueType, TargetType, ArgumentType...>
LogRecordHasType<ValueType, ArgumentType...>>::type
{};

inline Severity FindSeverityInArgs() noexcept
{
return Severity::kInvalid;
}

template <class... Rest>
inline Severity FindSeverityInArgs(Severity severity, Rest &&.../*rest*/) noexcept
{
return severity;
}

template <class First,
class... Rest,
typename std::enable_if<!std::is_same<typename std::decay<First>::type, Severity>::value,
int>::type = 0>
inline Severity FindSeverityInArgs(First && /*first*/, Rest &&...rest) noexcept
{
return FindSeverityInArgs(std::forward<Rest>(rest)...);
}

} // namespace detail

} // namespace logs
Expand Down
20 changes: 16 additions & 4 deletions api/test/logs/logger_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <vector>

#include "opentelemetry/common/attribute_value.h"
#include "opentelemetry/common/key_value_iterable.h"
#include "opentelemetry/common/key_value_iterable_view.h"
#include "opentelemetry/common/timestamp.h"
#include "opentelemetry/logs/event_id.h"
Expand All @@ -26,9 +25,7 @@
#include "opentelemetry/nostd/span.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/trace/span_id.h"
#include "opentelemetry/trace/trace_flags.h"
#include "opentelemetry/trace/trace_id.h"
#include "opentelemetry/nostd/utility.h"

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
# include "opentelemetry/context/context.h"
Expand Down Expand Up @@ -278,6 +275,9 @@ class TestLogger : public Logger
}
};

namespace
{

class EnablementAwareTestLogRecord : public opentelemetry::logs::LogRecord
{
public:
Expand Down Expand Up @@ -420,6 +420,8 @@ class EnablementAwareTestLogger : public Logger
bool event_id_enabled_;
};

} // namespace

// Define a basic LoggerProvider class that returns an instance of the logger class defined above
class TestProvider : public LoggerProvider
{
Expand Down Expand Up @@ -461,3 +463,13 @@ TEST(Logger, EnabledWithExplicitContextUsesContextAwareImplementation)
EXPECT_TRUE(logger.last_enabled_context_test_key_value_);
}
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2

TEST(Logger, EmitLogRecordTemplateShortCircuitsBelowMinimumSeverity)
{
EnablementAwareTestLogger logger(Severity::kWarn);

logger.Info(nostd::string_view{"filtered"});

EXPECT_EQ(logger.create_log_record_calls_, 1u);
EXPECT_EQ(logger.emit_log_record_calls_, 0u);
}
7 changes: 5 additions & 2 deletions sdk/src/logs/logger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,18 @@ void Logger::EmitLogRecord(
return;
}

if (!IsAllowedByTraceBasedFiltering(context::RuntimeContext::GetCurrent(), logger_config_))
Comment thread
dbarker marked this conversation as resolved.
Outdated
{
return;
}

std::unique_ptr<Recordable> recordable =
std::unique_ptr<Recordable>(static_cast<Recordable *>(log_record.release()));
recordable->SetResource(context_->GetResource());
recordable->SetInstrumentationScope(GetInstrumentationScope());

auto &processor = context_->GetProcessor();

// TODO: Sampler (should include check for minSeverity)

// Send the log recordable to the processor
processor.OnEmit(std::move(recordable));
}
Expand Down
65 changes: 61 additions & 4 deletions sdk/test/logs/logger_sdk_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "opentelemetry/logs/noop.h"
#include "opentelemetry/logs/severity.h"
#include "opentelemetry/nostd/shared_ptr.h"
#include "opentelemetry/nostd/span.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/variant.h"
#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
Expand All @@ -44,13 +45,13 @@
#include "opentelemetry/trace/trace_id.h"
#include "opentelemetry/trace/tracer.h"

#include "opentelemetry/trace/default_span.h"

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
# include <stddef.h>

# include "opentelemetry/context/context.h"
# include "opentelemetry/nostd/span.h"
# include "opentelemetry/trace/context.h"
# include "opentelemetry/trace/default_span.h"
#endif

using namespace opentelemetry::sdk::logs;
Expand All @@ -61,7 +62,6 @@ namespace context = opentelemetry::context;
namespace logs_api = opentelemetry::logs;
namespace nostd = opentelemetry::nostd;

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
namespace
{
nostd::shared_ptr<opentelemetry::trace::Span> MakeTestSpan(bool sampled)
Expand All @@ -81,6 +81,7 @@ nostd::shared_ptr<opentelemetry::trace::Span> MakeTestSpan(bool sampled)
new opentelemetry::trace::DefaultSpan(span_context));
}

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
context::Context MakeContextWithUnsampledSpanAndInvalidTraceId()
{
const uint8_t span_id_bytes[opentelemetry::trace::SpanId::kSize] = {0xde, 0xad, 0xbe, 0xef,
Expand All @@ -95,8 +96,8 @@ context::Context MakeContextWithUnsampledSpanAndInvalidTraceId()
nostd::shared_ptr<opentelemetry::trace::Span>(
new opentelemetry::trace::DefaultSpan(span_context)));
}
} // namespace
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2
} // namespace

TEST(LoggerSDK, LogToNullProcessor)
{
Expand Down Expand Up @@ -273,6 +274,9 @@ class MockProcessor final : public LogRecordProcessor
};

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
namespace
{

struct EnabledProcessorCallState
{
logs_api::Severity severity = logs_api::Severity::kInvalid;
Expand Down Expand Up @@ -335,6 +339,8 @@ class EnablementAwareProcessor final : public LogRecordProcessor
bool enabled_;
std::shared_ptr<EnabledProcessorCallState> call_state_;
};

} // namespace
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2

TEST(LoggerSDK, LogToAProcessor)
Expand Down Expand Up @@ -480,6 +486,57 @@ TEST(LoggerSDK, LoggerWithEnabledConfig)
ASSERT_FALSE(shared_recordable->GetSpanId().IsValid());
}

TEST(LoggerSDK, EmitLogRecordDropsUnsampledTraceBased)
{
ScopeConfigurator<LoggerConfig> trace_based =
ScopeConfigurator<LoggerConfig>::Builder(
LoggerConfig::Create(true, logs_api::Severity::kInvalid, true))
.Build();
auto shared_recordable = std::shared_ptr<MockLogRecordable>(new MockLogRecordable());
auto log_processor = std::unique_ptr<LogRecordProcessor>(new MockProcessor(shared_recordable));

const auto resource = opentelemetry::sdk::resource::Resource::Create({});
const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"};
auto api_lp = std::shared_ptr<logs_api::LoggerProvider>(
new LoggerProvider(std::move(log_processor), resource,
std::make_unique<ScopeConfigurator<LoggerConfig>>(trace_based)));
auto logger = api_lp->GetLogger("trace-based-logger", "opentelemetry_library", "", schema_url);

auto unsampled_span = MakeTestSpan(false);
opentelemetry::trace::Scope scope{unsampled_span};

logger->EmitLogRecord(logs_api::Severity::kInfo, "dropped");

EXPECT_EQ(shared_recordable->GetSeverity(), opentelemetry::logs::Severity::kInvalid);
EXPECT_EQ(shared_recordable->GetBody(), "");
EXPECT_EQ(shared_recordable->GetObservedTimestamp(), std::chrono::system_clock::from_time_t(0));
}

TEST(LoggerSDK, EmitLogRecordEmitsSampledTraceBased)
{
ScopeConfigurator<LoggerConfig> trace_based =
ScopeConfigurator<LoggerConfig>::Builder(
LoggerConfig::Create(true, logs_api::Severity::kInvalid, true))
.Build();
auto shared_recordable = std::shared_ptr<MockLogRecordable>(new MockLogRecordable());
auto log_processor = std::unique_ptr<LogRecordProcessor>(new MockProcessor(shared_recordable));

const auto resource = opentelemetry::sdk::resource::Resource::Create({});
const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"};
auto api_lp = std::shared_ptr<logs_api::LoggerProvider>(
new LoggerProvider(std::move(log_processor), resource,
std::make_unique<ScopeConfigurator<LoggerConfig>>(trace_based)));
auto logger = api_lp->GetLogger("trace-based-logger", "opentelemetry_library", "", schema_url);

auto sampled_span = MakeTestSpan(true);
opentelemetry::trace::Scope scope{sampled_span};

logger->EmitLogRecord(logs_api::Severity::kInfo, "allowed");

EXPECT_EQ(shared_recordable->GetSeverity(), logs_api::Severity::kInfo);
EXPECT_EQ(shared_recordable->GetBody(), "allowed");
}

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
TEST(LoggerSDK, LoggerWithMinimumSeverityConfig)
{
Expand Down
Loading