77import java .util .function .BooleanSupplier ;
88import java .util .logging .Level ;
99
10+ import jakarta .enterprise .context .ApplicationScoped ;
1011import jakarta .enterprise .inject .Instance ;
1112import jakarta .inject .Singleton ;
1213
1516import org .jboss .jandex .DotName ;
1617import org .jboss .jandex .ParameterizedType ;
1718import org .jboss .jandex .Type ;
19+ import org .objectweb .asm .Opcodes ;
1820
21+ import io .opentelemetry .sdk .internal .StandardComponentId ;
1922import io .opentelemetry .sdk .logs .export .LogRecordExporter ;
2023import io .opentelemetry .sdk .metrics .export .MetricExporter ;
2124import io .opentelemetry .sdk .trace .SpanProcessor ;
2225import io .opentelemetry .sdk .trace .export .SpanExporter ;
2326import io .quarkus .arc .deployment .BeanDiscoveryFinishedBuildItem ;
27+ import io .quarkus .arc .deployment .GeneratedBeanBuildItem ;
28+ import io .quarkus .arc .deployment .GeneratedBeanGizmoAdaptor ;
2429import io .quarkus .arc .deployment .SyntheticBeanBuildItem ;
2530import io .quarkus .arc .deployment .ValidationPhaseBuildItem ;
31+ import io .quarkus .arc .processor .MethodDescriptors ;
2632import io .quarkus .deployment .annotations .*;
2733import io .quarkus .deployment .annotations .Record ;
2834import io .quarkus .deployment .builditem .CombinedIndexBuildItem ;
2935import io .quarkus .deployment .builditem .LogCategoryBuildItem ;
3036import io .quarkus .deployment .builditem .RunTimeConfigBuilderBuildItem ;
37+ import io .quarkus .gizmo .ClassCreator ;
38+ import io .quarkus .gizmo .MethodCreator ;
39+ import io .quarkus .gizmo .MethodDescriptor ;
3140import io .quarkus .opentelemetry .runtime .config .build .OTelBuildConfig ;
3241import io .quarkus .opentelemetry .runtime .config .build .exporter .OtlpExporterBuildConfig ;
3342import io .quarkus .opentelemetry .runtime .config .runtime .exporter .OtlpExporterConfigBuilder ;
43+ import io .quarkus .opentelemetry .runtime .exporter .otlp .ExporterBridge ;
3444import io .quarkus .opentelemetry .runtime .exporter .otlp .OTelExporterRecorder ;
3545import io .quarkus .opentelemetry .runtime .exporter .otlp .tracing .LateBoundSpanProcessor ;
3646import io .quarkus .runtime .configuration .ConfigurationException ;
@@ -44,6 +54,7 @@ public class OtlpExporterProcessor {
4454 private static final DotName METRIC_EXPORTER = DotName .createSimple (MetricExporter .class .getName ());
4555 private static final DotName LOG_RECORD_EXPORTER = DotName .createSimple (LogRecordExporter .class .getName ());
4656 private static final DotName OKHTTP_INTERCEPTOR = DotName .createSimple ("okhttp3.Interceptor" );
57+ private static final String BRIDGE_NAME = "io.opentelemetry.sdk.internal.StandardComponentIdBridge" ;
4758
4859 static class OtlpTracingExporterEnabled implements BooleanSupplier {
4960 OtlpExporterBuildConfig exportBuildConfig ;
@@ -109,6 +120,58 @@ private boolean isTracesOtlp(OTelBuildConfig otelBuildConfig) {
109120 }
110121 }
111122
123+ /**
124+ * Make constructor public for io.opentelemetry.sdk.internal.StandardComponentId
125+ *
126+ * <pre>
127+ * @ApplicationScoped
128+ * public class StandardComponentIdBridge implements ExporterBridge {
129+ * public StandardComponentIdBridge() {
130+ * }
131+ *
132+ * public StandardComponentId createStandardComponentId(StandardComponentId.ExporterType standardType) {
133+ * return new StandardComponentId(standardType);
134+ * }
135+ * }
136+ * </pre>
137+ */
138+ @ BuildStep
139+ void generateBridgeService (BuildProducer <GeneratedBeanBuildItem > generatedBeanClasses ) {
140+ // Create a ClassOutput instance
141+ GeneratedBeanGizmoAdaptor gizmoAdaptor = new GeneratedBeanGizmoAdaptor (
142+ generatedBeanClasses );
143+
144+ try (ClassCreator classCreator = ClassCreator .builder ()
145+ .className (BRIDGE_NAME )
146+ .interfaces (ExporterBridge .class )
147+ .classOutput (gizmoAdaptor )
148+ .build ()) {
149+
150+ classCreator .addAnnotation (ApplicationScoped .class );
151+ MethodCreator constructor = classCreator .getMethodCreator ("<init>" , "V" );
152+ // Invoke super()
153+ constructor .invokeSpecialMethod (
154+ MethodDescriptors .OBJECT_CONSTRUCTOR ,
155+ constructor .getThis ());
156+ constructor .returnValue (null );
157+
158+ // public static StandardComponentId createStandardComponentId(StandardComponentId.ExporterType standardType)
159+ try (MethodCreator method = classCreator .getMethodCreator ("createStandardComponentId" ,
160+ StandardComponentId .class ,
161+ StandardComponentId .ExporterType .class )) {
162+ method .setModifiers (Opcodes .ACC_PUBLIC );
163+ var in = method .getMethodParam (0 );
164+
165+ // calls package-private constructor: StandardComponentId(ExporterType standardType)
166+ MethodDescriptor target = MethodDescriptor .ofConstructor (
167+ StandardComponentId .class , StandardComponentId .ExporterType .class );
168+
169+ var result = method .newInstance (target , in );
170+ method .returnValue (result );
171+ }
172+ }
173+ }
174+
112175 @ BuildStep
113176 void logging (BuildProducer <LogCategoryBuildItem > log ) {
114177 // Reduce the log level of the exporters because it's too much, and we do log important things ourselves.
@@ -156,6 +219,7 @@ void createSpanProcessor(OTelExporterRecorder recorder,
156219 .addInjectionPoint (ParameterizedType .create (DotName .createSimple (Instance .class ),
157220 new Type [] { ClassType .create (DotName .createSimple (SpanExporter .class .getName ())) }, null ))
158221 .addInjectionPoint (ClassType .create (DotName .createSimple (TlsConfigurationRegistry .class )))
222+ .addInjectionPoint (ClassType .create (DotName .createSimple (ExporterBridge .class )))
159223 .createWith (recorder .spanProcessorForOtlp (vertxBuildItem .getVertx ()))
160224 .done ());
161225 }
@@ -190,6 +254,7 @@ void createMetricsExporterProcessor(
190254 .addInjectionPoint (ParameterizedType .create (DotName .createSimple (Instance .class ),
191255 new Type [] { ClassType .create (DotName .createSimple (MetricExporter .class .getName ())) }, null ))
192256 .addInjectionPoint (ClassType .create (DotName .createSimple (TlsConfigurationRegistry .class )))
257+ .addInjectionPoint (ClassType .create (DotName .createSimple (ExporterBridge .class )))
193258 .createWith (recorder .createMetricExporter (vertxBuildItem .getVertx ()))
194259 .done ());
195260 }
@@ -224,6 +289,7 @@ void createLogRecordExporterProcessor(
224289 .addInjectionPoint (ParameterizedType .create (DotName .createSimple (Instance .class ),
225290 new Type [] { ClassType .create (DotName .createSimple (LogRecordExporter .class .getName ())) }, null ))
226291 .addInjectionPoint (ClassType .create (DotName .createSimple (TlsConfigurationRegistry .class )))
292+ .addInjectionPoint (ClassType .create (DotName .createSimple (ExporterBridge .class )))
227293 .createWith (recorder .createLogRecordExporter (vertxBuildItem .getVertx ()))
228294 .done ());
229295 }
0 commit comments