Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
c7360f5
fix: apply filtering in emit log record
proost May 12, 2026
46c13c8
refactor: filter once
proost May 12, 2026
849c52f
Merge branch 'fix-apply-filtering-emitlogrecord' of https://github.co…
proost May 12, 2026
47d1e37
refactor: enabled filtering on the API level
proost May 13, 2026
a0958a4
feat: use context for EmitLogRecord
proost May 14, 2026
355ac95
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost May 14, 2026
98b3e9c
doc: update changelog
proost May 14, 2026
05b865b
style: follow doc lint
proost May 14, 2026
8063cb6
doc: follow doc lint
proost May 14, 2026
efa0202
Merge branch 'fix-apply-filtering-emitlogrecord' of https://github.co…
proost May 14, 2026
17de264
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
proost May 14, 2026
b9871a4
style: follow doc lint
proost May 14, 2026
5e67680
perf: cached enabled required
proost May 15, 2026
80051a4
Merge branch 'fix-apply-filtering-emitlogrecord' of github.com:proost…
proost May 15, 2026
ff7e302
Merge branch 'main' into fix-apply-filtering-emitlogrecord
ThomsonTan May 15, 2026
dc306d5
feat: has enabled filter
proost May 16, 2026
1a8111f
Merge branch 'fix-apply-filtering-emitlogrecord' of github.com:proost…
proost May 16, 2026
89c8209
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost May 17, 2026
d4578ad
feat: use temp context
proost May 17, 2026
d62c8e4
refactor: unify function
proost May 17, 2026
67713e3
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost May 19, 2026
e717aab
refactor: change default to false
proost May 19, 2026
8a18dc7
refactor: use span context and context
proost May 20, 2026
c1997fe
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost May 20, 2026
d719d99
style: follow lint
proost May 20, 2026
95855f6
Merge branch 'main' into fix-apply-filtering-emitlogrecord
marcalff May 22, 2026
a6146d4
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost May 23, 2026
0d97b25
Merge branch 'fix-apply-filtering-emitlogrecord' of github.com:proost…
proost May 23, 2026
fc0c4cc
doc: concise changelog
proost May 23, 2026
8bacb74
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
proost May 24, 2026
784f542
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost May 26, 2026
f62cfcf
Merge branch 'fix-apply-filtering-emitlogrecord' of github.com:proost…
proost May 26, 2026
c6d5684
perf: use current context once
proost May 27, 2026
7ca49f2
fix: avoiding hided methods
proost May 27, 2026
ce5d3e0
test: add SDK test for context EmitLogRecord
proost May 27, 2026
956f820
fix: gate v2 flag
proost May 29, 2026
290f94c
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost May 29, 2026
f5e8558
doc: remove unnecessary comments
proost May 29, 2026
e31ce65
Merge branch 'main' into fix-apply-filtering-emitlogrecord
dbarker May 31, 2026
304d5d8
Merge branch 'main' into fix-apply-filtering-emitlogrecord
dbarker Jun 1, 2026
e64255f
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost Jun 2, 2026
8cae295
perf: use hot-path more
proost Jun 2, 2026
d817422
Merge branch 'fix-apply-filtering-emitlogrecord' of github.com:proost…
proost Jun 2, 2026
6a0b930
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost Jun 3, 2026
e17fd8e
Merge branch 'main' into fix-apply-filtering-emitlogrecord
proost Jun 4, 2026
a3f2c79
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost Jun 5, 2026
63e44db
Merge branch 'main' into fix-apply-filtering-emitlogrecord
dbarker Jun 5, 2026
5081253
refactor: set lifetimebound
proost Jun 6, 2026
b293548
test: change to fixture
proost Jun 6, 2026
af777f4
doc: fix wrong docs
proost Jun 6, 2026
8536f75
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
proost Jun 6, 2026
a172a5d
Merge branch 'fix-apply-filtering-emitlogrecord' of github.com:proost…
proost Jun 6, 2026
5b48020
doc: follow lint
proost Jun 6, 2026
ed09632
Merge branch 'main' into fix-apply-filtering-emitlogrecord
proost Jun 7, 2026
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
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,31 @@ Increment the:
LoggerConfig declarative configuration
[#4131](https://github.com/open-telemetry/opentelemetry-cpp/pull/4131)

* [API] `Logger::EmitLogRecord(...)` templates now apply the `Enabled` filter
chain when a `Severity` is in args.
[#2667](https://github.com/open-telemetry/opentelemetry-cpp/issues/2667)

* [API/SDK] (ABI v2) Add `Logger::CreateLogRecord` virtual taking
`const nostd::variant<trace::SpanContext, context::Context> &`
for explicit-context record creation. `Logger::EmitLogRecord(args...)`
also detects a `Context`, `SpanContext`
or `TraceId` + `SpanId` [+ `TraceFlags`] in args and routes filtering.
[#2667](https://github.com/open-telemetry/opentelemetry-cpp/issues/2667)

* [SDK] Add `LogRecordProcessor::HasEnabledFilter()` so the SDK Logger can
include processor-level filtering in its extended-enabled cache. Defaults
to `true`. Built-in `SimpleLogRecordProcessor` and
`BatchLogRecordProcessor` override to `false` since they use the default
Enabled.
[#2667](https://github.com/open-telemetry/opentelemetry-cpp/issues/2667)

* [API/SDK] Replace `Context`-only signatures on
`LogRecordProcessor::Enabled`,
`LogRecordProcessor::EnabledImplementation`,
`Logger::EnabledImplementation` (v2), and `Logger::CreateLogRecord` (v2)
with `nostd::variant<trace::SpanContext, context::Context>`.
[#2667](https://github.com/open-telemetry/opentelemetry-cpp/issues/2667)

## [1.27.0] 2026-05-13

* [RELEASE] Bump main branch to 1.27.0-dev
Expand Down
152 changes: 139 additions & 13 deletions api/include/opentelemetry/logs/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/version.h"

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
# include "opentelemetry/context/runtime_context.h"
# include "opentelemetry/nostd/variant.h"
# include "opentelemetry/trace/span_context.h"
# include "opentelemetry/trace/trace_flags.h"
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2

OPENTELEMETRY_BEGIN_NAMESPACE
namespace common
{
Expand Down Expand Up @@ -50,6 +57,22 @@ class Logger
*/
virtual nostd::unique_ptr<LogRecord> CreateLogRecord() noexcept = 0;

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
/**
* Create a Log Record object using either a Context or a SpanContext.
*
* @param context_or_span Variant carrying either a full Context or just a
* SpanContext.
* @return nostd::unique_ptr<LogRecord>
*/
virtual nostd::unique_ptr<LogRecord> CreateLogRecord(
Comment thread
proost marked this conversation as resolved.
const nostd::variant<trace::SpanContext, opentelemetry::context::Context> &
/*context_or_span*/) noexcept
{
return CreateLogRecord();
}
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2

/**
* Emit a Log Record object
*
Expand All @@ -58,7 +81,15 @@ class Logger
virtual void EmitLogRecord(nostd::unique_ptr<LogRecord> &&log_record) noexcept = 0;

/**
* Emit a Log Record object with arguments
* Emit a Log Record object with arguments.
*
* @note This overload does NOT apply the @c Enabled filter chain. Callers who
* constructed @p log_record themselves are responsible for calling
* @c Enabled(severity, ...) before invoking this overload if they want
* the LoggerConfig filtering rules (minimum severity, trace-based,
* processor.Enabled) to be honored. The no-record overload
* @c EmitLogRecord(args...) below does call the filter chain
* automatically when @c Severity is present in @p args.
*
* @param log_record Log record
* @param args Arguments which can be used to set data of log record by type.
Expand Down Expand Up @@ -120,11 +151,72 @@ class Logger
* KeyValueIterable -> attributes
* Key value iterable container -> attributes
* span<pair<string_view, AttributeValue>> -> attributes(return type of MakeAttributes)
* Context (v2 only) -> filter + trace stamp (recommended: pass last)
*
* When a @c Context or trace parts (@c SpanContext, or @c TraceId +
* @c SpanId [+ @c TraceFlags]) are in args, the filter chain uses
* @c Enabled(context_or_span, severity, ...) and the record is created
* via @c CreateLogRecord(context_or_span), so the filter evaluates
* against the trace this record is for instead of the implicit runtime
* context.
*/
template <class... ArgumentType>
void EmitLogRecord(ArgumentType &&...args)
{
const Severity arg_severity = detail::FindSeverityInArgs(args...);
if (arg_severity != Severity::kInvalid && !Enabled(arg_severity))
{
return;
}

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
Comment thread
proost marked this conversation as resolved.
nostd::variant<trace::SpanContext, opentelemetry::context::Context> context_or_span =
trace::SpanContext::GetInvalid();

if (const opentelemetry::context::Context *ctx = detail::FindContextInArgs(args...))
{
context_or_span = *ctx;
}
else if (const trace::SpanContext *sc = detail::FindSpanContextInArgs(args...))
{
context_or_span = *sc;
}
else
{
const trace::TraceId *trace_id_ptr = detail::FindTraceIdInArgs(args...);
const trace::SpanId *span_id_ptr = detail::FindSpanIdInArgs(args...);
if (trace_id_ptr != nullptr && span_id_ptr != nullptr)
{
const trace::TraceFlags *trace_flags_ptr = detail::FindTraceFlagsInArgs(args...);
context_or_span = trace::SpanContext(
*trace_id_ptr, *span_id_ptr,
trace_flags_ptr != nullptr ? *trace_flags_ptr : trace::TraceFlags{}, false);
}
else
{
context_or_span = opentelemetry::context::RuntimeContext::GetCurrent();
}
}

if (arg_severity != Severity::kInvalid)
{
const EventId *event_id_ptr = detail::FindEventIdInArgs(args...);
if (ExtendedEnabledRequired())
{
const bool extended_enabled =
event_id_ptr ? EnabledImplementation(context_or_span, arg_severity, *event_id_ptr)
: EnabledImplementation(context_or_span, arg_severity);
if (!extended_enabled)
{
return;
}
}
}

nostd::unique_ptr<LogRecord> log_record = CreateLogRecord(context_or_span);
#else
nostd::unique_ptr<LogRecord> log_record = CreateLogRecord();
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2

EmitLogRecord(std::move(log_record), std::forward<ArgumentType>(args)...);
}
Expand Down Expand Up @@ -278,25 +370,27 @@ class Logger
//

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
inline bool Enabled(const opentelemetry::context::Context &context,
Severity severity = Severity::kInvalid) const noexcept
inline bool Enabled(
const nostd::variant<trace::SpanContext, opentelemetry::context::Context> &context_or_span,
Severity severity = Severity::kInvalid) const noexcept
{
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity))
{
return false;
}
return EnabledImplementation(context, severity);
return EnabledImplementation(context_or_span, severity);
}

inline bool Enabled(const opentelemetry::context::Context &context,
Severity severity,
const EventId &event_id) const noexcept
inline bool Enabled(
const nostd::variant<trace::SpanContext, opentelemetry::context::Context> &context_or_span,
Severity severity,
const EventId &event_id) const noexcept
{
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity))
{
return false;
}
return EnabledImplementation(context, severity, event_id);
return EnabledImplementation(context_or_span, severity, event_id);
}
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2

Expand All @@ -323,6 +417,13 @@ class Logger
return static_cast<uint8_t>(severity) >= OPENTELEMETRY_ATOMIC_READ_8(&minimum_severity_);
}

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
inline bool ExtendedEnabledRequired() const noexcept
{
return OPENTELEMETRY_ATOMIC_READ_8(&extended_enabled_required_) != 0;
}
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2

/**
* Log an event
*
Expand Down Expand Up @@ -505,15 +606,19 @@ class Logger
}

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
virtual bool EnabledImplementation(const opentelemetry::context::Context & /*context*/,
Severity /*severity*/) const noexcept
virtual bool EnabledImplementation(
const nostd::variant<trace::SpanContext, opentelemetry::context::Context> &
/*context_or_span*/,
Severity /*severity*/) const noexcept
{
return false;
}

