SDK를 사용하여 Java 2.x로 로깅하기 - AWS SDK for Java 2.x

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

SDK를 사용하여 Java 2.x로 로깅하기

는 런타임 시 여러 로깅 시스템 중 하나를 사용할 수 있게 해주는 추상화 계층인 SLF4J 을 사용합니다. AWS SDK for Java 2.x

지원되는 로깅 시스템에는 Java Logging Framework와 Apache Log4j 2 등이 있습니다. 이 항목에서는 Log4j 2를 SDK 작업을 위한 로깅 시스템으로 사용하는 방법을 보여줍니다.

Log4j 구성 파일

일반적으로 Log4j 2을 포함하고 이름이 log4j2.xml로 지정된 구성 파일을 사용합니다. 아래에는 예제 구성 파일이 나와 있습니다. 구성 파일에 사용된 값에 대한 자세한 내용은 Log4j 구성에 대한 설명서를 참조하세요.

애플리케이션을 시작할 때 log4j2.xml 파일이 클래스 경로에 있어야 합니다. Maven 프로젝트의 경우 파일을 <project-dir>/src/main/resources 디렉터리에 넣으세요.

log4j2.xml 구성 파일은 로깅 출력이 전송될 대상인 로깅 수준(예를 들면, 파일 또는 콘솔), 출력 형식 같은 속성을 지정합니다. 로깅 수준은 Log4j 2가 출력하는 세부 수준을 지정합니다. Log4j는 여러 로깅 계층의 개념을 지원합니다. 로깅 수준은 각 계층마다 독립적으로 설정됩니다. 와 함께 사용하는 기본 로깅 AWS SDK for Java 2.x 계층은 software.amazon.awssdk 다음과 같습니다.

로깅 종속성 추가

빌드 파일에서 SLF4J Log4j 2 바인딩을 구성하려면 다음을 사용하세요.

Maven

다음 요소를 pom.xml 파일에 추가합니다.

... <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j2-impl</artifactId> <version>VERSION</version> </dependency> ...
Gradle–Kotlin DSL

다음을 build.gradle.kts 파일에 추가합니다.

... dependencies { ... implementation("org.apache.logging.log4j:log4j-slf4j2-impl:VERSION") ... } ...

log4j-slf4j2-impl 아티팩트의 최소 버전에 2.20.0를 사용 최신 버전의 경우 Maven Central에 게시된 버전을 사용하세요. VERSION을 사용할 버전으로 교체하세요.

서비스 관련 오류 및 경고

SDK 클라이언트 라이브러리에서 중요한 메시지를 포착하려면 항상 "software.amazon.awssdk" 로거 계층 구조를 "WARN"으로 설정해 두는 것이 좋습니다. 예를 들어 Amazon S3 클라이언트가 애플리케이션이 InputStream를 제대로 닫지 않았고 리소스가 누출될 수 있음을 감지하면 S3 클라이언트는 경고 메시지를 통해 이를 로그에 보고합니다. 또한 클라이언트에 요청 또는 응답 처리 문제가 발생하는 경우에도 메시지가 기록됩니다.

다음 log4j2.xml 파일은 rootLogger를 “WARN”으로 설정합니다. 그러면 “software.amazon.awssdk” 계층 구조에 있는 로거를 포함하여 애플리케이션에 있는 모든 로거에서 경고 및 오류 수준 메시지가 출력됩니다. 또는 <Root level="ERROR">를 사용하는 경우 “software.amazon.awssdk” 로거 계층을 명시적으로 “WARN”으로 설정할 수도 있습니다.

예제 Log4j2.xml 구성 파일

이 구성은 모든 로거 계층에 대해 “ERROR” 및 “WARN” 수준의 메시지를 콘솔에 기록합니다.

<Configuration status="WARN"> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT"> <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" /> </Console> </Appenders> <Loggers> <Root level="WARN"> <AppenderRef ref="ConsoleAppender"/> </Root> </Loggers> </Configuration>

요청 및 응답 요약 로깅

에 대한 모든 요청은 고유한 AWS 요청 ID를 AWS service 생성하는데, 이는 요청을 처리하는 방식에 문제가 AWS service 발생할 경우 유용합니다. AWS 요청 ID는 실패한 서비스 호출에 대해 SDK의 SdkServiceException객체를 통해 프로그래밍 방식으로 액세스할 수 있으며, “software.amazon.awssdk.request” 로거의 “디버그” 로그 수준을 통해 보고할 수도 있습니다.

