• EnglishEspañol日本語한국어Português
  • 로그인지금 시작하기

OpenTelemetry 튜토리얼: 샘플 Java 앱 계측

이 Java 튜토리얼을 통해 뉴렐릭 플랫폼이 OTLP 데이터로 무엇을 할 수 있는지 알아볼 수 있습니다. 세 가지 튜토리얼 중 선택할 수 있으며, 각 튜토리얼은 동일한 데모 Spring 앱을 사용합니다. 앱은 피보나치 수열의 n번째 숫자를 계산하고 트레이스, 메트릭 및 로그를 생성합니다.

이 튜토리얼을 통해 OpenTelemetry과 뉴렐릭을 사용하여 자신만의 앱을 설정하는 데 도움이 되는 기술을 배울 수 있습니다.

이 튜토리얼을 마친 후에는 차트에서 다음과 같은 JVM 메트릭를 볼 수 있습니다.

요구 사항

시작하려면 다음을 먼저 확인하십시오.

튜토리얼

각 튜토리얼은 동일한 데모 앱을 사용하지만 OpenTelemetry와 뉴렐릭에 익숙해지는 데 도움이 되는 다양한 접근 방식을 제공합니다.

  • Pre-instrumented app [사전 계측된 앱]: UI에서 데이터를 빠르게 확인하려면 사전 계측된 데모 앱을 실행하세요.
  • OpenTelemetry Java agent [OpenTelemetry Java 에이전트]: OpenTelemetry Java 에이전트를 사용하여 데모 앱을 모니터링합니다.
  • Manual setup [수동 설정]: 데모 앱을 수동으로 계측합니다.

완료하려는 튜토리얼의 탭을 클릭하십시오.

OpenTelemetry를 사용할 때 OTLP를 통해 애플리케이션에서 뉴렐릭으로 데이터를 내보내는 두 가지 방식 중 선택할 수 있습니다.

  • 앱에서 뉴렐릭으로 직접 내보내기

  • 앱이 데이터를 OpenTelemetry 컬렉터(수집기)로 보낸 후 뉴렐릭으로 내보내기

    이 튜토리얼에서는 첫 번째 옵션을 다룹니다. 컬렉터를 통해 데이터를 내보내려면 이 컬렉터 문서에서 보다 자세한 내용을 확인하십시오.

사전 계측된 데모 앱 실행

이는 뉴렐릭이 계측을 수행하도록 하여 뉴렐릭으로 어떻게 데이터를 보내고 UI에서 볼 수 있는지 빠르게 확인하려는 경우에 좋은 옵션입니다.

  1. 터미널에서 다음을 실행하여 데모 앱을 복제하고 시작 가이드의 java 디렉터리로 이동합니다.

    bash
    $
    git clone https://github.com/newrelic/newrelic-opentelemetry-examples.git
    $
    cd newrelic-opentelemetry-examples/getting-started-guides/java
  2. 뉴렐릭 계정으로 데이터를 보내려면 다음 두 가지 환경 변수를 설정해야 합니다.

    • 반드시 를 사용해야 합니다.

    • 뉴렐릭 데이터센터 지역이 미국이 아닌 EU인 경우 엔드포인트를 다음으로 설정합니다: https://otlp.eu01.nr-data.net

      • OTEL_EXPORTER_OTLP_HEADERS=api-key=INSERT_YOUR_NEW_RELIC_LICENSE_KEY
      • OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.nr-data.net
      • OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
  3. 아래의 첫 번째 환경 변수를 설정하여 서비스 이름을 지정하고, 두 번째 환경 변수를 서비스 인스턴스 ID로 설정하여 특정 플랫폼 기능을 활성화합니다. 마지막으로 로깅은 기본적으로 꺼져 있으므로 로그를 활성화합니다.

    • OTEL_SERVICE_NAME=getting-started-java

    • OTEL_RESOURCE_ATTRIBUTES=service.instance.id=INSERT_YOUR_ID_HERE

      • INSERT_YOUR_OWN_ID_HERE를 고유한 인스턴스 ID로 바꿉니다. 예: 1234
    • OTEL_LOGS_EXPORTER=otlp

  4. 동일한 getting-started-guides/java 디렉터리에서 애플리케이션을 빌드하고 실행합니다.

    • MacOS:

      bash
      $
      ./gradlew bootRun
    • PowerShell:

      bash
      $
      .\gradlew.bat build
  5. 새 터미널 탭을 열고 getting-started-guides/java/Instrumented 디렉터리로 전환한 후 다음 명령을 실행하여 애플리케이션에 대한 일부 트래픽을 생성합니다.

    • MacOS:

      bash
      $
      ./load-generator.sh
    • PowerShell:

      bash
      $
      .\load-generator.ps1

    또는 브라우저의 URL: http://localhost:8080/fibonacci?n=INSERT_A_VALUE에서 엔드포인트에 도달할 수 있습니다. INSERT_A_VALUE를 1에서 90 사이의 값으로 바꿉니다. 오류를 생성하려면 유효한 범위 밖의 정수를 삽입합니다.

  6. one.newrelic.com > All capabilities > APM & services 로 이동합니다.

  7. getting-started-java라는 새 엔터티(서비스)를 클릭하고 UI를 탐색합니다. UI에서 찾아야 할 사항에 대한 자세한 내용은 뉴렐릭에서 데이터 보기를 참조하십시오.

  8. UI에서 데이터 확인을 마쳤으면 두 터미널 세션 모두에서 Control+C를 눌러 애플리케이션을 종료합니다.

