AWS X-Ray SDK를 위한 Java - AWS X-Ray

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

AWS X-Ray SDK를 위한 Java

Java용 X-Ray SDK는 추적 데이터를 생성하고 X-Ray 데몬으로 전송하기 위한 클래스와 메서드를 제공하는 웹 애플리케이션용 라이브러리 Java 세트입니다. 추적 데이터에는 응용 프로그램에서 제공하는 수신 HTTP 요청 및 응용 프로그램이 AWS SDK, HTTP 클라이언트 또는 SQL 데이터베이스 커넥터를 사용하여 다운스트림 서비스에 보내는 호출에 대한 정보가 포함됩니다. 또한 수동으로 세그먼트를 생성하고 디버그 정보를 주석 및 메타데이터에 추가할 수도 있습니다.

Java용 X-Ray SDK는 오픈 소스 프로젝트입니다. github.com/aws/에서 프로젝트를 팔로우하고 이슈와 풀 리퀘스트를 제출할 수 있습니다 GitHub. aws-xray-sdk-java

AWSXRayServletFilter를 서블릿 필터로 츄가하여 수신 요청 트레이스를 시작합니다. 서블릿 필터가 세그먼트를 생성합니다. 세그먼트가 열려 있는 동안에는 SDK 클라이언트의 메서드를 이용해 정보를 세그먼트에 추가하고 하위 세그먼트를 만들어 다운스트림 호출을 트레이스할 수 있습니다. 또한 SDK는 세그먼트가 열려 있는 동안 애플리케이션에서 발생하는 예외를 자동으로 기록합니다.

릴리스 1.3부터는 Spring에서 관점 지향 프로그래밍(AOP)을 사용하여 애플리케이션을 계측할 수 있습니다. 즉, 애플리케이션 런타임에 코드를 추가하지 않고도 애플리케이션이 실행되는 AWS동안 애플리케이션을 계측할 수 있습니다.

다음으로, Java용 X-Ray SDK를 사용하여 빌드 구성에 SDK AWS SDK for Java 인스트루멘터 하위 모듈을 포함하여 클라이언트를 계측합니다. 인스트루먼트된 클라이언트를 사용하여 다운스트림 AWS 서비스 또는 리소스를 호출할 때마다 SDK는 해당 호출에 대한 정보를 하위 세그먼트에 기록합니다. AWS 서비스 또한 서비스 내에서 액세스하는 리소스는 추적 맵에 다운스트림 노드로 표시되어 개별 연결의 오류 및 제한 문제를 식별하는 데 도움이 됩니다.

모든 다운스트림 통화를 계측하지 않으려면 Instrumentor 하위 모듈을 생략하고 AWS 서비스계측할 클라이언트를 선택하면 됩니다. SDK 서비스 클라이언트에 a를 추가하여 개별 클라이언트를 TracingHandler 계측하십시오. AWS

다른 Java용 X-Ray SDK 하위 모듈은 HTTP web API 및 SQL 데이터베이스에 대한 다운스트림 호출을 계측합니다. Apache HTTP 하위 모듈의 Java용 X-Ray SDK 버전 HTTPClient와 HTTPClientBuilder를 사용하여 Apache HTTP 클라이언트를 계측할 수 있습니다. SQL 쿼리를 구성하려면 SDK의 인터셉터를 데이터 원본에 추가합니다.

SDK를 사용하기 시작한 후에, 레코더와 servlet 필터를 구성하여 SDK 동작을 구성하십시오. 플러그인을 추가해 애플리케이션을 실행하는 컴퓨팅 리소스에 대한 데이터를 기록하고, 샘플링 규칙을 정의해 샘플링 동작을 구성하고, 로그 레벨을 설정해 애플리케이션 로그의 SDK에서 표시되는 정보 수준을 조절할 수 있습니다.

요청에 대한 추가 정보와 애플리케이션이 주석 및 메타데이터에서 하는 작업을 기록합니다. 주석은 필터 표현식과 함께 사용할 수 있도록 인덱싱된 단순한 키 값 쌍이기 때문에, 특정 데이터를 포함한 트레이스를 검색할 수 있습니다. 메타데이터 항목은 제한이 적으며 JSON으로 직렬화할 수 있는 모든 객체와 어레이를 기록할 수 있습니다.

주석 및 메타데이터

주석 및 메타데이터는 X SDK를 사용하여 세그먼트에 추가하는 임의의 텍스트입니다. 주석은 필터 표현식에서 사용하기 위해 인덱싱됩니다. 메타데이터는 인덱싱되지 않지만 X-Ray 콘솔 또는 API를 사용하여 원시 세그먼트에서 볼 수 있습니다. X-Ray에 대한 읽기 액세스가 부여된 사용자는 누구나 이 데이터를 볼 수 있습니다.

코드에 계측된 클라이언트가 많다면, 계측된 클라이언트로 만든 각 요청의 하위 세그먼트를 대량으로 보관하는 요청 세그먼트 하나를 만들 수 있습니다. 사용자 지정 하위 세그먼트의 클라이언트 호출을 래핑해 하위 세그먼트를 조직하고 그룹화할 수 있습니다. 전체 함수나 특정 코드 부분에 대한 사용자 지정 하위 세그먼트를 만들고, 상위 세그먼트에 모든 것을 적는 대신 하위 세그먼트에 메타데이터와 주석을 기록할 수 있습니다.

하위 모듈

Maven에서 Java용 X-Ray SDK를 다운로드할 수 있습니다. Java용 X-Ray SDK는 사용 사례별로 하위 모듈로 나뉘며, 버전 관리용 BOM을 포함합니다:

Maven 또는 Gradle을 사용하여 애플리케이션을 빌드하는 경우, 빌드 구성에 Java용 X-Ray SDK를 추가합니다.

SDK의 클래스 및 메서드에 대한 참조 문서는 API 참조용 AWS X-Ray SDK를 참조하십시오. Java

요구 사항

Java용 X-Ray Java SDK에는 8개 이상의 서블릿 API 3, SDK 및 AWS 잭슨이 필요합니다.

SDK는 컴파일 및 실행 시간 시 다음 라이브러리에 의존합니다.

  • AWS 버전 1.11.398 이상용 Java SDK

  • Servlet API 3.1.0

이러한 종속성은 SDK의 pom.xml 파일에서 선언되며 Maven 또는 Gradle을 사용하여 빌드하는 경우 자동으로 포함됩니다.

Java용 X-Ray SDK에 포함된 라이브러리를 사용하는 경우 포함된 버전을 사용해야 합니다. 예를 들어 실행 시간 시 이미 Jackson에 의존하고 해당 종속성을 위해 배포에 JAR 파일을 포함시킨 경우에는 SDK JAR이 자체 버전의 Jackson 라이브러리를 포함하므로 이들 JAR 파일을 제거해야 합니다.

종속성 관리

Java용 X-Ray SDK는 Maven에서 사용할 수 있습니다.

  • 그룹com.amazonaws

  • 아티팩트aws-xray-recorder-sdk-bom

  • 버전2.11.0

Maven을 사용하여 애플리케이션을 빌드하는 경우 pom.xml 파일에서 SDK를 종속성으로 추가합니다.

예 pom.xml - 종속성
<dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-bom</artifactId> <version>2.11.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-core</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-apache-http</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-aws-sdk</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-aws-sdk-instrumentor</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-sql-postgres</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-sql-mysql</artifactId> </dependency> </dependencies>

Gradle의 경우, build.gradle 파일에서 SDK를 컴파일 시점 종속성으로 추가합니다.

예 build.gradle - 종속성
dependencies { compile("org.springframework.boot:spring-boot-starter-web") testCompile("org.springframework.boot:spring-boot-starter-test") compile("com.amazonaws:aws-java-sdk-dynamodb") compile("com.amazonaws:aws-xray-recorder-sdk-core") compile("com.amazonaws:aws-xray-recorder-sdk-aws-sdk") compile("com.amazonaws:aws-xray-recorder-sdk-aws-sdk-instrumentor") compile("com.amazonaws:aws-xray-recorder-sdk-apache-http") compile("com.amazonaws:aws-xray-recorder-sdk-sql-postgres") compile("com.amazonaws:aws-xray-recorder-sdk-sql-mysql") testCompile("junit:junit:4.11") } dependencyManagement { imports { mavenBom('com.amazonaws:aws-java-sdk-bom:1.11.39') mavenBom('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0') } }

Elastic Beanstalk를 사용하여 애플리케이션을 배포하는 경우, 모든 종속 요소를 포함하는 대규모 아카이브를 빌드하고 업로드하는 대신 배포할 때마다 Maven 또는 Gradle을 사용하여 온-인스턴스를 빌드할 수 있습니다. Gradle 사용 예시를 보려면 샘플 애플리케이션을 참조하십시오.

