

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Configure el AWS SDK para Kotlin
<a name="configuration"></a>

En esta sección se explica cómo configurar un cliente de servicio mediante el AWS SDK para Kotlin. Para obtener más información, consulte la [guía de referencia del SDK y las herramientas](https://docs.aws.amazon.com/sdkref/latest/guide/overview.html), que incluye una descripción general de la configuración que se aplica a todos AWS SDKs.

**Contents**
+ [Crear un cliente de servicio](creating-clients.md)
  + [Configura un cliente en código](creating-clients.md#programmatic-config)
  + [Configuración de un cliente basada en el entorno](creating-clients.md#loading-from-the-environment)
  + [Cierre el cliente](creating-clients.md#closing-the-client)
+ [Región de AWS selección](region-selection.md)
  + [Cadena de proveedores por región predeterminada](region-selection.md#default-region-provider-chain)
+ [Proveedores de credenciales](credential-providers.md)
  + [La cadena de proveedores de credenciales predeterminada](credential-providers.md#default-credential-provider-chain)
    + [Más información sobre la cadena de proveedores de credenciales predeterminada](credential-providers.md#default-credentials-retrieval-order)
  + [Especifique un proveedor de credenciales](credential-providers.md#explicit-credential-provider)
    + [Guarde las credenciales en caché con un proveedor independiente](credential-providers.md#credentials-caching)
+ [Configure los puntos finales del cliente](config-endpoint.md)
  + [Configuración personalizada](config-endpoint.md#config-endpoint-custom-config)
    + [Establezca `endpointUrl`](config-endpoint.md#config-endpoint-custom-config-endpointurl)
    + [Establezca `endpointProvider`](config-endpoint.md#config-endpoint-custom-config-endpointprovider)
      + [Propiedades de `EndpointProvider`](config-endpoint.md#config-endpoint-custom-config-endpointprovider-params)
    + [`endpointUrl` o `endpointProvider`](config-endpoint.md#config-endpoint-custom-config-which)
    + [Nota acerca de Amazon S3](config-endpoint.md#config-endpoint-custom-config-s3)
  + [Ejemplos](config-endpoint.md#config-endpoint-examples)
    + [`endpointUrl`Ejemplo de](config-endpoint.md#config-endpoint-examples-endpointurl)
    + [`endpointProvider`Ejemplo de](config-endpoint.md#config-endpoint-examples-endpointprovider)
    + [`endpointUrl` y `endpointProvider`](config-endpoint.md#config-endpoint-examples-both)
+ [HTTP](http.md)
  + [Configuración del cliente HTTP](http-client-config.md)
    + [Configuración básica](http-client-config.md#basic-http-confg)
      + [Importaciones](http-client-config.md#basic-config-ex-imports)
      + [Código](http-client-config.md#basic-config-ex-code)
    + [Configuración avanzada](http-client-config.md#advanced-http-config)
      + [Especifique un tipo de motor HTTP](http-client-config.md#http-config-engine)
        + [Importaciones](http-client-config.md#http-config-specify-engine-imports)
        + [Código](http-client-config.md#http-config-specify-engine-code)
        + [Utilizar `OkHttp4Engine`](http-client-config.md#http-config-okhttp4engine)
        + [Utilice un cliente HTTP explícito](http-client-config.md#http-client-explicit-usage)
          + [Importaciones](http-client-config.md#http-client-explicit-usage-ex-imports)
          + [Código](http-client-config.md#http-client-explicit-usage-ex-code)
      + [Supervisión de conexiones inactivas](http-client-config.md#http-idle-connection-monitoring)
        + [Importaciones](http-client-config.md#http-idle-connection-ex-imports)
        + [Código](http-client-config.md#http-idle-connection-ex-code)
  + [Usar un proxy HTTP](using-http-proxy.md)
    + [Uso de las propiedades del sistema JVM](using-http-proxy.md#http-proxy-jvm-properties)
    + [Utilización de variables de entorno](using-http-proxy.md#http-proxy-environment-variables)
    + [Utilice un proxy en las instancias de EC2](using-http-proxy.md#http-proxy-ec2)
  + [Interceptores HTTP](interceptors.md)
    + [Registro de interceptores](interceptors.md#interceptor-registration)
      + [Interceptor para todas las operaciones del cliente de servicio](interceptors.md#interceptor-all-ops)
      + [Interceptor solo para operaciones específicas](interceptors.md#interceptor-specific-ops)
  + [Aplicar una versión mínima de TLS](configure-http-tls.md)
    + [Configure el motor HTTP](configure-http-tls.md#configure-http-tls-engine)
    + [Establezca la propiedad del `sdk.minTls` sistema JVM](configure-http-tls.md#configure-http-tls-sysprop)
    + [Defina la variable de entorno `SDK_MIN_TLS`](configure-http-tls.md#configure-http-tls-envvar)
+ [Se vuelve a intentar en AWS SDK para Kotlin](retries.md)
  + [Comprender el comportamiento de los reintentos](retries.md#retries-understanding)
    + [Configuración de reintento predeterminada](retries.md#retries-default)
    + [¿Qué excepciones se pueden volver a intentar?](retries.md#retries-default-policy-details)
      + [Se puede volver a intentar mediante código de error](retries.md#retries-retryable-by-error-code)
      + [Se puede volver a intentar mediante el código de estado HTTP](retries.md#retries-retryable-by-status-code)
      + [Se puede volver a intentar por tipo de error](retries.md#retries-retryable-by-error-type)
      + [Se puede volver a intentar mediante metadatos del SDK](retries.md#retries-retryable-by-metadata)
    + [Comprueba si una excepción se puede volver a intentar](retries.md#retries-check-exception-retryable)
    + [¿Qué excepciones llegan a tu código cuando los reintentos fallan](retries.md#retries-exception-types-during-retries)
  + [Personalización del comportamiento de los reintentos](retries.md#retries-customizing)
    + [Configura el número máximo de intentos](retries.md#retires-max-attempts)
    + [Configure los retrasos y los retrasos](retries.md#retries-delays-backoff)
    + [Configure el depósito de fichas de reintento](retries.md#retries-token-bucket)
    + [Configure los reintentos adaptativos](retries.md#retries-adaptive-retries)
+ [Observabilidad](observability.md)
  + [Configuración de un `TelemetryProvider`](observability.md#observability-conf-telemetry-provider)
    + [Configuración del proveedor de telemetría global predeterminado](observability.md#observability-conf-telemetry-provider-global)
    + [Configuración de un proveedor de telemetría para un cliente de servicio específico](observability.md#observability-conf-telemetry-provider-client)
  + [Métricas](observability-telemetry-metrics.md)
  + [Registro](logging.md)
    + [Especifique el modo de registro para los mensajes a nivel de cable](logging.md#sdk-log-mode)
      + [Configure el modo de registro en el código](logging.md#set-log-mode-programmatically)
      + [Establezca el modo de registro desde el entorno](logging.md#set-log-mode-from-enviironment)
  + [Proveedores de telemetría](observability-telemetry-providers.md)
    + [Configure el proveedor de OpenTelemetry telemetría basado](observability-telemetry-providers-otel.md)
      + [Requisitos previos](observability-telemetry-providers-otel.md#observability-telemetry-providers-otel-prereqs)
      + [Configurar el SDK](observability-telemetry-providers-otel.md#observability-telemetry-providers-otel-conf)
      + [Recursos](observability-telemetry-providers-otel.md#observability-telemetry-providers-otel-res)
+ [Anule la configuración del cliente del servicio](override-client-config.md)
  + [Ciclo de vida de un cliente anulado](override-client-config.md#override-client-lifecycle)
  + [Recursos compartidos entre clientes](override-client-config.md#override-client-shared-res)

# Crear un cliente de servicio
<a name="creating-clients"></a>

Para realizar una solicitud a un Servicio de AWS, primero debes crear una instancia de un cliente para ese servicio.

Puede configurar los ajustes comunes para los clientes del servicio, como el cliente HTTP que van a utilizar, el nivel de registro y la configuración de reintentos. Además, cada cliente de servicio requiere un proveedor de credenciales Región de AWS y un proveedor de credenciales. El SDK usa estos valores para enviar solicitudes a la región correcta y firmarlas con las credenciales correctas.

Puede especificar estos valores mediante programación en el código o hacer que se carguen automáticamente desde el entorno.

## Configura un cliente en código
<a name="programmatic-config"></a>

Para configurar un cliente de servicio con valores específicos, puede especificarlos en una función lambda que se pase al método de fábrica del cliente de servicio, como se muestra en el siguiente fragmento.

```
val dynamoDbClient = DynamoDbClient {
    region = "us-east-1"
    credentialsProvider = ProfileCredentialsProvider(profileName = "myprofile")
}
```

Todos los valores que no especifique en el bloque de configuración se establecen como valores predeterminados. Por ejemplo, si no especifica un proveedor de credenciales como lo hacía el código anterior, el proveedor de credenciales utilizará de [forma predeterminada la cadena de proveedores de credenciales predeterminada](credential-providers.md#default-credential-provider-chain).

**aviso**  
Algunas propiedades, como, por ejemplo, `region` no tienen un valor predeterminado. Debe especificarlas de forma explícita en el bloque de configuración cuando utilice la configuración programática. Si el SDK no puede resolver la propiedad, es posible que se produzcan errores en las solicitudes de API.

## Configuración de un cliente basada en el entorno
<a name="loading-from-the-environment"></a>

Al crear un cliente de servicio, el SDK puede inspeccionar las ubicaciones del entorno de ejecución actual para determinar algunas propiedades de configuración. Estas ubicaciones incluyen [archivos de configuración y credenciales compartidos](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html), [variables de entorno](https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html) y [propiedades del sistema JVM](https://docs.aws.amazon.com/sdkref/latest/guide/jvm-system-properties.html). Las propiedades disponibles para ser resueltas incluyen [AWS la región, la](region-selection.md) [estrategia de reintento](retries.md), el [modo de registro](logging.md#sdk-log-mode) y otras. Para obtener más información sobre todos los ajustes que el SDK puede resolver desde el entorno de ejecución, consulta la [Guía de referencia sobre la configuración AWS SDKs y las herramientas](https://docs.aws.amazon.com/sdkref/latest/guide/settings-reference.html).

Para crear un cliente con una configuración basada en el entorno, utilice el método `suspend fun fromEnvironment()` estático de la interfaz del cliente del servicio:

```
val dynamoDbClient = DynamoDbClient.fromEnvironment()
```

Crear un cliente de esta manera resulta útil cuando se ejecuta en Amazon EC2 o en cualquier otro contexto en el que la configuración de un cliente de servicio esté disponible en el entorno. AWS Lambda Esto desvincula el código del entorno en el que se ejecuta y facilita la implementación de la aplicación en varias regiones sin cambiar el código. 

Además, puedes anular propiedades específicas pasando un bloque lambda a. `fromEnvironment` El siguiente ejemplo carga algunas propiedades de configuración del entorno (por ejemplo, la región), pero anula específicamente el proveedor de credenciales para usar las credenciales de un perfil.

```
val dynamoDbClient = DynamoDbClient.fromEnvironment { 
    credentialsProvider = ProfileCredentialsProvider(profileName = "myprofile")
}
```

El SDK usa valores predeterminados para cualquier propiedad de configuración que no se pueda determinar a partir de la configuración programática o del entorno. Por ejemplo, si no especificas un proveedor de credenciales en el código o en una configuración de entorno, el proveedor de credenciales utilizará de [forma predeterminada la cadena de proveedores de credenciales predeterminada](credential-providers.md#default-credential-provider-chain).

**aviso**  
Algunas propiedades, como la región, no tienen un valor predeterminado. Debe especificarlas en una configuración de entorno o de forma explícita en el bloque de configuración. Si el SDK no puede resolver la propiedad, es posible que se produzcan errores en las solicitudes de API.

**nota**  
Si bien las propiedades relacionadas con las credenciales, como las claves de acceso temporales y la configuración de SSO, se encuentran en el entorno de ejecución, el cliente no obtiene los valores en el momento de la creación. En su lugar, la capa del proveedor de credenciales accede a los valores en cada solicitud. 

## Cierre el cliente
<a name="closing-the-client"></a>

Cuando ya no necesite el cliente de servicio, ciérrelo para liberar los recursos que esté utilizando:

```
val dynamoDbClient = DynamoDbClient.fromEnvironment()
// Invoke several DynamoDB operations.
dynamoDbClient.close()
```

Como los clientes de servicio amplían la [https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.io/-closeable/index.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.io/-closeable/index.html)interfaz, puedes usar la [https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.io/use.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.io/use.html)extensión para cerrar el cliente automáticamente al final de un bloque, como se muestra en el siguiente fragmento.

```
DynamoDbClient.fromEnvironment().use { dynamoDbClient ->
    // Invoke several DynamoDB operations.
}
```

En el ejemplo anterior, el bloque lambda recibe una referencia al cliente que se acaba de crear. Puede invocar operaciones en esta referencia de cliente y, cuando se complete el bloqueo (incluso mediante una excepción), el cliente estará cerrado.

# Región de AWS selección
<a name="region-selection"></a>

Con Regiones de AWS, puede acceder a los Servicios de AWS que operan en un área geográfica específica. Esto puede ser útil para evitar redundancias y para que sus datos y aplicaciones se ejecuten cerca del lugar desde donde usted y sus usuarios obtendrán acceso a ellos.

## Cadena de proveedores por región predeterminada
<a name="default-region-provider-chain"></a>

Al cargar la configuración de un cliente de servicio [desde el entorno](creating-clients.md#loading-from-the-environment), se utiliza el siguiente proceso de búsqueda:

1. Cualquier región explícita establecida en el generador.

1. La propiedad del sistema `aws.region` JVM está marcada. Si está establecida, esa región se utiliza en la configuración del cliente.

1. Se comprueba la variable de entorno `AWS_REGION`. Si está establecida, esa región se usa en la configuración del cliente.

   1. **Nota**: Esta variable de entorno la establece el contenedor Lambda.

1. El SDK comprueba el archivo de configuración AWS compartido. Si la `region` propiedad está establecida para el perfil activo, el SDK la usa.

   1. La variable de entorno `AWS_CONFIG_FILE` se puede utilizar para personalizar la ubicación del archivo de configuración compartida.

   1. La propiedad del sistema `aws.profile` JVM o la variable de `AWS_PROFILE` entorno se pueden usar para personalizar el perfil que carga el SDK.

1. El SDK intenta utilizar el servicio de metadatos de instancias Amazon EC2 para determinar la región de la instancia EC2 que se está ejecutando actualmente.

1. Si la región sigue sin resolverse en este momento, se produce un error en la creación del cliente, salvo una excepción.

# Proveedores de credenciales
<a name="credential-providers"></a>

****  
**El orden en el que la cadena de proveedores de credenciales predeterminada resuelve las credenciales modificadas con la versión 1.4.0 Para obtener más información, consulte la nota siguiente.**

Cuando envíe solicitudes a Amazon Web Services mediante el AWS SDK para Kotlin, las solicitudes deben estar firmadas criptográficamente con las credenciales emitidas por AWS. El SDK de Kotlin firma la solicitud automáticamente. Para adquirir las credenciales, el SDK puede utilizar los ajustes de configuración que se encuentran en varios lugares, por ejemplo, las propiedades del sistema JVM, las variables de entorno, `credentials` los archivos AND compartidos AWS `config` y los metadatos de las instancias Amazon EC2.

El SDK utiliza la abstracción del *proveedor de credenciales* para simplificar el proceso de recuperación de credenciales de diversas fuentes. El SDK contiene [varias implementaciones de proveedores de credenciales](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/aws-config/aws.sdk.kotlin.runtime.auth.credentials/index.html).

Por ejemplo, si la configuración recuperada incluye la configuración de acceso de inicio de sesión único al Centro de identidades de IAM desde el `config` archivo compartido, el SDK trabaja con el Centro de identidades de IAM para recuperar las credenciales temporales que utiliza para realizar solicitudes. Servicios de AWS Con este enfoque de adquisición de credenciales, el SDK utiliza el proveedor del Centro de Identidad de IAM (también conocido como proveedor de credenciales de SSO). En la [sección de configuración](setup-basic-onetime-setup.md#setup-sso-access) de esta guía se describe esta configuración.

Para usar un proveedor de credenciales específico, puede especificar uno al crear un cliente de servicio. Como alternativa, puede utilizar la cadena de proveedores de credenciales predeterminada para buscar automáticamente los ajustes de configuración.

## La cadena de proveedores de credenciales predeterminada
<a name="default-credential-provider-chain"></a>

Si no se especifica de forma explícita en la construcción del cliente, el SDK para Kotlin utiliza un proveedor de credenciales que comprueba secuencialmente todos los lugares en los que puedes introducir las credenciales. Este proveedor de credenciales predeterminado se implementa como una cadena de proveedores de credenciales.

Para usar la cadena predeterminada para proporcionar credenciales a su aplicación, cree un cliente de servicio sin proporcionar una `credentialsProvider` propiedad de forma explícita.

```
val ddb = DynamoDbClient {
    region = "us-east-2"
}
```

Para obtener más información sobre la creación de clientes de servicio, [consulte crear y configurar un cliente](creating-clients.md).

### Más información sobre la cadena de proveedores de credenciales predeterminada
<a name="default-credentials-retrieval-order"></a>

La cadena de proveedores de credenciales predeterminada busca la configuración de las credenciales mediante la siguiente secuencia predefinida. Cuando los parámetros configurados proporcionan credenciales válidas, la cadena se detiene.

**1. [AWS claves de acceso (propiedades del sistema JVM)](https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html)**  
El SDK busca las propiedades del sistema `aws.accessKeyId``aws.secretAccessKey`, y `aws.sessionToken` JVM.

**2. [AWS claves de acceso (variables de entorno)](https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html)**  
El SDK intenta cargar credenciales de las variables de entorno `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` y `AWS_SESSION_TOKEN`.

**3. [token de identidad web](https://docs.aws.amazon.com/sdkref/latest/guide/access-assume-role-web.html)**  
El SDK busca las variables `AWS_WEB_IDENTITY_TOKEN_FILE` de entorno `AWS_ROLE_ARN` (o las propiedades del sistema JVM `aws.webIdentityTokenFile` y`aws.roleArn`). En función de la información del token y de la función, el SDK adquiere credenciales temporales.

**4. [Un perfil en un archivo de configuración](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html)**  
En este paso, el SDK usa la configuración asociada a un perfil. De forma predeterminada, el SDK usa los `credentials` archivos AWS `config` y compartidos, pero si se establece la variable de `AWS_CONFIG_FILE` entorno, el SDK usa ese valor. Si la variable de `AWS_PROFILE` entorno (o la propiedad del sistema `aws.profile` JVM) *no* está configurada, el SDK busca el perfil «predeterminado»; de lo contrario, busca el perfil que coincida con el `AWS_PROFILE’s` valor.   
El SDK busca el perfil en función de la configuración descrita en el párrafo anterior y utiliza los ajustes allí definidos. Si la configuración que encuentra el SDK contiene una combinación de configuraciones para diferentes enfoques de proveedores de credenciales, el SDK usa el siguiente orden:  

1. [AWS claves de acceso (archivo de configuración)](https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html): el SDK usa la configuración de `aws_access_key_id``aws_access_key_id`, y. `aws_session_token`

1. [Asumir la configuración del rol](https://docs.aws.amazon.com/sdkref/latest/guide/access-assume-role.html): si el SDK encuentra `role_arn` una `credential_source` configuración `source_profile` o configuración, intenta asumir un rol. Si el SDK encuentra la `source_profile` configuración, obtiene las credenciales de otro perfil para recibir las credenciales temporales para el rol especificado por`role_arn`. Si el SDK encuentra la `credential_source` configuración, obtiene las credenciales de un contenedor de Amazon ECS, de una instancia de Amazon EC2 o de variables de entorno en función del valor de la `credential_source` configuración. A continuación, utiliza esas credenciales para adquirir credenciales temporales para el rol.

   Un perfil debe contener la `source_profile` configuración o la `credential_source` configuración, pero no ambas.

1. [Configuración del token de identidad web](https://docs.aws.amazon.com/sdkref/latest/guide/access-assume-role-web.html): si el SDK encuentra `role_arn` una `web_identity_token_file` configuración, adquiere credenciales temporales para acceder a AWS los recursos en función del token `role_arn` y del token.

1. [Configuración del token](https://docs.aws.amazon.com/sdkref/latest/guide/feature-sso-credentials.html) de inicio de sesión único: si el SDK encuentra `sso_session` una `sso_role_name` configuración (junto con una `sso-session` sección complementaria en los archivos de configuración), el SDK recupera las credenciales temporales del servicio del Centro de identidad de IAM. `sso_account_id`

1. [Configuración de SSO antigua](https://docs.aws.amazon.com/sdkref/latest/guide/feature-sso-credentials.html#sso-legacy): si el SDK encuentra` sso_start_url`, y `sso_role_name` ajustes `sso_region``sso_account_id`, el SDK recupera las credenciales temporales del servicio del Centro de Identidad de IAM.

1. [Configuración de inicio de sesión](https://docs.aws.amazon.com/sdkref/latest/guide/feature-sso-credentials.html#sso-legacy): si el SDK encuentra una `login_session` configuración, utiliza las credenciales temporales de la sesión de inicio de sesión o intenta actualizarlas si caducan en menos de 5 minutos. Para obtener información sobre cómo iniciar una sesión de inicio de sesión, consulte la [guía del usuario de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sign-in.html).

1. [Configuración del proceso](https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html): si el SDK encuentra una `credential_process` configuración, utiliza el valor de la ruta para invocar un proceso y adquirir credenciales temporales.

**5. [Credenciales de contenedor](https://docs.aws.amazon.com/sdkref/latest/guide/feature-container-credentials.html)**  
El SDK busca variables de entorno `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` o `AWS_CONTAINER_CREDENTIALS_FULL_URI` `AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE` o`AWS_CONTAINER_AUTHORIZATION_TOKEN`. Utiliza estos valores para cargar las credenciales desde el punto final HTTP especificado mediante una solicitud GET. 

**6. [Credenciales de IMDS](https://docs.aws.amazon.com/sdkref/latest/guide/feature-imds-credentials.html)**  
El SDK intenta obtener las credenciales del [servicio de metadatos de la instancia](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) en el punto final HTTP predeterminado o configurado. El SDK solo es compatible [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html).

Si las credenciales siguen sin resolverse en este momento, se produce un error en la creación del cliente, con una excepción.

**Nota: Cambio en el orden de resolución de las credenciales**  
La resolución sobre el orden de las credenciales descrita anteriormente es la vigente para la `1.4.x+` versión del SDK para Kotlin. Antes del `1.4.0` lanzamiento, los elementos número 3 y 4 se cambiaban y el elemento 4a actual siguió al elemento 4g actual.

## Especifique un proveedor de credenciales
<a name="explicit-credential-provider"></a>

Puede especificar un proveedor de credenciales en lugar de utilizar la cadena de proveedores predeterminada. Este enfoque te proporciona un control directo sobre las credenciales que utiliza el SDK.

Por ejemplo, para usar las credenciales de una función de IAM asumida, especifique una `StsAssumeRoleCredentialsProvider` al crear el cliente:

```
val ddb = DynamoDbClient {
    region = "us-east-1"
    credentialsProvider = StsAssumeRoleCredentialsProvider()
}
```

También puede crear una cadena personalizada (`CredentialsProviderChain`) que combine varios proveedores en el orden que prefiera.

### Guarde las credenciales en caché con un proveedor independiente
<a name="credentials-caching"></a>

**importante**  
La cadena predeterminada almacena en caché las credenciales automáticamente. Los proveedores independientes no almacenan en caché las credenciales. Para evitar tener que buscar credenciales en cada llamada a la API, incluye a tu proveedor con un. `CachedCredentialsProvider` El proveedor almacenado en caché obtiene las nuevas credenciales solo cuando caducan las actuales.

Para almacenar en caché las credenciales con un proveedor independiente, usa la clase: `CachedCredentialsProvider`

```
val ddb = DynamoDbClient {
     region = "us-east-1"
     credentialsProvider = CachedCredentialsProvider(StsAssumeRoleCredentialsProvider())
 }
```

 Como alternativa, utilice la función de `cached()` extensión para obtener un código más conciso:

```
val ddb = DynamoDbClient {
      region = "us-east-1"
      credentialsProvider = StsAssumeRoleCredentialsProvider().cached()
 }
```

# Configure los puntos finales del cliente
<a name="config-endpoint"></a>

Cuando AWS SDK para Kotlin llama a una Servicio de AWS, uno de sus primeros pasos es determinar dónde enrutar la solicitud. Este proceso se conoce como resolución de puntos de conexión.

Puede configurar la resolución de puntos finales para el SDK al crear un cliente de servicio. La configuración predeterminada para la resolución de puntos finales suele ser adecuada, pero hay varios motivos que pueden llevarle a modificar la configuración predeterminada. Dos motivos a modo de ejemplo son los siguientes:
+ Realice solicitudes a una versión preliminar de un servicio o a una implementación local de un servicio.
+ Acceda a funciones de servicio específicas que aún no están modeladas en el SDK.

**aviso**  
La resolución de puntos de conexión es un tema complejo del SDK. Si cambia la configuración predeterminada, corre el riesgo de invalidar el código. La configuración predeterminada debería aplicarse a la mayoría de los usuarios en entornos de producción.

## Configuración personalizada
<a name="config-endpoint-custom-config"></a>

Puede personalizar la resolución de punto final de un cliente de servicio con dos propiedades que están disponibles al crear el cliente:

1. `endpointUrl: Url`

1. `endpointProvider: EndpointProvider`

### Establezca `endpointUrl`
<a name="config-endpoint-custom-config-endpointurl"></a>

Puede establecer un valor para `endpointUrl` que indique un nombre de host “básico” para el servicio. Sin embargo, este valor no es definitivo, ya que se pasa como parámetro a la instancia `EndpointProvider` del cliente. Luego, la `EndpointProvider` implementación puede inspeccionar y, posiblemente, modificar ese valor para determinar el punto final. 

Por ejemplo, si especificas un `endpointUrl` valor para un cliente de Amazon Simple Storage Service (Amazon S3) y realizas `GetObject` una operación, la implementación del proveedor de puntos de conexión predeterminado inserta el nombre del bucket en el valor del nombre de host.

En la práctica, los usuarios establecen un `endpointUrl` valor para que apunte a una instancia de desarrollo o vista previa de un servicio.

### Establezca `endpointProvider`
<a name="config-endpoint-custom-config-endpointprovider"></a>

La `EndpointProvider` implementación de un cliente de servicio determina la resolución final del punto final. La `EndpointProvider` interfaz que se muestra en el siguiente bloque de código expone el `resolveEndpoint` método.

```
public fun interface EndpointProvider<T> {
    public suspend fun resolveEndpoint(params: T): Endpoint
}
```

Un cliente de servicio llama al `resolveEndpoint` método para cada solicitud. El cliente del servicio utiliza el `Endpoint` valor devuelto por el proveedor sin más cambios.

#### Propiedades de `EndpointProvider`
<a name="config-endpoint-custom-config-endpointprovider-params"></a>

El `resolveEndpoint` método acepta un `EndpointParameters` objeto específico del servicio que contiene las propiedades utilizadas en la resolución de puntos finales.

Cada servicio incluye las siguientes propiedades base.


****  

| Name | Tipo | Description (Descripción) | 
| --- | --- | --- | 
| region | Cadena | La AWS región del cliente | 
| endpoint | Cadena | Representación de cadena del conjunto de valores de endpointUrl. | 
| useFips | Booleano | Indica si los puntos de conexión de FIPS están habilitados en la configuración del cliente. | 
| useDualStack | Booleano | Indica si los puntos de conexión de doble pila están habilitados en la configuración del cliente. | 

Los servicios pueden especificar las propiedades adicionales necesarias para la resolución. Por ejemplo, Amazon S3 [https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/s3/aws.sdk.kotlin.services.s3.endpoints/-s3-endpoint-parameters/index.html](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/s3/aws.sdk.kotlin.services.s3.endpoints/-s3-endpoint-parameters/index.html)incluye el nombre del bucket y también varios ajustes de funciones específicos de Amazon S3. Por ejemplo, la propiedad `forcePathStyle` determina si se puede utilizar el direccionamiento de host virtual. 

Si implementas tu propio proveedor, no deberías necesitar crear tu propia instancia de. `EndpointParameters` El SDK proporciona las propiedades de cada solicitud y las pasa a su implementación de `resolveEndpoint`.

### `endpointUrl` o `endpointProvider`
<a name="config-endpoint-custom-config-which"></a>

Es importante entender que las dos afirmaciones siguientes NO producen clientes con un comportamiento de resolución de punto final equivalente:

```
// Use endpointUrl.
S3Client.fromEnvironment { 
    endpointUrl = Url.parse("https://endpoint.example")
}

// Use endpointProvider.
S3Client.fromEnvironment {
    endpointProvider = object : S3EndpointProvider {
        override suspend fun resolveEndpoint(params: S3EndpointParameters): Endpoint = Endpoint("https://endpoint.example")
    }
}
```

La sentencia que establece la `endpointUrl` propiedad especifica una URL *base* que se pasa al proveedor (predeterminado) y que se puede modificar como parte de la resolución del punto final. 

La declaración que establece el `endpointProvider` especifica la URL *final* que `S3Client` utilizará.

Aunque puede configurar ambas propiedades, en la mayoría de los casos en las que es necesario personalizarlas, debe proporcionar una de ellas. Como usuario general del SDK, lo más frecuente es que proporciones un `endpointUrl` valor.

### Nota acerca de Amazon S3
<a name="config-endpoint-custom-config-s3"></a>

Amazon S3 es un servicio complejo con muchas de sus características modeladas a través de personalizaciones de puntos de enlace personalizadas, como el alojamiento virtual por cubos. El alojamiento virtual es una función de Amazon S3 en la que el nombre del bucket se inserta en el nombre del host.

Por este motivo, le recomendamos que no sustituya la `EndpointProvider` implementación en un cliente de servicio Amazon S3. Si necesita ampliar su comportamiento de resolución, por ejemplo enviando solicitudes a una pila de desarrollo local teniendo en cuenta otros aspectos relacionados con los puntos finales, le recomendamos empaquetar la implementación predeterminada. El siguiente `endpointProvider` ejemplo muestra un ejemplo de implementación de este enfoque.

## Ejemplos
<a name="config-endpoint-examples"></a>

### `endpointUrl`Ejemplo de
<a name="config-endpoint-examples-endpointurl"></a>

El siguiente fragmento de código muestra cómo se puede anular el punto final de servicio general para un cliente de Amazon S3.

```
val client = S3Client.fromEnvironment {
    endpointUrl = Url.parse("https://custom-s3-endpoint.local")
    // EndpointProvider is left as the default.
}
```

### `endpointProvider`Ejemplo de
<a name="config-endpoint-examples-endpointprovider"></a>

En el siguiente fragmento de código se muestra cómo proporcionar un proveedor de puntos de conexión personalizado que incluya la implementación predeterminada de Amazon S3.

```
import aws.sdk.kotlin.services.s3.endpoints.DefaultS3EndpointProvider
import aws.sdk.kotlin.services.s3.endpoints.S3EndpointParameters
import aws.sdk.kotlin.services.s3.endpoints.S3EndpointProvider
import aws.smithy.kotlin.runtime.client.endpoints.Endpoint

public class CustomS3EndpointProvider : S3EndpointProvider {
    override suspend fun resolveEndpoint(params: S3EndpointParameters) =
        if (/* Input params indicate we must route another endpoint for whatever reason. */) {
            Endpoint(/* ... */)
        } else {
            // Fall back to the default resolution.
            DefaultS3EndpointProvider().resolveEndpoint(params)
        }
}
```

### `endpointUrl` y `endpointProvider`
<a name="config-endpoint-examples-both"></a>

El siguiente programa de ejemplo demuestra la interacción entre la `endpointUrl` configuración y. `endpointProvider` Este es un caso de uso avanzado.

```
import aws.sdk.kotlin.services.s3.S3Client
import aws.sdk.kotlin.services.s3.endpoints.DefaultS3EndpointProvider
import aws.sdk.kotlin.services.s3.endpoints.S3EndpointParameters
import aws.sdk.kotlin.services.s3.endpoints.S3EndpointProvider
import aws.smithy.kotlin.runtime.client.endpoints.Endpoint

fun main() = runBlocking {
    S3Client.fromEnvironment {
        endpointUrl = Url.parse("https://example.endpoint")
        endpointProvider = CustomS3EndpointProvider()
    }.use { s3 ->
        // ...
    }
}

class CustomS3EndpointProvider : S3EndpointProvider {
    override suspend fun resolveEndpoint(params: S3EndpointParameters) {
        // The resolved string value of the endpointUrl set in the client above is available here.
        println(params.endpoint) 
        // ...
    }
}
```

# HTTP
<a name="http"></a>

En esta sección se describe la configuración de los ajustes relacionados con HTTP en. AWS SDK para Kotlin

**Topics**
+ [Configuración del cliente HTTP](http-client-config.md)
+ [Usar un proxy HTTP](using-http-proxy.md)
+ [Interceptores HTTP](interceptors.md)
+ [Aplicar una versión mínima de TLS](configure-http-tls.md)

# Configuración del cliente HTTP
<a name="http-client-config"></a>

De forma predeterminada, AWS SDK para Kotlin utiliza un cliente HTTP basado en [OkHttp](https://square.github.io/okhttp). Puede anular el cliente HTTP y su configuración proporcionando un cliente configurado de forma explícita.

**aviso**  
Independientemente del motor HTTP que utilices, es posible que otras dependencias de tu proyecto tengan dependencias transitivas que entren en conflicto con la versión específica del motor que requiere el SDK. En concreto, se sabe que los marcos como Spring Boot administran las dependencias OkHttp y se basan en versiones anteriores al SDK. Consulte [¿Cómo resuelvo los conflictos de dependencia?](ts-faq-dep-conflict-resolution.md) para obtener más información.

**nota**  
De forma predeterminada, cada cliente de servicio usa su propia copia de un cliente HTTP. Si utiliza varios servicios en la aplicación, puede que desee crear un único cliente HTTP y compartirlo entre todos los clientes del servicio.

## Configuración básica
<a name="basic-http-confg"></a>

Al configurar un cliente de servicio, puede configurar el tipo de motor predeterminado. El SDK administra el motor de cliente HTTP resultante y lo cierra automáticamente cuando ya no es necesario.

El siguiente ejemplo muestra la configuración de un cliente HTTP durante la inicialización de un cliente de DynamoDB.

### Importaciones
<a name="basic-config-ex-imports"></a>

```
import aws.sdk.kotlin.services.dynamodb.DynamoDbClient
import kotlin.time.Duration.Companion.seconds
```

### Código
<a name="basic-config-ex-code"></a>

```
DynamoDbClient {
    region = "us-east-2"
    httpClient {
        maxConcurrency = 64u
        connectTimeout = 10.seconds
    }
}.use { ddb ->

    // Perform some actions with Amazon DynamoDB.
}
```

## Configuración avanzada
<a name="advanced-http-config"></a>

La configuración HTTP predeterminada es adecuada para la mayoría de los casos de uso. Para algunos casos de uso avanzados, como los entornos de alto rendimiento, las siguientes opciones de configuración avanzada ofrecen funciones y capacidades adicionales: 

### Especifique un tipo de motor HTTP
<a name="http-config-engine"></a>

Para especificar un tipo de motor HTTP no predeterminado o para personalizar la configuración específica de un tipo de motor HTTP concreto, puede pasar un parámetro adicional `httpClient` que especifique el tipo de motor. 

En el siguiente ejemplo, se especifica lo [https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine/index.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine/index.html)que se puede usar para configurar la [https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine-config/index.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine-config/index.html)propiedad.

#### Importaciones
<a name="http-config-specify-engine-imports"></a>

```
import aws.sdk.kotlin.services.dynamodb.DynamoDbClient
import aws.smithy.kotlin.runtime.http.engine.okhttp.OkHttpEngine
```

#### Código
<a name="http-config-specify-engine-code"></a>

```
DynamoDbClient {
    region = "us-east-2"
    httpClient(OkHttpEngine) {  // The first parameter specifies the HTTP engine type.
        // The following parameter is generic HTTP configuration available in any engine type.
        maxConcurrency = 64u

            // The following parameter is OkHttp-specific configuration.
        maxConcurrencyPerHost = 32u
    }
}.use { ddb ->

    // Perform some actions with Amazon DynamoDB.
}
```

Los valores posibles para el tipo de motor son `OkHttpEngine` [https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp4/aws.smithy.kotlin.runtime.http.engine.okhttp4/-ok-http4-engine/index.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp4/aws.smithy.kotlin.runtime.http.engine.okhttp4/-ok-http4-engine/index.html), y [https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-crt/aws.smithy.kotlin.runtime.http.engine.crt/-crt-http-engine/index.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-crt/aws.smithy.kotlin.runtime.http.engine.crt/-crt-http-engine/index.html). 

Para usar los parámetros de configuración específicos de un motor HTTP, debe agregar el motor como una dependencia en tiempo de compilación. Para ello`OkHttpEngine`, agrega la siguiente dependencia mediante Gradle.

(Puedes navegar hasta el *X.Y.Z* enlace para ver la última versión disponible).

```
implementation(platform("aws.smithy.kotlin:bom:[https://github.com/smithy-lang/smithy-kotlin/releases/latest](https://github.com/smithy-lang/smithy-kotlin/releases/latest)"))
implementation("aws.smithy.kotlin:http-client-engine-okhttp")
```

Para el`CrtHttpEngine`, añada la siguiente dependencia.

```
implementation(platform("aws.smithy.kotlin:bom:[https://github.com/smithy-lang/smithy-kotlin/releases/latest](https://github.com/smithy-lang/smithy-kotlin/releases/latest)"))
implementation("aws.smithy.kotlin:http-client-engine-crt")
```

#### Utilizar `OkHttp4Engine`
<a name="http-config-okhttp4engine"></a>

Use la opción predeterminada `OkHttp4Engine` si no puede usar la opción predeterminada`OkHttpEngine`. El [ GitHub repositorio smithy-kotlin](https://github.com/smithy-lang/smithy-kotlin/tree/main/runtime/protocol/http-client-engines/http-client-engine-okhttp4) tiene información sobre cómo configurar y usar el. `OkHttp4Engine`

#### Utilice un cliente HTTP explícito
<a name="http-client-explicit-usage"></a>

Cuando utilizas un cliente HTTP explícito, eres responsable de su vida útil, incluido el cierre cuando ya no lo necesites. Un cliente HTTP debe tener una vida útil como mínimo igual a la de cualquier cliente de servicio que lo utilice.

El siguiente ejemplo de código muestra el código que mantiene activo al cliente HTTP mientras `DynamoDbClient` está activo. La [https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.io/use.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.io/use.html)función se asegura de que el cliente HTTP se cierre correctamente.

##### Importaciones
<a name="http-client-explicit-usage-ex-imports"></a>

```
import aws.sdk.kotlin.services.dynamodb.DynamoDbClient
import aws.smithy.kotlin.runtime.http.engine.okhttp.OkHttpEngine
import kotlin.time.Duration.Companion.seconds
```

##### Código
<a name="http-client-explicit-usage-ex-code"></a>

```
OkHttpEngine {
    maxConcurrency = 64u
    connectTimeout = 10.seconds
}.use { okHttpClient ->

     DynamoDbClient {
        region = "us-east-2"
        httpClient = okHttpClient
    }.use { ddb ->
        {
            // Perform some actions with Amazon DynamoDB.
        }
    }
}
```

### Supervisión de conexiones inactivas
<a name="http-idle-connection-monitoring"></a>

**importante**  
 La función de sondeo en vacío de la conexión del OkHttp motor ([https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine-config/connection-idle-polling-interval.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine-config/connection-idle-polling-interval.html)) ha sido sustituida por reintentos automáticos de conexión fallidos (). [https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine-config/retry-on-connection-failure.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine-config/retry-on-connection-failure.html) **El sondeo de conexiones inactivas quedará **obsoleto** en la versión **1.7** del SDK y se **eliminará** en la versión 1.8 del SDK.** Consulte [la publicación de GitHub debate relacionada](https://github.com/aws/aws-sdk-kotlin/discussions/1797) para obtener más información. 

[https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine/](https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine/)proporciona la opción [https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine-config/connection-idle-polling-interval.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/http-client-engine-okhttp/aws.smithy.kotlin.runtime.http.engine.okhttp/-ok-http-engine-config/connection-idle-polling-interval.html)de configuración para monitorear las conexiones inactivas para su cierre remoto. Esta función detecta cuando los servicios tienen conexiones cerradas que aún se encuentran en el grupo de conexiones, lo que evita errores en las solicitudes posteriores. 

Cuando `connectionIdlePollingInterval` se establece en un valor no nulo, el motor sondea las conexiones que se devuelven al conjunto de conexiones. El proceso de sondeo bloquea las lecturas con el tiempo de espera del socket establecido en el intervalo especificado. El sondeo se cancela automáticamente cuando el motor adquiere la conexión del grupo o cuando la conexión se desaloja y se cierra. 

Si este valor es `null` (el predeterminado), el sondeo se desactiva. Las conexiones inactivas del grupo que se cierran de forma remota pueden producir errores cuando se adquieren para llamadas posteriores.

**nota**  
 Como el ciclo de sondeo utiliza lecturas bloqueantes, las llamadas del motor para adquirir o cerrar una conexión pueden demorarse tanto como el `connectionIdlePollingInterval` intervalo. Si se elige un valor bajo para el intervalo, el SDK adquirirá las conexiones más rápido, a costa de un mayor uso de los recursos inactivos. 

#### Importaciones
<a name="http-idle-connection-ex-imports"></a>

```
import aws.sdk.kotlin.services.s3.S3Client
import aws.smithy.kotlin.runtime.http.engine.okhttp.OkHttpEngine
import kotlin.time.Duration.Companion.milliseconds
```

#### Código
<a name="http-idle-connection-ex-code"></a>

```
S3Client.fromEnvironment {
    httpEngine(OkHttpEngine) {
        connectionIdlePollingInterval = 50.milliseconds
    }
}.use { s3 -> 
  // Use the Amazon S3 client
}
```

# Usar un proxy HTTP
<a name="using-http-proxy"></a>

Para acceder a AWS través de servidores proxy mediante el AWS SDK para Kotlin, puede configurar las propiedades del sistema JVM o las variables de entorno. Si se proporcionan ambas, las propiedades del sistema JVM tienen prioridad.

## Uso de las propiedades del sistema JVM
<a name="http-proxy-jvm-properties"></a>

El SDK busca las propiedades del sistema JVM `https.proxyHost` y`https.proxyPort`. `http.nonProxyHosts` Para obtener más información sobre estas propiedades comunes del sistema JVM, consulte [Redes y proxies](https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html) en la documentación de Java.

```
java -Dhttps.proxyHost=10.15.20.25 -Dhttps.proxyPort=1234 -Dhttp.nonProxyHosts=localhost|api.example.com MyApplication
```

## Utilización de variables de entorno
<a name="http-proxy-environment-variables"></a>

El SDK busca las variables `https_proxy``http_proxy`, y de `no_proxy` entorno (y las versiones en mayúsculas de cada una de ellas).

```
export http_proxy=http://10.15.20.25:1234
export https_proxy=http://10.15.20.25:5678
export no_proxy=localhost,api.example.com
```

## Utilice un proxy en las instancias de EC2
<a name="http-proxy-ec2"></a>

[Si configura un proxy en una instancia EC2 lanzada con una función de IAM asociada, asegúrese de eximir la dirección que se utiliza para acceder a los metadatos de la instancia.](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) Para ello, defina la propiedad del sistema `http.nonProxyHosts` JVM o la variable de `no_proxy` entorno en la dirección IP del servicio de metadatos de la instancia, que es. `169.254.169.254` Esta dirección no varía.

```
export no_proxy=169.254.169.254
```

# Interceptores HTTP
<a name="interceptors"></a>

Puede usar interceptores para conectarse a la ejecución de las solicitudes y respuestas de API. Los interceptores son mecanismos abiertos en los que el SDK invoca el código que se escribe para introducir un comportamiento en el ciclo de vida. request/response De esta forma puede modificar una solicitud en tránsito, depurar el procesamiento de las solicitudes, ver las excepciones y mucho más. 

El siguiente ejemplo muestra un interceptor simple que agrega un encabezado adicional a todas las solicitudes salientes antes de entrar en el bucle de reintentos.

```
class AddHeader(
    private val key: String,
    private val value: String
) : HttpInterceptor {
    override suspend fun modifyBeforeRetryLoop(context: ProtocolRequestInterceptorContext<Any, HttpRequest>): HttpRequest {
        val httpReqBuilder = context.protocolRequest.toBuilder()
        httpReqBuilder.headers[key] = value
        return httpReqBuilder.build()
    }
}
```

[Para obtener más información y los ganchos de intercepción disponibles, consulte la interfaz Interceptor.](https://docs.aws.amazon.com/smithy-kotlin/api/latest/smithy-client/aws.smithy.kotlin.runtime.client/-interceptor/index.html)

## Registro de interceptores
<a name="interceptor-registration"></a>

Los interceptores se registran cuando se crea un cliente de servicio o cuando se anula la configuración de un conjunto específico de operaciones.

### Interceptor para todas las operaciones del cliente de servicio
<a name="interceptor-all-ops"></a>

El siguiente código añade una `AddHeader` instancia a la propiedad de interceptores del generador. Esta adición añade el `x-foo-version` encabezado a todas las operaciones antes de entrar en el bucle de reintento.

```
val s3 = S3Client.fromEnvironment {
    interceptors += AddHeader("x-foo-version", "1.0")
}

// All service operations invoked using 's3' will have the header appended.
s3.listBuckets { ... }
s3.listObjectsV2 { ... }
```

### Interceptor solo para operaciones específicas
<a name="interceptor-specific-ops"></a>

Al utilizar la `withConfig` extensión, puede [anular la configuración del cliente de servicio](override-client-config.md) para una o más operaciones de cualquier cliente de servicio. Con esta capacidad, puede registrar interceptores adicionales para un subconjunto de operaciones. 

El siguiente ejemplo anula la configuración de la `s3` instancia para las operaciones dentro de la extensión. `use` Las operaciones ejecutadas `s3Scoped` contienen tanto los encabezados como `x-foo-version` los `x-bar-version` encabezados.

```
// 's3' instance created in the previous code snippet.
s3.withConfig {
    interceptors += AddHeader("x-bar-version", "3.7")
}.use { s3Scoped ->
    // All service operations invoked using 's3Scoped' trigger interceptors
    // that were registered when the client was created and any added in the
    // withConfig { ... } extension.
}
```

# Aplicar una versión mínima de TLS
<a name="configure-http-tls"></a>

Con el AWS SDK para Kotlin, puede configurar la versión mínima de TLS cuando se conecte a los puntos finales del servicio. El SDK ofrece diferentes opciones de configuración. En orden de mayor a menor prioridad, las opciones son:
+ Configure explícitamente el motor HTTP
+ Establezca la propiedad del sistema `sdk.minTls` JVM
+ Defina la variable de `SDK_MIN_TLS` entorno

## Configure el motor HTTP
<a name="configure-http-tls-engine"></a>

Al especificar un motor HTTP no predeterminado para un cliente de servicio, puede configurar el `tlsContext.minVersion` campo.

El siguiente ejemplo configura el motor HTTP y cualquier cliente de servicio que lo utilice para que utilicen TLS v1.2 como mínimo.

```
DynamoDbClient {
    region = "us-east-2"
    httpClient {
        tlsContext {
            minVersion = TlsVersion.TLS_1_2
        }
    }
}.use { ddb ->

    // Perform some actions with Amazon DynamoDB.
}
```

## Establezca la propiedad del `sdk.minTls` sistema JVM
<a name="configure-http-tls-sysprop"></a>

Puede establecer la propiedad del sistema `sdk.minTls` JVM. Al lanzar una aplicación con las propiedades del sistema establecidas, todos los motores HTTP creados con ella AWS SDK para Kotlin utilizan la versión mínima de TLS especificada de forma predeterminada. Sin embargo, puede anular esto de forma explícita en la configuración del motor HTTP. Los valores permitidos son:
+ TLS\$11\$10
+ TLS\$11\$11
+ TLS\$11\$12
+ TLS\$11\$13

## Defina la variable de entorno `SDK_MIN_TLS`
<a name="configure-http-tls-envvar"></a>

Puede configurar la variable de `SDK_MIN_TLS` entorno. Al lanzar una aplicación con la variable de entorno configurada, todos los motores HTTP creados con ella AWS SDK para Kotlin utilizan la versión mínima de TLS especificada, a menos que se sustituya por otra opción.

Los valores permitidos son:
+ TLS\$11\$10
+ TLS\$11\$11
+ TLS\$11\$12
+ TLS\$11\$13

# Se vuelve a intentar en AWS SDK para Kotlin
<a name="retries"></a>

Las llamadas devuelven Servicios de AWS ocasionalmente excepciones inesperadas. Pueden producirse determinados tipos errores, como la limitación o errores temporales, si se vuelve a intentar la llamada.

En esta página, se describe cómo AWS SDK para Kotlin gestiona los reintentos automáticamente y cómo personalizar el comportamiento de los reintentos de las aplicaciones.

## Comprender el comportamiento de los reintentos
<a name="retries-understanding"></a>

En las siguientes secciones, se explica cómo el SDK determina cuándo reintentar las solicitudes y qué excepciones se consideran reintentables.

### Configuración de reintento predeterminada
<a name="retries-default"></a>

De forma predeterminada, cada cliente de servicio se configura automáticamente con una estrategia de reintento [estándar](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries/-standard-retry-strategy/index.html). La configuración predeterminada intenta realizar una llamada que falla hasta tres veces (el intento inicial más dos reintentos). El retardo intermedio entre cada llamada se configura con un retardo exponencial y una fluctuación aleatoria para evitar tormentas de reintentos. Esta configuración funciona en la mayoría de los casos de uso, pero puede no ser adecuada en algunas circunstancias, como en los sistemas de alto rendimiento.

El SDK solo intenta volver a intentarlo cuando hay errores que se puedan volver a intentar. Algunos ejemplos de errores reintentables son los tiempos de espera de socket, la limitación de servicio, los errores de bloqueo positivo o simultáneo y los errores de servicio transitorios. Los parámetros faltantes o no válidos, los authentication/security errores y las excepciones de configuración incorrectas no se consideran reintentables.

Puede personalizar la estrategia de reintentos estándar estableciendo el número máximo de intentos, los retrasos y los retrasos, así como la configuración del conjunto de fichas.

### ¿Qué excepciones se pueden volver a intentar?
<a name="retries-default-policy-details"></a>

 AWS SDK para Kotlin Utiliza una política de reintentos preconfigurada que determina qué excepciones se pueden volver a intentar. La configuración del cliente de servicio tiene una `retryPolicy` propiedad que especifica la política que se aplica a los reintentos. Si no se especifica ningún valor personalizado, el valor predeterminado es [AwsRetryPolicy](https://docs.aws.amazon.com/sdk-for-kotlin/api/latest/aws-http/aws.sdk.kotlin.runtime.http.retries/-aws-retry-policy/).

Se determina que las siguientes excepciones se pueden volver a intentar mediante: `AwsRetryPolicy`

#### Se puede volver a intentar mediante código de error
<a name="retries-retryable-by-error-code"></a>

Cualquiera `ServiceException` con uno de los siguientes valores`sdkErrorMetadata.errorCode`:
+ `BandwidthLimitExceeded`
+ `EC2ThrottledException`
+ `IDPCommunicationError`
+ `LimitExceededException`
+ `PriorRequestNotComplete`
+ `ProvisionedThroughputExceededException`
+ `RequestLimitExceeded`
+ `RequestThrottled`
+ `RequestThrottledException`
+ `RequestTimeout`
+ `RequestTimeoutException`
+ `SlowDown`
+ `ThrottledException`
+ `Throttling`
+ `ThrottlingException`
+ `TooManyRequestsException`
+ `TransactionInProgressException`

#### Se puede volver a intentar mediante el código de estado HTTP
<a name="retries-retryable-by-status-code"></a>

Cualquiera `ServiceException` con uno de los siguientes valores`sdkErrorMetadata.statusCode`:
+ 500 (error de servicio interno)
+ 502 (puerta de enlace defectuosa)
+ 503 (servicio no disponible)
+ 504 (tiempo de espera de la puerta de enlace)

#### Se puede volver a intentar por tipo de error
<a name="retries-retryable-by-error-type"></a>

Cualquiera `ServiceException` con uno de los siguientes valores`sdkErrorMetadata.errorType`:
+ `ErrorType.Server`(como errores de servicio interno)
+ `ErrorType.Client`(como una solicitud no válida, un recurso no encontrado, acceso denegado, etc.)

#### Se puede volver a intentar mediante metadatos del SDK
<a name="retries-retryable-by-metadata"></a>

En cualquier lugar`SdkBaseException`:
+ `sdkErrorMetadata.isRetryable`es `true` (como un tiempo de espera del lado del cliente, un networking/socket error, etc.)
+ `sdkErrorMetadata.isThrottling`es `true` (por ejemplo, hacer demasiadas solicitudes en poco tiempo)

Para obtener una lista completa de las excepciones que puede introducir cada cliente de servicio, consulta la documentación de [referencia de la API específica del servicio](https://docs.aws.amazon.com/#products).

### Comprueba si una excepción se puede volver a intentar
<a name="retries-check-exception-retryable"></a>

Para determinar si el SDK considera que una excepción se puede volver a intentar, comprueba la propiedad de las excepciones detectadas: `isRetryable`

```
try {
    dynamoDbClient.putItem {
        tableName = "MyTable"
        item = mapOf("id" to AttributeValue.S("123"))
    }
} catch (e: SdkBaseException) {
    println("Exception occurred: ${e.message}")
    
    if (e.sdkErrorMetadata.isRetryable) {
        println("This exception is retryable - SDK will automatically retry")
        println("If you're seeing this, retries may have been exhausted")
    } else {
        println("This exception is not retryable - fix the underlying issue")
        
        // Common non-retryable scenarios.
        when {
            e.message?.contains("ValidationException") == true -> 
                println("Check your request parameters")
            e.message?.contains("AccessDenied") == true -> 
                println("Check your IAM permissions")
            e.message?.contains("ResourceNotFound") == true -> 
                println("Verify the resource exists")
        }
    }
}
```

### ¿Qué excepciones llegan a tu código cuando los reintentos fallan
<a name="retries-exception-types-during-retries"></a>

Cuando el mecanismo de reintento del SDK no puede resolver un problema, se añaden excepciones al código de la aplicación. Comprender estos tipos de excepciones te ayuda a implementar una gestión de errores adecuada. Estas *no* son las excepciones que desencadenan las recuperaciones, sino que las gestiona internamente el SDK.

Su código detectará los siguientes tipos de excepciones cuando se agoten o deshabiliten los reintentos:

Excepciones de servicio tras el agotamiento de los reintentos  
Cuando todos los reintentos fallan, el código detecta la última excepción de servicio (subclase de`AwsServiceException`) que provocó el error del último reintento. Podría tratarse de un error de limitación, un error del servidor u otra excepción específica del servicio que el SDK no pudo resolver mediante reintentos.

Excepciones de red tras agotarse los reintentos  
Cuando los problemas de red persisten tras todos los intentos, el código detecta las `ClientException` instancias para detectar problemas como los tiempos de espera de la conexión, los fallos de resolución del DNS y otros problemas de conectividad que el SDK no ha podido resolver.

Usa el siguiente patrón para gestionar estas excepciones en tu aplicación:

```
try {
    s3Client.getObject { 
        bucket = "amzn-s3-demo-bucket"
        key = "my-key" 
    }
} catch (e: AwsServiceException) {
    // Service-side errors that persisted through all retries.
    println("Service error after retries: ${e.errorDetails?.errorCode} - ${e.message}")
    
    // Handle specific service errors that couldn't be resolved.
    if (e.errorDetails?.errorCode == "ServiceQuotaExceededException" || 
        e.errorDetails?.errorCode == "ThrottlingException") {
        println("Rate limiting persisted - consider longer delays or quota increase")
    }
} catch (e: ClientException) {
    // Client-side errors (persistent network issues, DNS resolution failures, etc.)
    println("Client error after retries: ${e.message}")
}
```

## Personalización del comportamiento de los reintentos
<a name="retries-customizing"></a>

En las siguientes secciones, se muestra cómo personalizar el comportamiento de reintentos del SDK para cada caso de uso específico.

### Configura el número máximo de intentos
<a name="retires-max-attempts"></a>

Puede personalizar el número máximo de intentos predeterminado (3) en el [bloque `retryStrategy` DSL](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries/-standard-retry-strategy/-config/-builder/index.html) durante la construcción del cliente.

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        maxAttempts = 5
    }
}
```

Con el cliente del servicio DynamoDB mostrado en el fragmento anterior, el SDK intenta realizar llamadas a la API que fallan hasta cinco veces (el intento inicial más cuatro reintentos).

Para deshabilitar completamente los reintentos automáticos, establezca el número máximo de intentos en uno, como se muestra en el siguiente fragmento.

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        maxAttempts = 1  // The SDK makes no retries.
    }
}
```

### Configure los retrasos y los retrasos
<a name="retries-delays-backoff"></a>

Si es necesario un reintento, la estrategia de reintento predeterminada espera antes de realizar el siguiente intento. El retraso del primer reintento es pequeño, pero aumenta de manera exponencial en los reintentos posteriores. La cantidad máxima de retraso está limitada para que no aumente demasiado. 

Por último, se aplica una fluctuación aleatoria a los retrasos entre todos los intentos. La fluctuación ayuda a mitigar el efecto de las grandes flotas, que pueden provocar avalanchas de reintentos. (Consulte esta entrada del [blog de AWS arquitectura](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) para obtener un análisis más profundo sobre el retroceso y la fluctuación exponenciales).

[Los parámetros de retardo se pueden configurar en el bloque DSL`delayProvider`.](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries.delay/-exponential-backoff-with-jitter/-config/index.html)

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        delayProvider {
            initialDelay = 100.milliseconds
            maxBackoff = 5.seconds
        }
    }
}
```

Con la configuración que se muestra en el fragmento anterior, el cliente retrasa el primer intento hasta 100 milisegundos. El tiempo máximo entre un reintento es de 5 segundos.

Están disponibles los siguientes parámetros para los retrasos y el retardo del ajuste.


| Parámetro | Predeterminado | Description (Descripción) | 
| --- | --- | --- | 
| initialDelay | 10 milisegundos | La cantidad máxima de retraso para el primer reintento. Cuando se aplica una fluctuación de fase, la cantidad real de retraso puede ser menor. | 
| jitter | 1.0 (fluctuación total) |  La amplitud máxima con la que se puede reducir aleatoriamente el retraso calculado. El valor predeterminado de 1,0 significa que el retraso calculado se puede reducir a cualquier cantidad, hasta el 100% (por ejemplo, hasta 0). Un valor de 0,5 significa que el retraso calculado se puede reducir hasta la mitad. Por lo tanto, un retraso máximo de 10 ms podría reducirse a entre 5 ms y 10 ms. Un valor de 0.0 significa que no se aplica ninguna fluctuación.  ️ La configuración de fluctuación es una función avanzada. Normalmente no se recomienda personalizar este comportamiento.   | 
| maxBackoff | 20 segundos | La cantidad máxima de demora que se puede aplicar a cualquier intento. Si se establece este valor, se limita el crecimiento exponencial que se produce entre los intentos posteriores y se evita que el máximo calculado sea demasiado grande. Este parámetro limita el retraso calculado antes de que se aplique la fluctuación de fase. Si se aplica, la fluctuación podría reducir aún más el retraso. | 
| scaleFactor | 1.5 | La base exponencial a partir de la cual se incrementarán los retardos máximos subsiguientes. Por ejemplo, si uno es `initialDelay` de 10 ms y uno `scaleFactor` de 1,5, se calcularían los siguientes retrasos máximos:[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/sdk-for-kotlin/latest/developer-guide/retries.html)Cuando se aplica una fluctuación, la cantidad real de cada retraso puede ser menor. | 

### Configure el depósito de fichas de reintento
<a name="retries-token-bucket"></a>

Puede modificar aún más el comportamiento de la estrategia de reintentos estándar ajustando la configuración predeterminada del depósito de fichas. El conjunto de fichas de reintentos ayuda a reducir los reintentos que tienen menos probabilidades de éxito o que pueden tardar más tiempo en resolverse, como los errores de tiempo de espera o de aceleración.

**importante**  
La configuración del depósito de fichas es una función avanzada. Por lo general, no se recomienda personalizar este comportamiento.

Cada reintento (incluido opcionalmente el intento inicial) reduce parte de la capacidad del depósito de fichas. La cantidad disminuida depende del tipo de intento. Por ejemplo, volver a intentar los errores transitorios puede resultar económico, pero volver a intentarlo cuando se agota el tiempo de espera o se reduce el tiempo de espera puede resultar más caro. 

Si el intento se realiza correctamente, se devuelve la capacidad al depósito. El depósito no puede incrementarse más allá de su capacidad máxima ni reducirse por debajo de cero. 

Según el valor de la `useCircuitBreakerMode` configuración, los intentos de reducir la capacidad por debajo de cero dan como resultado uno de los siguientes resultados:
+ Si la configuración es TRUE, se produce una excepción: por ejemplo, si se han realizado demasiados reintentos y es poco probable que se logren más reintentos.
+ Si el valor es FALSO, se produce un retraso, por ejemplo, hasta que el depósito vuelva a tener suficiente capacidad.

**nota**  
Cuando se activa el disyuntor (el depósito de fichas alcanza su capacidad cero), el SDK muestra un mensaje `ClientException` con el mensaje «Se ha superado la capacidad de reintento». Se trata de una excepción del lado del cliente, no de una excepción`AwsServiceException`, porque se origina en la lógica de reintentos del SDK y no en el servicio. AWS La excepción se produce inmediatamente sin intentar realizar la operación, lo que ayuda a evitar que se repitan los intentos durante las interrupciones del servicio.

Los parámetros del depósito de fichas se pueden configurar en el bloque [`tokenBucket`DSL](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries.delay/-standard-retry-token-bucket/-config/index.html):

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy {
        tokenBucket {
            maxCapacity = 100
            refillUnitsPerSecond = 2
        }
    }
}
```

Están disponibles los siguientes parámetros para ajustar el grupo de reintentos:


| Parámetro | Predeterminado | Description (Descripción) | 
| --- | --- | --- | 
| initialTryCost | 0 | La cantidad que se va a reducir con respecto a la cubeta en los intentos iniciales. El valor predeterminado de 0 significa que no se reducirá la capacidad y, por lo tanto, los intentos iniciales no se detendrán ni retrasarán. | 
| initialTrySuccessIncrement | 1 | La cantidad necesaria para incrementar la capacidad cuando el intento inicial se realizó correctamente. | 
| maxCapacity | 500 | La capacidad máxima del depósito de fichas. El número de fichas disponibles no puede superar este número. | 
| refillUnitsPerSecond | 0 | La cantidad de capacidad que se vuelve a añadir al depósito cada segundo. Un valor de 0 significa que no se vuelve a añadir capacidad automáticamente. (Por ejemplo, solo los intentos exitosos dan como resultado un aumento de la capacidad). Un valor de 0 debe useCircuitBreakerMode ser VERDADERO. | 
| retryCost | 5 | La cantidad que se debe reducir de la cubeta en caso de un intento tras un error transitorio. La misma cantidad se vuelve a acumular en el depósito si el intento tiene éxito. | 
| timeoutRetryCost | 10 | La cantidad que se deduce de la cubeta para un intento tras un fallo en el tiempo de espera o en la aceleración. La misma cantidad se vuelve a acumular en el depósito si el intento tiene éxito. | 
| useCircuitBreakerMode | TRUE | Determina el comportamiento en caso de que un intento de reducir la capacidad del depósito caiga por debajo de cero. Si el valor es TRUE, el depósito de fichas generará una excepción que indicará que no existe más capacidad de reintentos. Si el valor es FALSO, el depósito de fichas retrasará el intento hasta que se haya rellenado la capacidad suficiente. | 

Para obtener información detallada sobre los tipos de excepciones que se producen durante los escenarios de reintento, incluidas las excepciones a los disyuntores, consulte. [¿Qué excepciones llegan a tu código cuando los reintentos fallan](#retries-exception-types-during-retries)

### Configure los reintentos adaptativos
<a name="retries-adaptive-retries"></a>

Como alternativa a la estrategia de reintentos estándar, la estrategia de reintentos adaptativa es un enfoque avanzado que busca la tasa de solicitudes ideal para minimizar los errores de limitación.

**importante**  
Los reintentos adaptables son un modo de reintento avanzado. Por lo general, no se recomienda utilizar esta estrategia de reintentos.

Los reintentos flexibles incluyen todas las características de los reintentos estándar. Incorpora un limitador de velocidad en el cliente que mide la tasa de solicitudes limitadas en comparación con las no limitadas. También limita el tráfico para intentar mantenerse dentro de un ancho de banda seguro, lo que idealmente provoca cero errores de limitación.

La velocidad se adapta en tiempo real a las condiciones cambiantes del servicio y a los patrones de tráfico, y es posible que aumente o disminuya la velocidad del tráfico en consonancia. Es importante destacar que el limitador de velocidad puede retrasar los intentos iniciales en situaciones de mucho tráfico.

La estrategia de reintento adaptativo se selecciona proporcionando un parámetro adicional al `retryStrategy` método. Los parámetros del limitador de velocidad se pueden configurar en el bloque [`rateLimiter`DSL](https://docs.aws.amazon.com/smithy-kotlin/api/latest/runtime-core/aws.smithy.kotlin.runtime.retries.delay/-adaptive-rate-limiter/-config/index.html).

```
val dynamoDb = DynamoDbClient.fromEnvironment {
    retryStrategy(AdaptiveRetryStrategy) {
        maxAttempts = 10
        rateLimiter {
            minFillRate = 1.0
            smoothing = 0.75
        }
    }
}
```

**nota**  
La estrategia de reintento adaptativa implica que el cliente trabaja con un único recurso (por ejemplo, una tabla de DynamoDB o un bucket de Amazon S3).   
Si utiliza un solo cliente para varios recursos, la limitación o las interrupciones asociadas a un recurso provocan un aumento de la latencia y los errores cuando el cliente accede a todos los demás recursos. Cuando utiliza la estrategia de reintento adaptativa es recomendable utilizar un único cliente para cada recurso.

# Observabilidad
<a name="observability"></a>

La observabilidad es la medida en que se puede deducir el estado actual de un sistema a partir de los datos que emite. Los datos emitidos se denominan comúnmente “telemetría”.

 AWS SDK para Kotlin Pueden proporcionar las tres señales telemétricas más comunes: métricas, trazas y registros. Puedes configurar un cable [https://docs.aws.amazon.com/smithy-kotlin/api/latest/telemetry-api/aws.smithy.kotlin.runtime.telemetry/-telemetry-provider/index.html](https://docs.aws.amazon.com/smithy-kotlin/api/latest/telemetry-api/aws.smithy.kotlin.runtime.telemetry/-telemetry-provider/index.html)para enviar datos de telemetría a un backend de observabilidad (como [AWS X-Ray](https://docs.aws.amazon.com/xray/?icmpid=docs_homepage_devtools)[Amazon CloudWatch](https://docs.aws.amazon.com/cloudwatch/?icmpid=docs_homepage_mgmtgov)) y luego actuar en consecuencia.

De forma predeterminada, solo el registro está habilitado y otras señales de telemetría están deshabilitadas en el SDK. En este tema se explica cómo habilitar y configurar la salida de telemetría.

**importante**  
`TelemetryProvider`actualmente es una API experimental que debe estar habilitada para su uso.

## Configuración de un `TelemetryProvider`
<a name="observability-conf-telemetry-provider"></a>

Puede configurar una `TelemetryProvider` en su aplicación de forma global para todos los clientes de servicio o para clientes individuales. Los siguientes ejemplos utilizan una `getConfiguredProvider()` función hipotética para demostrar las operaciones de la `TelemetryProvider` API. [Proveedores de telemetría](observability-telemetry-providers.md)En la sección se describe la información de las implementaciones proporcionada por el SDK. Si un proveedor no es compatible, puedes implementar tu propio soporte o [abrir una solicitud de funcionalidad en GitHub](https://github.com/awslabs/aws-sdk-kotlin/issues/new/choose).

### Configuración del proveedor de telemetría global predeterminado
<a name="observability-conf-telemetry-provider-global"></a>

De forma predeterminada, todos los clientes del servicio intentan utilizar el proveedor de telemetría disponible en todo el mundo. De esta forma, puede configurar el proveedor una vez y todos los clientes lo utilizarán. Esto debe hacerse solo una vez, antes de crear una instancia de cualquier cliente de servicio.

Para usar el proveedor de telemetría global, primero actualiza las dependencias del proyecto para agregar el módulo de telemetría predeterminado, como se muestra en el siguiente fragmento de código de Gradle.

(Puedes navegar hasta el enlace para ver la *X.Y.Z* última versión disponible).

```
dependencies {
    implementation(platform("aws.smithy.kotlin:bom:[https://github.com/smithy-lang/smithy-kotlin/releases/latest](https://github.com/smithy-lang/smithy-kotlin/releases/latest)"))
    implementation("aws.smithy.kotlin:telemetry-defaults")
    ...
}
```

A continuación, configure el proveedor de telemetría global antes de crear un cliente de servicio, como se muestra en el siguiente código.

```
import aws.sdk.kotlin.services.s3.S3Client
import aws.smithy.kotlin.runtime.telemetry.GlobalTelemetryProvider
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val myTelemetryProvider = getConfiguredProvider()
    GlobalTelemetryProvider.set(myTelemetryProvider)

    S3Client.fromEnvironment().use { s3 ->
        …
    }     
}

fun getConfiguredProvider(): TelemetryProvider {
    TODO("TODO - configure a provider")
}
```

### Configuración de un proveedor de telemetría para un cliente de servicio específico
<a name="observability-conf-telemetry-provider-client"></a>

Puede configurar un cliente de servicio individual con un proveedor de telemetría específico (distinto del global). Esto se muestra en el siguiente ejemplo.

```
import aws.sdk.kotlin.services.s3.S3Client
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    S3Client.fromEnvironment{
        telemetryProvider = getConfiguredProvider()
    }.use { s3 ->
        ...
    }
}

fun getConfiguredProvider(): TelemetryProvider {
    TODO("TODO - configure a provider")
}
```

# Métricas
<a name="observability-telemetry-metrics"></a>

En la siguiente tabla, se enumeran las métricas de telemetría que el SDK emite. [Configure un proveedor de telemetría](observability.md#observability-conf-telemetry-provider) para que las métricas sean observables.


**¿Qué métricas se emiten?**  

| Nombre de métrica | Unidades | Tipo | Atributos | Description (Descripción) | 
| --- | --- | --- | --- | --- | 
| smithy.client.call.duration | s | Histograma | rpc.service, rpc.method | Duración total de la llamada (incluidos los reintentos) | 
| smithy.client.call.attempts | \$1attempt\$1 | MonotonicCounter | rpc.service, rpc.method | Número de intentos para una operación individual | 
| smithy.client.call.errors | \$1error\$1 | MonotonicCounter | rpc.service, rpc.method, exception.type | Número de errores de una operación | 
| smithy.client.call.attempt t\$1duration | s | Histograma | rpc.service, rpc.method | Tiempo que se tarda en establecer la conexión con el servicio, enviar la solicitud y recuperar el código de estado HTTP y los encabezados (incluido el tiempo en cola esperando el envío) | 
| smithy.client.call.resolve\$1endpoint\$1duration | s | Histograma | rpc.service, rpc.method | Tiempo que se tarda en resolver un punto de conexión (el solucionador de puntos de conexión, no el DNS) de la solicitud | 
| smithy.client.call.serialization\$1duration | s | Histograma | rpc.service, rpc.method | Tiempo que se tarda en serializar el cuerpo de un mensaje | 
| smithy.client.call.deserialization\$1duration | s | Histograma | rpc.service, rpc.method | Tiempo que se tarda en deserializar el cuerpo de un mensaje | 
| smithy.client.call.auth.signing\$1duration | s | Histograma | rpc.service, rpc.method, auth.scheme\$1id | Tiempo que lleva firmar la solicitud HTTP | 
| smithy.client.call.auth.resolve\$1identity\$1duration | s | Histograma | rpc.service, rpc.method, auth.scheme\$1id | El tiempo que se tarda en adquirir una identidad (como AWS credenciales o un token portador) de un proveedor de identidades | 
| smithy.client.http.connections.acquire\$1duration | s | Histograma |  | El tiempo que tarda una solicitud en adquirir una conexión | 
| smithy.client.http.connections.limit | \$1conexión\$1 | [Asincrónico] UpDownCounter |  | El número máximo de conexiones abiertas allowed/configured para el cliente HTTP | 
| smithy.client.http.connections.usage | \$1conexión\$1 | [Asincrónico] UpDownCounter | estado: inactivo \$1 adquirido | Estado actual del pool de conexiones | 
| smithy.client.http.connections.uptime | s | Histograma |  | El tiempo que ha estado abierta una conexión | 
| smithy.client.http.requests.usage | \$1solicitud\$1 | [Asincrónico] UpDownCounter | estado: en cola \$1 en vuelo | El estado actual de la concurrencia de solicitudes de clientes HTTP | 
| smithy.client.http.requests.queued\$1duration | s | Histograma |  | La cantidad de tiempo que una solicitud pasó en cola y esperando ser ejecutada por el cliente HTTP | 
| smithy.client.http.bytes\$1sent | Mediante | MonotonicCounter | server.address | Número total de bytes enviados por el cliente HTTP | 
| smithy.client.http.bytes\$1received | Mediante | MonotonicCounter | server.address | Número total de bytes recibidos por el cliente HTTP | 

A continuación, se muestran las descripciones de las columnas:
+ **Nombre de métrica**: el nombre de la métrica.
+ **Unidades**: la unidad de medida de la métrica. Las unidades se indican en la notación [UCUM](https://unitsofmeasure.org/ucum) que distingue entre mayúsculas y minúsculas.
+ **Tipo**: el tipo de instrumento utilizado para capturar la métrica.
+ **Descripción**: una descripción de lo que mide la métrica.
+ **Atributos**: el conjunto de atributos (dimensiones) emitidos con la métrica.

# Registro
<a name="logging"></a>

 AWS SDK para Kotlin Configura un registrador compatible con [SLF4J](https://www.slf4j.org/manual.html) como el predeterminado del proveedor `LoggerProvider` de telemetría. Con SLF4 J, que es una capa de abstracción, puede utilizar cualquiera de los varios sistemas de registro en tiempo de ejecución. [Los sistemas de registro compatibles incluyen [Java Logging APIs](https://docs.oracle.com/javase/8/docs/technotes/guides/logging/), [Log4j 2](https://logging.apache.org/log4j/2.x/) y Logback.](https://logback.qos.ch/)

**aviso**  
Le recomendamos que utilice el registro de cables únicamente con fines de depuración. (El registro de cables se analiza más adelante). Desactívelo en sus entornos de producción porque puede registrar datos confidenciales, como direcciones de correo electrónico, identificadores de seguridad, claves de API, contraseñas y AWS Secrets Manager secretos. El registro electrónico registra la solicitud o respuesta completa sin cifrar, incluso en el caso de una llamada HTTPS.   
En el caso de solicitudes o respuestas de gran tamaño (como subir un archivo a Amazon S3), el registro detallado de las conexiones también puede afectar considerablemente al rendimiento de la aplicación.

## Ejemplo de configuración de registro de Log4j 2
<a name="log4j2-example"></a>

 Si bien se puede utilizar cualquier biblioteca de registros `SLF4J` compatible, en este ejemplo se habilita la salida de registros desde el SDK en programas de JVM que utilizan Log4j 2:

**Dependencias de Gradle**

(Puedes navegar hasta el *X.Y.Z* enlace para ver la última versión disponible).

```
implementation("org.apache.logging.log4j:log4j-slf4j2-impl:[https://search.maven.org/#search|gav|1|g:org.apache.logging.log4j%20AND%20a:log4j-slf4j2-impl](https://search.maven.org/#search|gav|1|g:org.apache.logging.log4j%20AND%20a:log4j-slf4j2-impl)")
```

**Archivo de configuración de Log4j 2**

Cree un archivo con un nombre `log4j2.xml` en su `resources` directorio (por ejemplo,`<project-dir>/src/main/resources`). Añada la siguiente configuración XML al archivo:

```
<Configuration status="ERROR">
    <Appenders>
        <Console name="Out">
            <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} %-5p %c:%L %X - %encode{%m}{CRLF}%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Out"/>
        </Root>
    </Loggers>
</Configuration>
```

Esta configuración incluye el `%X` especificador en el `pattern` atributo que permite el registro del MDC (contexto de diagnóstico mapeado).

El SDK agrega los siguientes elementos MDC para cada operación.

**rpc**  
El nombre del RPC invocado, por ejemplo. `S3.GetObject`

**sdkInvocationId**  
Un identificador único asignado por el cliente del servicio para la operación. El ID correlaciona todos los eventos de registro relacionados con la invocación de una sola operación.

## Especifique el modo de registro para los mensajes a nivel de cable
<a name="sdk-log-mode"></a>

De forma predeterminada, AWS SDK para Kotlin no registra los mensajes a nivel de cable porque pueden contener datos confidenciales de las solicitudes y respuestas de la API. Sin embargo, a veces se necesita este nivel de detalle para realizar tareas de depuración. 

Con el SDK de Kotlin, puedes configurar un modo de registro en el código o usar la configuración del entorno para habilitar los mensajes de depuración en los siguientes casos:
+ Solicitudes HTTP
+ Respuestas HTTP

El modo de registro está respaldado por un campo de bits en el que cada bit es un indicador (modo) y los valores son aditivos. Puede combinar un modo de solicitud y un modo de respuesta.

### Configure el modo de registro en el código
<a name="set-log-mode-programmatically"></a>

Para optar por un registro adicional, defina la `logMode` propiedad cuando cree un cliente de servicio.

El siguiente ejemplo muestra cómo habilitar el registro de las solicitudes (con el cuerpo) y la respuesta (sin el cuerpo).

```
import aws.smithy.kotlin.runtime.client.LogMode

// ...

val client = DynamoDbClient {
    // ...
    logMode = LogMode.LogRequestWithBody + LogMode.LogResponse
}
```

Un valor de modo de registro establecido durante la construcción del cliente de servicio anula cualquier valor de modo de registro establecido en el entorno.

### Establezca el modo de registro desde el entorno
<a name="set-log-mode-from-enviironment"></a>

Para establecer un modo de registro global para todos los clientes de servicio que no estén configurados explícitamente en el código, utilice una de las siguientes opciones:
+ Propiedad del sistema JVM: `sdk.logMode`
+ Variable de entorno: `SDK_LOG_MODE`

Están disponibles los siguientes valores que no distinguen mayúsculas de minúsculas:
+ `LogRequest`
+ `LogRequestWithBody`
+ `LogResponse`
+ `LogResponseWithBody`

Para crear un modo de registro combinado utilizando la configuración del entorno, separe los valores con un símbolo de barra vertical (`|`).

Por ejemplo, en los ejemplos siguientes se establece el mismo modo de registro que en el ejemplo anterior.

```
# Environment variable.
export SDK_LOG_MODE=LogRequestWithBody|LogResponse
```

```
# JVM system property.
java -Dsdk.logMode=LogRequestWithBody|LogResponse ...
```

**nota**  
También debe configurar un registrador SLF4 J compatible y establecer el nivel de registro en DEBUG para habilitar el registro a nivel de cable.

# Proveedores de telemetría
<a name="observability-telemetry-providers"></a>

El SDK actualmente admite [OpenTelemetry](https://opentelemetry.io/)(OTel) como proveedor. El SDK podría ofrecer proveedores de telemetría adicionales en el futuro.

**Topics**
+ [Configure el proveedor de OpenTelemetry telemetría basado](observability-telemetry-providers-otel.md)

# Configure el proveedor de OpenTelemetry telemetría basado
<a name="observability-telemetry-providers-otel"></a>

El SDK para Kotlin proporciona una implementación de la `TelemetryProvider` interfaz respaldada por OpenTelemetry.

## Requisitos previos
<a name="observability-telemetry-providers-otel-prereqs"></a>

Actualiza las dependencias de tu proyecto para añadir el OpenTelemetry proveedor, tal y como se muestra en el siguiente fragmento de código de Gradle. Puedes navegar hasta el *X.Y.Z* enlace para ver la última versión disponible.

```
dependencies {
    implementation(platform("aws.smithy.kotlin:bom:[https://github.com/smithy-lang/smithy-kotlin/releases/latest](https://github.com/smithy-lang/smithy-kotlin/releases/latest)"))
    implementation(platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom:[https://search.maven.org/#search|gav|1|g:io.opentelemetry.instrumentation%20AND%20a:opentelemetry-instrumentation-bom](https://search.maven.org/#search|gav|1|g:io.opentelemetry.instrumentation%20AND%20a:opentelemetry-instrumentation-bom)"))
    implementation("aws.smithy.kotlin:telemetry-provider-otel")

    // OPTIONAL: If you use log4j, the following entry enables the ability to export logs through OTel.
    runtimeOnly("io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17")
}
```

## Configurar el SDK
<a name="observability-telemetry-providers-otel-conf"></a>

El siguiente código configura un cliente de servicio mediante el proveedor de OpenTelemetry telemetría.

```
import aws.sdk.kotlin.services.s3.S3Client
import aws.smithy.kotlin.runtime.telemetry.otel.OpenTelemetryProvider
import io.opentelemetry.api.GlobalOpenTelemetry
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val otelProvider = OpenTelemetryProvider(GlobalOpenTelemetry.get())

    S3Client.fromEnvironment().use { s3 ->
        telemetryProvider = otelProvider
        …
    }
}
```

**nota**  
El análisis de cómo configurar el OpenTelemetry SDK queda fuera del ámbito de esta guía. La [documentación de OpenTelemetry Java](https://opentelemetry.io/docs/instrumentation/java/) contiene información de configuración sobre los distintos enfoques: de [forma manual](https://opentelemetry.io/docs/instrumentation/java/manual/), automática mediante el [agente Java](https://opentelemetry.io/docs/instrumentation/java/automatic/) o mediante el [recopilador](https://opentelemetry.io/docs/collector/) (opcional).

## Recursos
<a name="observability-telemetry-providers-otel-res"></a>

Los siguientes recursos están disponibles para ayudarle a empezar OpenTelemetry.
+ [AWS Distro for OpenTelemetry: página](https://aws-otel.github.io/docs/introduction) principal de AWS OTe L Distro
+ [aws-otel-java-instrumentation](https://github.com/aws-observability/aws-otel-java-instrumentation)- Biblioteca de AWS instrumentación de Distro para Java OpenTelemetry 
+ [aws-otel-lambda](https://github.com/aws-observability/aws-otel-lambda)- capas OpenTelemetry Lambda AWS gestionadas
+ [aws-otel-collector](https://github.com/aws-observability/aws-otel-collector)- AWS Distro para Collector OpenTelemetry
+ AWS Mejores prácticas [de observabilidad: mejores prácticas](https://aws-observability.github.io/observability-best-practices/) generales para la observabilidad específicas de AWS

# Anule la configuración del cliente del servicio
<a name="override-client-config"></a>

Una vez [creado un cliente de servicio](creating-clients.md), el cliente de servicio utiliza una configuración fija para todas las operaciones. Sin embargo, a veces es posible que necesite anular la configuración para una o más operaciones específicas.

Cada cliente de servicio tiene una `withConfig` extensión para que pueda modificar una copia de la configuración existente. La `withConfig` extensión devuelve un nuevo cliente de servicio con una configuración modificada. El cliente original existe de forma independiente y utiliza su configuración original.

El siguiente ejemplo muestra la creación de una `S3Client` instancia que llama a dos operaciones.

```
val s3 = S3Client.fromEnvironment {
    logMode = LogMode.LogRequest
    region = "us-west-2"
    // ...other configuration settings...
}

s3.listBuckets { ... }
s3.listObjectsV2 { ... }
```

En el siguiente fragmento se muestra cómo anular la configuración de una sola operación. `listObjectV2`

```
s3.withConfig {
    region = "eu-central-1"
}.use { overriddenS3 ->
    overriddenS3.listObjectsV2 { ... }
}
```

Las llamadas a la operación del `s3` cliente utilizan la configuración original que se especificó cuando se creó el cliente. Su configuración incluye el [registro de solicitudes](logging.md#sdk-log-mode) y `us-west-2 region` para la región. 

La `listObjectsV2` invocación en el `overriddenS3` cliente utiliza la misma configuración que en el `s3` cliente original, excepto en la región, que es ahora`eu-central-1`.

## Ciclo de vida de un cliente anulado
<a name="override-client-lifecycle"></a>

En el ejemplo anterior, el `s3` cliente y el `overriddenS3` cliente son independientes entre sí. Las operaciones se pueden invocar en cualquiera de los clientes mientras permanezcan abiertos. Cada uno usa una configuración diferente, pero puede compartir los recursos subyacentes (como un motor HTTP) a menos que también se anulen. 

Cierra un cliente con una configuración anulada y el cliente original por separado. Puede cerrar un cliente con una configuración anulada antes o después de cerrar su cliente original. A menos que necesite utilizar un cliente con una configuración anulada durante mucho tiempo, le recomendamos que incluya este método en su ciclo de vida. `use` El `use` método garantiza que el cliente esté cerrado en caso de que se produzcan excepciones. 

## Recursos compartidos entre clientes
<a name="override-client-shared-res"></a>

Al crear un cliente de servicio mediante el uso`withConfig`, es posible que comparta recursos con el cliente original. Por el contrario, cuando se crea un cliente mediante [FromEnvironment](creating-clients.md#loading-from-the-environment) o se [configura de forma explícita](creating-clients.md#programmatic-config), el cliente utiliza recursos independientes. Los recursos, como los motores HTTP y los proveedores de credenciales, se comparten a menos que se anulen en el bloque. `withConfig` 

Como el ciclo de vida de cada cliente es independiente, los recursos compartidos permanecen abiertos y utilizables hasta que se cierre el último cliente. Por lo tanto, es importante que cierre los clientes de servicio anulados cuando ya no los necesite. Esto evita que los recursos compartidos permanezcan abiertos y consuman recursos del sistema, como la memoria, la conexión y los ciclos de CPU.

El siguiente ejemplo muestra los recursos compartidos e independientes.

Los `overriddenS3` clientes `s3` y comparten la misma instancia del proveedor de credenciales, incluida su configuración de almacenamiento en caché. Las llamadas realizadas mediante credenciales `overriddenS3` reutilizan si el valor almacenado en caché sigue siendo el mismo que el de las llamadas realizadas por el `s3` cliente.

 El motor HTTP no se comparte entre los dos clientes. Cada cliente tiene un motor HTTP independiente porque se anuló en la `withConfig` llamada.

```
val s3 = S3Client.fromEnvironment {
    region = "us-west-2"
    credentialsProvider = CachedCredentialsProvider(CredentialsProviderChain(...))
    httpClientEngine = OkHttpEngine { ... }
}

s3.listBuckets { ... }

s3.withConfig {
    httpClientEngine = CrtHttpEngine { ... }
}.use { overriddenS3 ->
    overriddenS3.listObjectsV2 { ... }
}
```