OpenTelemetry Java 에이전트를 통한 데모 앱 모니터링

다음은 동일한 데모 앱을 사용하는 다른 방법을 설명하는 튜토리얼입니다. 이 경우 OpenTelemetry Java 에이전트를 사용하여 데모 앱을 자동으로 모니터링하게 됩니다. Java 소스 코드를 수정할 필요가 없습니다. 에이전트를 사용하면 샘플 데이터를 뉴렐릭으로 빠르게 내보내기할 수 있습니다.

자동 계측 에이전트는 널리 사용되는 라이브러리 및 프레임워크에서 텔메트리를 캡처하기 위해 바이트코드를 동적으로 삽입하는 JAR 파일입니다. 또한 이를 사용하여 인바운드 요청, 아웃바운드 HTTP 호출 및 데이터베이스 호출과 같은 데이터를 캡처할 수 있습니다. 모든 Java 8+ 애플리케이션에 첨부할 수 있습니다.

추가 구성 옵션은 공식 Java 에이전트 문서를 참조하십시오.

OpenTelemetry Java 에이전트를 사용하여 데모 앱을 모니터링하려면:

  1. 에이전트 및 계측 라이브러리가 포함된 에이전트 JAR 파일을 다운로드합니다. 원하는 디렉터리에 배치하고 나중에 사용할 수 있도록 경로를 기록해 둡니다.

  2. 아직 다운로드하지 않았다면 데모 애플리케이션 저장소를 다운로드하고 다음 디렉터리로 전환합니다.

    bash
    $
    git clone https://github.com/newrelic/newrelic-opentelemetry-examples.git
    $
    cd newrelic-opentelemetry-examples/getting-started-guides/java
  3. 다음 명령을 사용하여 데모 앱을 빌드합니다.

    • MacOS:

      bash
      $
      ./gradlew build
    • PowerShell:

      bash
      $
      .\gradlew.bat build

      성공적으로 빌드되면 Uninstrumented/build/libs에서 uninstrumented.jar라는 애플리케이션 JAR 파일을 찾을 수 있습니다.

  4. 아래의 환경 변수 참조 섹션으로 이동하여 내보내야 하는 변수를 확인한 후 이 단계로 돌아옵니다.

  5. 앱으로 에이전트를 시작하려면 getting-started-guides/java/Uninstrumented에서 계속합니다.

    중요

    path/to를 다운로드해 둔 JAR 파일의 위치로 교체합니다.

    bash
    $
    java -javaagent:path/to/opentelemetry-javaagent.jar \
    >
    -jar ./build/libs/uninstrumented.jar
  6. getting-started-guides/java/Uninstrumented 디렉터리에서 새 터미널을 열고 로드 생성기를 실행하여 애플리케이션에 대한 트래픽을 생성합니다.

    • MacOS:

      bash
      $
      ./load-generator.sh
    • PowerShell:

      bash
      $
      .\load-generator.ps1

    또는 브라우저의 URL: http://localhost:8080/fibonacci?n=INSERT_A_VALUE에서 엔드포인트에 도달할 수 있습니다. INSERT_A_VALUE를 1에서 90 사이의 값으로 바꿉니다. 오류를 생성하려면 유효한 범위 밖의 정수를 삽입합니다.

  7. 이제 일부 데이터를 뉴렐릭으로 보냈으므로 UI에서 데이터를 보는 방법에 대한 지침을을 참조합니다.

  8. UI에서 데이터 확인을 마쳤으면 두 터미널 세션 모두에서 Control+C를 눌러 애플리케이션을 종료합니다.

데모 앱 수동 설정

이 트랙에서는 직접 실습해볼 수 있습니다. 텔레메트리의 보고 내용을 가장 잘 제어하고 작동 방법에 대한 세부 정보를 확인하려는 경우 취하는 접근 방식입니다.

계측을 데모 앱에 수동으로 삽입하여 텔레메트리를 캡처하고, 해당 데이터를 뉴렐릭으로 내보내도록 SDK를 구성할 수 있습니다.