다음 log4j2.xml 파일은 요청 및 응답의 요약을 제공합니다.

<Configuration status="WARN"> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT"> <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" /> </Console> </Appenders> <Loggers> <Root level="ERROR"> <AppenderRef ref="ConsoleAppender"/> </Root> <Logger name="software.amazon.awssdk" level="WARN" /> <Logger name="software.amazon.awssdk.request" level="DEBUG" /> </Loggers> </Configuration>

다음은 로그 출력의 예입니다:

2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=POST, protocol=https, host=dynamodb.us-east-1.amazonaws.com, encodedPath=/, headers=[amz-sdk-invocation-id, Content-Length, Content-Type, User-Agent, X-Amz-Target], queryParameters=[]) 2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Received successful response: 200, Request ID: QS9DUMME2NHEDH8TGT9N5V53OJVV4KQNSO5AEMVJF66Q9ASUAAJG, Extended Request ID: not available

요청 ID에만 관심이 있는 경우 <Logger name="software.amazon.awssdk.requestId" level="DEBUG" />를 사용하세요.

디버그 수준 SDK 로깅

SDK가 수행하는 작업에 대한 자세한 정보가 필요한 경우 로거의 로거 로깅 수준을 로 설정할 수 있습니다. software.amazon.awssdk DEBUG 이 수준에서는 SDK가 많은 양의 세부 정보를 출력하므로 통합 테스트를 사용하여 오류를 해결하려면 이 수준을 설정하는 것이 좋습니다.

이 로깅 수준에서 SDK는 구성, 자격 증명 확인, 실행 인터셉터, 상위 수준 TLS 활동, 요청 서명 등에 대한 정보를 기록합니다.

다음은 SDK가 호출 수준에서 출력하는 명령문의 샘플입니다. DEBUG S3Client#listBuckets()

