Repository: open-telemetry/opentelemetry-java
File: exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/InternalTelemetryConfiguration.java (Java)

Code before:
/*
 * Copyright The OpenTelemetry Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package io.opentelemetry.exporter.otlp.internal;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.common.InternalTelemetryVersion;
import java.util.Locale;
import javax.annotation.Nullable;

/**
 * Reads the desired SDK internal telemetry version from {@link ConfigProperties}.
 *
 * <p>This is the same as {@code io.opentelemetry.sdk.autoconfigure.InternalTelemetryConfiguration}.
 * Any changes should be reflected there as well.
 */
final class InternalTelemetryConfiguration {

  @Nullable
  static InternalTelemetryVersion getVersion(ConfigProperties config) {
    String version = config.getString("otel.experimental.sdk.telemetry.version");
    if (version == null) {
      return null;
    }
    switch (version.toLowerCase(Locale.ROOT)) {
      case "legacy":
        return InternalTelemetryVersion.LEGACY;
      case "latest":
        return InternalTelemetryVersion.LATEST;
      default:
        throw new ConfigurationException("Invalid sdk telemetry version: " + version);
    }
  }

  private InternalTelemetryConfiguration() {}
}


Review comment (performance):
Hey I was thinking about internal telemetry and defaults more. Right now, we have SDK components which have different versions of internal telemetry according to their programmatic config API. For example, `SdkTracerProvider` / `SdkLoggerProvider` / `SimpleSpanProcessor` / `SimpleLogRecordProcessor` did not emit any telemetry prior to the new semantic conventions, and so they default to the latest. `BatchSpanProcessor`, `BatchLogRecordProcessor`, `Otlp{Signal}{Protocol}Exporter` all emit legacy by default.

That means that if `otel.experimental.sdk.telemetry.version` is omitted, or if `otel.experimental.sdk.telemetry.version=legacy`, the SDK ends up emitting split brain telemetry. 

I think we need to address that here in and in #8045. My proposal:

- Both system prop / env var config and declarative config should take measures to prevent ever emitting split brain internal telemetry
- System prop / env var config defaults to legacy if `otel.experimental.sdk.telemetry.version` is unspecified.
- Declarative config defaults to no internal telemetry if `.instrumentation/development.java.otel_sdk.internal_telemetry_version` is unspecified
- Once the semconv for internal telemetry is stable, declarative config updates the default to the stable version
- If the internal telemetry version resolves to legacy, internal telemetry is only emitted from components that emit legacy. I.e. internal telemetry is disabled for `BatchSpanProcessor`, `BatchLogRecordProcessor`, `Otlp{Signal}{Protocol}Exporter`.


Code after:
/*
 * Copyright The OpenTelemetry Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package io.opentelemetry.exporter.otlp.internal;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.common.InternalTelemetryVersion;
import java.util.Locale;

/**
 * Reads the desired SDK internal telemetry version from {@link ConfigProperties}.
 *
 * <p>This is the same as {@code io.opentelemetry.sdk.autoconfigure.InternalTelemetryConfiguration}.
 * Any changes should be reflected there as well.
 */
final class InternalTelemetryConfiguration {

  static InternalTelemetryVersion getVersion(ConfigProperties config) {
    String version = config.getString("otel.experimental.sdk.telemetry.version");
    if (version == null) {
      return InternalTelemetryVersion.LEGACY;
    }

    switch (version.toLowerCase(Locale.ROOT)) {
      case "legacy":
        return InternalTelemetryVersion.LEGACY;
      case "latest":
        return InternalTelemetryVersion.LATEST;
      default:
        throw new ConfigurationException("Invalid sdk telemetry version: " + version);
    }
  }

  private InternalTelemetryConfiguration() {}
}