@@ -36,12 +36,10 @@ public static IResourceBuilder<OpenTelemetryCollectorResource> AddOpenTelemetryC
3636
3737 var isHttpsEnabled = ! settings . ForceNonSecureReceiver && url . StartsWith ( "https" , StringComparison . OrdinalIgnoreCase ) ;
3838
39- var dashboardOtlpEndpoint = ReplaceLocalhostWithContainerHost ( url , builder . Configuration ) ;
40-
4139 var resource = new OpenTelemetryCollectorResource ( name ) ;
4240 var resourceBuilder = builder . AddResource ( resource )
4341 . WithImage ( settings . CollectorImage , settings . CollectorTag )
44- . WithEnvironment ( "ASPIRE_ENDPOINT" , dashboardOtlpEndpoint )
42+ . WithEnvironment ( "ASPIRE_ENDPOINT" , new HostUrl ( url ) )
4543 . WithEnvironment ( "ASPIRE_API_KEY" , builder . Configuration [ DashboardOtlpApiKeyVariableName ] ) ;
4644
4745 if ( settings . EnableGrpcEndpoint )
@@ -53,8 +51,11 @@ public static IResourceBuilder<OpenTelemetryCollectorResource> AddOpenTelemetryC
5351 if ( ! settings . ForceNonSecureReceiver && isHttpsEnabled && builder . ExecutionContext . IsRunMode && builder . Environment . IsDevelopment ( ) )
5452 {
5553 resourceBuilder . RunWithHttpsDevCertificate ( ) ;
56- var certFilePath = Path . Combine ( DevCertHostingExtensions . DEV_CERT_BIND_MOUNT_DEST_DIR , DevCertHostingExtensions . CERT_FILE_NAME ) ;
57- var certKeyPath = Path . Combine ( DevCertHostingExtensions . DEV_CERT_BIND_MOUNT_DEST_DIR , DevCertHostingExtensions . CERT_KEY_FILE_NAME ) ;
54+
55+ // Not using `Path.Combine` as we MUST use unix style paths in the container
56+ var certFilePath = $ "{ DevCertHostingExtensions . DEV_CERT_BIND_MOUNT_DEST_DIR } /{ DevCertHostingExtensions . CERT_FILE_NAME } ";
57+ var certKeyPath = $ "{ DevCertHostingExtensions . DEV_CERT_BIND_MOUNT_DEST_DIR } /{ DevCertHostingExtensions . CERT_KEY_FILE_NAME } ";
58+
5859 if ( settings . EnableHttpEndpoint )
5960 {
6061 resourceBuilder . WithArgs (
@@ -78,19 +79,23 @@ public static IResourceBuilder<OpenTelemetryCollectorResource> AddOpenTelemetryC
7879 /// <returns></returns>
7980 public static IResourceBuilder< OpenTelemetryCollectorResource> WithAppForwarding( this IResourceBuilder < OpenTelemetryCollectorResource > builder )
8081 {
81- builder . AddEnvironmentVariablesEventHook ( )
82- . WithFirstStartup ( ) ;
82+ builder . ApplicationBuilder . Eventing . Subscribe < BeforeStartEvent > ( ( evt , ct ) =>
83+ {
84+ var logger = evt . Services . GetRequiredService < ResourceLoggerService > ( ) . GetLogger ( builder . Resource ) ;
85+ var otelSenders = evt . Model . Resources
86+ . OfType < IResourceWithEnvironment > ( )
87+ . Where ( x => x . HasAnnotationOfType < OtlpExporterAnnotation > ( ) ) ;
8388
84- return builder;
85- }
89+ foreach ( var otelSender in otelSenders )
90+ {
91+ var otelSenderBuilder = builder . ApplicationBuilder . CreateResourceBuilder ( otelSender ) ;
92+ otelSenderBuilder . WithOpenTelemetryCollectorRouting ( builder ) ;
93+ }
8694
87- private static string ReplaceLocalhostWithContainerHost ( string value , IConfiguration configuration )
88- {
89- var hostName = configuration[ "AppHost:ContainerHostname" ] ?? "host.docker.internal" ;
95+ return Task . CompletedTask ;
96+ } ) ;
9097
91- return value. Replace ( "localhost" , hostName , StringComparison . OrdinalIgnoreCase )
92- . Replace ( "127.0.0.1" , hostName )
93- . Replace ( "[::1]" , hostName ) ;
98+ return builder;
9499 }
95100
96101 /// <summary>
@@ -106,73 +111,4 @@ public static IResourceBuilder<OpenTelemetryCollectorResource> WithConfig(this I
106111 . WithArgs ( $ "--config=/config/{ configFileInfo . Name } ") ;
107112 }
108113
109- /// <summary>
110- /// Sets up the OnBeforeResourceStarted event to add a wait annotation to all resources that have the OtlpExporterAnnotation
111- /// </summary>
112- /// <param name="builder"></param>
113- /// <returns></returns>
114- private static IResourceBuilder < OpenTelemetryCollectorResource > WithFirstStartup ( this IResourceBuilder < OpenTelemetryCollectorResource > builder )
115- {
116- builder . OnBeforeResourceStarted ( ( collectorResource , beforeStartedEvent , cancellationToken ) =>
117- {
118- var logger = beforeStartedEvent . Services . GetRequiredService < ResourceLoggerService > ( ) . GetLogger ( collectorResource ) ;
119- var appModel = beforeStartedEvent . Services . GetRequiredService < DistributedApplicationModel > ( ) ;
120- var resources = appModel . GetProjectResources ( ) ;
121-
122- foreach ( var resourceItem in resources . Where ( r => r . HasAnnotationOfType < OtlpExporterAnnotation > ( ) ) )
123- {
124- resourceItem . Annotations . Add ( new WaitAnnotation ( collectorResource , WaitType . WaitUntilHealthy ) ) ;
125- }
126- return Task . CompletedTask ;
127- } ) ;
128- return builder;
129- }
130-
131- /// <summary>
132- /// Sets up the OnResourceEndpointsAllocated event to add/update the OTLP environment variables for the collector to the various resources
133- /// </summary>
134- /// <param name="builder"></param>
135- private static IResourceBuilder< OpenTelemetryCollectorResource > AddEnvironmentVariablesEventHook ( this IResourceBuilder < OpenTelemetryCollectorResource > builder )
136- {
137- builder . OnResourceEndpointsAllocated ( ( collectorResource , allocatedEvent , cancellationToken ) =>
138- {
139- var logger = allocatedEvent . Services . GetRequiredService < ResourceLoggerService > ( ) . GetLogger ( collectorResource ) ;
140- var appModel = allocatedEvent . Services . GetRequiredService < DistributedApplicationModel > ( ) ;
141- var resources = appModel . GetProjectResources ( ) ;
142-
143- var grpcEndpoint = collectorResource . GetEndpoint ( collectorResource . GrpcEndpoint . EndpointName ) ;
144- var httpEndpoint = collectorResource . GetEndpoint ( collectorResource . HttpEndpoint . EndpointName ) ;
145-
146- if ( ! resources . Any ( ) )
147- {
148- logger . LogInformation ( "No resources to add Environment Variables to" ) ;
149- }
150-
151- foreach ( var resourceItem in resources . Where ( r => r . HasAnnotationOfType < OtlpExporterAnnotation > ( ) ) )
152- {
153- logger . LogDebug ( "Forwarding Telemetry for {name} to the collector" , resourceItem . Name ) ;
154- if ( resourceItem is null ) continue ;
155-
156- resourceItem . Annotations . Add ( new EnvironmentCallbackAnnotation ( context =>
157- {
158- var protocol = context . EnvironmentVariables . GetValueOrDefault ( "OTEL_EXPORTER_OTLP_PROTOCOL" , "" ) ;
159- var endpoint = protocol . ToString ( ) == "http/protobuf" ? httpEndpoint : grpcEndpoint ;
160-
161- if ( endpoint is null )
162- {
163- logger . LogWarning ( "No {protocol} endpoint on the collector for {resourceName} to use" ,
164- protocol , resourceItem . Name ) ;
165- return ;
166- }
167-
168- context . EnvironmentVariables . Remove ( "OTEL_EXPORTER_OTLP_ENDPOINT" ) ;
169- context . EnvironmentVariables . Add ( "OTEL_EXPORTER_OTLP_ENDPOINT" , endpoint . Url ) ;
170- } ) ) ;
171- }
172-
173- return Task . CompletedTask ;
174- } ) ;
175-
176- return builder;
177- }
178114}
0 commit comments