Repository: open-telemetry/opentelemetry-java
File: sdk/logs/src/main/java/io/opentelemetry/sdk/logs/ExtendedSdkLogRecordBuilder.java (Java)

Code before:
final class ExtendedSdkLogRecordBuilder extends SdkLogRecordBuilder
    implements ExtendedLogRecordBuilder {

  @Nullable private ExtendedAttributesMap extendedAttributes;

  ExtendedSdkLogRecordBuilder(
      LoggerSharedState loggerSharedState, InstrumentationScopeInfo instrumentationScopeInfo) {
    super(loggerSharedState, instrumentationScopeInfo);
  }

  @Override
  public ExtendedSdkLogRecordBuilder setEventName(String eventName) {
    super.setEventName(eventName);
    return this;
  }

  @Override
  public ExtendedSdkLogRecordBuilder setException(Throwable throwable) {
    if (throwable == null) {
      return this;
    }

    loggerSharedState
        .getExceptionAttributeResolver()
        .setExceptionAttributes(
            new ExceptionAttributeSetterWithPrecedence(),
            throwable,
            loggerSharedState.getLogLimits().getMaxAttributeValueLength());

    return this;
  }

  @Override
  public ExtendedSdkLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
    super.setTimestamp(timestamp, unit);
    return this;
  }

  @Override
  public ExtendedSdkLogRecordBuilder setTimestamp(Instant instant) {
    super.setTimestamp(instant);
    return this;
  }

  @Override
  public ExtendedSdkLogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit) {
    super.setObservedTimestamp(timestamp, unit);
    return this;
  }

  @Override

Review comment (suggestion):
Could add a private method `setExceptionAttribute` (or similar) with the same signature as `setAttribute`. This would avoid allocating the extra `ExceptionAttributeSetterWithPrecedence` object. Not that its hugely important because we're in the `setException` code path which is allocation-heavy.

Code after:
    implements ExtendedLogRecordBuilder {

  @Nullable private ExtendedAttributesMap extendedAttributes;

  ExtendedSdkLogRecordBuilder(
      LoggerSharedState loggerSharedState, InstrumentationScopeInfo instrumentationScopeInfo) {
    super(loggerSharedState, instrumentationScopeInfo);
  }

  @Override
  public ExtendedSdkLogRecordBuilder setEventName(String eventName) {
    super.setEventName(eventName);
    return this;
  }

  @Override
  public ExtendedSdkLogRecordBuilder setException(Throwable throwable) {
    if (throwable == null) {
      return this;
    }

    loggerSharedState
        .getExceptionAttributeResolver()
        .setExceptionAttributes(
            this::setExceptionAttribute,
            throwable,
            loggerSharedState.getLogLimits().getMaxAttributeValueLength());

    return this;
  }

  @Override
  public ExtendedSdkLogRecordBuilder setTimestamp(long timestamp, TimeUnit unit) {
    super.setTimestamp(timestamp, unit);
    return this;
  }

  @Override
  public ExtendedSdkLogRecordBuilder setTimestamp(Instant instant) {
    super.setTimestamp(instant);
    return this;
  }

  @Override
  public ExtendedSdkLogRecordBuilder setObservedTimestamp(long timestamp, TimeUnit unit) {
    super.setObservedTimestamp(timestamp, unit);
    return this;
  }

  @Override
  public ExtendedSdkLogRecordBuilder setObservedTimestamp(Instant instant) {