SDK를 수동으로 구성할 수도 있지만 환경 변수와 시스템 속성을 사용하여 프로세스를 간소화하는 자동 구성 옵션을 사용해 SDK를 구성하는 방법을 보여 드리겠습니다.

데모 애플리케이션 다운로드

아직 데모 앱을 다운로드하지 않았다면 다음을 실행합니다.

bash
$
git clone https://github.com/newrelic/newrelic-opentelemetry-examples.git

종속성(dependencies) 설치

종속성을 추가하려면:

  1. 애플리케이션 디렉터리로 이동합니다.

    bash
    $
    cd newrelic-opentelemetry-examples/getting-started-guides/java/uninstrumented
  2. build.gradle을 엽니다.

  3. 다음 강조 표시된 항목을 dependencies 블록에 추가합니다. (코드 블록 내에서 아래로 스크롤해야 할 수도 있음)

    plugins {
    id 'org.springframework.boot' version '2.7.5'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
    }
    java {
    toolchain {
    languageVersion = JavaLanguageVersion.of(17)
    }
    }
    repositories {
    mavenCentral()
    }
    bootRun {
    mainClass.set 'com.example.demo.Application'
    }
    configurations.all {
    exclude module: 'spring-boot-starter-logging'
    }
    dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-log4j2'
    // OpenTelemetry core
    implementation platform('io.opentelemetry:opentelemetry-bom:1.22.0')
    implementation platform('io.opentelemetry:opentelemetry-bom-alpha:1.22.0-alpha')
    implementation 'io.opentelemetry:opentelemetry-api'
    implementation 'io.opentelemetry:opentelemetry-sdk'
    implementation 'io.opentelemetry:opentelemetry-exporter-otlp'
    implementation 'io.opentelemetry:opentelemetry-exporter-otlp-logs'
    implementation 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure'
    // OpenTelemetry instrumentation
    implementation platform('io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:1.22.1-alpha')
    implementation 'io.opentelemetry.instrumentation:opentelemetry-runtime-metrics'
    implementation 'io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17'
    implementation 'io.opentelemetry.instrumentation:opentelemetry-spring-webmvc-6.0'
    }

    참고:

  • bom(자재 명세서) 종속성은 특정 생태계를 위한 종속성 버전을 동기화하는 데 사용됩니다. OpenTelemetry는 많은 Java 구성 요소를 게시하므로 사용 개수에 관계없이 모든 버전을 동기화하는 데 도움이 됩니다.
  • 나머지 종속성은 SDK, API, OTLP 엑스포터, 계측 라이브러리에 대한 액세스를 제공합니다.
  • spring-boot-starter-logging 모듈을 제외하는 추가 설정이 있습니다. 이렇게 하면 log4j-slf4j-impl cannot be present with log4j-to-slf4j와 관련된 빌드 오류 메시지가 표시되지 않습니다.

자동 구성 확장을 사용한 SDK 구성

SDK를 수동으로 구성할 수도 있지만 프로세스를 간소화하는 자동 구성 확장을 사용하는 것이 좋습니다.

  1. 앱의 소스 코드 디렉터리로 이동합니다.

    bash
    $
    cd newrelic-opentelemetry-examples/getting-started-guides/java/uninstrumented/src/main/java/com/example/demo
  2. Application.java을 엽니다.

  3. 강조 표시된 줄을 삽입합니다.

    @SpringBootApplication
    public class Application {
    private static volatile OpenTelemetry openTelemetry = OpenTelemetry.noop();
    public static void main(String[] args) {
    // Build the SDK auto-configuration extension module
    OpenTelemetrySdk openTelemetrySdk = AutoConfiguredOpenTelemetrySdk.builder()
    .setResultAsGlobal(false)
    .build()
    .getOpenTelemetrySdk();
    Application.openTelemetry = openTelemetrySdk;
    SpringApplication.run(Application.class, args);
    }
    @Bean
    public OpenTelemetry openTelemetry() {
    return openTelemetry;
    }
    }
  4. 아래의 환경 변수 참조 섹션으로 이동하여 내보내야 하는 변수를 확인한 후 이 단계로 돌아옵니다.

계측 라이브러리 추가: 트레이스

Application.java에서 추적 필터를 등록하여 Spring Web MVC에 대해 강조 표시된 계측을 추가합니다.

@SpringBootApplication
public class Application {
private static volatile OpenTelemetry openTelemetry = OpenTelemetry.noop();
public static void main(String[] args) {
// Build the SDK auto-configuration extension module
OpenTelemetrySdk openTelemetrySdk = AutoConfiguredOpenTelemetrySdk.builder()
.setResultAsGlobal(false)
.build()
.getOpenTelemetrySdk();
Application.openTelemetry = openTelemetrySdk;
SpringApplication.run(Application.class, args);
}
@Bean
public OpenTelemetry openTelemetry() {
return openTelemetry;
}
// Add Spring WebMVC instrumentation by registering a tracing filter
@Bean
public Filter webMvcTracingFilter(OpenTelemetry openTelemetry) {
return SpringWebMvcTelemetry.create(openTelemetry).createServletFilter();
}
}

