Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log Records passed to log processor OnEmit is non-mutable #5219

Open
MrAlias opened this issue Apr 16, 2024 · 10 comments
Open

Log Records passed to log processor OnEmit is non-mutable #5219

MrAlias opened this issue Apr 16, 2024 · 10 comments
Assignees
Labels
area:logs Part of OpenTelemetry logs blocked:specification Waiting on clarification of the OpenTelemetry specification before progress can be made bug Something isn't working pkg:SDK Related to an SDK package

Comments

@MrAlias
Copy link
Contributor

MrAlias commented Apr 16, 2024

Blocked by:

Description

The specification requires that log processors be provided a LogRecordProcessor:

OnEmit

[...]

Parameters:

Our current implementation Defines the Processor interface as such:

type Processor interface {
	// OnEmit is called when a Record is emitted.
	//
	// OnEmit will be called independent of Enabled. Implementations need to
	// validate the arguments themselves before processing.
	//
	// Implementation should not interrupt the record processing
	// if the context is canceled.
	//
	// All retry logic must be contained in this function. The SDK does not
	// implement any retry logic. All errors returned by this function are
	// considered unrecoverable and will be reported to a configured error
	// Handler.
	//
	// Before modifying a Record, the implementation must use Record.Clone
	// to create a copy that shares no state with the original.
	OnEmit(ctx context.Context, record Record) error
/* ... */
}

Any modification made to the record passed to a processor's OnEmit method will not be applied to the subsequent processor. The record is not mutable, it does not comply with the specification requirement.

@MrAlias MrAlias added bug Something isn't working pkg:SDK Related to an SDK package area:logs Part of OpenTelemetry logs labels Apr 16, 2024
@MrAlias MrAlias changed the title Log Records passed to log processors' OnEmit need to mutable Log Records passed to log processor OnEmit is non-mutable Apr 16, 2024
@MrAlias
Copy link
Contributor Author

MrAlias commented Apr 16, 2024

One solution is to have OnEmit accept a reference:

OnEmit(ctx context.Context, record *Record) error

This will mean that every record will need to be allocated to the heap.

@MrAlias
Copy link
Contributor Author

MrAlias commented Apr 16, 2024

Another solution is to have OnEmit return a Record

OnEmit(ctx context.Context, record Record) (Record, error)

The returned Record can be the same record passed, or a mutated clone of the Record. That returned value will be passed to the next processor in the SDK's processing chain.

@pellared
Copy link
Member

I could work on this but it would be nice to have #5093 merged first to reduce the amount of conflicts.

@MrAlias
Copy link
Contributor Author

MrAlias commented Apr 18, 2024

I could work on this but it would be nice to have #5093 merged first to reduce the amount of conflicts.

Merged

@pellared
Copy link
Member

pellared commented Apr 23, 2024

I remember what was my idea.

It was to use Processor as decorators in order to make modifications. A processor can modify the received record before passing to the next processor:

type mutatingProcessor struct {
  wrapped log.Processor
}

func (mutatingProcessor p) OnEmit(ctx context.Context, record Record) error {
  r.SetBody(log.StringValue("REDACTED"))
  return p.wrapped.OnEmit(ctx, r.Clone())
}

Thanks to it you can have even two "processor" pipelines which do not interfere with each other. So you can have one processor pipeline which e.g. has a processor redacts secrets and wraps a simple processor with stdout exporter and then a second pipeline which uses a batch processor (no redacting) with OTLP exporter:

log.NewLoggerProvider(
  log.WithProcessor(mutatingProcessor{ log.NewSimpleProcessor(stdoutExp) }), // stdout exporter with simple processor, the log records' body are redacted
  log.WithProcessor(log.NewBatchProcessor(otlpExp)), // otlp exporter with a batch processor
)

@MrAlias, can we close this issue? I do not see how this implementation would break the specification and I think it is a safer and more usable design.

@pellared pellared added the question Further information is requested label Apr 23, 2024
@MrAlias
Copy link
Contributor Author

MrAlias commented Apr 23, 2024

No, I don't think we can close the issue. We are not compatible with the specification. The specification states the log records are mutable and that processors are executed in order. The processors after a mutation should receive the mutated record.

@pellared
Copy link
Member

The processors after a mutation should receive the mutated record.

Where is it defined?

What do you think about updating the specification?

@MrAlias
Copy link
Contributor Author

MrAlias commented Apr 23, 2024

Where is it defined?

In the definition of a read/write record.

@pellared
Copy link
Member

pellared commented Apr 23, 2024

I think it is "in spirit" of the specification. I would rather ask the Specification SIG if it is an acceptable design and clarify the specification.

@pellared
Copy link
Member

I created open-telemetry/opentelemetry-specification#4010

@pellared pellared added blocked:specification Waiting on clarification of the OpenTelemetry specification before progress can be made and removed question Further information is requested labels Apr 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:logs Part of OpenTelemetry logs blocked:specification Waiting on clarification of the OpenTelemetry specification before progress can be made bug Something isn't working pkg:SDK Related to an SDK package
Projects
Status: Blocked
Development

No branches or pull requests

2 participants