DEBUG s.a.a.r.p.AwsRegionProviderChain:57 - Unable to load region from software.amazon.awssdk.regions.providers.SystemSettingsRegionProvider@324dcd31:Unable to load region from system settings. Region must be specified either via environment variable (AWS_REGION) or system property (aws.region). DEBUG s.a.a.c.i.h.l.ClasspathSdkHttpServiceProvider:85 - The HTTP implementation loaded is software.amazon.awssdk.http.apache.ApacheSdkHttpService@a23a01d DEBUG s.a.a.c.i.ExecutionInterceptorChain:85 - Creating an interceptor chain that will apply interceptors in the following order: [software.amazon.awssdk.core.internal.interceptor.HttpChecksumValidationInterceptor@69b2f8e5, software.amazon.awssdk.awscore.interceptor.HelpfulUnknownHostExceptionInterceptor@6331250e, software.amazon.awssdk.awscore.eventstream.EventStreamInitialRequestInterceptor@a10c1b5, software.amazon.awssdk.awscore.interceptor.TraceIdExecutionInterceptor@644abb8f, software.amazon.awssdk.services.s3.auth.scheme.internal.S3AuthSchemeInterceptor@1a411233, software.amazon.awssdk.services.s3.endpoints.internal.S3ResolveEndpointInterceptor@70325d20, software.amazon.awssdk.services.s3.endpoints.internal.S3RequestSetEndpointInterceptor@7c2327fa, software.amazon.awssdk.services.s3.internal.handlers.StreamingRequestInterceptor@4d847d32, software.amazon.awssdk.services.s3.internal.handlers.CreateBucketInterceptor@5f462e3b, software.amazon.awssdk.services.s3.internal.handlers.CreateMultipartUploadRequestInterceptor@3d7fa3ae, software.amazon.awssdk.services.s3.internal.handlers.DecodeUrlEncodedResponseInterceptor@58065f0c, software.amazon.awssdk.services.s3.internal.handlers.GetBucketPolicyInterceptor@3605c4d3, software.amazon.awssdk.services.s3.internal.handlers.S3ExpressChecksumInterceptor@585c13de, software.amazon.awssdk.services.s3.internal.handlers.AsyncChecksumValidationInterceptor@187eb9a8, software.amazon.awssdk.services.s3.internal.handlers.SyncChecksumValidationInterceptor@726a6b94, software.amazon.awssdk.services.s3.internal.handlers.EnableTrailingChecksumInterceptor@6ad11a56, software.amazon.awssdk.services.s3.internal.handlers.ExceptionTranslationInterceptor@522b2631, software.amazon.awssdk.services.s3.internal.handlers.GetObjectInterceptor@3ff57625, software.amazon.awssdk.services.s3.internal.handlers.CopySourceInterceptor@1ee29c84, software.amazon.awssdk.services.s3.internal.handlers.ObjectMetadataInterceptor@7c8326a4] DEBUG s.a.a.u.c.CachedSupplier:85 - (SsoOidcTokenProvider()) Cached value is stale and will be refreshed. ... DEBUG s.a.a.c.i.ExecutionInterceptorChain:85 - Creating an interceptor chain that will apply interceptors in the following order: [software.amazon.awssdk.core.internal.interceptor.HttpChecksumValidationInterceptor@51351f28, software.amazon.awssdk.awscore.interceptor.HelpfulUnknownHostExceptionInterceptor@21618fa7, software.amazon.awssdk.awscore.eventstream.EventStreamInitialRequestInterceptor@15f2eda3, software.amazon.awssdk.awscore.interceptor.TraceIdExecutionInterceptor@34cf294c, software.amazon.awssdk.services.sso.auth.scheme.internal.SsoAuthSchemeInterceptor@4d7aaca2, software.amazon.awssdk.services.sso.endpoints.internal.SsoResolveEndpointInterceptor@604b1e1d, software.amazon.awssdk.services.sso.endpoints.internal.SsoRequestSetEndpointInterceptor@62566842] ... DEBUG s.a.a.request:85 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=GET, protocol=https, host=portal.sso.us-east-1.amazonaws.com, encodedPath=/federation/credentials, headers=[amz-sdk-invocation-id, User-Agent, x-amz-sso_bearer_token], queryParameters=[role_name, account_id]) DEBUG s.a.a.c.i.h.p.s.SigningStage:85 - Using SelectedAuthScheme: smithy.api#noAuth DEBUG s.a.a.h.a.i.c.SdkTlsSocketFactory:366 - Connecting socket to portal.sso.us-east-1.amazonaws.com/18.235.195.183:443 with timeout 2000 ... DEBUG s.a.a.requestId:85 - Received successful response: 200, Request ID: bb4f40f4-e920-4b5c-8648-58f26e7e08cd, Extended Request ID: not available DEBUG s.a.a.request:85 - Received successful response: 200, Request ID: bb4f40f4-e920-4b5c-8648-58f26e7e08cd, Extended Request ID: not available DEBUG s.a.a.u.c.CachedSupplier:85 - (software.amazon.awssdk.services.sso.auth.SsoCredentialsProvider@b965857) Successfully refreshed cached value. Next Prefetch Time: 2024-04-25T22:03:10.097Z. Next Stale Time: 2024-04-25T22:05:30Z DEBUG s.a.a.c.i.ExecutionInterceptorChain:85 - Interceptor 'software.amazon.awssdk.services.s3.endpoints.internal.S3RequestSetEndpointInterceptor@7c2327fa' modified the message with its modifyHttpRequest method. ... DEBUG s.a.a.c.i.h.p.s.SigningStage:85 - Using SelectedAuthScheme: aws.auth#sigv4 ... DEBUG s.a.a.a.s.Aws4Signer:85 - AWS4 Canonical Request: GET ... DEBUG s.a.a.h.a.a.i.s.DefaultV4RequestSigner:85 - AWS4 String to sign: AWS4-HMAC-SHA256 20240425T210631Z 20240425/us-east-1/s3/aws4_request aafb7784627fa7a49584256cb746279751c48c2076f813259ef767ecce304d64 DEBUG s.a.a.h.a.i.c.SdkTlsSocketFactory:366 - Connecting socket to s3.us-east-1.amazonaws.com/52.217.41.86:443 with timeout 2000 ...

다음 log4j2.xml 파일은 이전 출력을 구성합니다.

<Configuration status="WARN"> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT"> <PatternLayout pattern="%-5p %c{1.}:%L - %m%n" /> </Console> </Appenders> <Loggers> <Root level="WARN"> <AppenderRef ref="ConsoleAppender"/> </Root> <Logger name="software.amazon.awssdk" level="DEBUG" /> </Loggers> </Configuration>

와이어 로깅을 활성화합니다.

Java 2.x용 SDK가 보내고 받는 정확한 요청과 응답을 확인하는 것이 유용할 수 있습니다. 이 정보에 액세스해야 하는 경우 서비스 클라이언트가 사용하는 HTTP 클라이언트에 따라 필요한 구성을 추가하여 일시적으로 활성화할 수 있습니다.