계측 라이브러리 추가: 메트릭

Application.java 파일에 다음을 등록하여 Java 런타임에 대한 메트릭를 생성하고 수집합니다. 아래에 강조 표시된 줄을 삽입합니다.

@SpringBootApplication
public class Application {
private static volatile OpenTelemetry openTelemetry = OpenTelemetry.noop();
public static void main(String[] args) {
// Build the SDK auto-configuration extension module
OpenTelemetrySdk openTelemetrySdk = AutoConfiguredOpenTelemetrySdk.builder()
.setResultAsGlobal(false)
.build()
.getOpenTelemetrySdk();
Application.openTelemetry = openTelemetrySdk;
// Register runtime metrics instrumentation
BufferPools.registerObservers(openTelemetrySdk);
Classes.registerObservers(openTelemetrySdk);
Cpu.registerObservers(openTelemetrySdk);
GarbageCollector.registerObservers(openTelemetrySdk);
MemoryPools.registerObservers(openTelemetrySdk);
Threads.registerObservers(openTelemetrySdk);
SpringApplication.run(Application.class, args);
}
@Bean
public OpenTelemetry openTelemetry() {
return openTelemetry;
}
// Add Spring WebMVC instrumentation by registering a tracing filter
@Bean
public Filter webMvcTracingFilter(OpenTelemetry openTelemetry) {
return SpringWebMvcTelemetry.create(openTelemetry).createServletFilter();
}
}

계측 라이브러리 추가: 로그

이 데모 애플리케이션은 GlobalLoggerProvider를 사용하는 OpenTelemetryAppender( log4j.xml을 통해)을 사용하도록 구성되었습니다. GlobalLoggerProvider를 설정하면 여기에서 자동 구성을 사용하여 구성된 로그 SDK에 OpenTelemetryAppender가 연결됩니다.

  1. Application.java을 엽니다.

  2. 다음 강조 표시된 줄을 삽입합니다.

    @SpringBootApplication
    public class Application {
    private static volatile OpenTelemetry openTelemetry = OpenTelemetry.noop();
    public static void main(String[] args) {
    // Build the SDK auto-configuration extension module
    OpenTelemetrySdk openTelemetrySdk = AutoConfiguredOpenTelemetrySdk.builder()
    .setResultAsGlobal(false)
    .build()
    .getOpenTelemetrySdk();
    Application.openTelemetry = openTelemetrySdk;
    // Set GlobalLoggerProvider, which is used by Log4j2 appender
    GlobalLoggerProvider.set(openTelemetrySdk.getSdkLoggerProvider());
    // Register runtime metrics instrumentation
    BufferPools.registerObservers(openTelemetrySdk);
    Classes.registerObservers(openTelemetrySdk);
    Cpu.registerObservers(openTelemetrySdk);
    GarbageCollector.registerObservers(openTelemetrySdk);
    MemoryPools.registerObservers(openTelemetrySdk);
    Threads.registerObservers(openTelemetrySdk);
    SpringApplication.run(Application.class, args);
    }
    @Bean
    public OpenTelemetry openTelemetry() {
    return openTelemetry;
    }
    // Add Spring WebMVC instrumentation by registering a tracing filter
    @Bean
    public Filter webMvcTracingFilter(OpenTelemetry openTelemetry) {
    return SpringWebMvcTelemetry.create(openTelemetry).createServletFilter();
    }
    }
  3. Uninstrumented/src/mainresources라는 디렉터리를 만듭니다.

  4. 이 새 디렉터리에서 다음 콘텐츠로 log4j2.xml이라는 파일을 만듭니다.

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN" packages="io.opentelemetry.instrumentation.log4j.appender.v2_17">
    <Appenders>
    <Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true">
    <PatternLayout pattern="%d{yyyy-mm-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <OpenTelemetry name="OpenTelemetryAppender" />
    </Appenders>
    <Loggers>
    <Root level="info">
    <AppenderRef ref="OpenTelemetryAppender" />
    <AppenderRef ref="ConsoleAppender" />
    </Root>
    </Loggers>
    </Configuration>

    이 줄의 packages=... 섹션을 사용하면 Log4J가 OpenTelemetryAppender를 찾고 구성할 수 있습니다. 소스 코드는 OpenTelemetry 저장소에 있으며, io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 통해 하나의 종속성으로 추가되었습니다.

커스텀 트레이스 계측: 스팬 속성 상수 생성

