All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.opentelemetry.maven.OpenTelemetrySdkService Maven / Gradle / Ivy

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

package io.opentelemetry.maven;

import com.google.common.annotations.VisibleForTesting;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.maven.semconv.MavenOtelSemanticAttributes;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.resources.Resource;
import java.io.Closeable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
import javax.inject.Named;
import javax.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Service to configure the {@link OpenTelemetry} instance. */
@Named
@Singleton
public final class OpenTelemetrySdkService implements Closeable {

  static final String VERSION =
      OpenTelemetrySdkService.class.getPackage().getImplementationVersion();

  private static final Logger logger = LoggerFactory.getLogger(OpenTelemetrySdkService.class);

  private final OpenTelemetrySdk openTelemetrySdk;

  @VisibleForTesting final Resource resource;

  private final ConfigProperties configProperties;

  private final Tracer tracer;

  private final boolean mojosInstrumentationEnabled;

  private boolean disposed;

  public OpenTelemetrySdkService() {
    logger.debug(
        "OpenTelemetry: Initialize OpenTelemetrySdkService v{}...",
        MavenOtelSemanticAttributes.TELEMETRY_DISTRO_VERSION_VALUE);

    AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk =
        AutoConfiguredOpenTelemetrySdk.builder()
            .setServiceClassLoader(getClass().getClassLoader())
            .addPropertiesCustomizer(
                OpenTelemetrySdkService::requireExplicitConfigOfTheOtlpExporter)
            .disableShutdownHook()
            .build();

    this.openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk();
    this.configProperties =
        Optional.ofNullable(AutoConfigureUtil.getConfig(autoConfiguredOpenTelemetrySdk))
            .orElseGet(() -> DefaultConfigProperties.createFromMap(Collections.emptyMap()));

    this.resource = AutoConfigureUtil2.getResource(autoConfiguredOpenTelemetrySdk);
    // Display resource attributes in debug logs for troubleshooting when traces are not found in
    // the observability backend, helping understand `service.name`, `service.namespace`, etc.
    logger.debug("OpenTelemetry: OpenTelemetrySdkService initialized, resource:{}", resource);

    this.mojosInstrumentationEnabled =
        configProperties.getBoolean("otel.instrumentation.maven.mojo.enabled", true);

    this.tracer = openTelemetrySdk.getTracer("io.opentelemetry.contrib.maven", VERSION);
  }

  /**
   * The OTel SDK by default sends data to the OTLP gRPC endpoint localhost:4317 if no exporter and
   * no OTLP exporter endpoint are defined. This is not suited for a build tool for which we want
   * the OTel SDK to be disabled by default.
   *
   * 

Change the OTel SDL behavior: if none of the exporter and the OTLP exporter endpoint are * defined, explicitly disable the exporter setting "{@code * otel.[traces,metrics,logs].exporter=none}" * * @return The properties to be returned by {@link * io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder#addPropertiesCustomizer(java.util.function.Function)} */ static Map requireExplicitConfigOfTheOtlpExporter( ConfigProperties configProperties) { Map properties = new HashMap<>(); if (configProperties.getString("otel.exporter.otlp.endpoint") != null) { logger.debug("OpenTelemetry: OTLP exporter endpoint is explicitly configured"); return properties; } String[] signalTypes = {"traces", "metrics", "logs"}; for (String signalType : signalTypes) { boolean isExporterImplicitlyConfiguredToOtlp = configProperties.getString("otel." + signalType + ".exporter") == null; boolean isOtlpExporterEndpointSpecified = configProperties.getString("otel.exporter.otlp." + signalType + ".endpoint") != null; if (isExporterImplicitlyConfiguredToOtlp && !isOtlpExporterEndpointSpecified) { logger.debug( "OpenTelemetry: Disabling default OTLP exporter endpoint for signal {} exporter", signalType); properties.put("otel." + signalType + ".exporter", "none"); } } return properties; } @PreDestroy @Override public synchronized void close() { if (disposed) { logger.debug("OpenTelemetry: OpenTelemetry SDK already shut down, ignore"); } else { logger.debug("OpenTelemetry: Shutdown OpenTelemetry SDK..."); CompletableResultCode openTelemetrySdkShutdownResult = this.openTelemetrySdk.shutdown().join(10, TimeUnit.SECONDS); if (openTelemetrySdkShutdownResult.isSuccess()) { logger.debug("OpenTelemetry: OpenTelemetry SDK successfully shut down"); } else { logger.warn( "OpenTelemetry: Failure to shutdown OpenTelemetry SDK (done: {})", openTelemetrySdkShutdownResult.isDone()); } this.disposed = true; } } public Tracer getTracer() { return this.tracer; } public ConfigProperties getConfigProperties() { return configProperties; } /** Returns the {@link ContextPropagators} for this {@link OpenTelemetry}. */ public ContextPropagators getPropagators() { return this.openTelemetrySdk.getPropagators(); } public boolean isMojosInstrumentationEnabled() { return mojosInstrumentationEnabled; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy