Skip to content

Fix SeverityProcessor example#4541

Closed
pellared wants to merge 3 commits intoopen-telemetry:mainfrom
pellared:fix-SeverityProcessor
Closed

Fix SeverityProcessor example#4541
pellared wants to merge 3 commits intoopen-telemetry:mainfrom
pellared:fix-SeverityProcessor

Conversation

@pellared
Copy link
Member

@pellared pellared commented Jun 4, 2025

Why

#### Comparing Severity
In the contexts where severity participates in less-than / greater-than
comparisons `SeverityNumber` field should be used. `SeverityNumber` can be
compared to another `SeverityNumber` or to numbers in the 1..24 range (or to the
corresponding short names).

Currently the spec only describes how to compare values between 1 and 24.
All other values have undefined meaning.
People are free to do with them whatever they seem appropriate but at this point of time the spec shouldn't give any recommendations for them for the sake of future compatibility.

What

Fix the SeverityProcessor example implementation so that it filters out only the records with SeverityNumber in the 1..24 range.

Extracted from #4535

Prototype

I do not think it is needed but maybe it would help the reviewers:

@pellared pellared marked this pull request as ready for review June 4, 2025 06:29
@pellared pellared requested review from a team June 4, 2025 06:29
@pellared pellared added the spec:logs Related to the specification/logs directory label Jun 4, 2025
@pellared pellared self-assigned this Jun 4, 2025
@pellared pellared added this to Logs SIG Jun 4, 2025
@pellared pellared moved this to In progress in Logs SIG Jun 4, 2025
func (p *SeverityProcessor) OnEmit(ctx context.Context, record *sdklog.Record) error {
if record.Severity() != log.SeverityUndefined && record.Severity() < p.Min {
sev := record.Severity()
if sev >= log.SeverityTrace1 && sev <= log.SeverityFatal4 && sev < p.Min {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking, might be too go-specific: Should severity have an IsValid() or IsComparable() helper? Reminds me of handling zero values for trace context.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I push for severity being treated as a number. It's always valid and always comparable, but you probably don't want to use <=0 values unless you're building something custom.

Copy link
Member Author

@pellared pellared Jun 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dashpole, I think that currently nothing in the spec says that values outside the 1..24 range are invalid. However, it might have be indeed the intention of the authors.
See #4509 (comment)

I also do not want to make this PR too controversial.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that based on today's SIG discussion this could even be

Suggested change
if sev >= log.SeverityTrace1 && sev <= log.SeverityFatal4 && sev < p.Min {
if sev < p.Min {

Copy link
Member

@lmolkova lmolkova Jun 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be in favor of treating 0 as yet another severity when it comes to filtering and comparison, i.e. logs with unspecified/0 severity are dropped when threshold > 0 and are recorded otherwise.

Reasoning:
Producers that don't set severity don't work nicely with threshold-based log filtering. Assuming one of the producers sends spammy logs, they would go through app log filter and may significantly increase telemetry volume and costs.

However, It doesn't seem like there is a consensus around it.


Maybe we can take discussion around 0 separately and/or make it configurable.
We should have cross-language default for log filtering unspecified/0 severity, but if it's controversial, let's separate it from this PR and focus on integer range.

The example, however, should be adjusted to force anyone copy-pasting it to think how they want to handle unspecified/0 value. I believe it's what @jack-berg suggested earlier as custom treatment for nulls.

@trask suggested something like:

Suggested change
if sev >= log.SeverityTrace1 && sev <= log.SeverityFatal4 && sev < p.Min {
if (sev == 0 && dropLogsWithUnspecifiedSeverity()) || sev < p.Min {
// drop

This would at least make someone copy-pasting the example to think how they want to handle 0.

(PS: I spent a minute to triple-check this expression and I'm pretty sure you, my reader, did it too, that's exactly the reason why sev < p.Min is easier for everyone)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this non-normative example, I think I like the simplicity of

if sev < p.Min {
// drop
}

it provides a very reasonable default behavior, which is to drop logs that don't have any severity, and people can always build more complex logic to factor those logs in as needed

@pellared pellared requested a review from dashpole June 9, 2025 10:43
Copy link
Member Author

@pellared pellared left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on today's SIG discussion it looks like we want to "fix" the specification so that SeverityNumber can always be compared (not limited to only 1..24 values)

func (p *SeverityProcessor) Enabled(ctx context.Context, param sdklog.EnabledParameters) bool {
sev := param.Severity
if sev != log.SeverityUndefined && sev < p.Min {
if sev >= log.SeverityTrace1 && sev <= log.SeverityFatal4 && sev < p.Min {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that based on today's SIG discussion this could even be

Suggested change
if sev >= log.SeverityTrace1 && sev <= log.SeverityFatal4 && sev < p.Min {
if sev < p.Min {

func (p *SeverityProcessor) OnEmit(ctx context.Context, record *sdklog.Record) error {
if record.Severity() != log.SeverityUndefined && record.Severity() < p.Min {
sev := record.Severity()
if sev >= log.SeverityTrace1 && sev <= log.SeverityFatal4 && sev < p.Min {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that based on today's SIG discussion this could even be

Suggested change
if sev >= log.SeverityTrace1 && sev <= log.SeverityFatal4 && sev < p.Min {
if sev < p.Min {

@pellared pellared requested a review from lmolkova June 10, 2025 15:38
@pellared pellared marked this pull request as draft June 10, 2025 17:02
@pellared
Copy link
Member Author

Closing per #4552

@pellared pellared closed this Jun 12, 2025
@github-project-automation github-project-automation bot moved this from In progress to Done in Logs SIG Jun 12, 2025
github-merge-queue bot pushed a commit that referenced this pull request Jul 21, 2025
Follows:
-
#4535

## Why

Related to
#4540

Supersedes
#4541
per
#4541 (comment)
and discussions from the last OTel Specification and Logs SIG meetings.

**Some comments that were already expressed as comments.**

From
#4541 (comment):

> I'd be in favor of treating `0` as yet another severity when it comes
to filtering and comparison, i.e. logs with unspecified/0 severity are
dropped when `threshold > 0` and are recorded otherwise.

From
#4541 (comment):

> I think I like the simplicity of
> 
> > if sev < p.Min {
> >   // drop
> > }
> 
> it provides a very reasonable default behavior, which is to drop logs
that don't have any severity

This is also inline with 


https://github.com/open-telemetry/opentelemetry-specification/blob/7e7c0bd12a535b332284ecabd228c4749886455f/specification/logs/data-model.md?plain=1#L323-L329

From
#4540 (comment):

> Relying on int comparison seems to be the most natural option 

We agreed that this PR does conflict proposal to allow only
allow/support 0..24 SeverityNumber values.

## What

Removal of

> `SeverityNumber` can be compared to another `SeverityNumber` or to
numbers in the 1..24 range (or to the corresponding short names).

as I find that this sentence is more confusing than clarifying:
1. why comparing values of different types?
2. why can we compare only with integers between 1..24?
3. what about `SeverityNumber` that are greater than 24 or lesser than
1?
4. are the short names normative?

Removal of duplicated description

> Smaller numerical values in each range represent less important (less
severe) events. Larger numerical values in each range represent more
important (more severe) events.

Moving the comparison example to a better place where the
`SeverityNumber` comparison is described

> For example `SeverityNumber=17` describes an error that is less
critical than an error with `SeverityNumber=20`.

Simplify `SeverityProcessor` example.

## Prototype

This is exactly how
https://pkg.go.dev/go.opentelemetry.io/contrib/processors/minsev
currently works.

---------

Co-authored-by: Reiley Yang <reyang@microsoft.com>
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

spec:logs Related to the specification/logs directory

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants