@@ -11,6 +11,8 @@ namespace NewRelic.Providers.Wrapper.AwsSdk;
11
11
12
12
public class AmazonServiceClientWrapper : IWrapper
13
13
{
14
+ private bool _disableServiceClientWrapper ;
15
+
14
16
private const int LRUCapacity = 100 ;
15
17
// cache the account id per instance of AmazonServiceClient.Config
16
18
public static LRUCache < WeakReferenceKey < object > , string > AwsAccountIdByClientConfigCache = new ( LRUCapacity ) ;
@@ -27,32 +29,81 @@ public CanWrapResponse CanWrap(InstrumentedMethodInfo instrumentedMethodInfo)
27
29
28
30
public AfterWrappedMethodDelegate BeforeWrappedMethod ( InstrumentedMethodCall instrumentedMethodCall , IAgent agent , ITransaction transaction )
29
31
{
32
+ if ( _disableServiceClientWrapper ) // something bad happened on a previous call, so we're disabling this wrapper
33
+ return Delegates . NoOp ;
34
+
30
35
object client = instrumentedMethodCall . MethodCall . InvocationTarget ;
31
36
32
37
var weakReferenceKey = new WeakReferenceKey < object > ( client ) ;
33
- if ( AmazonServiceClientInstanceCache . Contains ( weakReferenceKey ) ) // don't do anything if we've already seen this client instance
38
+
39
+ // don't do anything if we've already seen this client instance -- the account ID is cached already
40
+ if ( AmazonServiceClientInstanceCache . Contains ( weakReferenceKey ) )
34
41
return Delegates . NoOp ;
35
42
43
+ // add this client instance to cache so we don't process it again
36
44
AmazonServiceClientInstanceCache . Add ( weakReferenceKey ) ;
37
45
38
- string awsAccountId ;
46
+ // retrieve and cache the account id
47
+ string awsAccountId = null ;
39
48
try
40
49
{
41
50
// get the AWSCredentials parameter
42
- dynamic awsCredentials = instrumentedMethodCall . MethodCall . MethodArguments [ 0 ] ;
51
+ if ( instrumentedMethodCall . MethodCall . MethodArguments . Length > 0 )
52
+ {
53
+ dynamic awsCredentials = instrumentedMethodCall . MethodCall . MethodArguments [ 0 ] ;
54
+ if ( awsCredentials != null )
55
+ {
56
+ dynamic immutableCredentials = awsCredentials . GetCredentials ( ) ;
57
+ if ( immutableCredentials != null )
58
+ {
59
+ string accessKey = immutableCredentials . AccessKey ;
43
60
44
- dynamic immutableCredentials = awsCredentials . GetCredentials ( ) ;
45
- string accessKey = immutableCredentials . AccessKey ;
61
+ if ( ! string . IsNullOrEmpty ( accessKey ) )
62
+ {
63
+ try
64
+ {
65
+ // convert the access key to an account id
66
+ awsAccountId = AwsAccountIdDecoder . GetAccountId ( accessKey ) ;
67
+ }
68
+ catch ( Exception e )
69
+ {
70
+ agent . Logger . Debug ( e , "Unexpected exception parsing AWS Account ID from AccessKey." ) ;
71
+ }
72
+ }
73
+ else
74
+ agent . Logger . Debug ( "Unable to parse AWS Account ID from AWSCredentials because AccessKey was null." ) ;
75
+ }
76
+ else
77
+ agent . Logger . Debug ( "Unable to parse AWS Account ID from AWSCredentials because GetCredentials() returned null." ) ;
78
+ }
79
+ else
80
+ agent . Logger . Debug ( "Unable to parse AWS Account ID from AWSCredentials because AWSCredentials was null." ) ;
81
+ }
82
+ else
83
+ agent . Logger . Debug ( "Unable to parse AWS Account ID from AWSCredentials because there were no arguments in the method call." ) ;
46
84
47
- // convert the access key to an account id
48
- awsAccountId = AwsAccountIdDecoder . GetAccountId ( accessKey ) ;
85
+ // fall back to configuration if we didn't get an account id from the credentials
86
+ if ( string . IsNullOrEmpty ( awsAccountId ) )
87
+ {
88
+ agent . Logger . Debug ( "Using AccountId from configuration." ) ;
89
+ awsAccountId = agent . Configuration . AwsAccountId ;
90
+ }
49
91
}
50
92
catch ( Exception e )
51
93
{
52
- agent . Logger . Info ( $ "Unable to parse AWS Account ID from AccessKey. Using AccountId from configuration instead. Exception: { e . Message } ") ;
94
+ agent . Logger . Debug ( e , "Unexpected exception in AmazonServiceClientWrapper.BeforeWrappedMethod(). Using AccountId from configuration. ") ;
53
95
awsAccountId = agent . Configuration . AwsAccountId ;
54
96
}
55
97
98
+ // disable the wrapper if we get this far and there's no account id
99
+ if ( string . IsNullOrEmpty ( awsAccountId ) )
100
+ {
101
+ agent . Logger . Warn ( "Unable to parse AWS Account ID from AWSCredentials or configuration. Further AWS Account ID parsing will be disabled." ) ;
102
+ _disableServiceClientWrapper = true ;
103
+
104
+ return Delegates . NoOp ;
105
+ }
106
+
56
107
return Delegates . GetDelegateFor ( onComplete : ( ) =>
57
108
{
58
109
// get the _config field from the client
0 commit comments