open-telemetry / opentelemetry-java

OpenTelemetry Java SDK

Home Page:https://opentelemetry.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Make built-in spanProcessor extendable

doki23 opened this issue · comments

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
The implementations of SpanProcessor are final class, we cannot extend it.

Describe the solution you'd like
A clear and concise description of what you want to happen.
Make them extendable.

Can you explain what your use-case is, and why you need to extend, rather than just create a wrapper that delegates some functionality to the underlying SpanProcessor?

I want BatchSpanProcessor to skip executing forceFlush when shutdown. It's impossible to create a wrapper that delegates the shutdown because it's a private method of the inner class Worker.

Seems easy enough to have your delegate keep track of the shutdown state, and just use that to make forceFlush a no-op after shutdown has been called. Am I missing something?

Seems easy enough to have your delegate keep track of the shutdown state, and just use that to make forceFlush a no-op after shutdown has been called. Am I missing something?

Sorry, I can't get it. Would you please show me a code example?

Seems easy enough to have your delegate keep track of the shutdown state, and just use that to make forceFlush a no-op after shutdown has been called. Am I missing something?

Sorry, I can't get it. Would you please show me a code example?

public class DelegatingSpanProcessor implements SpanProcessor {
  private final SpanProcessor delegate;
  private final AtomicBoolean isShutdown = new AtomicBoolean();

  public DelegatingSpanProcessor(SpanProcessor delegate) {this.delegate = delegate;}

  @Override
  public CompletableResultCode shutdown() {
    CompletableResultCode shutdown = delegate.shutdown();
    isShutdown.set(true);
    return shutdown;
  }

  @Override
  public CompletableResultCode forceFlush() {
    if (isShutdown.get()) {
      return CompletableResultCode.ofSuccess();
    }
    return delegate.forceFlush();
  }

  @Override
  public void onStart(Context parentContext, ReadWriteSpan span) {
    delegate.onStart(parentContext, span);
  }

  @Override
  public boolean isStartRequired() {
    return delegate.isStartRequired();
  }

  @Override
  public void onEnd(ReadableSpan span) {
    delegate.onEnd(span);
  }

  @Override
  public boolean isEndRequired() {
    return delegate.isEndRequired();
  }

  @Override
  public void close() {
    delegate.close();
  }
}

delegate.shutdown() calls worker.shutdown(), and then the worker will flush itself. The forceFlush of BatchSpanProcessor itself doesn't make sense.
Let's see the implementation of the forceFlush of BatchSpanProcessor:

@Override
public CompletableResultCode shutdown() {
  if (isShutdown.getAndSet(true)) {
    return CompletableResultCode.ofSuccess();
  }
  return worker.shutdown(); // <=== I want to skip this flush
}

Why do you want to skip the controlled shutdown of the worker?

I don't want to flush spans when shutdown.

Making the BatchSpanProcessor extendable wouldn't solve your issue, then, since we will still need to shut down the worker thread, even if it doesn't flush its spans before doing so.

I recommend making a copy of the BatchSpanProcessor code and modifying it to your liking. If you need this as a first-class feature (skipping the flushing of the spans on shutdown), I recommend creating an issue in the specification for it, as this is required behavior from the BatchSpanProcessor. See here for the specific requirement.