각 트레이스는 논리적 작업 단위 또는 특정 요청 내의 작업을 나타내는 스팬(span)으로 구성됩니다. 아래 코드는 다음을 보여줍니다.

  • 스팬에서 요청 수준 인사이트를 제공하는 데 사용할 속성 키를 보유하는 정적 상수

  • 스팬을 생성하는 트레이서 초기화 방법

    강조 표시된 다음 줄을 Controller.java에 삽입합니다.

    @RestController
    public class Controller {
    // Attribute constants
    private static final AttributeKey<Long> ATTR_N = AttributeKey.longKey("fibonacci.n");
    private static final AttributeKey<Long> ATTR_RESULT = AttributeKey.longKey("fibonacci.result");
    private final Tracer tracer;
    @Autowired
    Controller(OpenTelemetry openTelemetry) {
    // Initialize tracer
    tracer = openTelemetry.getTracer(Controller.class.getName());
    }
    @GetMapping(value = "/fibonacci")
    . . .
    }

커스텀 트레이스 계측: 커스텀 스팬 생성

원하는 모든 스팬을 생성할 수 있으며, 특정 작업에 대한 속성으로 스팬에 주석을 추가할 수도 있습니다. 설정한 속성은 결과나 작업 속성 등 추적 중인 특정 작업에 대한 추가 컨텍스트를 제공합니다.

  1. Controller.java에서 강조 표시된 줄을 삽입하여 다음을 수행하는 fibonacci라는 새 스팬을 시작합니다.

    • 이 메소드 실행에 대한 데이터를 캡처합니다.
    • 사용자 요청의 n 값을 저장하는 속성을 설정합니다.
    private long fibonacci(long n) {
    // Start a new span and set your first attribute
    var span = tracer.spanBuilder("fibonacci").setAttribute(ATTR_N, n).startSpan();
    . . .
    }
  2. 성공적인 요청에 대한 정보를 저장하기 위해 스팬에 속성을 추가하여 코드에 세부적인 세부 정보를 추가합니다.

    private long fibonacci(long n) {
    // Start a new span and set your first attribute
    var span = tracer.spanBuilder("fibonacci").setAttribute(ATTR_N, n).startSpan();
    try {
    if (n < 1 || n > 90) {
    throw new IllegalArgumentException("n must be 1 <= n <= 90.");
    }
    long result = 1;
    if (n > 2) {
    long a = 0;
    long b = 1;
    for (long i = 1; i < n; i++) {
    result = a + b;
    a = b;
    b = result;
    }
    // Set a span attribute to capture information about successful requests
    span.setAttribute(ATTR_RESULT, last);
    return last;
    } catch (IllegalArgumentException e) {
    throw e;
    }
    }

커스텀 트레이스 계측: 예외 기록

예외가 발생하는 대로 기록하길 원할 수 있습니다. 스팬 상태 설정과 함께 이 작업을 수행하는 것이 좋습니다. 먼저 스팬을 현재 스팬으로 설정하고, 예외 발생 시 상태 코드를 오류로 설정한 후 스팬을 종료합니다.

private long fibonacci(long n) {
// Start a new span and set your first attribute
var span = tracer.spanBuilder("fibonacci").setAttribute(ATTR_N, n).startSpan();
// Set the span as the current span
try (var scope = span.makeCurrent()) {
if (n < 1 || n > 90) {
throw new IllegalArgumentException("n must be 1 <= n <= 90.");
}
long result = 1;
if (n > 2) {
long a = 0;
long b = 1;
for (long i = 1; i < n; i++) {
result = a + b;
a = b;
b = result;
}
}
// Set a span attribute to capture information about successful requests
span.setAttribute(ATTR_RESULT, result);
return result;
} catch (IllegalArgumentException e) {
// Record the exception and set the span status
span.recordException(e).setStatus(StatusCode.ERROR, e.getMessage());
throw e;
} finally {
// End the span
span.end();
}
}

사용자가 잘못된 입력을 제공하는 경우 이 메서드는 IllegalArgumentException을 발생시킵니다. 이 경우 예외는 스팬에 이벤트로 기록되고 스팬의 상태는 ERROR로 설정됩니다. 예외 메시지는 상태 설명으로 캡처됩니다. 예외는 발생한 스팬에서 이벤트로 기록됩니다.

마지막으로 ErrorHandler 클래스의 handleException()에서 다음과 같이 강조 표시된 줄을 사용하여 스팬 상태를 ERROR로 설정합니다.

@ControllerAdvice
private static class ErrorHandler {
@ExceptionHandler({
IllegalArgumentException.class,
MissingServletRequestParameterException.class,
HttpRequestMethodNotSupportedException.class
})
public ResponseEntity<Object> handleException(Exception e) {
// Set the span status and description
Span.current().setStatus(StatusCode.ERROR, e.getMessage());
return new ResponseEntity<>(Map.of("message", e.getMessage()), HttpStatus.BAD_REQUEST);
}
}

이전 단계와 마찬가지로, 이렇게 하면 사용자가 잘못된 숫자를 입력하는 경우 스팬의 상태 코드가 설정됩니다. 그러나 이는 fibonacci()가 아닌 예외 핸들러에서 발생하므로 현재 스팬은 요청에 대한 상위 스팬입니다. 이 상위 스팬은 Spring Web MVC 계측에서 가져온 것으로, 애플리케이션 클래스의 필터를 통해 추가되었습니다. 이제 애플리케이션 엔드포인트에서 예외가 발생하면 상위 스팬과 하위 스팬 모두 스팬 상태가 ERROR가 됩니다.

커스텀 메트릭 계측: 커스텀 메트릭 카운터 추가

메트릭은 개별 측정을 집계로 결합하고 시스템 로드에 따라 일정한 데이터를 생성하기 때문에 매우 유용한 텔레메트리 데이터 유형입니다. 스팬과 함께 이 데이터를 사용하여 추세를 파악하고 애플리케이션 런타임 텔레메트리를 제공할 수 있습니다. 또한 메트릭가 나타내는 측정의 하위 구분을 설명하는 데 도움이 되는 속성으로 메트릭에 주석을 달 수 있습니다.

OpenTelemetry 메트릭 API는 메트릭 SDK에 의해 집계되고 프로세스 외부로 내보내진 측정을 기록하는 계측 개수를 정의합니다. 다음과 같은 두 가지 유형이 있습니다.

  • 동기: 이러한 계측은 발생 시에 측정 값을 기록합니다.

  • 비동기: 컬렉션당 한 번만 호출되고 관련 컨텍스트가 없는 콜백을 등록합니다.

    OpenTelemetry 프로젝트의 메트릭 상태에 대해 질문이 있는 경우 신호 상태를 참조하십시오.

    커스텀 카운터를 추가하려면 다음을 완료해야 합니다.

  1. 커스텀 메트릭에 대한 부울 속성을 인스턴스화하고 메트릭 리소스를 초기화합니다.

    이 경우에는 양수 값만 기록하고 네트워크를 통해 전송된 바이트 수와 같은 항목을 계산하는 데 유용한 LongCounter를 사용하고 있습니다. 기본적으로 카운터 측정은 항상 증가하는 합계로 집계됩니다.

    @RestController
    public class Controller {
    // Attribute constants
    private static final AttributeKey<Long> ATTR_N = AttributeKey.longKey("fibonacci.n");
    private static final AttributeKey<Long> ATTR_RESULT = AttributeKey.longKey("fibonacci.result");
    private static final AttributeKey<Boolean> ATTR_VALID_N = AttributeKey.booleanKey("fibonacci.valid.n");
    private final Tracer tracer;
    private final LongCounter fibonacciInvocations;
    @Autowired
    Controller(OpenTelemetry openTelemetry) {
    // Initialize tracer
    tracer = openTelemetry.getTracer(Controller.class.getName());
    // Initialize instrument
    Meter meter = openTelemetry.getMeter(Controller.class.getName());
    fibonacciInvocations = meter
    .counterBuilder("fibonacci.invocations")
    .setDescription("Measures the number of times the fibonacci method is invoked.")
    .build();
    }
    . . .
    }
  2. 커스텀 카운터가 유효한 입력과 유효하지 않은 입력은 물론 각각의 발생 횟수를 캡처할 수 있도록 다음과 같이 강조 표시된 줄을 삽입합니다.

    private long fibonacci(long n) {
    // Start a new span and set your first attribute
    var span = tracer.spanBuilder("fibonacci").setAttribute(ATTR_N, n).startSpan();
    // Set the span as the current span
    try (var scope = span.makeCurrent()) {
    if (n < 1 || n > 90) {
    throw new IllegalArgumentException("n must be 1 <= n <= 90.");
    }
    long result = 1;
    if (n > 2) {
    long a = 0;
    long b = 1;
    for (long i = 1; i < n; i++) {
    result = a + b;
    a = b;
    b = result;
    }
    }
    // Set a span attribute to capture information about successful requests
    span.setAttribute(ATTR_RESULT, result);
    // Counter to increment the number of times a valid input is recorded
    fibonacciInvocations.add(1, Attributes.of(ATTR_VALID_N, true));
    return result;
    } catch (IllegalArgumentException e) {
    // Record the exception and set the span status
    span.recordException(e).setStatus(StatusCode.ERROR, e.getMessage());
    // Counter to increment the number of times an invalid input is recorded
    fibonacciInvocations.add(1, Attributes.of(ATTR_VALID_N, false));
    throw e;
    } finally {
    // End the span
    span.end();
    }
    }

커스텀 로그 계측

OpenTelemetry Java의 로그 신호 상태는 현재 실험 중 입니다. 로그 메시지는 루트 핸들러에 의해 관리되며, 기본적으로 INFO 수준 이상의 로그를 콘솔로 보냅니다. 그러나 특정 클래스를 포함하여 로깅 수준을 변경하거나 커스텀 핸들러 또는 필터를 설치하여 로거 동작을 변경할 수 있습니다.

로거 초기화

이전에 설명한 대로 이는 java.util.logging 라이브러리에서 가져온 것입니다. 로거는 OpenTelemetry 구성 요소가 아니지만 애플리케이션은 Log4j 로그를 OpenTelemetry SDK로 보내도록 구성되었습니다.

@RestController
public class Controller {
// Logger (note that this is not an OTel component)
private static final Logger LOGGER = LogManager.getLogger(Controller.class);
// Attribute constants
private static final AttributeKey<Long> ATTR_N = AttributeKey.longKey("fibonacci.n");
private static final AttributeKey<Long> ATTR_RESULT = AttributeKey.longKey("fibonacci.result");
private static final AttributeKey<Boolean> ATTR_VALID_N = AttributeKey.booleanKey("fibonacci.valid.n");
. . .
}
커스텀 로그 메시지 추가 [#cust-log-messages]

로거를 초기화한 후에는 로거를 사용하여 다음을 기록할 수 있습니다.

  • 유효한 입력의 결과와 해당 결과의 값
  • 출력이 기록되지 않은 경우

강조 표시된 다음 줄을 삽입합니다.

private long fibonacci(long n) {
// Start a new span and set your first attribute
var span = tracer.spanBuilder("fibonacci").setAttribute(ATTR_N, n).startSpan();
// Set the span as the current span
try (var scope = span.makeCurrent()) {
if (n < 1 || n > 90) {
throw new IllegalArgumentException("n must be 1 <= n <= 90.");
}
long result = 1;
if (n > 2) {
long a = 0;
long b = 1;
for (long i = 1; i < n; i++) {
result = a + b;
a = b;
b = result;
}
}
// Set a span attribute to capture information about successful requests
span.setAttribute(ATTR_RESULT, result);
// Counter to increment the number of times a valid input is recorded
fibonacciInvocations.add(1, Attributes.of(ATTR_VALID_N, true));
// Log the result of a valid input
LOGGER.info("Compute fibonacci(" + n + ") = " + result);
return result;
} catch (IllegalArgumentException e) {
// Record the exception and set the span status
span.recordException(e).setStatus(StatusCode.ERROR, e.getMessage());
// Counter to increment the number of times an invalid input is recorded
fibonacciInvocations.add(1, Attributes.of(ATTR_VALID_N, false));
// Log when no output was recorded
LOGGER.info("Failed to compute fibonacci(" + n + ")");
throw e;
} finally {
// End the span
span.end();
}
}

앱을 실행하여 트래픽을 생성합니다.

뉴렐릭으로 데이터를 보낼 준비가 되었습니다!

  1. getting-started-guides/java 디렉터리로 이동하고 다음 명령을 사용하여 앱을 빌드하고 실행합니다.

    • MacOS:

      bash
      $
      ./gradlew bootRun
    • PowerShell:

      bash
      $
      .\gradlew.bat build

      터미널에 Spring ASCII가 표시되면 앱이 성공적으로 빌드되어 실행 중임을 의미합니다.

  2. getting-started-guides/java/Uninstrumented 디렉터리에서 새 터미널을 열고 로드 생성기를 실행하여 애플리케이션에서 트래픽을 생성합니다.

    • MacOS:

      bash
      $
      ./load-generator.sh
    • PowerShell:

      bash
      $
      .\load-generator.ps1

    또는 브라우저의 URL: http://localhost:8080/fibonacci?n=INSERT_A_VALUE에서 엔드포인트에 도달할 수 있습니다. INSERT_A_VALUE를 1에서 90 사이의 값으로 바꿉니다. 오류를 생성하려면 유효한 범위 밖의 정수를 삽입합니다.

  3. 이제 일부 데이터를 뉴렐릭으로 보냈으므로 UI에서 데이터를 보는 방법에 대한 지침을을 참조합니다.

뉴렐릭에서 데모 데이터 보기

어떤 튜토리얼을 완료했는지에 관계없이 아래 팁에 따라 뉴렐릭 UI에서 데이터를 발견할 수 있습니다.

  1. one.newrelic.com > All capabilities > APM & services 로 이동합니다.
  2. getting-started-java (또는 제공한 이름)이라는 새 엔터티(서비스)를 클릭합니다.
  3. 각 데이터 유형에 대한 섹션의 세부정보를 확인합니다.

Windows를 사용 중이고 뉴렐릭 계정에 데이터가 표시되지 않는 경우, 방화벽이 트래픽을 허용하고 있는지 확인하시기 바랍니다.

트레이스

뉴렐릭의 getting-started-java 엔터티에 도달하면:

  1. 왼쪽 창의 Monitor [모니터] 섹션에서 Distributed tracing [분산 추적을] 클릭한 다음 Fibonacci 추적 그룹을 클릭합니다.

  2. 거기에서 오류가 있는 트레이스를 찾아 클릭하여 엽니다.

  3. 트레이스가 열려 있으면 Show in-process spans을 클릭한 후, 표시되는 스팬을 클릭하면 오른쪽에 세부 정보 패널이 열립니다. 사용자 입력이 유효하지 않을 때 기록된 예외를 보려면 View span events를 클릭합니다.

수동 계측 튜토리얼을 완료한 경우 스팬으로 기록된 예외가 뉴렐릭에 다음과 같이 표시됩니다.

스팬 속성, 스팬 이름, 상태 코드 등 설정한 추가 세부 정보를 보려면 Attributes 탭을 클릭합니다. 이 창에서는 이 가이드에서 사용한 계측 라이브러리에서 자동으로 수집된 추가 메타데이터와 뉴렐릭에 의해 첨부된 메타데이터를 볼 수도 있습니다.

데이터 보기에 대한 자세한 내용은 뉴렐릭 UI의 OpenTelemetry를 참조하십시오.

메트릭

뉴렐릭의 getting-started-java 엔터티에 도달하면 런타임 메트릭(JVM) 및 커스텀 카운터 속성 같이 수집된 모든 메트릭 목록을 볼 수 있습니다.

메트릭 탐색기

설정된 메트릭 목록을 볼 수 있게 해주는 도구입니다.

  1. 왼쪽 창에서 Data > Metrics explorer 를 선택한 다음 fibonacci.invocations 를 선택합니다.

  2. Dimensions 아래에서 커스텀 메트릭과 함께 수집된 속성을 확인한 다음 fibonacci.valid.n을 클릭합니다.

보다 자세한 내용은 메트릭 탐색기 뷰에 대한 문서를 참조하십시오.

JVM

JVM 페이지로 이동하여 처리량, 메모리 사용량, 분당 가비지 수집 시간 등 Java 런타임 메트릭을 시각화해 볼 수도 있습니다.

단일 인스턴스에 대한 메트릭를 보거나 여러 인스턴스를 선택하여 비교할 수 있습니다.

인스턴스를 선택하고 Compare를 클릭하면 다음과 같은 내용이 표시되며, 각 인스턴스는 쉽게 식별할 수 있도록 색상으로 구분되어 있습니다.

보다 자세한 내용은 JVM 뷰에 대한 문서를 참조하십시오.

로그

로그에 액세스할 수 있는 위치는 다음과 같습니다.

터미널에서도 로그를 확인할 수 있습니다.

로그 뷰로 돌아가서 로그를 선택하면, 로그 메시지와 수집된 추가 속성(예: 관련 스팬과 트레이스 ID)은 물론 뉴렐릭이 삽입한 메타데이터가 포함된 창이 열립니다.

작은 파란색 아이콘을 클릭하면 상호 연관된 트레이스로 이동할 수 있습니다.

트레이스에 대한 자세한 내용을 볼 수 있는 상호 연관된 트레이스가 표시된 창이 열립니다. 이 페이지에 대한 보다 자세한 내용은 UI의 OpenTelemetry: 분산 추적 페이지분산 추적 UI에 대한 이해 및 사용을 참조하십시오.

분산 트레이스 뷰에서도 상호 연관된 로그를 확인할 수 있습니다. 해당 로그가 있는 트레이스를 선택하면, 그것이 탭으로 표시된 것을 볼 수 있으며, 뷰를 전환할 필요 없이 트레이스에서 직접 로그를 볼 수 있습니다.

로그 뷰에 대해 자세히 알아보려면 여기를 클릭하십시오.

참조: 환경 변수

이는 튜토리얼 2 또는 3을 수행하는 경우 내보내야 하는 환경 변수 목록입니다. 변수 내보내기를 마친 후 변수 목록 뒤에 있는 링크를 사용하여 튜토리얼로 돌아갑니다.

위의 축소기에 나열된 환경 변수를 생성한 후 튜토리얼로 돌아가 설정을 완료합니다.

다음 단계는?

이제 OpenTelemetry 계측 및 SDK 구성을 실험해보았으므로 배운 내용을 기반으로 OpenTelemetry 및 뉴렐릭을 사용하여 자체 앱이나 서비스를 설정할 수 있습니다. 보다 자세한 내용은 OpenTelemetry를 사용한 앱 또는 서비스 설정을 참조하십시오.

Copyright © 2024 New Relic Inc.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.