Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import java.io.Closeable;
Expand All @@ -15,12 +16,14 @@
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/** Declarative configuration context and state carrier. */
class DeclarativeConfigContext {

private final SpiHelper spiHelper;
private final List<Closeable> closeables = new ArrayList<>();
@Nullable private MeterProvider meterProvider;

DeclarativeConfigContext(SpiHelper spiHelper) {
this.spiHelper = spiHelper;
Expand All @@ -39,6 +42,15 @@ List<Closeable> getCloseables() {
return Collections.unmodifiableList(closeables);
}

@Nullable
public MeterProvider getMeterProvider() {
return meterProvider;
}

public void setMeterProvider(MeterProvider meterProvider) {
this.meterProvider = meterProvider;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any chance this needs to be cross-thread safe? In which case, putting a memory barrier around the assignment would be necessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, this doesn't need to be thread safe - it belongs to the set up logic that is done in a single thread at the start

}

/**
* Find a registered {@link ComponentProvider} with {@link ComponentProvider#getType()} matching
* {@code type}, {@link ComponentProvider#getName()} matching {@code name}, and call {@link
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.sdk.extension.incubator.fileconfig;

import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel;
Expand Down Expand Up @@ -52,6 +53,10 @@ public LogRecordProcessor create(
if (batchModel.getScheduleDelay() != null) {
builder.setScheduleDelay(Duration.ofMillis(batchModel.getScheduleDelay()));
}
MeterProvider meterProvider = context.getMeterProvider();
if (meterProvider != null) {
builder.setMeterProvider(meterProvider);
}

return context.addCloseable(builder.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.OpenTelemetrySdkBuilder;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.resources.Resource;
import java.util.Objects;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -53,6 +54,16 @@ public OpenTelemetrySdk create(
resource = ResourceFactory.getInstance().create(model.getResource(), context);
}

if (model.getMeterProvider() != null) {
SdkMeterProvider meterProvider =
MeterProviderFactory.getInstance()
.create(model.getMeterProvider(), context)
.setResource(resource)
.build();
context.setMeterProvider(meterProvider);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be less error prone if context.setMeterProvider call addCloseable internally.
Then builder.setMeterProvider(context.addCloseable(meterProvider)); could be just: builder.setMeterProvider(meterProvider); and we would be guaranteed that meterProvider will always be closed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would work if we change the parameter type to SdkMeterProvider - but it would be harder to understand why the closeable logic is hidden here, but not for tracer and logger

builder.setMeterProvider(context.addCloseable(meterProvider));
}

if (model.getLoggerProvider() != null) {
builder.setLoggerProvider(
context.addCloseable(
Expand All @@ -77,15 +88,6 @@ public OpenTelemetrySdk create(
.build()));
}

if (model.getMeterProvider() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there any reason to move this code block upper? If not then it leaving it in the same place would make changes analysis a bit simpler.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the meter provider is taken out of the context for logger and tracer

builder.setMeterProvider(
context.addCloseable(
MeterProviderFactory.getInstance()
.create(model.getMeterProvider(), context)
.setResource(resource)
.build()));
}

return context.addCloseable(builder.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.sdk.extension.incubator.fileconfig;

import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel;
Expand Down Expand Up @@ -47,6 +48,11 @@ public SpanProcessor create(SpanProcessorModel model, DeclarativeConfigContext c
if (batchModel.getScheduleDelay() != null) {
builder.setScheduleDelay(Duration.ofMillis(batchModel.getScheduleDelay()));
}
MeterProvider meterProvider = context.getMeterProvider();
if (meterProvider != null) {
builder.setMeterProvider(meterProvider);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This partially solves the problem, but we still won't get the internal exporter telemetry.

The way we solve this in autoconfigure today is with the AutoConfigureListener. SDK components which are loaded via SPI and which report internal telemetry implement AutoConfigureListener and get a callback to update MeterProvider after OpenTelemetrySdk has been initialized. For example, see OtlpSpanExporterProvider.

I think what you've done here does work for SDK components which report internal telemetry and which are NOT loaded via SPI.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That SPI would implement create and can just take the meter provider from DeclarativeConfigContext IIUC.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the SPI guaranteed to be run on the same thread that set the value onto the context? If not, then we will need a memory barrier on the setting of the value into the context, I think.

}

return context.addCloseable(builder.build());
}

Expand Down
Loading