Java용 X-Ray SDK 구성

Java용 X-Ray SDK에는 전역 레코더를 제공하는 AWSXRay라는 클래스가 있습니다. 이는 코드를 구성하는 데 사용할 수 있는 TracingHandler입니다. 전역 레코더를 구성하여 수신 HTTP 호출에 대해 세그먼트를 생성하는 AWSXRayServletFilter를 사용자 지정할 수 있습니다.

서비스 플러그인

plugins을 사용하여 애플리케이션을 호스팅하는 서비스에 대한 정보를 기록할 수 있습니다.

플러그인
  • Amazon EC2 — 인스턴스 ID, 가용 영역 및 CloudWatch 로그 그룹을 EC2Plugin 추가합니다.

  • Elastic Beanstalk – ElasticBeanstalkPlugin이 환경 이름, 버전 레이블 및 배포 ID를 추가합니다.

  • Amazon ECS — ECSPlugin이 컨테이너 ID를 추가합니다.

  • Amazon EKS — 컨테이너 ID, 클러스터 이름, 포드 ID 및 CloudWatch 로그 그룹을 EKSPlugin 추가합니다.


        Amazon EC2 및 Elastic Beanstalk 플러그인으로 리소스 데이터를 세분화하세요.

플러그인을 사용하려면 AWSXRayRecorderBuilder에서 withPlugin을 호출하십시오.

예 src/main/java/scorekeep/ .java WebConfig - 레코더
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorderBuilder; import com.amazonaws.xray.plugins.EC2Plugin; import com.amazonaws.xray.plugins.ElasticBeanstalkPlugin; import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy; @Configuration public class WebConfig { ... static { AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()).withPlugin(new ElasticBeanstalkPlugin()); URL ruleFile = WebConfig.class.getResource("/sampling-rules.json"); builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile)); AWSXRay.setGlobalRecorder(builder.build()); } }

SDK는 플러그인 설정을 사용하여 세그먼트에 origin 필드를 설정하기도 합니다. 이는 애플리케이션을 실행하는 리소스 유형을 나타냅니다. AWS 여러 플러그인을 사용하는 경우 SDK는 ElasticBeanstalk > EKS > ECS > EC2와 같은 해결 순서를 사용하여 출처를 결정합니다.

샘플링 규칙

SDK는 X-Ray 콘솔에서 정의하는 샘플링 규칙을 사용하여 기록할 요청을 결정합니다. 기본 규칙은 매초 첫 번째 요청을 추적하고, 모든 서비스에서 추가 요청의 5%를 X-Ray로 추적 전송합니다. X-Ray 콘솔에서 추가 규칙을 생성하여 각 애플리케이션에 대해 기록되는 데이터의 양을 사용자 지정합니다.

SDK는 사용자 지정 규칙을 정의된 순서대로 적용합니다. 요청이 여러 사용자 지정 규칙과 일치하는 경우 SDK는 첫 번째 규칙만 적용합니다.

참고

SDK가 샘플링 규칙을 가져오기 위해 X-Ray에 연결할 수 없는 경우, 매초 첫 번째 요청과 호스트당 추가 요청의 5%에 대한 기본 로컬 규칙으로 되돌아갑니다. 호스트가 샘플링 API를 직접 호출할 수 있는 권한이 없거나, X-Ray 대몬(daemon)에 연결할 수 없을 경우 이러한 상황이 발생할 수 있고 이 대몬(daemon)은 SDK에서 수행한 API 직접 호출에 대한 TCP 프록시 역할을 합니다.

JSON 문서에서 샘플링 규칙을 불러오도록 SDK를 구성할 수도 있습니다. SDK는 X-Ray 샘플링을 사용할 수 없을 경우 로컬 규칙을 백업으로 사용하거나, 로컬 규칙을 전용으로 사용할 수 있습니다.

예 sampling-rules.json
{ "version": 2, "rules": [ { "description": "Player moves.", "host": "*", "http_method": "*", "url_path": "/api/move/*", "fixed_target": 0, "rate": 0.05 } ], "default": { "fixed_target": 1, "rate": 0.1 } }

이 예에서는 하나의 사용자 지정 규칙과 기본 규칙을 정의합니다. 사용자 지정 규칙은 최소 추적 요청 수 없이 5% 샘플링 비율을 /api/move/ 아래 경로에 적용합니다. 기본 규칙은 매초 최초 요청과 추가 요청의 10%를 추적합니다.

로컬로 규칙의 정의할 때의 단점은 고정 대상이 X-Ray 서비스를 통해 관리되는 대신, 레코더의 각 인스턴스별로 독립적으로 적용된다는 것입니다. 호스트를 많이 배포할수록 고정 속도가 크게 증대하기 때문에 기록되는 데이터의 양을 제어하기가 어려워집니다.

아니요 AWS Lambda, 샘플링 속도는 수정할 수 없습니다. 구성된 서비스가 함수를 호출하는 경우 해당 서비스에서 샘플링한 요청을 생성한 호출이 Lambda에 의해 기록됩니다. 활성 추적이 활성화되고 트레이스 헤더가 없는 경우 Lambda에서 샘플링 결정을 내립니다.

Spring에서 백업 규칙을 제공하려면 구성 클래스에서 CentralizedSamplingStrategy를 사용하여 전역 레코더를 구성합니다.

예 WebConfigsrc/main/java/myapp/.java - 레코더 구성
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorderBuilder; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; import com.amazonaws.xray.plugins.EC2Plugin; import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy; @Configuration public class WebConfig { static { AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()); URL ruleFile = WebConfig.class.getResource("/sampling-rules.json"); builder.withSamplingStrategy(new CentralizedSamplingStrategy(ruleFile)); AWSXRay.setGlobalRecorder(builder.build()); }

Tomcat의 경우 ServletContextListener를 확장하는 리스너를 추가하고 이 리스너를 배포 설명자에 등록합니다.

예 src/com/myapp/web/Startup.java
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorderBuilder; import com.amazonaws.xray.plugins.EC2Plugin; import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy; import java.net.URL; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class Startup implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent event) { AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()); URL ruleFile = Startup.class.getResource("/sampling-rules.json"); builder.withSamplingStrategy(new CentralizedSamplingStrategy(ruleFile)); AWSXRay.setGlobalRecorder(builder.build()); } @Override public void contextDestroyed(ServletContextEvent event) { } }
예 WEB-INF/web.xml
... <listener> <listener-class>com.myapp.web.Startup</listener-class> </listener>

로컬 규칙만 사용하려면 CentralizedSamplingStrategyLocalizedSamplingStrategy로 바꿉니다.

builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));

로깅

기본적으로 이 SDK는 ERROR 수준 및 수준 메시지를 애플리케이션 로그로 출력합니다. SDK에 대한 디버그 수준 로깅을 활성화하여 보다 상세한 로그를 애플리케이션 로그 파일로 출력할 수 있습니다. 유효한 로그 수준은DEBUG, INFO, WARN, ERROR, 및 FATAL입니다. FATAL 로그 수준은 SDK가 치명적 수준에서 로깅하지 않기 때문에 모든 로그 메시지를 무음 처리합니다.

예 애플리케이션 속성

logging.level.com.amazonaws.xray 속성을 사용하여 로깅 수준을 설정합니다.

logging.level.com.amazonaws.xray = DEBUG

디버그 로그를 사용하여 수동으로 하위 세그먼트를 생성할 때 미완료 하위 세그먼트와 같은 문제를 식별할 수 있습니다.

로그에 추적 ID 주입

현재 정규화된 트레이스 ID를 로그 문에 표시하려면 매핑된 진단 컨텍스트(MDC)에 해당 ID를 주입할 수 있습니다. 메서드는 SegmentListener 인터페이스를 사용하여 세그먼트 수명 주기 이벤트 중에 X-Ray 레코더에서 호출됩니다. 세그먼트 또는 하위 세그먼트가 시작되면 정규화된 트레이스 ID가 AWS-XRAY-TRACE-ID 키를 사용하여 MDC에 주입됩니다. 해당 세그먼트가 끝나면 MDC에서 키가 제거됩니다. 이렇게 하면 사용 중인 로깅 라이브러리에 트레이스 ID가 표시됩니다. 하위 세그먼트가 끝나면 부모 ID가 MDC에 주입됩니다.

예 정규화된 트레이스 ID

정규화된 ID는 TraceID@EntityID로 표시됩니다.

1-5df42873-011e96598b447dfca814c156@541b3365be3dafc3

이 기능은 Java용 AWS X-Ray SDK로 계측된 Java 애플리케이션에서 작동하며 다음과 같은 로깅 구성을 지원합니다.

  • Logback 백엔드가 있는 SLF4J 프런트 엔드 API

  • Log4J2 백엔드가 있는 SLF4J 프런트 엔드 API

  • Log4J2 백엔드가 있는 Log4J2 프런트 엔드 API

