forked from inspectIT/inspectit-ocelot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
inspectIT#1269: Changed OpenTelemetryControllerImpl to not rebuild th…
…e SdkTracerProvider when individual trace exporter services change. For this, the DynamicMultiSpanExporter and DynamicSampler have been implemented that can be updated while OpenTelemetry is running. The DynamicallyActivatableTraceExporterService now expose the spanExporter instead of the spanProcessor.
- Loading branch information
Heiko Holz
committed
Jan 13, 2022
1 parent
1ed44c5
commit 4b20a8b
Showing
16 changed files
with
570 additions
and
327 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
...lot-core/src/main/java/rocks/inspectit/ocelot/core/exporter/DynamicMultiSpanExporter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package rocks.inspectit.ocelot.core.exporter; | ||
|
||
import io.opentelemetry.sdk.common.CompletableResultCode; | ||
import io.opentelemetry.sdk.trace.SpanProcessor; | ||
import io.opentelemetry.sdk.trace.data.SpanData; | ||
import io.opentelemetry.sdk.trace.export.SpanExporter; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.function.Function; | ||
|
||
/** | ||
* {@link SpanExporter} that forwards all received spans to a list of {@link SpanExporter}, similar to {@link io.opentelemetry.sdk.trace.export.MultiSpanExporter}. In contrast to {@link io.opentelemetry.sdk.trace.export.MultiSpanExporter}, {@link SpanExporter}s can by dynamically registered and unregisted. | ||
* | ||
* <p>Can be used to export to multiple backends using the same {@link io.opentelemetry.sdk.trace.SpanProcessor} like {@link io.opentelemetry.sdk.trace.export.SimpleSpanProcessor} or {@link io.opentelemetry.sdk.trace.export.BatchSpanProcessor} | ||
*/ | ||
@Slf4j | ||
public class DynamicMultiSpanExporter implements SpanExporter { | ||
|
||
/** | ||
* The {@link SpanExporter}s that all received spans are forwarded to. | ||
*/ | ||
private Map<String, SpanExporter> spanExporters = new ConcurrentHashMap<>(); | ||
|
||
private Object lock = new Object(); | ||
|
||
@Override | ||
public CompletableResultCode export(Collection<SpanData> spans) { | ||
CompletableResultCode resultCode; | ||
synchronized (lock) { | ||
resultCode = execute(spanExporters.values(), (spanExporter) -> spanExporter.export(spans)); | ||
} | ||
return resultCode; | ||
} | ||
|
||
@Override | ||
public CompletableResultCode flush() { | ||
CompletableResultCode resultCode; | ||
synchronized (lock) { | ||
resultCode = execute(spanExporters.values(), (spanExporter) -> spanExporter.flush()); | ||
} | ||
return resultCode; | ||
} | ||
|
||
@Override | ||
public CompletableResultCode shutdown() { | ||
CompletableResultCode resultCode; | ||
synchronized (lock) { | ||
resultCode = execute(spanExporters.values(), (spanExporter) -> spanExporter.shutdown()); | ||
} | ||
return resultCode; | ||
} | ||
|
||
/** | ||
* Executes the given function on a {@link Collection<SpanExporter>} | ||
* | ||
* @param spanExporters The {@link SpanExporter}s | ||
* @param spanExporterFun The {@link Function<SpanExporter, CompletableResultCode>} to apply on each {@link SpanExporter} | ||
* | ||
* @return The {@link CompletableResultCode} of all applications of the function | ||
*/ | ||
private static CompletableResultCode execute(Collection<SpanExporter> spanExporters, Function<SpanExporter, CompletableResultCode> spanExporterFun) { | ||
List<CompletableResultCode> resultCodes = new ArrayList<>(spanExporters.size()); | ||
for (SpanExporter spanExporter : spanExporters) { | ||
CompletableResultCode resultCode; | ||
try { | ||
resultCode = spanExporterFun.apply(spanExporter); | ||
} catch (RuntimeException e) { | ||
log.error("Exception thrown in execute", e); | ||
resultCodes.add(CompletableResultCode.ofFailure()); | ||
continue; | ||
} | ||
resultCodes.add(resultCode); | ||
} | ||
return CompletableResultCode.ofAll(resultCodes); | ||
} | ||
|
||
/** | ||
* Registers the given {@link SpanExporter} to export {@link SpanData} for sampled spans. | ||
* | ||
* @param registerName The name of the span exporter service. Must be unique for each service. | ||
* @param spanExporter The {@link SpanExporter} that is called for each {@link #export(Collection)}, {@link #flush()}, and {@link #shutdown()} | ||
* | ||
* @return Whether a {@link SpanProcessor} was **not** previously registered with the same name. Returns false if a {@link SpanExporter} with the given name was already registered. | ||
*/ | ||
public boolean registerSpanExporter(String registerName, SpanExporter spanExporter) { | ||
return null == spanExporters.put(registerName, spanExporter); | ||
} | ||
|
||
/** | ||
* Unregisters the given {@link SpanExporter} | ||
* | ||
* @param registerName The name of the span exporter service. | ||
* | ||
* @return Whether a {@link SpanExporter} with the given name was successfully removed. Returns false if no {@link SpanExporter} with the given name was previously registered. | ||
*/ | ||
public boolean unregisterSpanExporter(String registerName) { | ||
return null != spanExporters.remove(registerName); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "SpanExporterImpl{" + "spanExporters=" + spanExporters + '}'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.