-
Notifications
You must be signed in to change notification settings - Fork 831
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.sdk.autoconfigure.internal; | ||
|
||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; | ||
import io.opentelemetry.sdk.autoconfigure.spi.Ordered; | ||
import java.util.ArrayList; | ||
import java.util.Comparator; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.ServiceLoader; | ||
import java.util.function.BiFunction; | ||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
|
||
/** | ||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at | ||
* any time. | ||
*/ | ||
public final class ServiceLoaderHelper { | ||
|
||
private final ClassLoader classLoader; | ||
private final ServiceLoaderFinder serviceLoaderFinder; | ||
|
||
// Visible for testing | ||
ServiceLoaderHelper(ClassLoader classLoader, ServiceLoaderFinder serviceLoaderFinder) { | ||
this.classLoader = classLoader; | ||
this.serviceLoaderFinder = serviceLoaderFinder; | ||
} | ||
Check warning on line 33 in sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java Codecov / codecov/patchsdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java#L30-L33
|
||
|
||
/** Create a {@link ServiceLoaderHelper} which loads SPIs using the {@code classLoader}. */ | ||
public static ServiceLoaderHelper create(ClassLoader classLoader) { | ||
return new ServiceLoaderHelper(classLoader, ServiceLoader::load); | ||
Check warning on line 37 in sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java Codecov / codecov/patchsdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java#L37
|
||
} | ||
|
||
/** | ||
* Load implementations of an SPI which are configurable (i.e. they accept {@link | ||
* ConfigProperties}. | ||
* | ||
* @param spiClass the SPI class | ||
* @param getName function returning the name of an SPI implementation | ||
* @param getConfigurable function returning a configured instance | ||
* @param config the configuration to pass to invocations of {@code #getConfigurable} | ||
* @param <T> the configurable type | ||
* @param <S> the SPI type | ||
* @return a {@link NamedSpiManager} used to access configured instances of the SPI by name | ||
*/ | ||
public <T, S> NamedSpiManager<T> loadConfigurable( | ||
Class<S> spiClass, | ||
Function<S, String> getName, | ||
BiFunction<S, ConfigProperties, T> getConfigurable, | ||
ConfigProperties config) { | ||
Map<String, Supplier<T>> nameToProvider = new HashMap<>(); | ||
Check warning on line 57 in sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java Codecov / codecov/patchsdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java#L57
|
||
for (S provider : load(spiClass)) { | ||
String name = getName.apply(provider); | ||
nameToProvider.put(name, () -> getConfigurable.apply(provider, config)); | ||
} | ||
return NamedSpiManager.create(nameToProvider); | ||
Check warning on line 62 in sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java Codecov / codecov/patchsdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java#L59-L62
|
||
} | ||
|
||
/** | ||
* Load implementations of an ordered SPI (i.e. implements {@link Ordered}). | ||
* | ||
* @param spiClass the SPI class | ||
* @param <T> the SPI type | ||
* @return list of SPI implementations, in order | ||
*/ | ||
public <T extends Ordered> List<T> loadOrdered(Class<T> spiClass) { | ||
List<T> result = load(spiClass); | ||
result.sort(Comparator.comparing(Ordered::order)); | ||
return result; | ||
Check warning on line 75 in sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java Codecov / codecov/patchsdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java#L73-L75
|
||
} | ||
|
||
/** | ||
* Load implementations of an SPI. | ||
* | ||
* @param spiClass the SPI class | ||
* @param <T> the SPI type | ||
* @return list of SPI implementations | ||
*/ | ||
public <T> List<T> load(Class<T> spiClass) { | ||
List<T> result = new ArrayList<>(); | ||
Check warning on line 86 in sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java Codecov / codecov/patchsdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java#L86
|
||
for (T service : serviceLoaderFinder.load(spiClass, classLoader)) { | ||
result.add(service); | ||
} | ||
return result; | ||
Check warning on line 90 in sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java Codecov / codecov/patchsdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ServiceLoaderHelper.java#L88-L90
|
||
} | ||
|
||
// Visible for testing | ||
interface ServiceLoaderFinder { | ||
<T> Iterable<T> load(Class<T> spiClass, ClassLoader classLoader); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.sdk.extension.incubator.fileconfig; | ||
|
||
import io.opentelemetry.sdk.OpenTelemetrySdk; | ||
import io.opentelemetry.sdk.autoconfigure.internal.ServiceLoaderHelper; | ||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; | ||
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfiguration; | ||
import java.io.Closeable; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.logging.Logger; | ||
|
||
/** | ||
* Parses YAML configuration files conforming to the schema in <a | ||
* href="https://github.com/open-telemetry/opentelemetry-configuration">open-telemetry/opentelemetry-configuration</a> | ||
* to a {@link OpenTelemetryConfiguration} in-memory representation. Interprets the in-memory | ||
* representation to produce an {@link OpenTelemetrySdk}. | ||
* | ||
* @see #parseAndInterpret(InputStream) | ||
*/ | ||
public final class ConfigurationFactory { | ||
|
||
private static final Logger logger = Logger.getLogger(ConfigurationFactory.class.getName()); | ||
|
||
private ConfigurationFactory() {} | ||
|
||
/** | ||
* Parse the {@code inputStream} YAML to {@link OpenTelemetryConfiguration} and interpret the | ||
* model to create {@link OpenTelemetrySdk} instance corresponding to the configuration. | ||
* | ||
* @param inputStream the configuration YAML | ||
* @return the {@link OpenTelemetrySdk} | ||
*/ | ||
public static OpenTelemetrySdk parseAndInterpret(InputStream inputStream) { | ||
OpenTelemetryConfiguration model; | ||
try { | ||
model = ConfigurationReader.parse(inputStream); | ||
} catch (RuntimeException e) { | ||
throw new ConfigurationException("Unable to parse inputStream", e); | ||
} | ||
|
||
List<Closeable> closeables = new ArrayList<>(); | ||
try { | ||
return OpenTelemetryConfigurationFactory.getInstance() | ||
.create( | ||
model, | ||
ServiceLoaderHelper.create(ConfigurationFactory.class.getClassLoader()), | ||
closeables); | ||
} catch (RuntimeException e) { | ||
logger.info( | ||
"Error encountered interpreting configuration. Closing partially configured components."); | ||
for (Closeable closeable : closeables) { | ||
try { | ||
logger.fine("Closing " + closeable.getClass().getName()); | ||
closeable.close(); | ||
} catch (IOException ex) { | ||
logger.warning( | ||
"Error closing " + closeable.getClass().getName() + ": " + ex.getMessage()); | ||
} | ||
} | ||
if (e instanceof ConfigurationException) { | ||
throw e; | ||
} | ||
throw new ConfigurationException("Unexpected configuration error", e); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.sdk.extension.incubator.fileconfig; | ||
|
||
import io.opentelemetry.sdk.autoconfigure.internal.ServiceLoaderHelper; | ||
import java.io.Closeable; | ||
import java.util.List; | ||
import javax.annotation.Nullable; | ||
|
||
interface Factory<ModelT, ResultT> { | ||
|
||
/** | ||
* Interpret the model and create {@link ResultT} with corresponding configuration. | ||
* | ||
* @param model the configuration model | ||
* @param serviceLoaderHelper the service loader helper | ||
* @param closeables mutable list of closeables created | ||
* @return the {@link ResultT} | ||
*/ | ||
ResultT create( | ||
@Nullable ModelT model, ServiceLoaderHelper serviceLoaderHelper, List<Closeable> closeables); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.sdk.extension.incubator.fileconfig; | ||
|
||
import java.io.Closeable; | ||
import java.util.List; | ||
import javax.annotation.Nullable; | ||
|
||
final class FileConfigUtil { | ||
|
||
private FileConfigUtil() {} | ||
|
||
/** Add the {@code closeable} to the {@code closeables} and return it. */ | ||
static <T extends Closeable> T addAndReturn(List<Closeable> closeables, T closeable) { | ||
closeables.add(closeable); | ||
return closeable; | ||
} | ||
|
||
static <T> T assertNotNull(@Nullable T object, String description) { | ||
if (object == null) { | ||
throw new NullPointerException(description + " is null"); | ||
} | ||
return object; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.sdk.extension.incubator.fileconfig; | ||
|
||
import io.opentelemetry.sdk.autoconfigure.internal.ServiceLoaderHelper; | ||
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimits; | ||
import io.opentelemetry.sdk.logs.LogLimits; | ||
import io.opentelemetry.sdk.logs.LogLimitsBuilder; | ||
import java.io.Closeable; | ||
import java.util.List; | ||
import javax.annotation.Nullable; | ||
|
||
final class LogLimitsFactory implements Factory<LogRecordLimits, LogLimits> { | ||
|
||
private static final LogLimitsFactory INSTANCE = new LogLimitsFactory(); | ||
|
||
private LogLimitsFactory() {} | ||
|
||
static LogLimitsFactory getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
@Override | ||
public LogLimits create( | ||
@Nullable LogRecordLimits model, | ||
ServiceLoaderHelper serviceLoaderHelper, | ||
List<Closeable> closeables) { | ||
if (model == null) { | ||
return LogLimits.getDefault(); | ||
} | ||
|
||
LogLimitsBuilder builder = LogLimits.builder(); | ||
if (model.getAttributeCountLimit() != null) { | ||
builder.setMaxNumberOfAttributes(model.getAttributeCountLimit()); | ||
} | ||
if (model.getAttributeValueLengthLimit() != null) { | ||
builder.setMaxAttributeValueLength(model.getAttributeValueLengthLimit()); | ||
} | ||
return builder.build(); | ||
} | ||
} |