각 프런트 엔드와 각 백엔드의 요구 사항은 다음 탭을 참조하십시오.

SLF4J Frontend
  1. 다음 Maven 종속성을 프로젝트에 추가합니다.

    <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-slf4j</artifactId> <version>2.11.0</version> </dependency>
  2. AWSXRayRecorder를 구축할 때 withSegmentListener 메서드를 포함시킵니다. 이렇게 하면 새 트레이스 ID를 SLF4J MDC에 자동으로 주입하는 SegmentListener 클래스가 추가됩니다.

    SegmentListener는 선택적 문자열을 파라미터로 사용하여 log 문 접두사를 구성합니다. 접두사는 다음과 같은 방법으로 구성할 수 있습니다.

    • 없음 – 기본 AWS-XRAY-TRACE-ID 접두사를 사용합니다.

    • 비어 있음 – 빈 문자열(예: "")을 사용합니다.

    • 사용자 지정 – 문자열에 정의된 사용자 지정 접두사를 사용합니다.

    AWSXRayRecorderBuilder 명령문
    AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder .standard().withSegmentListener(new SLF4JSegmentListener("CUSTOM-PREFIX"));
Log4J2 front end
  1. 다음 Maven 종속성을 프로젝트에 추가합니다.

    <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-log4j</artifactId> <version>2.11.0</version> </dependency>
  2. AWSXRayRecorder를 구축할 때 withSegmentListener 메서드를 포함시킵니다. 이렇게 하면 새 정규화된 트레이스 ID를 SLF4J MDC에 자동으로 주입하는 SegmentListener 클래스가 추가됩니다.

    SegmentListener는 선택적 문자열을 파라미터로 사용하여 log 문 접두사를 구성합니다. 접두사는 다음과 같은 방법으로 구성할 수 있습니다.

    • 없음 – 기본 AWS-XRAY-TRACE-ID 접두사를 사용합니다.

    • 비어 있음 – 빈 문자열(예: "")을 사용하고 접두사를 제거합니다.

    • 사용자 지정 – 문자열에 정의된 사용자 지정 접두사를 사용합니다.

    AWSXRayRecorderBuilder 명령문
    AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder .standard().withSegmentListener(new Log4JSegmentListener("CUSTOM-PREFIX"));
Logback backend

트레이스 ID를 로그 이벤트에 삽입하려면 각 로깅 문의 형식을 지정하는 로거의 PatternLayout을 수정해야 합니다.

  1. patternLayout이 구성된 위치를 찾습니다. 이 작업은 프로그래밍 방식으로 또는 XML 구성 파일을 통해 수행할 수 있습니다. 자세한 내용은 Logback 구성을 참조하십시오.

  2. 이후 로깅 문에 트레이스 ID를 삽입하려면 patternLayout의 아무 곳에나 %X{AWS-XRAY-TRACE-ID}를 삽입합니다. %X{}는 MDC에서 제공된 키를 사용해 값을 검색하고 있음을 나타냅니다. PatternLayouts Logback에 대한 자세한 내용은 을 참조하십시오. PatternLayout

Log4J2 backend
  1. patternLayout이 구성된 위치를 찾습니다. 이 작업은 XML, JSON, YAML 또는 속성 형식으로 작성된 구성 파일을 통해 또는 프로그래밍 방식으로 수행할 수 있습니다.

    구성 파일을 통해 Log4J2를 구성하는 방법에 대한 자세한 내용은 구성을 참조하십시오.

    프로그래밍 방식으로 Log4J2를 구성하는 방법에 대한 자세한 내용은 프로그래밍 방식으로 구성을 참조하십시오.

  2. 이후 로깅 문에 트레이스 ID를 삽입하려면 PatternLayout의 아무 곳에나 %X{AWS-XRAY-TRACE-ID}를 삽입합니다. %X{}는 MDC에서 제공된 키를 사용해 값을 검색하고 있음을 나타냅니다. PatternLayoutsLog4J2에 대한 자세한 내용은 패턴 레이아웃을 참조하십시오.

트레이스 ID 주입 예제

다음은 트레이스 ID를 포함하도록 수정된 PatternLayout 문자열을 보여줍니다. 트레이스 ID는 스레드 이름(%t) 뒤에 및 로그 레벨(%-5p) 앞에 인쇄됩니다.

예 ID 주입이 있는 PatternLayout
%d{HH:mm:ss.SSS} [%t] %X{AWS-XRAY-TRACE-ID} %-5p %m%n

AWS X-Ray 쉽게 파싱할 수 있도록 로그문에 키와 추적 ID를 자동으로 인쇄합니다. 다음은 수정된 PatternLayout을 사용하는 로그 문을 보여줍니다.

예 ID 주입이 있는 로그 문
2019-09-10 18:58:30.844 [nio-5000-exec-4] AWS-XRAY-TRACE-ID: 1-5d77f256-19f12e4eaa02e3f76c78f46a@1ce7df03252d99e1 WARN 1 - Your logging message here

로깅 메시지 자체는 패턴 %m에 보관되며 로거를 호출할 때 설정됩니다.

세그먼트 리스너

세그먼트 리스너는 AWSXRayRecorder에 의해 생성된 세그먼트의 시작 및 끝과 같은 수명 주기 이벤트를 가로챌 수 있는 인터페이스입니다. 세그먼트 리스너 이벤트 함수의 구현은 onBeginSubsegment로 생성될 때 모든 하위 세그먼트에 동일한 주석을 추가하거나, afterEndSegment를 사용하여 각 세그먼트를 데몬에 전송한 후 메시지를 기록하거나, beforeEndSubsegment를 사용하여 SQL 인터셉터가 전송한 쿼리를 기록하여 하위 세그먼트가 SQL 쿼리를 나타내는지 확인하고, 그렇다면 추가적인 메타데이터를 추가합니다.

전체 SegmentListener 함수 목록을 보려면 AWS X-Ray X-Ray Recorder SDK for Java API에 대한 설명서를 참조하십시오.

다음 예제에서는 onBeginSubsegment를 사용하여 생성할 때 모든 하위 세그먼트에 일관된 주석을 추가하고 afterEndSegment를 사용하여 각 세그먼트의 끝에 로그 메시지를 인쇄하는 방법을 보여줍니다.

