18
18
using System . Web ;
19
19
using OpenTelemetry . Instrumentation . AspNet ;
20
20
#endif
21
+ using System . Runtime . CompilerServices ;
21
22
using System . Text . RegularExpressions ;
22
23
using AWS . Distro . OpenTelemetry . AutoInstrumentation . Logging ;
23
24
using AWS . Distro . OpenTelemetry . Exporter . Xray . Udp ;
@@ -129,7 +130,7 @@ public void TracerProviderInitialized(TracerProvider tracerProvider)
129
130
130
131
MeterProvider provider = Sdk . CreateMeterProviderBuilder ( )
131
132
. AddReader ( metricReader )
132
- . ConfigureResource ( builder => this . ResourceBuilderCustomizer ( builder ) )
133
+ . ConfigureResource ( builder => this . ResourceBuilderCustomizer ( builder , tracerProvider . GetResource ( ) ) )
133
134
. AddMeter ( "AwsSpanMetricsProcessor" )
134
135
. AddView ( instrument =>
135
136
{
@@ -194,7 +195,12 @@ public TracerProviderBuilder BeforeConfigureTracerProvider(TracerProviderBuilder
194
195
{
195
196
if ( this . IsApplicationSignalsEnabled ( ) )
196
197
{
197
- var resourceBuilder = this . ResourceBuilderCustomizer ( ResourceBuilder . CreateDefault ( ) ) ;
198
+ var resourceBuilder = ResourceBuilder
199
+ . CreateEmpty ( ) // Don't use CreateDefault because it puts service name unknown by default.
200
+ . AddEnvironmentVariableDetector ( )
201
+ . AddTelemetrySdk ( ) ;
202
+
203
+ resourceBuilder = this . ResourceBuilderCustomizer ( resourceBuilder ) ;
198
204
var resource = resourceBuilder . Build ( ) ;
199
205
var processor = AwsMetricAttributesSpanProcessorBuilder . Create ( resource ) . Build ( ) ;
200
206
builder . AddProcessor ( processor ) ;
@@ -214,7 +220,12 @@ public TracerProviderBuilder BeforeConfigureTracerProvider(TracerProviderBuilder
214
220
/// <returns>Returns configured builder</returns>
215
221
public TracerProviderBuilder AfterConfigureTracerProvider ( TracerProviderBuilder builder )
216
222
{
217
- var resourceBuilder = this . ResourceBuilderCustomizer ( ResourceBuilder . CreateDefault ( ) ) ;
223
+ var resourceBuilder = ResourceBuilder
224
+ . CreateEmpty ( ) // Don't use CreateDefault because it puts service name unknown by default.
225
+ . AddEnvironmentVariableDetector ( )
226
+ . AddTelemetrySdk ( ) ;
227
+
228
+ resourceBuilder = this . ResourceBuilderCustomizer ( resourceBuilder ) ;
218
229
var resource = resourceBuilder . Build ( ) ;
219
230
this . sampler = SamplerUtil . GetSampler ( resource ) ;
220
231
@@ -516,14 +527,29 @@ private bool IsApplicationSignalsRuntimeEnabled()
516
527
! "false" . Equals ( System . Environment . GetEnvironmentVariable ( ApplicationSignalsRuntimeEnabledConfig ) ) ;
517
528
}
518
529
519
- private ResourceBuilder ResourceBuilderCustomizer ( ResourceBuilder builder )
530
+ private ResourceBuilder ResourceBuilderCustomizer ( ResourceBuilder builder , Resource ? existingResource = null )
520
531
{
532
+ // base case: If there is an already existing resource passed as a parameter, we will copy
533
+ // those resource attributes into the resource builder.
534
+ if ( existingResource != null )
535
+ {
536
+ builder . AddAttributes ( existingResource . Attributes ) ;
537
+ }
538
+
521
539
builder . AddAttributes ( DistroAttributes ) ;
522
540
var resource = builder . Build ( ) ;
541
+ if ( ! resource . Attributes . Any ( kvp => kvp . Key == ResourceSemanticConventions . AttributeServiceName ) )
542
+ {
543
+ // service.name was not configured yet use the fallback.
544
+ Logger . Log ( LogLevel . Warning , "No valid service name provided. Using fallback logic of using assembly name!" ) ;
545
+ builder . AddAttributes ( new Dictionary < string , object > { { ResourceSemanticConventions . AttributeServiceName , this . GetFallbackServiceName ( ) } } ) ;
546
+ }
547
+
548
+ // Incase the above logic failed to get assembly or process name for any reason
523
549
var serviceName = ( string ? ) resource . Attributes . FirstOrDefault ( attr => attr . Key == ResourceSemanticConventions . AttributeServiceName ) . Value ;
524
550
if ( serviceName == null || serviceName . StartsWith ( OtelUnknownServicePrefix ) )
525
551
{
526
- Logger . Log ( LogLevel . Warning , "No valid service name provided. ") ;
552
+ Logger . Log ( LogLevel . Warning , $ "Fallback logic failed. Using { AwsSpanProcessingUtil . UnknownService } as service name! ") ;
527
553
serviceName = AwsSpanProcessingUtil . UnknownService ;
528
554
}
529
555
@@ -628,4 +654,43 @@ private int GetTracesOtlpTimeout()
628
654
629
655
return DefaultOtlpTracesTimeoutMilli ;
630
656
}
657
+
658
+ private string GetFallbackServiceName ( )
659
+ {
660
+ try
661
+ {
662
+ #if NETFRAMEWORK
663
+ // System.Web.dll is only available on .NET Framework
664
+ if ( System . Web . Hosting . HostingEnvironment . IsHosted )
665
+ {
666
+ // if this app is an ASP.NET application, return "SiteName/ApplicationVirtualPath".
667
+ // note that ApplicationVirtualPath includes a leading slash.
668
+ return ( System . Web . Hosting . HostingEnvironment . SiteName + System . Web . Hosting . HostingEnvironment . ApplicationVirtualPath ) . TrimEnd ( '/' ) ;
669
+ }
670
+ #endif
671
+ return Assembly . GetEntryAssembly ( ) ? . GetName ( ) . Name ?? this . GetCurrentProcessName ( ) ;
672
+ }
673
+ catch
674
+ {
675
+ return OtelUnknownServicePrefix ;
676
+ }
677
+ }
678
+
679
+ /// <summary>
680
+ /// <para>Wrapper around <see cref="Process.GetCurrentProcess"/> and <see cref="Process.ProcessName"/></para>
681
+ /// <para>
682
+ /// On .NET Framework the <see cref="Process"/> class is guarded by a
683
+ /// LinkDemand for FullTrust, so partial trust callers will throw an exception.
684
+ /// This exception is thrown when the caller method is being JIT compiled, NOT
685
+ /// when Process.GetCurrentProcess is called, so this wrapper method allows
686
+ /// us to catch the exception.
687
+ /// </para>
688
+ /// </summary>
689
+ /// <returns>Returns the name of the current process.</returns>
690
+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
691
+ private string GetCurrentProcessName ( )
692
+ {
693
+ using var currentProcess = Process . GetCurrentProcess ( ) ;
694
+ return currentProcess . ProcessName ;
695
+ }
631
696
}
0 commit comments