+ Timing SDK operations +
+How to perform basic instrumentation in the AWS SDK for Go V2 to time SDK operations
+From 0c2efedc9a2b5d67ef84ea0949e2ec88b2cb4d33 Mon Sep 17 00:00:00 2001 From: Luc Talatinian <102624213+lucix-aws@users.noreply.github.com> Date: Thu, 21 Dec 2023 17:27:32 -0500 Subject: [PATCH] regen docs (#2435) --- docs/404.html | 2 +- docs/docs/cloud9-go/index.html | 4 +- docs/docs/code-examples/cloudwatch/index.html | 4 +- docs/docs/code-examples/dynamodb/index.html | 4 +- docs/docs/code-examples/ec2/index.html | 4 +- docs/docs/code-examples/iam/index.html | 4 +- docs/docs/code-examples/index.html | 4 +- docs/docs/code-examples/kms/index.html | 4 +- docs/docs/code-examples/s3/index.html | 4 +- docs/docs/code-examples/sns/index.html | 4 +- docs/docs/code-examples/sqs/index.html | 4 +- docs/docs/code-examples/ssm/index.html | 4 +- docs/docs/code-examples/sts/index.html | 4 +- docs/docs/configuring-sdk/auth/index.html | 863 ++++++++++++++++++ .../configuring-sdk/custom-http/index.html | 4 +- .../docs/configuring-sdk/endpoints/index.html | 4 +- docs/docs/configuring-sdk/index.html | 4 +- docs/docs/configuring-sdk/logging/index.html | 4 +- .../retries-timeouts/index.html | 4 +- docs/docs/faq/index.html | 701 ++++++++++++++ docs/docs/faq/index.xml | 260 ++++++ docs/docs/faq/timing-operations/index.html | 819 +++++++++++++++++ docs/docs/getting-started/index.html | 4 +- docs/docs/handling-errors/index.html | 4 +- docs/docs/index.html | 4 +- docs/docs/index.xml | 339 +++---- docs/docs/making-requests/index.html | 10 +- docs/docs/middleware/index.html | 4 +- docs/docs/migrating/index.html | 4 +- docs/docs/sdk-utilities/cloudfront/index.html | 4 +- docs/docs/sdk-utilities/ec2-imds/index.html | 4 +- docs/docs/sdk-utilities/index.html | 4 +- docs/docs/sdk-utilities/rds/index.html | 4 +- docs/docs/sdk-utilities/s3/index.html | 4 +- .../security/compliance-validation/index.html | 4 +- docs/docs/security/data-protection/index.html | 4 +- .../disaster-recovery-resiliency/index.html | 4 +- docs/docs/security/iam/index.html | 4 +- docs/docs/security/index.html | 4 +- .../infrastructure-security/index.html | 4 +- docs/docs/security/tls/index.html | 4 +- docs/docs/unit-testing/index.html | 4 +- docs/index.html | 2 +- ...ndex.f367ad73ebaf545fd290f98fd7fb18f5.json | 1 + docs/sitemap.xml | 6 +- 45 files changed, 2895 insertions(+), 248 deletions(-) create mode 100644 docs/docs/configuring-sdk/auth/index.html create mode 100644 docs/docs/faq/index.html create mode 100644 docs/docs/faq/index.xml create mode 100644 docs/docs/faq/timing-operations/index.html create mode 100644 docs/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json diff --git a/docs/404.html b/docs/404.html index 7aa2859227b..10c529a2649 100644 --- a/docs/404.html +++ b/docs/404.html @@ -99,7 +99,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/cloud9-go/index.html b/docs/docs/cloud9-go/index.html index e05c171ecba..f4b54f57dec 100644 --- a/docs/docs/cloud9-go/index.html +++ b/docs/docs/cloud9-go/index.html @@ -105,7 +105,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -127,7 +127,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/cloudwatch/index.html b/docs/docs/code-examples/cloudwatch/index.html index 0f1051878c6..8cd828f56c0 100644 --- a/docs/docs/code-examples/cloudwatch/index.html +++ b/docs/docs/code-examples/cloudwatch/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/dynamodb/index.html b/docs/docs/code-examples/dynamodb/index.html index 0fb2b369bcd..1e8bf1ad5b5 100644 --- a/docs/docs/code-examples/dynamodb/index.html +++ b/docs/docs/code-examples/dynamodb/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/ec2/index.html b/docs/docs/code-examples/ec2/index.html index 6f359516ff0..51b41408ef1 100644 --- a/docs/docs/code-examples/ec2/index.html +++ b/docs/docs/code-examples/ec2/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/iam/index.html b/docs/docs/code-examples/iam/index.html index 5bb998b7d29..4769502f85c 100644 --- a/docs/docs/code-examples/iam/index.html +++ b/docs/docs/code-examples/iam/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/index.html b/docs/docs/code-examples/index.html index 1539ba60682..0381c07a3c0 100644 --- a/docs/docs/code-examples/index.html +++ b/docs/docs/code-examples/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/kms/index.html b/docs/docs/code-examples/kms/index.html index db894f06470..23a24953d3c 100644 --- a/docs/docs/code-examples/kms/index.html +++ b/docs/docs/code-examples/kms/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/s3/index.html b/docs/docs/code-examples/s3/index.html index 89e69791c27..146c759e4bb 100644 --- a/docs/docs/code-examples/s3/index.html +++ b/docs/docs/code-examples/s3/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/sns/index.html b/docs/docs/code-examples/sns/index.html index 3f3c7b62b7f..b88078a4faa 100644 --- a/docs/docs/code-examples/sns/index.html +++ b/docs/docs/code-examples/sns/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/sqs/index.html b/docs/docs/code-examples/sqs/index.html index 4f02367166a..08269422784 100644 --- a/docs/docs/code-examples/sqs/index.html +++ b/docs/docs/code-examples/sqs/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/ssm/index.html b/docs/docs/code-examples/ssm/index.html index 32b1a2c4b6d..6df7cb29713 100644 --- a/docs/docs/code-examples/ssm/index.html +++ b/docs/docs/code-examples/ssm/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/code-examples/sts/index.html b/docs/docs/code-examples/sts/index.html index 5f9bf62ddf0..2176d37dcc9 100644 --- a/docs/docs/code-examples/sts/index.html +++ b/docs/docs/code-examples/sts/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.f367ad73ebaf545fd290f98fd7fb18f5.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/configuring-sdk/auth/index.html b/docs/docs/configuring-sdk/auth/index.html new file mode 100644 index 00000000000..7b2e8df4df8 --- /dev/null +++ b/docs/docs/configuring-sdk/auth/index.html @@ -0,0 +1,863 @@ + + +
+ + + + + + + + + + + + + + + + + +The AWS SDK for Go V2 provides the ability to configure the authentication +behavior service. In most cases, the default configuration will suffice, but +configuring custom authentication allows for additional behavior such as +working with pre-release service features.
+This section provides a high-level description of authentication components in +the AWS SDK for Go V2.
+AuthScheme
An AuthScheme is the +interface that defines the workflow through which the SDK retrieves a caller +identity and attaches it to an operation request.
+An auth scheme uses the following components, described in detail further +below:
+Authorization
HTTP header)Each service client options includes an AuthSchemes
field, which by default
+is populated with the list of auth schemes supported by that service.
AuthSchemeResolver
Each service client options includes an AuthSchemeResolver
field. This
+interface, defined per-service, is the API called by the SDK to determine the
+possible authentication options for each operation.
IMPORTANT: The auth scheme resolver does NOT dictate what auth scheme is +used. It returns a list of schemes that can be used (“options”), the final +scheme is selected through a fixed algorithm described +here.
+Option
Returned from a call to ResolverAuthSchemes
, an Option represents a possible authentication option.
An option consists of three sets of information:
+For 99% of use cases, callers need not be concerned with the opaque properties +for identity resolution and signing. The SDK will pull out the necessary +properties for each scheme and pass them to the strongly-typed interfaces +exposed in the SDK. For example, the default auth resolver for services encode +the SigV4 option to have signer properties for the signing name and region, the +values of which are passed to the client’s configured +v4.HTTPSigner implementation when SigV4 +is selected.
+Identity
An Identity is an abstract +representation of who the SDK caller is.
+The most common type of identity used in the SDK is a set of aws.Credentials
.
+For most use cases, the caller need not concern themselves with Identity
as
+an abstraction and can work with the concrete types directly.
Note: to preserve backwards compatibility and prevent API confusion, the
+AWS SDK-specific identity type aws.Credentials
does not directly satisfy the
+Identity
interface. This mapping is handled internally.
IdentityResolver
IdentityResolver is the
+interface through which an Identity
is retrieved.
Concrete versions of IdentityResolver
exist in the SDK in strongly-typed form
+(e.g. aws.CredentialsProvider), the
+SDK handles this mapping internally.
A caller will only need to directly implement the IdentityResolver
interface
+when defining an external auth scheme.
Signer
Signer is the interface
+through which a request is supplemented with the retrieved caller Identity
.
Concrete versions of Signer
exist in the SDK in strongly-typed form
+(e.g. v4.HTTPSigner), the SDK
+handles this mapping internally.
A caller will only need to directly implement the Signer
interface
+when defining an external auth scheme.
AuthResolverParameters
Each service takes a specific set of inputs which are passed to its resolution
+function, defined in each service package as AuthResolverParameters
.
The base resolver parameters are as follows:
+name | +type | +description | +
---|---|---|
Operation |
+string |
+The name of the operation being invoked. | +
Region |
+string |
+The client’s AWS region. Only present for services that use SigV4[A]. | +
If you are implementing your own resolver, you should never need to construct +your own instance of its parameters. The SDK will source these values +per-request and pass them to your implementation.
+When you call an AWS service operation through the SDK, the following sequence +of actions occurs after the request has been serialized:
+AuthSchemeResolver.ResolveAuthSchemes()
API,
+sourcing the input parameters as necessary, to obtain a list of possible
+Options for the operation.AuthSchemes
listnil
) on the client’s Options
+(checked via the scheme’s GetIdentityResolver
method, the mapping to the
+concrete identity resolver types described above is handled internally) (1)GetIdentityResolver()
API to retrieve the caller’s identity. For example,
+the builtin SigV4 auth scheme will map to the client’s Credentials
provider
+internally.GetIdentity()
(e.g.
+aws.CredentialProvider.Retrieve()
for SigV4).ResolveEndpoint()
to find the
+endpoint for the request. The endpoint may include additional metadata that
+influences the signing process (e.g. unique signing name for S3 Object Lambda).Signer()
API to retrieve its signer, and
+uses its SignRequest()
API to sign the request with the
+previously-retrieved caller identity.(1) If the SDK encounters the anonymous option (ID smithy.api#noAuth
) in the
+list, it is selected automatically, as there is no corresponding identity
+resolver.
AuthScheme
sThe following auth schemes are natively supported by AWS SDK for Go V2.
+Name | +Scheme ID | +Identity resolver | +Signer | +Notes | +
---|---|---|---|---|
SigV4 | +aws.auth#sigv4 |
+aws.CredentialsProvider | +v4.HTTPSigner | +The current default for most AWS service operations. | +
SigV4A | +aws.auth#sigv4a |
+aws.CredentialsProvider | +n/a | +SigV4A usage is limited at this time, the signer implementation is internal. | +
SigV4Express | +com.amazonaws.s3#sigv4express |
+s3.ExpressCredentialsProvider | +v4.HTTPSigner | +Used for Express One Zone. | +
HTTP Bearer | +smithy.api#httpBearerAuth |
+smithybearer.TokenProvider | +smithybearer.Signer | +Used by codecatalyst. | +
Anonymous | +smithy.api#noAuth |
+n/a | +n/a | +No authentication - no identity is required, and the request is not signed or authenticated. | +
In AWS SDK for Go V2, the identity components of an auth scheme are
+configured in SDK client Options
. The SDK will automatically pick up and use
+the values for these components for the scheme it selects when an operation is
+called.
Note: For backwards compatibility reasons, the SDK implicitly allows the
+use of the anonymous auth scheme if no identity resolvers are configured.
+This can be manually achieved by setting all identity resolvers on a client’s
+Options
to nil
(the sigv4 identity resolver can also be set to
+aws.AnonymousCredentials{}
).
In AWS SDK for Go V2, the signer components of an auth scheme are
+configured in SDK client Options
. The SDK will automatically pick up and use
+the values for these components for the scheme it selects when an operation is
+called. No additional configuration is necessary.
In order to define a custom auth scheme and configure it for use, the caller +must do the following:
+AuthSchemes
listAuthSchemeResolver
to return an auth Option
+with the scheme’s ID where applicableThe following services have unique or customized authentication behavior. We +recommend you delegate to the default implementation and wrap accordingly if +you require custom authentication behavior therein:
+Service | +Notes | +
---|---|
S3 | +Conditional use of SigV4A and SigV4Express depending on operation input. | +
EventBridge | +Conditional use of SigV4A depending on operation input. | +
Cognito | +Certain operations are anonymous-only. | +
SSO | +Certain operations are anonymous-only. | +
STS | +Certain operations are anonymous-only. | +
We are unable to provide guidance to customers on how to configure their HTTP +workflow in a manner that is most effective for their particular workload. The +answer to this is the product of a multivariate equation, with input factors +including but not limited to:
+Much like the previous question, it depends. Elements to consider here include +the following:
+The answer to this question should almost NEVER be based on pure empirical +observation of upstream behavior - e.g. “I made 1000 calls to this operation, +it took at most 5 seconds so I will set the timeout based on that with a safety +factor of 2x to 10 seconds”. Environment conditions can change, services can +temporarily degrade, and these types of assumptions can become wrong without +warning.
+We are unable to assist with extended or timed-out operation calls due to +extended time spent on the wire. “Wire time” in the SDK is defined as any of +the following:
+HTTPClient.Do()
methodRead()
s on an HTTP response body that has been forwarded to
+the caller (e.g. GetObject
)If you are experiencing issues due to operation latency or timeouts, your first +course of action should be to obtain telemetry of the SDK operation lifecycle +to determine the timing breakdown between time spent on the wire and the +surrounding overhead of the operation. See the guide on +timing SDK operations, +which contains a reusable code snippet that can achieve this.
+read: connection reset
error?The SDK retries any errors matching the connection reset
pattern by default.
+This will cover error handling for most operations, where the operation’s HTTP
+response is fully consumed and deserialized into its modeled result type.
However, this error can still occur in a context outside of the retry loop:
+certain service operations directly forward the API’s HTTP response body to the
+caller to be consumed from the wire directly via io.ReadCloser
(e.g.
+GetObject
’s object payload). You may encounter this error when performing a
+Read
on the response body.
This error indicates that your host, the service or any intermediary party +(e.g. NAT gateways, proxies, load balancers) closed the connection while +attempting to read the response.
+This can occur for several reasons:
+io.ReadCloser
+instances provided in an operation’s response, regardless of whether you
+consume its contents.Beyond that, try running a tcpdump for an affected connection at the edge of +your network (e.g. after any proxies that you control). If you see that the AWS +endpoint seems to be sending a TCP RST, you should use the AWS support console +to open a case against the offending service. Be prepared to provide request +IDs and specific timestamps of when the issue occured.
+The signature algorithm for AWS services (generally sigv4) is tied to the
+serialized request’s headers, more specifically most headers prefixed with
+X-
. Proxies are prone to modifying the outgoing request by adding additional
+forwarding information (often via an X-Forwarded-For
header) which
+effectively breaks the signature that the SDK calculated.
If you’re using an HTTP proxy and experiencing signature errors, you should +work to capture the request as it appears outgoing from the proxy and +determine whether it is different.
+ +How to perform basic instrumentation in the AWS SDK for Go V2 to time SDK operations
+When debugging timeout / latency issues in the SDK, it is critical to identify +the components of the operation lifecycle which are taking more time to execute +than expected. As a starting point, you will generally need to inspect the +timing breakdown between the overall operation call and the HTTP call itself.
+The following sample program implements a basic instrumentation probe in terms
+of smithy-go
middleware for SQS clients and demonstrates how it is used. The
+probe emits the following information for each operation call:
Each emitted message is prefixed with a unique (to a single operation) +“invocation ID” which is set at the beginning of the handler stack.
+The entry point for instrumentation is exposed as WithOperationTiming
, which
+is parameterized to accept a message handling function which will receive
+instrumentation “events” as formatted strings. PrintfMSGHandler
is provided
+as a convenience which will simply dump messages to stdout.
The service used here is interchangeable - ALL service client options accept
+APIOptions
and an HTTPClient
as configuration. For example,
+WithOperationTiming
could instead be declared as:
func WithOperationTiming(msgHandler func(string)) func(*s3.Options)
+func WithOperationTiming(msgHandler func(string)) func(*dynamodb.Options)
+// etc.
+
If you change it, be sure to change the signature of the function it returns as +well.
+import (
+ "context"
+ "fmt"
+ "log"
+ "net/http"
+ "sync"
+ "time"
+
+ awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
+ awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
+ "github.com/aws/aws-sdk-go-v2/config"
+ "github.com/aws/aws-sdk-go-v2/service/sqs"
+ "github.com/aws/smithy-go/middleware"
+ smithyrand "github.com/aws/smithy-go/rand"
+)
+
+// WithOperationTiming instruments an SQS client to dump timing information for
+// the following spans:
+// - overall operation time
+// - HTTPClient call time
+//
+// This instrumentation will also emit the request ID, service name, and
+// operation name for each invocation.
+//
+// Accepts a message "handler" which is invoked with formatted messages to be
+// handled externally, you can use the declared PrintfMSGHandler to simply dump
+// these values to stdout.
+func WithOperationTiming(msgHandler func(string)) func(*sqs.Options) {
+ return func(o *sqs.Options) {
+ o.APIOptions = append(o.APIOptions, addTimingMiddlewares(msgHandler))
+ o.HTTPClient = &timedHTTPClient{
+ client: awshttp.NewBuildableClient(),
+ msgHandler: msgHandler,
+ }
+ }
+}
+
+// PrintfMSGHandler writes messages to stdout.
+func PrintfMSGHandler(msg string) {
+ fmt.Printf("%s\n", msg)
+}
+
+type invokeIDKey struct{}
+
+func setInvokeID(ctx context.Context, id string) context.Context {
+ return middleware.WithStackValue(ctx, invokeIDKey{}, id)
+}
+
+func getInvokeID(ctx context.Context) string {
+ id, _ := middleware.GetStackValue(ctx, invokeIDKey{}).(string)
+ return id
+}
+
+// Records the current time, and returns a function to be called when the
+// target span of events is completed. The return function will emit the given
+// span name and time elapsed to the given message consumer.
+func timeSpan(ctx context.Context, name string, consumer func(string)) func() {
+ start := time.Now()
+ return func() {
+ elapsed := time.Now().Sub(start)
+ consumer(fmt.Sprintf("[%s] %s: %s", getInvokeID(ctx), name, elapsed))
+ }
+}
+
+type timedHTTPClient struct {
+ client *awshttp.BuildableClient
+ msgHandler func(string)
+}
+
+func (c *timedHTTPClient) Do(r *http.Request) (*http.Response, error) {
+ defer timeSpan(r.Context(), "http", c.msgHandler)()
+
+ resp, err := c.client.Do(r)
+ if err != nil {
+ return nil, fmt.Errorf("inner client do: %v", err)
+ }
+
+ return resp, nil
+}
+
+type addInvokeIDMiddleware struct {
+ msgHandler func(string)
+}
+
+func (*addInvokeIDMiddleware) ID() string { return "addInvokeID" }
+
+func (*addInvokeIDMiddleware) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
+ out middleware.InitializeOutput, md middleware.Metadata, err error,
+) {
+ id, err := smithyrand.NewUUID(smithyrand.Reader).GetUUID()
+ if err != nil {
+ return out, md, fmt.Errorf("new uuid: %v", err)
+ }
+
+ return next.HandleInitialize(setInvokeID(ctx, id), in)
+}
+
+type timeOperationMiddleware struct {
+ msgHandler func(string)
+}
+
+func (*timeOperationMiddleware) ID() string { return "timeOperation" }
+
+func (m *timeOperationMiddleware) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
+ middleware.InitializeOutput, middleware.Metadata, error,
+) {
+ defer timeSpan(ctx, "operation", m.msgHandler)()
+ return next.HandleInitialize(ctx, in)
+}
+
+type emitMetadataMiddleware struct {
+ msgHandler func(string)
+}
+
+func (*emitMetadataMiddleware) ID() string { return "emitMetadata" }
+
+func (m *emitMetadataMiddleware) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
+ middleware.InitializeOutput, middleware.Metadata, error,
+) {
+ out, md, err := next.HandleInitialize(ctx, in)
+
+ invokeID := getInvokeID(ctx)
+ requestID, _ := awsmiddleware.GetRequestIDMetadata(md)
+ service := awsmiddleware.GetServiceID(ctx)
+ operation := awsmiddleware.GetOperationName(ctx)
+ m.msgHandler(fmt.Sprintf(`[%s] requestID = "%s"`, invokeID, requestID))
+ m.msgHandler(fmt.Sprintf(`[%s] service = "%s"`, invokeID, service))
+ m.msgHandler(fmt.Sprintf(`[%s] operation = "%s"`, invokeID, operation))
+
+ return out, md, err
+}
+
+func addTimingMiddlewares(mh func(string)) func(*middleware.Stack) error {
+ return func(s *middleware.Stack) error {
+ if err := s.Initialize.Add(&timeOperationMiddleware{msgHandler: mh}, middleware.Before); err != nil {
+ return fmt.Errorf("add time operation middleware: %v", err)
+ }
+ if err := s.Initialize.Add(&addInvokeIDMiddleware{msgHandler: mh}, middleware.Before); err != nil {
+ return fmt.Errorf("add invoke id middleware: %v", err)
+ }
+ if err := s.Initialize.Insert(&emitMetadataMiddleware{msgHandler: mh}, "RegisterServiceMetadata", middleware.After); err != nil {
+ return fmt.Errorf("add emit metadata middleware: %v", err)
+ }
+ return nil
+ }
+}
+
+func main() {
+ cfg, err := config.LoadDefaultConfig(context.Background())
+ if err != nil {
+ log.Fatal(fmt.Errorf("load default config: %v", err))
+ }
+
+ svc := sqs.NewFromConfig(cfg, WithOperationTiming(PrintfMSGHandler))
+
+ var wg sync.WaitGroup
+
+ for i := 0; i < 6; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ _, err = svc.ListQueues(context.Background(), nil)
+ if err != nil {
+ fmt.Println(fmt.Errorf("list queues: %v", err))
+ }
+ }()
+ }
+ wg.Wait()
+}
+
A sample output of this program:
+[e9a801bb-c51d-45c8-8e9f-a202e263fde8] http: 192.24067ms
+[e9a801bb-c51d-45c8-8e9f-a202e263fde8] requestID = "dbee3082-96a3-5b23-adca-6d005696fa94"
+[e9a801bb-c51d-45c8-8e9f-a202e263fde8] service = "SQS"
+[e9a801bb-c51d-45c8-8e9f-a202e263fde8] operation = "ListQueues"
+[e9a801bb-c51d-45c8-8e9f-a202e263fde8] operation: 193.098393ms
+[0740f0e0-953e-4328-94fc-830a5052e763] http: 195.185732ms
+[0740f0e0-953e-4328-94fc-830a5052e763] requestID = "48b301fa-fc9f-5f1f-9007-5c783caa9322"
+[0740f0e0-953e-4328-94fc-830a5052e763] service = "SQS"
+[0740f0e0-953e-4328-94fc-830a5052e763] operation = "ListQueues"
+[0740f0e0-953e-4328-94fc-830a5052e763] operation: 195.725491ms
+[c0589832-f351-4cc7-84f1-c656eb79dbd7] http: 200.52383ms
+[444030d0-6743-4de5-bd91-bc40b2b94c55] http: 200.525919ms
+[c0589832-f351-4cc7-84f1-c656eb79dbd7] requestID = "4a73cc82-b47b-56e1-b327-9100744e1b1f"
+[c0589832-f351-4cc7-84f1-c656eb79dbd7] service = "SQS"
+[c0589832-f351-4cc7-84f1-c656eb79dbd7] operation = "ListQueues"
+[c0589832-f351-4cc7-84f1-c656eb79dbd7] operation: 201.214365ms
+[444030d0-6743-4de5-bd91-bc40b2b94c55] requestID = "ca1523ed-1879-5610-bf5d-7e6fd84cabee"
+[444030d0-6743-4de5-bd91-bc40b2b94c55] service = "SQS"
+[444030d0-6743-4de5-bd91-bc40b2b94c55] operation = "ListQueues"
+[444030d0-6743-4de5-bd91-bc40b2b94c55] operation: 201.197071ms
+[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] http: 206.449568ms
+[12b2b39d-df86-4648-a436-ff0482d13340] http: 206.526603ms
+[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] requestID = "64229710-b552-56ed-8f96-ca927567ec7b"
+[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] service = "SQS"
+[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] operation = "ListQueues"
+[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] operation: 207.252357ms
+[12b2b39d-df86-4648-a436-ff0482d13340] requestID = "76d9cbc0-07aa-58aa-98b7-9642c79f9851"
+[12b2b39d-df86-4648-a436-ff0482d13340] service = "SQS"
+[12b2b39d-df86-4648-a436-ff0482d13340] operation = "ListQueues"
+[12b2b39d-df86-4648-a436-ff0482d13340] operation: 207.360621ms
+
+
+
+