예 MySegmentListener.java
import com.amazonaws.xray.entities.Segment; import com.amazonaws.xray.entities.Subsegment; import com.amazonaws.xray.listeners.SegmentListener; public class MySegmentListener implements SegmentListener { ..... @Override public void onBeginSubsegment(Subsegment subsegment) { subsegment.putAnnotation("annotationKey", "annotationValue"); } @Override public void afterEndSegment(Segment segment) { // Be mindful not to mutate the segment logger.info("Segment with ID " + segment.getId()); } }

이 사용자 지정 세그먼트 리스너는 AWSXRayRecorder를 빌드할 때 참조됩니다.

예 AWSXRayRecorderBuilder 성명서
AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder .standard().withSegmentListener(new MySegmentListener());

환경 변수

환경 변수를 사용하여 Java용 X-Ray SDK를 구성할 수 있습니다. SDK는 다음 변수를 지원합니다.

  • AWS_XRAY_TRACING_NAME – SDK가 세그먼트에 사용할 서비스 이름을 설정합니다. 서블릿 필터의 세그먼트 이름 지정 전략에 설정한 서비스 이름을 재정의합니다.

  • AWS_XRAY_DAEMON_ADDRESS – X-Ray 대몬(daemon) 리스너의 호스트와 포트를 설정합니다. 기본적으로 SDK는 추적 데이터(UDP)와 샘플링(TCP) 모두에 127.0.0.1:2000을 사용합니다. 다른 포트에서 수신 대기하도록 대몬(daemon)을 구성한 경우 또는 다른 호스트에서 실행 중인 경우 이 변수를 사용합니다.

    형식
    • 동일한 포트address:port

    • 다른 포트tcp:address:port udp:address:port

  • AWS_XRAY_CONTEXT_MISSING – 열려 있는 세그먼트가 없는 경우 구성된 코드가 데이터를 기록하려고 할 때 발생하는 예외를 방지하려면 RUNTIME_ERROR로 설정합니다.

    유효한 값
    • RUNTIME_ERROR— 런타임 예외가 발생합니다.

    • LOG_ERROR – 오류를 기록하고 계속합니다 (기본값).

    • IGNORE_ERROR— 오류를 무시하고 계속합니다.

    열린 요청이 없을 때 실행되는 시작 코드 또는 새 스레드를 생성하는 코드에서 계측된 클라이언트를 사용하려고 하는 경우 누락된 세그먼트 또는 하위 세그먼트와 관련된 오류가 발생할 수 있습니다.

환경 변수는 코드에 설정된 동등한 시스템 속성 및 값을 재정의합니다.

시스템 속성

시스템 속성을 환경 변수에 대한 JVM 지정 대체로 사용할 수 있습니다. SDK는 다음 속성을 지원합니다.

  • com.amazonaws.xray.strategy.tracingNameAWS_XRAY_TRACING_NAME와 동등합니다.

  • com.amazonaws.xray.emitters.daemonAddressAWS_XRAY_DAEMON_ADDRESS와 동등합니다.

  • com.amazonaws.xray.strategy.contextMissingStrategyAWS_XRAY_CONTEXT_MISSING와 동등합니다.

시스템 속성과 환경 변수가 모두 설정될 경우 환경 변수 값이 사용됩니다. 어느 방법도 코드에 설정된 값을 재정의합니다.

Java용 X-Ray SDK로 수신 요청 추적하기

X-Ray SDK를 사용하여 애플리케이션이 Amazon EC2 또는 Amazon ECS의 EC2 인스턴스에서 처리하는 수신 HTTP 요청을 추적할 수 있습니다. AWS Elastic Beanstalk

Filter를 사용하여 수신 HTTP 요청을 구성합니다. 애플리케이션에 X-Ray 서블릿 필터를 추가하면 Java용 X-Ray SDK가 샘플링된 각 요청에 대해 세그먼트를 생성합니다. 이 세그먼트에는 HTTP 요청의 시간, 메서드 및 배치가 포함됩니다. 추가로 구성하면 이 세그먼트의 하위 세그먼트가 생성됩니다.

참고

AWS Lambda 함수의 경우 Lambda는 샘플링된 각 요청에 대해 세그먼트를 생성합니다. 자세한 정보는 AWS Lambda 그리고 AWS X-Ray을 참조하세요.

각 세그먼트에는 서비스 맵 안에서 애플리케이션을 식별하는 이름이 있습니다. 이 세그먼트의 이름이 정적으로 지정되도록 하거나, 수신 요청의 호스트 헤더를 기반으로 SDK가 동적으로 이름을 지정하도록 구성할 수 있습니다. 동적 이름 지정을 사용하면 요청의 도메인 이름에 따라 그룹을 추적하고 이름이 예상 패턴과 일치하지 않을 경우(예: 호스트 헤더가 위조된 경우) 기본 이름을 적용할 수 있습니다.

전달된 요청

로드 밸런서 또는 기타 중개자가 애플리케이션으로 요청을 전달하는 경우, X-Ray는 IP 패킷 내 소스 IP가 아니라 요청의 X-Forwarded-For 헤더로부터 클라이언트 IP를 가져옵니다. 전달된 요청에 대해 기록된 클라어언트 IP는 위조될 수 있으므로 신뢰하면 안 됩니다.

요청이 전달되면 SDK는 세그먼트에 추가 필드를 설정하여 이를 나타냅니다. 세그먼트에 x_forwarded_for로 설정된 true 필드가 포함된 경우 클라이언트 IP는 HTTP 요청의 X-Forwarded-For 헤더로부터 가져옵니다.

메시지 핸들러는 다음 정보를 포함하는 http 블록을 이용해 각 수신 요청에 대한 세그먼트를 생성합니다.

  • HTTP 메서드 – GET, POST, PUT, DELETE 등.

  • 클라이언트 주소 – 요청을 전송한 클라이언트의 IP 주소.

  • 응답 코드 – 완료된 요청의 HTTP 응답 코드.

  • 시간 – 시작 시간(요청 수신) 및 종료 시간(응답 전송).

  • 유저 에이전트 — 요청에서 가져온 user-agent입니다.

  • 콘텐츠 길이 — 응답의 content-length입니다.

애플리케이션에 추적 필터 추가(Tomcat)

Tomcat의 경우, <filter>를 프로젝트의 web.xml 파일에 추가합니다. fixedName 파라미터로 수신 요청을 위해 생성된 세그먼트에 적용할 서비스 이름을 지정하십시오.

예 WEB-INF/web.xml – Tomcat
<filter> <filter-name>AWSXRayServletFilter</filter-name> <filter-class>com.amazonaws.xray.javax.servlet.AWSXRayServletFilter</filter-class> <init-param> <param-name>fixedName</param-name> <param-value>MyApp</param-value> </init-param> </filter> <filter-mapping> <filter-name>AWSXRayServletFilter</filter-name> <url-pattern>*</url-pattern> </filter-mapping>

애플리케이션에 추적 필터 추가(Spring)

Spring의 경우, FilterWebConfig 클래스에 추가합니다. 세그먼트 이름을 하나의 문자열로 AWSXRayServletFilter 생성자에 보냅니다.

예 src/main/java/myapp/.java - 스프링 WebConfig
package myapp; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import javax.servlet.Filter; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter("Scorekeep"); } }

세그먼트 이름 지정 전략 구성

AWS X-Ray 서비스 이름을 사용하여 애플리케이션을 식별하고 애플리케이션에서 사용하는 다른 애플리케이션, 데이터베이스, 외부 API 및 리소스와 구별합니다. AWS X-Ray SDK는 수신 요청에 대한 세그먼트를 생성할 때 해당 세그먼트의 이름 필드에 애플리케이션의 서비스 이름을 기록합니다.

X-Ray SDK는 HTTP 요청 헤더의 호스트 이름 뒤에 세그먼트를 지정할 수 있습니다. 그러나 이 헤더가 위조되면 서비스 맵에 예기치 않은 노드가 발생할 수 있습니다. 위조된 호스트 헤더가 포함된 요청으로 인해 SDK가 잘못된 세그먼트 이름을 지정하는 현상을 방지하려면 들어오는 요청의 기본 이름을 지정해야 합니다.

애플리케이션이 여러 도메인의 요청을 처리하는 경우, 동적 이름 지정 전략을 사용하여 이를 세그먼트 이름에 반영하도록 SDK를 구성할 수 있습니다. 동적 이름 지정 전략을 사용하면 SDK가 예상 패턴과 일치하는 요청에 호스트 이름을 사용하고, 그렇지 않은 요청에 기본 이름을 적용할 수 있습니다.

예를 들어, 하나의 애플리케이션이 세 개의 하위 도메인 (www.example.com, api.example.com, static.example.com) 에 요청을 전송할 수 있습니다. *.example.com 패턴으로 동적 이름 지정 전략을 사용하여 각 하위도메인의 세그먼트를 서로 다른 이름으로 표시하면 서비스 맵에 서비스 노드가 세 개 생깁니다. 이 패턴에 맞지 않는 호스트 이름의 요청이 애플리케이션에 수신되면, 사용자가 지정한 대체 이름의 네 번째 노드가 서비스 맵에 표시됩니다.

모든 요청 세그먼트에 같은 이름을 사용하려면, 이전 단원에 나온 것처럼 서블릿 필터를 초기화할 때 애플리케이션 이름을 지정하십시오. 이는 수정자를 SegmentNamingStrategy.fixed() 호출하고 AWSXRayServletFilter생성자에 SegmentNamingStrategy전달하여 수정 버전을 만드는 것과 같은 효과가 있습니다.

참고

코드에 정의한 기본 서비스 이름을 AWS_XRAY_TRACING_NAME 환경 변수를 사용하여 재정의할 수 있습니다.

동적 이름 지정 전략은 호스트 이름이 일치해야 하는 패턴 및 HTTP 요청의 호스트 이름이 패턴과 일치하지 않는 경우 사용할 기본 이름을 정의합니다. Tomcat에서 세그먼트 이름을 동적으로 지정하려면, dynamicNamingRecognizedHostsdynamicNamingFallbackName을 이용해 패턴과 기본 이름을 따로 정의하십시오.

예 WEB-INF/web.xml – 동적 이름 지정을 이용하는 서블릿 필터
<filter> <filter-name>AWSXRayServletFilter</filter-name> <filter-class>com.amazonaws.xray.javax.servlet.AWSXRayServletFilter</filter-class> <init-param> <param-name>dynamicNamingRecognizedHosts</param-name> <param-value>*.example.com</param-value> </init-param> <init-param> <param-name>dynamicNamingFallbackName</param-name> <param-value>MyApp</param-value> </init-param> </filter> <filter-mapping> <filter-name>AWSXRayServletFilter</filter-name> <url-pattern>*</url-pattern> </filter-mapping>

Spring의 경우, 를 SegmentNamingStrategy호출하여 SegmentNamingStrategy.dynamic() 동적을 만든 다음 AWSXRayServletFilter 생성자에 전달하십시오.

예 WebConfigsrc/main/java/myapp/ .java - 동적 네이밍을 사용하는 서블릿 필터
package myapp; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import javax.servlet.Filter; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; import com.amazonaws.xray.strategy.SegmentNamingStrategy; @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter(SegmentNamingStrategy.dynamic("MyApp", "*.example.com")); } }