기본적으로 S3Client와 같은 동기 서비스 클라이언트는 기본 HttpClient Apache를 사용하고 S3와 같은 비동기 서비스 클라이언트는 Netty 비차단 HTTP 클라이언트를 사용합니다. AsyncClient

다음은 두 가지 범주의 서비스 클라이언트에 사용할 수 있는 HTTP 클라이언트의 분석입니다.

동기식 HTTP 클라이언트 동기식 HTTP 클라이언트
ApacheHttpClient(기본값) NettyNioAsyncHttpClient(기본값)
UrlConnectionHttpClient AwsCrtAsyncHttpClient

기본 HTTP 클라이언트에 따라 추가해야 하는 구성 설정은 아래 해당 탭을 참조하세요.

주의

유선 로깅은 디버깅 목적에만 사용하는 것이 좋습니다. 로그에 민감한 데이터가 될 수 있기 때문에 프로덕션 환경에서는 비활성화합니다. HTTPS 호출을 포함, 암호화 없는 전체 요청이나 응답을 로그로 기록합니다. 대규모 요청 (예: 파일 업로드 Amazon S3) 이나 응답의 경우 자세한 유선 로깅도 애플리케이션 성능에 큰 영향을 미칠 수 있습니다.

ApacheHttpClient

log4j2.xml 구성 파일에 “org.apache.http.wire” 로거를 추가하고 레벨을 “DEBUG”로 설정합니다.

다음 log4j2.xml 파일은 Apache의 전체 유선 로깅을 활성화합니다. HttpClient

<Configuration status="WARN"> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT"> <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" /> </Console> </Appenders> <Loggers> <Root level="WARN"> <AppenderRef ref="ConsoleAppender"/> </Root> <Logger name="software.amazon.awssdk" level="WARN" /> <Logger name="software.amazon.awssdk.request" level="DEBUG" /> <Logger name="org.apache.http.wire" level="DEBUG" /> </Loggers> </Configuration>

Apache는 내부적으로 1.2를 사용하기 때문에 Apache를 통한 유선 로깅에는 log4j-1.2-api 아티팩트에 대한 추가 Maven 종속성이 필요합니다.

Apache HTTP 클라이언트의 유선 로깅을 포함하여 log4j 2의 전체 Maven 종속성 집합은 다음 빌드 파일 코드 조각에 나와 있습니다.

Maven

... <dependencyManagement> ... <dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-bom</artifactId> <version>VERSION</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ... <!-- The following is needed for Log4j2 with SLF4J --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j2-impl</artifactId> </dependency> <!-- The following is needed for Apache HttpClient wire logging --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-1.2-api</artifactId> </dependency> ...

Gradle - Kotlin DSL

... dependencies { ... implementation(platform("org.apache.logging.log4j:log4j-bom:VERSION")) implementation("org.apache.logging.log4j:log4j-slf4j2-impl") implementation("org.apache.logging.log4j:log4j-1.2-api") } ...

log4j-bom 아티팩트의 최소 버전에 2.20.0를 사용 최신 버전의 경우 Maven Central에 게시된 버전을 사용하세요. VERSION을 사용할 버전으로 교체하세요.

UrlConnectionHttpClient

UrlConnectionHttpClient를 사용하는 서비스 클라이언트의 세부 정보를 기록하려면 먼저 다음 내용이 포함된 logging.properties 파일을 만드세요.

handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level=FINEST sun.net.www.protocol.http.HttpURLConnection.level=ALL

logging.properties의 전체 경로를 사용하여 다음 JVM 시스템 속성을 설정합니다.

-Djava.util.logging.config.file=/full/path/to/logging.properties

이 구성은 요청 및 응답의 헤더만 기록합니다. 예를 들면 다음과 같습니다.