virtual bool EnabledImplementation(const opentelemetry::context::Context & /*context*/,
Severity /*severity*/,
const EventId & /*event_id*/) const noexcept
virtual bool EnabledImplementation(
const nostd::variant<trace::SpanContext, opentelemetry::context::Context> &
/*context_or_span*/,
Severity /*severity*/,
const EventId & /*event_id*/) const noexcept
{
return false;
}
Expand All @@ -524,6 +629,14 @@ class Logger
OPENTELEMETRY_ATOMIC_WRITE_8(&minimum_severity_, severity_or_max);
}

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
void SetExtendedEnabledRequired(bool required) noexcept
{
OPENTELEMETRY_ATOMIC_WRITE_8(&extended_enabled_required_,
static_cast<uint8_t>(required ? 1 : 0));
}
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2

private:
template <class... ValueType>
void IgnoreTraitResult(ValueType &&...)
Expand All @@ -535,6 +648,19 @@ class Logger
// compatible for OpenTelemetry C++ API.
//
mutable uint8_t minimum_severity_{kMaxSeverity};

#if OPENTELEMETRY_ABI_VERSION_NO >= 2
//
// Controls whether the EmitLogRecord(args...) template calls the
// EnabledImplementation virtual in addition to the cheap atomic
// minimum_severity_ check. When 0, the template trusts the atomic check
// as the complete enabled decision and skips the virtual dispatch. When
// 1, the template also consults EnabledImplementation, which lets a
// Logger subclass apply richer filtering (trace-based, processor-level
// Enabled, custom predicates).
//
mutable uint8_t extended_enabled_required_{0};
Comment thread
dbarker marked this conversation as resolved.
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2
};
} // namespace logs
OPENTELEMETRY_END_NAMESPACE
Loading
Loading