Java용 X-Ray AWS SDK를 사용하여 SDK 호출 추적하기

애플리케이션이 를 AWS 서비스 호출하여 데이터를 저장하거나, 대기열에 기록하거나, 알림을 보내는 경우, X-Ray SDK for Java는 호출을 하위 세그먼트로 다운스트림으로 추적합니다. 해당 서비스 (예: Amazon S3 버킷 또는 Amazon SQS 대기열) 내에서 액세스하는 추적 AWS 서비스 및 리소스는 X-Ray 콘솔의 추적 맵에 다운스트림 노드로 표시됩니다.

빌드에서 aws-sdkaws-sdk-instrumentor 하위 모듈을 포함하면 Java용 X-Ray SDK가 모든 AWS SDK 클라이언트를 자동으로 계측합니다. Instrumentor 하위 모듈을 포함하지 않을 경우 다른 클라이언트는 배제하고 일부 클라이언트만 선택하여 구성할 수 있습니다.

개별 클라이언트를 계측하려면 빌드에서 aws-sdk-instrumentor 하위 모듈을 제거하고 서비스의 클라이언트 빌더를 사용하여 AWS SDK 클라이언트에 XRayClient as를 추가하십시오. TracingHandler

예를 들어 AmazonDynamoDB 클라이언트를 구성하려면 트레이스 핸들러를AmazonDynamoDBClientBuilder로 전달합니다.

예 MyModel.java - DynamoDB 클라이언트
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.handlers.TracingHandler; ... public class MyModel { private AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard() .withRegion(Regions.fromName(System.getenv("AWS_REGION"))) .withRequestHandlers(new TracingHandler(AWSXRay.getGlobalRecorder())) .build(); ...

모든 서비스의 경우, X-Ray 콘솔에서 호출된 API의 이름을 볼 수 있습니다. 서비스 하위 집합에 대해서는 X-Ray SDK가 세그먼트에 정보를 추가하여 서비스 맵에서 추가 세분화를 제공합니다.

예를 들어 계측된 DynamoDB 클라이언트에서 직접 호출을 생성하는 경우 SDK가 특정 테이블을 대상으로 한 직접 호출에 대해 테이블 이름을 세그먼트에 추가합니다. 콘솔에서, 각 테이블이 개별 노드로 서비스 맵에 표시되고, 특정 테이블을 대상으로 하지 않은 직접 호출에 대해 일반 DynamoDB 노드가 표시됩니다.

예 항목을 저장하기 위한 DynamoDB 직접 호출에 대한 하위 세그먼트
{ "id": "24756640c0d0978a", "start_time": 1.480305974194E9, "end_time": 1.4803059742E9, "name": "DynamoDB", "namespace": "aws", "http": { "response": { "content_length": 60, "status": 200 } }, "aws": { "table_name": "scorekeep-user", "operation": "UpdateItem", "request_id": "UBQNSO5AEM8T4FDA4RQDEB94OVTDRVV4K4HIRGVJF66Q9ASUAAJG", } }

명명된 리소스에 액세스할 때 다음 서비스를 호출할 경우 서비스 맵에 추가 노드가 생성됩니다. 특정 리소스를 대상으로 하지 않는 경우 서비스를 직접 호출하면 해당 서비스에 대한 일반 노드가 생성됩니다.

  • Amazon DynamoDB – 테이블 이름

  • Amazon Simple Storage Service –버킷 및 키 이름

  • Amazon Simple Queue Service – 대기열 이름

AWS SDK for Java 2.2 이상에서 다운스트림 호출을 계측하려면 AWS 서비스 빌드 구성에서 aws-xray-recorder-sdk-aws-sdk-v2-instrumentor 모듈을 생략할 수 있습니다. 대신 aws-xray-recorder-sdk-aws-sdk-v2 module을 포함한 다음, TracingInterceptor로 구성하여 개별 클라이언트를 계측합니다.

예 AWS SDK for Java 2.2 이상 - 트레이싱 인터셉터
import com.amazonaws.xray.interceptors.TracingInterceptor; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration import software.amazon.awssdk.services.dynamodb.DynamoDbClient; //... public class MyModel { private DynamoDbClient client = DynamoDbClient.builder() .region(Region.US_WEST_2) .overrideConfiguration(ClientOverrideConfiguration.builder() .addExecutionInterceptor(new TracingInterceptor()) .build() ) .build(); //...

Java용 X-Ray SDK를 사용하여 다운스트림 HTTP 웹 서비스에 대한 호출 추적하기

애플리케이션이 마이크로서비스 또는 공개 HTTP API를 호출할 때 Java용 X-Ray SDK 버전의 HttpClient를 사용하여 해당 호출을 계측하고 API를 다운스트림 서비스로 서비스 그래프에 추가할 수 있습니다.

Java용 X-Ray SDK에는 발신 HttpClientBuilder HTTP 호출을 계측하는 데 사용할 수 있는 HttpComponents Apache SDK 대신 사용할 수 있는 클래스가 DefaultHttpClient 포함되어 있습니다.

  • com.amazonaws.xray.proxies.apache.http.DefaultHttpClient - org.apache.http.impl.client.DefaultHttpClient

  • com.amazonaws.xray.proxies.apache.http.HttpClientBuilder - org.apache.http.impl.client.HttpClientBuilder

이러한 라이브러리는 aws-xray-recorder-sdk-apache-http 하위 모듈에 있습니다.

모든 클라이언트를 계측하기 위해 기존 가져오기 문을 X-Ray에 해당하는 것으로 대체하거나, 특정 클라이언트를 계측하기 위해 클라이언트를 초기화할 때 정규화된 이름을 사용할 수 있습니다.

예 HttpClientBuilder
import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import com.amazonaws.xray.proxies.apache.http.HttpClientBuilder; ... public String randomName() throws IOException { CloseableHttpClient httpclient = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet("http://names.example.com/api/"); CloseableHttpResponse response = httpclient.execute(httpGet); try { HttpEntity entity = response.getEntity(); InputStream inputStream = entity.getContent(); ObjectMapper mapper = new ObjectMapper(); Map<String, String> jsonMap = mapper.readValue(inputStream, Map.class); String name = jsonMap.get("name"); EntityUtils.consume(entity); return name; } finally { response.close(); } }

다운스트림 웹 API에 대한 직접 호출을 계측할 때 Java용 X-Ray SDK가 HTTP 요청 및 응답에 대한 정보가 포함된 하위 세그먼트를 기록합니다. X-Ray는 하위 세그먼트를 사용하여 원격 API에 대해 추정된 세그먼트를 생성합니다.

예 다운스트림 HTTP 호출에 대한 하위 세그먼트
{ "id": "004f72be19cddc2a", "start_time": 1484786387.131, "end_time": 1484786387.501, "name": "names.example.com", "namespace": "remote", "http": { "request": { "method": "GET", "url": "https://names.example.com/" }, "response": { "content_length": -1, "status": 200 } } }
예 다운스트림 HTTP 호출에 대한 추정된 세그먼트
{ "id": "168416dc2ea97781", "name": "names.example.com", "trace_id": "1-62be1272-1b71c4274f39f122afa64eab", "start_time": 1484786387.131, "end_time": 1484786387.501, "parent_id": "004f72be19cddc2a", "http": { "request": { "method": "GET", "url": "https://names.example.com/" }, "response": { "content_length": -1, "status": 200 } }, "inferred": true }

Java용 X-Ray SDK로 SQL 쿼리 추적하기

SQL 인터셉터

Java용 X-Ray SDK JDBC 인터셉터를 데이터 소스 구성에 추가해 SQL 데이터베이스 쿼리를 계측하십시오.

  • PostgreSQLcom.amazonaws.xray.sql.postgres.TracingInterceptor

  • MySQLcom.amazonaws.xray.sql.mysql.TracingInterceptor

이러한 인터셉터는 각각 aws-xray-recorder-sql-postgres 및 aws-xray-recorder-sql-mysql 하위 모듈에 있습니다. 인터셉터는 org.apache.tomcat.jdbc.pool.JdbcInterceptor를 구현하며 Tomcat 연결 풀과 호환됩니다.

참고

SQL 인터셉터는 보안을 위해 하위 세그먼트 내에서 SQL 쿼리 자체를 기록하지 않습니다.

Spring인 경우에는 인터셉터를 속성 파일에 추가하고 Spring Boot의 DataSourceBuilder로 데이터 소스를 구축하십시오.

src/main/java/resources/application.properties - PostgreSQL JDBC 인터셉터
spring.datasource.continue-on-error=true spring.jpa.show-sql=false spring.jpa.hibernate.ddl-auto=create-drop spring.datasource.jdbc-interceptors=com.amazonaws.xray.sql.postgres.TracingInterceptor spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL94Dialect
src/main/java/myapp/WebConfig.java - 데이터 소스
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import javax.servlet.Filter; import javax.sql.DataSource; import java.net.URL; @Configuration @EnableAutoConfiguration @EnableJpaRepositories("myapp") public class RdsWebConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { logger.info("Initializing PostgreSQL datasource"); return DataSourceBuilder.create() .driverClassName("org.postgresql.Driver") .url("jdbc:postgresql://" + System.getenv("RDS_HOSTNAME") + ":" + System.getenv("RDS_PORT") + "/ebdb") .username(System.getenv("RDS_USERNAME")) .password(System.getenv("RDS_PASSWORD")) .build(); } ... }