<Request> FINE: sun.net.www.MessageHeader@35a9782c11 pairs: {GET /fileuploadtest HTTP/1.1: null}{amz-sdk-invocation-id: 5f7e707e-4ac5-bef5-ba62-00d71034ffdc}{amz-sdk-request: attempt=1; max=4}{Authorization: AWS4-HMAC-SHA256 Credential=<deleted>/20220927/us-east-1/s3/aws4_request, SignedHeaders=amz-sdk-invocation-id;amz-sdk-request;host;x-amz-content-sha256;x-amz-date;x-amz-te, Signature=e367fa0bc217a6a65675bb743e1280cf12fbe8d566196a816d948fdf0b42ca1a}{User-Agent: aws-sdk-java/2.17.230 Mac_OS_X/12.5 OpenJDK_64-Bit_Server_VM/25.332-b08 Java/1.8.0_332 vendor/Amazon.com_Inc. io/sync http/UrlConnection cfg/retry-mode/legacy}{x-amz-content-sha256: UNSIGNED-PAYLOAD}{X-Amz-Date: 20220927T133955Z}{x-amz-te: append-md5}{Host: tkhill-test1.s3.amazonaws.com}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive} <Response> FINE: sun.net.www.MessageHeader@70a36a6611 pairs: {null: HTTP/1.1 200 OK}{x-amz-id-2: sAFeZDOKdUMsBbkdjyDZw7P0oocb4C9KbiuzfJ6TWKQsGXHM/dFuOvr2tUb7Y1wEHGdJ3DSIxq0=}{x-amz-request-id: P9QW9SMZ97FKZ9X7}{Date: Tue, 27 Sep 2022 13:39:57 GMT}{Last-Modified: Tue, 13 Sep 2022 14:38:12 GMT}{ETag: "2cbe5ad4a064cedec33b452bebf48032"}{x-amz-transfer-encoding: append-md5}{Accept-Ranges: bytes}{Content-Type: text/plain}{Server: AmazonS3}{Content-Length: 67}

요청 alc 응답 본문을 보려면 JVM 속성에 -Djavax.net.debug=all를 추가하세요. 이 추가 속성은 모든 SSL 정보를 포함하여 많은 양의 정보를 기록합니다.

로그 콘솔 또는 로그 파일 내에서 실제 요청 및 응답이 포함된 로그 단원으로 빠르게 이동하려면 "GET""POST"를 검색하세요. 요청으로는 "Plaintext before ENCRYPTION"을 검색하고 응답으로는 "Plaintext after DECRYPTION" 검색하면 헤더와 본문의 전체 텍스트를 볼 수 있습니다.

NettyNioAsyncHttpClient

비동기 서비스 클라이언트가 기본값 NettyNioAsyncHttpClient을 사용하는 경우 HTTP 헤더와 요청 및 응답 본문에 대한 log4j2.xml 파일에 로거 2개를 추가하세요.

<Logger name="io.netty.handler.logging" level="DEBUG" /> <Logger name="io.netty.handler.codec.http2.Http2FrameLogger" level="DEBUG" />

다음은 전체 log4j2.xml 예제입니다.

<Configuration status="WARN"> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT"> <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" /> </Console> </Appenders> <Loggers> <Root level="WARN"> <AppenderRef ref="ConsoleAppender"/> </Root> <Logger name="software.amazon.awssdk" level="WARN" /> <Logger name="software.amazon.awssdk.request" level="DEBUG" /> <Logger name="io.netty.handler.logging" level="DEBUG" /> <Logger name="io.netty.handler.codec.http2.Http2FrameLogger" level="DEBUG" /> </Loggers> </Configuration>

이러한 설정은 모든 헤더 세부 정보와 요청 및 응답 본문을 기록합니다.

AwsCrtAsyncHttpClient

AwsCrtAsyncHttpClient의 인스턴스를 사용하도록 서비스 클라이언트를 구성한 경우 JVM 시스템 속성을 설정하거나 프로그래밍 방식으로 세부 정보를 기록할 수 있습니다.

Log to a file at "Debug" level

시스템 속성 사용:

-Daws.crt.log.level=Trace -Daws.crt.log.destination=File -Daws.crt.log.filename=<path to file>

프로그래밍 방식으로

import software.amazon.awssdk.crt.Log; // Execute this statement before constructing the SDK service client. Log.initLoggingToFile(Log.LogLevel.Trace, "<path to file>");
Log to the console at "Debug" level

시스템 속성 사용:

-Daws.crt.log.level=Trace -Daws.crt.log.destination=Stdout

프로그래밍 방식으로

import software.amazon.awssdk.crt.Log; // Execute this statement before constructing the SDK service client. Log.initLoggingToStdout(Log.LogLevel.Trace);

보안상의 이유로 “Trace” 레벨에서 AwsCrtAsyncHttpClient는 응답 헤더만 로깅합니다. 요청 헤더, 요청 본문 및 응답 본문은 로깅되지 않습니다.