Tomcat의 경우에는 JDBC 데이터 소스에서 Java용 X-Ray SDK 클래스를 참조하여 setJdbcInterceptors를 직접 호출합니다.

src/main/myapp/model.java - 데이터 소스
import org.apache.tomcat.jdbc.pool.DataSource; ... DataSource source = new DataSource(); source.setUrl(url); source.setUsername(user); source.setPassword(password); source.setDriverClassName("com.mysql.jdbc.Driver"); source.setJdbcInterceptors("com.amazonaws.xray.sql.mysql.TracingInterceptor;");

Tomcat JDBC 데이터 소스 라이브러리는 Java용 X-Ray SDK에 포함되지만, 사용하는 문서에 제공된 종속성으로 이 라이브러리를 선언할 수 있습니다.

pom.xml - JDBC 데이터 소스
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> <version>8.0.36</version> <scope>provided</scope> </dependency>

네이티브 SQL 트레이싱 데코레이터

  • aws-xray-recorder-sdk-sql을 종속성에 추가합니다.

  • 데이터베이스 데이터 소스, 연결 또는 명령문을 꾸며보세요.

    dataSource = TracingDataSource.decorate(dataSource) connection = TracingConnection.decorate(connection) statement = TracingStatement.decorateStatement(statement) preparedStatement = TracingStatement.decoratePreparedStatement(preparedStatement, sql) callableStatement = TracingStatement.decorateCallableStatement(callableStatement, sql)

Java용 X-Ray SDK를 사용하여 사용자 지정 하위 세그먼트 생성하기

하위 세그먼트는 추적의 세그먼트를 확장하여 요청을 처리하기 위해 완료된 작업에 대한 세부 정보를 표시합니다. 계측되는 클라이언트에서 직접 호출할 때마다, X-Ray SDK는 하위 세그먼트 안에 생성된 정보를 기록합니다. 추가 하위 세그먼트를 생성하여 다른 하위 세그먼트를 그룹화하거나, 코드 섹션의 성능을 평가하거나, 주석 및 메타데이터를 기록할 수 있습니다.

하위 세그먼트를 관리하려면 beginSubsegmentendSubsegment 메서드를 사용합니다.

예 GameModel.java - 사용자 지정 하위 세그먼트
import com.amazonaws.xray.AWSXRay; ... public void saveGame(Game game) throws SessionNotFoundException { // wrap in subsegment Subsegment subsegment = AWSXRay.beginSubsegment("Save Game"); try { // check session String sessionId = game.getSession(); if (sessionModel.loadSession(sessionId) == null ) { throw new SessionNotFoundException(sessionId); } mapper.save(game); } catch (Exception e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(); } }

이 예제에서 하위 세그먼트 내의 코드는 세션 모델의 메서드를 사용하여 DynamoDB에서 게임 세션을 로드하고 AWS SDK for Java의 DynamoDB 매퍼를 사용하여 게임을 저장합니다. 하위 세그먼트에서 이 코드를 래핑하면 콘솔의 추적 보기에서 Save Game 하위 세그먼트의 DynamoDB 하위가 호출됩니다.

하위 세그먼트 내 코드가 확인된 예외를 내보낼 경우 하위 세그먼트가 항상 닫히도록 코드를 try 블록에 래핑하고 finally 블록에서 AWSXRay.endSubsegment()를 호출합니다. 하위 세그먼트가 닫히지 않는 경우 상위 세그먼트가 완료될 수 없으며 X-Ray로 전송되지 않습니다.

확인된 예외를 내보내지 않는 코드의 경우 코드를 Lambda 함수로 AWSXRay.CreateSubsegment에 전달할 수 있습니다.

예 하위 세그먼트 Lambda 함수
import com.amazonaws.xray.AWSXRay; AWSXRay.createSubsegment("getMovies", (subsegment) -> { // function code });

하위 세그먼트를 세그먼트 또는 다른 하위 세그먼트 내에서 생성하면 Java용 X-Ray SDK가 해당 하위 세그먼트에 대해 ID를 생성하고 시작 시간 및 종료 시간을 기록합니다.

예 메타데이터가 포함된 하위 세그먼트
"subsegments": [{ "id": "6f1605cd8a07cb70", "start_time": 1.480305974194E9, "end_time": 1.4803059742E9, "name": "Custom subsegment for UserModel.saveUser function", "metadata": { "debug": { "test": "Metadata string from UserModel.saveUser" } },

비동기 및 다중 스레드 프로그래밍의 경우 비동기 실행 중에 X-Ray 컨텍스트가 수정될 수 있으므로 하위 세그먼트를 endSubsegment() 메서드에 수동으로 전달하여 올바르게 닫히도록 해야 합니다. 상위 세그먼트가 닫힌 후 비동기 하위 세그먼트가 닫히면, 이 메서드는 전체 세그먼트를 자동으로 X-Ray 대몬(daemon)으로 스트리밍합니다.

예 비동기 서브세그먼트
@GetMapping("/api") public ResponseEntity<?> api() { CompletableFuture.runAsync(() -> { Subsegment subsegment = AWSXRay.beginSubsegment("Async Work"); try { Thread.sleep(3000); } catch (InterruptedException e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(subsegment); } }); return ResponseEntity.ok().build(); }

Java용 X-Ray SDK로 세그먼트에 주석 및 메타데이터 추가하기

주석과 메타데이터를 사용하여 요청, 환경 또는 애플리케이션에 대한 추가 정보를 기록할 수 있습니다. X-Ray SDK에서 생성하는 세그먼트 또는 사용자가 생성하는 사용자 지정 하위 세그먼트에 주석 및 메타데이터를 추가할 수 있습니다.

주석은 문자열, 숫자 또는 부울 값과 결합한 키-값 페어입니다. 주석은 필터 표현식에서 사용하기 위해 인덱싱됩니다. 주석은 콘솔의 트레이스를 그룹화할 때 사용할 데이터를 기록하거나 GetTraceSummaries API를 호출할 때 사용하십시오.

메타데이터는 객체 및 목록을 포함한 모든 유형의 값을 가질 수 있는 키-값 페어지만, 필터 표현식에 사용할 수 있도록 인덱싱되지는 않습니다. 트레이스에 저장하고 싶지만 검색에는 사용하지 않을 추가 데이터는 메타데이터를 사용하여 기록하십시오.

세그먼트에는 주석과 메타데이터 외에 사용자 ID 문자열도 기록할 수 있습니다. 사용자 ID는 세그먼트의 별도 필드에 기록되면 검색용으로 인덱스되지 않습니다.

Java용 X-Ray SDK로 주석 기록하기

주석을 사용하여 검색용으로 인덱싱할 정보를 세그먼트나 하위 세그먼트에 기록하십시오.

주석 요구 사항
  • — X-Ray 주석의 키는 최대 500자의 영숫자를 포함할 수 있습니다. 밑줄 기호 (_) 이외의 공백이나 기호는 사용할 수 없습니다.

  • — X-Ray 주석의 값은 최대 1,000개의 유니코드 문자를 포함할 수 있습니다.

  • 주석 수 — 트레이스당 최대 50개의 주석을 사용할 수 있습니다.

주석 기록 방법
  1. AWSXRay에서 현재 세그먼트나 하위 세그먼트의 참조를 가져오십시오.

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; ... Segment document = AWSXRay.getCurrentSegment();

    또는

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Subsegment; ... Subsegment document = AWSXRay.getCurrentSubsegment();
  2. 문자열 키, 부울, 숫자 또는 문자열 값으로 putAnnotation을 호출합니다.

    document.putAnnotation("mykey", "my value");

SDK는 세그먼트 문서의 annotations 객체에 주석을 키-값 페어로 기록합니다. 같은 키로 putAnnotation을 두 번 호출하면 같은 세그먼트나 하위 세그먼트에 기록했던 값을 덮어씁니다.

특정 값을 포함한 주석이 있는 트레이스를 찾으려면 annotations.key 키워드를 필터 표현식에 사용하십시오.

src/main/java/scorekeep/GameModel.java – 주석 및 메타데이터
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; import com.amazonaws.xray.entities.Subsegment; ... public void saveGame(Game game) throws SessionNotFoundException { // wrap in subsegment Subsegment subsegment = AWSXRay.beginSubsegment("## GameModel.saveGame"); try { // check session String sessionId = game.getSession(); if (sessionModel.loadSession(sessionId) == null ) { throw new SessionNotFoundException(sessionId); } Segment segment = AWSXRay.getCurrentSegment(); subsegment.putMetadata("resources", "game", game); segment.putAnnotation("gameid", game.getId()); mapper.save(game); } catch (Exception e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(); } }

Java용 X-Ray SDK로 메타데이터 기록하기

메타데이터를 이용해 검색용으로 인덱싱하지 않아도 되는 정보를 세그먼트나 하위 세그먼트에 기록하십시오. 메타데이터 값은 문자열, 숫자, 부울 또는 JSON 객체나 어레이에 직렬화할 수 있는 모든 객체가 될 수 있습니다.

메타데이터 기록 방법
  1. AWSXRay에서 현재 세그먼트나 하위 세그먼트의 참조를 가져오십시오.

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; ... Segment document = AWSXRay.getCurrentSegment();

    또는

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Subsegment; ... Subsegment document = AWSXRay.getCurrentSubsegment();
  2. 문자열 네임스페이스, 문자열 키 및 부울, 숫자, 문자열 또는 객체 값으로 putMetadata를 호출합니다.

    document.putMetadata("my namespace", "my key", "my value");

    또는

    키와 값만 이용해 putMetadata를 호출합니다.

    document.putMetadata("my key", "my value");

네임스페이스를 지정하지 않으면, SDK는 default를 사용합니다. 같은 키로 putMetadata을 두 번 호출하면 같은 세그먼트나 하위 세그먼트에 기록했던 값을 덮어씁니다.

src/main/java/scorekeep/GameModel.java – 주석 및 메타데이터
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; import com.amazonaws.xray.entities.Subsegment; ... public void saveGame(Game game) throws SessionNotFoundException { // wrap in subsegment Subsegment subsegment = AWSXRay.beginSubsegment("## GameModel.saveGame"); try { // check session String sessionId = game.getSession(); if (sessionModel.loadSession(sessionId) == null ) { throw new SessionNotFoundException(sessionId); } Segment segment = AWSXRay.getCurrentSegment(); subsegment.putMetadata("resources", "game", game); segment.putAnnotation("gameid", game.getId()); mapper.save(game); } catch (Exception e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(); } }

Java용 X-Ray SDK로 사용자 ID 기록하기

사용자 ID를 요청 세그먼트에 기록하여 요청을 보낸 사용자를 식별합니다.

사용자 ID 기록 방법
  1. AWSXRay에서 현재 세그먼트에 대한 참조를 가져옵니다.

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; ... Segment document = AWSXRay.getCurrentSegment();
  2. 요청을 보낸 사용자의 문자열 ID로 setUser를 호출합니다.

    document.setUser("U12345");

컨트롤러에서 setUser를 호출하면 애플리케이션이 요청을 처리하는 순간부터 사용자 ID를 기록할 수 있습니다. 사용자 ID 설정용으로만 세그먼트를 사용한다면, 호출을 1줄로 연결할 수 있습니다.

src/main/java/scorekeep/ .java — 사용자 ID MoveController
import com.amazonaws.xray.AWSXRay; ... @RequestMapping(value="/{userId}", method=RequestMethod.POST) public Move newMove(@PathVariable String sessionId, @PathVariable String gameId, @PathVariable String userId, @RequestBody String move) throws SessionNotFoundException, GameNotFoundException, StateNotFoundException, RulesException { AWSXRay.getCurrentSegment().setUser(userId); return moveFactory.newMove(sessionId, gameId, userId, move); }

사용자 ID의 트레이스를 찾으려면, user 키워드를 필터 표현식에 적용하십시오.

AWS X-Ray Java용 X-Ray SDK의 메트릭스

이 항목에서는 AWS X-Ray 네임스페이스, 지표 및 차원에 대해 설명합니다. Java용 X-Ray SDK를 사용하여 수집된 X-Ray 세그먼트에서 샘플링되지 않은 CloudWatch Amazon 지표를 게시할 수 있습니다. 이러한 지표는 세그먼트의 시작 및 종료 시간과 오류, 장애 및 스로틀된 상태 플래그에서 파생됩니다. 이러한 트레이스 지표를 사용하여 하위 세그먼트 내에서 재시도 및 종속성 문제를 표시할 수 있습니다.

CloudWatch 기본적으로 지표 리포지토리입니다. 지표는 의 기본 CloudWatch 개념이며 시간에 따라 정렬된 데이터 요소 집합을 나타냅니다. 지표 데이터 포인트를 게시하거나 AWS 서비스해당 데이터 포인트에 대한 통계를 정렬된 시계열 데이터 세트로 검색합니다. CloudWatch

지표는 이름, 네임스페이스 및 하나 이상의 차원으로 고유하게 정의됩니다. 각 데이터 포인트에는 타임스탬프가 있으며 선택 사항으로 측정 단위가 있습니다. 통계를 요청하면 네임스페이스, 지표 이름 및 차원으로 반환된 데이터 스트림이 식별됩니다.

에 대한 CloudWatch 자세한 내용은 Amazon CloudWatch 사용 설명서를 참조하십시오.

X-Ray CloudWatch 메트릭스

ServiceMetrics/SDK 네임스페이스에 포함된 지표는 다음과 같습니다.

지표 사용 가능 통계 설명 단위

Latency

평균, 최소, 최대, 개수

시작 시간과 종료 시간 간의 차이입니다. 평균, 최소 및 최대 항목은 모두 작업 지연 시간을 나타냅니다. 개수는 호출 수를 나타냅니다.

밀리초

ErrorRate

평균, 합계

4xx Client Error 상태 코드로 실패하여 오류가 발생한 요청 비율입니다.

%

FaultRate

평균, 합계

5xx Server Error 상태 코드로 실패하여 오류가 발생한 트레이스 비율입니다.

%

ThrottleRate

평균, 합계

429 상태 코드를 반환하는 스로틀된 트레이스 비율입니다. 이는 ErrorRate 지표의 하위 집합입니다.

%

OkRate

평균, 합계

OK 상태 코드를 발생시킨 트레이스된 요청 비율입니다.

%

X선 CloudWatch 치수

다음 표의 치수를 사용하여 X-Ray 계측된 Java 애플리케이션에 대해 반환되는 지표를 구체화할 수 있습니다.

치수 설명

ServiceType

서비스 유형 (예: AWS::EC2::Instance 또는 알 수 없는 경우 NONE)입니다.

ServiceName

서비스의 정식 이름입니다.

X-Ray CloudWatch 지표 활성화

구성된 Java 애플리케이션에서 트레이스 지표를 활성화하려면 다음 절차를 따릅니다.

트레이스 지표를 구성하려면
  1. Maven 종속성으로서 aws-xray-recorder-sdk-metrics 패키지를 추가합니다. 자세한 내용은 Java 서브모듈용 X-Ray SDK를 참조하세요.

  2. 전역 레코더 빌드의 일부로서 새 MetricsSegmentListener()를 활성화합니다.

    예 src/com/myapp/web/Startup.java
    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorderBuilder; import com.amazonaws.xray.plugins.EC2Plugin; import com.amazonaws.xray.plugins.ElasticBeanstalkPlugin; import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy; @Configuration public class WebConfig { ... static { AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder .standard() .withPlugin(new EC2Plugin()) .withPlugin(new ElasticBeanstalkPlugin()) .withSegmentListener(new MetricsSegmentListener()); URL ruleFile = WebConfig.class.getResource("/sampling-rules.json"); builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile)); AWSXRay.setGlobalRecorder(builder.build()); } }
  3. Amazon Elastic Compute Cloud (Amazon EC2), 아마존 Elastic Container Service (Amazon ECS) 또는 아마존 Elastic Kubernetes 서비스 (Amazon EKS) 를 사용하여 지표를 수집하도록 CloudWatch 에이전트를 배포합니다.

  4. 에이전트와 통신하도록 SDK를 구성합니다. CloudWatch 기본적으로 SDK는 주소의 CloudWatch 에이전트와 통신합니다. 127.0.0.1 환경 변수 또는 Java 속성을 address:port로 설정하여 대체 주소를 구성할 수 있습니다.

    예 환경 변수
    AWS_XRAY_METRICS_DAEMON_ADDRESS=address:port
    예 Java 속성
    com.amazonaws.xray.metrics.daemonAddress=address:port
구성을 확인하려면
  1. https://console.aws.amazon.com/cloudwatch/ 에서 AWS Management Console 로그인하고 CloudWatch 콘솔을 엽니다.

  2. 지표 탭을 열어 지표의 유입을 관찰합니다.

  3. (선택 사항) CloudWatch 콘솔의 로그 탭에서 ServiceMetricsSDK 로그 그룹을 엽니다. 호스트 지표와 일치하는 로그 스트림을 찾고 로그 메시지를 확인합니다.

멀티스레드 애플리케이션에서 스레드 간 세그먼트 컨텍스트 전달

애플리케이션에서 새 스레드를 생성하는 경우 AWSXRayRecorder가 현재 세그먼트 또는 하위 세그먼트 개체에 대한 참조를 유지하지 않습니다. 새 스레드에서 인스트루먼트된 클라이언트를 사용하는 경우 SDK가 존재하지 않는 세그먼트에 쓰려고 시도하여 오류가 발생합니다. SegmentNotFoundException

개발 중에 예외가 발생하지 않도록 하려면 대신 오류를 기록하도록 ContextMissingStrategy지시하는 레코더를 구성할 수 있습니다. 를 사용하여 코드로 SetContextMissingStrategy전략을 구성하거나 환경 변수 또는 시스템 속성을 사용하여 동등한 옵션을 구성할 수 있습니다.

오류를 처리하는 하나의 방법은 스레드를 시작할 때 beginSegment를 호출하고 스레드를 닫을 때 endSegment를 호출하여 새 세그먼트를 사용하는 것입니다. 이는 애플리케이션이 시작할 때 실행하는 코드와 같이 HTTP 요청에 대한 응답에서 실행하지 않는 코드를 구성하는 경우 유용합니다.

여러 스레드를 사용하여 수신 요청을 처리하는 경우 현재 세그먼트 또는 하위 세그먼트를 새 스레드에 전달하고 이를 전역 레코더에 제공할 수 있습니다. 이렇게 하면 새 스레드 내에서 레코딩된 정보가 해당 요청에 대해 레코딩된 나머지 정보와 동일한 세그먼트와 연결됩니다. 새 스레드에서 세그먼트를 사용할 수 있게 되면 segment.run(() -> { ... }) 메서드를 사용하여 해당 세그먼트의 컨텍스트에 대한 액세스 권한이 있는 실행 가능 항목을 실행할 수 있습니다.

예제는 작업자 스레드에서 구성된 클라이언트 사용 단원을 참조하세요.

비동기 프로그래밍과 함께 X-Ray 사용하기

Java용 X-Ray SDK는 다음과 같은 비동기 자바 프로그램에서 사용할 수 있습니다. SegmentContextExecutors 는 Executor 인터페이스를 SegmentContextExecutor 구현합니다. 즉, a의 모든 비동기 작업에 이 인터페이스를 전달할 수 있습니다. CompletableFuture 이렇게 하면 모든 비동기 작업이 해당 컨텍스트에서 올바른 세그먼트를 사용하여 실행될 수 있습니다.

예제 App.java: 전달 대상 SegmentContextExecutor CompletableFuture
DynamoDbAsyncClient client = DynamoDbAsyncClient.create(); AWSXRay.beginSegment(); // ... client.getItem(request).thenComposeAsync(response -> { // If we did not provide the segment context executor, this request would not be traced correctly. return client.getItem(request2); }, SegmentContextExecutors.newSegmentContextExecutor());

Spring 및 Java용 X-Ray SDK를 사용한 AOP

이 주제에서는 X-Ray SDK와 Spring 프레임워크를 사용하여 핵심 로직을 변경하지 않고 애플리케이션을 구성하는 방법을 설명합니다. 즉, 이제 원격으로 실행 중인 애플리케이션을 비침습적으로 계측할 수 있는 방법이 있습니다. AWS

Spring 구성하기

Maven 또는 Gradle을 사용하면 AOP를 사용해 애플리케이션을 도구화하도록 Spring을 구성할 수 있습니다.

Maven을 사용하여 애플리케이션을 빌드하는 경우 pom.xml 파일에서 다음 종속성을 추가합니다.

<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-spring</artifactId> <version>2.11.0</version> </dependency>

Gradle의 경우 build.gradle 파일에 다음 종속성을 추가합니다.

compile 'com.amazonaws:aws-xray-recorder-sdk-spring:2.11.0'

Spring Boot 구성하기

이전 섹션에서 설명한 Spring 종속성 외에도 Spring Boot를 사용하는 경우 클래스 경로에 아직 없는 경우 다음 종속성을 추가하세요.

Maven:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version>2.5.2</version> </dependency>

Gradle:

compile 'org.springframework.boot:spring-boot-starter-aop:2.5.2'

애플리케이션에 트레이싱 필터 추가

WebConfig 클래스에 Filter를 추가하세요. 세그먼트 이름을 하나의 문자열로 AWSXRayServletFilter 생성자에 보냅니다. 추적 필터 및 수신 요청 계측 방법에 대한 자세한 내용은 Java용 X-Ray SDK로 수신 요청 추적하기을 참조하세요.

예 src/main/java/myapp/.java WebConfig - 스프링
package myapp; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import javax.servlet.Filter; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter("Scorekeep"); } }

자카르타 지원

Spring 6는 엔터프라이즈 에디션에 Javax 대신 자카르타를 사용합니다. 이 새로운 네임스페이스를 지원하기 위해 X-Ray는 자체 자카르타 네임스페이스에 있는 병렬 클래스 집합을 만들었습니다.

필터 클래스의 경우 javaxjakarta로 바꾸십시오. 세그먼트 네이밍 전략을 구성할 때는 다음 예시와 같이 네이밍 전략 클래스 이름 앞에 jakarta을 추가합니다:

package myapp; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import jakarta.servlet.Filter; import com.amazonaws.xray.jakarta.servlet.AWSXRayServletFilter; import com.amazonaws.xray.strategy.jakarta.SegmentNamingStrategy; @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter(SegmentNamingStrategy.dynamic("Scorekeep")); } }

코드에 주석 추가 또는 인터페이스 구현

클래스는 @XRayEnabled 어노테이션으로 주석을 달거나 XRayTraced 인터페이스를 구현해야 합니다. 이는 AOP 시스템에 X-Ray 구성을 위해 영향을 받는 클래스의 함수를 래핑하도록 지시합니다.

애플리케이션에서 X-Ray 활성화하기

애플리케이션에서 X-Ray 트레이싱을 활성화하려면 코드에서 다음 메서드를 재정의하여 추상 클래스 BaseAbstractXRayInterceptor를 확장해야 합니다.

  • generateMetadata—이 함수를 사용하면 현재 함수의 트레이스에 첨부된 메타데이터를 사용자 지정할 수 있습니다. 기본적으로 실행 함수의 클래스 이름은 메타데이터에 기록됩니다. 추가 정보가 필요한 경우 데이터를 더 추가할 수 있습니다.

  • xrayEnabledClasses—이 함수는 비어 있으며 그대로 유지해야 합니다. 이 함수는 인터셉터에게 래핑할 메서드를 지시하는 Pointcut에 대해 호스트의 역할을 합니다. @XRayEnabled 주석이 추가된 클래스 중 트레이스할 클래스를 지정하여 Pointcut을 정의합니다. 다음 Pointcut 문은 인터셉터에 @XRayEnabled 주석이 추가된 모든 컨트롤러 빈을 래핑하도록 지시합니다.

    @Pointcut(“@within(com.amazonaws.xray.spring.aop.XRayEnabled) && bean(*Controller)”)

프로젝트에서 Spring 데이터 JPA를 사용하는 경우 BaseAbstractXRayInterceptor 대신 AbstractXRayInterceptor에서 확장하는 것을 고려하세요.

다음 코드는 추상 클래스 BaseAbstractXRayInterceptor를 확장합니다.

@Aspect @Component public class XRayInspector extends BaseAbstractXRayInterceptor { @Override protected Map<String, Map<String, Object>> generateMetadata(ProceedingJoinPoint proceedingJoinPoint, Subsegment subsegment) throws Exception { return super.generateMetadata(proceedingJoinPoint, subsegment); } @Override @Pointcut("@within(com.amazonaws.xray.spring.aop.XRayEnabled) && bean(*Controller)") public void xrayEnabledClasses() {} }

다음 코드는 X-Ray에 의해 구성될 클래스입니다.

@Service @XRayEnabled public class MyServiceImpl implements MyService { private final MyEntityRepository myEntityRepository; @Autowired public MyServiceImpl(MyEntityRepository myEntityRepository) { this.myEntityRepository = myEntityRepository; } @Transactional(readOnly = true) public List<MyEntity> getMyEntities(){ try(Stream<MyEntity> entityStream = this.myEntityRepository.streamAll()){ return entityStream.sorted().collect(Collectors.toList()); } } }

애플리케이션을 올바로 구성했다면 다음 콘솔 스크린샷과 같이 컨트롤러에서 서비스 호출에 이르기까지 애플리케이션의 전체 호출 스택이 보일 것입니다.


        전체 호출 스택