[스프링] 스프링 부트 애플리케이션의 관찰 가능성과 모니터링

모니터링과 관찰 가능성

서비스(단일 애플리케이션이나 여러 애플리케이션으로 구성된 시스템)의 관리를 위해서는 서비스의 상태와 관련된 데이터를 확인할 필요성이 있다. 여기서 서비스의 상태 데이터란 서비스의 정상 작동 여부, 리소스(컴퓨팅 및 네트워크) 상태(점유율, 대역폭 등), 에러 발생 시 관련 텍스트 형식의 로그 등을 말한다. 모니터링(monitoring)이란 이러한 데이터들을 한눈에 볼 수 있도록 시각화하기 위한 대시보드를 구성하고, 특정 이벤트 발생 시 알림을 설정하여 서비스의 상태를 관찰함으로써 서비스를 관리하는 것을 말한다.

서비스가 외부로 출력하는 데이터를 사용하여 서비스의 내부 상태를 확인하는 방법 및 특성을 서비스의 관찰 가능성(observability)(또는 관측 가능성, 관측성, 관찰성, 가시성 등)이라는 용어로 표현한다. 관찰 가능성을 위한 데이터를 텔레메트리(telemetry)(또는 관측, 측정) 데이터라고 한다. 모니터링은 텔레메트리 데이터 중 일부 또는 전체를 대상으로 이루어진다.

관찰 가능성의 텔레메트리 데이터는 로그, 메트릭, 트레이스(또는 추적) 세 가지로 구분할 수 있다.

  • 로그 (log): 서비스에서 발생하는 이벤트의 타임스탬프 기록이다.
  • 메트릭 (metric): 시간 경과에 따른 서비스의 상태 및 성능을 측정하는 시계열 데이터이다.
  • 트레이스(또는 추적) (trace): 요청이 서로 다른 서비스를 통해 전달될 때 발생하는 일련의 서비스 이벤트 기록이다. 여러 서비스에서 발생하는 이벤트들은 하나의 고유한 식별자로 연결된다.


서비스에 관찰 가능성을 부여하여 서비스의 내부 상태를 잘 이해하고 문제 발생 시 그 원인을 파악하기 위해 서비스는 적절히 계측(instrument)되어야 한다. 계측이란 서비스에 관찰 가능성 코드를 추가하는 작업이다. 서비스를 계측하는 코드는 로그, 메트릭, 트레이스와 같은 텔레메트리 데이터를 방출(emit)한다. 서비스에 관찰 가능성을 부여하는 도구나 프레임워크는 서비스를 계측함으로써 텔레메트리 데이터를 생성, 수집(컬렉터의 역할) 및 익스포트하는 일련의 작업을 수행한다.

서비스의 관찰 가능성은 마이크로서비스 아키텍처 기반 분산 시스템(distributed system)에서 더욱 중요하다. 복잡한 마이크로서비스 환경에서 분산 시스템을 관리하고 관찰하기 위해서는 분산되어 있는 서비스 간 발생하는 이벤트 및 트랜잭션을 파악하는 분산 트레이싱(distributed tracing)이 필요하기 때문이다.

모니터링과 관찰 가능성이라는 용어의 의미 차이는 존재하지만 구분 경계가 모호한 점이 있다. 모니터링은 서비스의 문제 발생 여부와 시점을 확인하는 것이며, 관찰 가능성은 서비스에 어떤 문제가 언제, 그리고 왜 발생했는지 분석할 수 있도록 관련 데이터를 제공하는 방법 및 특성을 의미하는 것으로 구분해 볼 수 있다. 또한 관찰 가능성은 모니터링의 한계인 서비스 간 의존성에 따른 문제 파악, 분산 추적과 관련된 기능을 강화한다는 측면이 있다.

소프트웨어를 위한 인프라의 기술 요소가 발전하면서 마이크로서비스 아키텍처, 클라우드 네이티브 기술들의 도입이 가속화됨에 따라 서비스의 관찰 가능성에 대한 필요성과 중요성이 높아지고 있다.


분산 트레이싱

엔드 유저가 서비스 및 시스템을 사용할 때 발생하는 트랜잭션은 프론트엔드로의 첫 요청에서부터 백엔드 데이터베이스 호출까지 연결된다. 트레이스 데이터란 하나의 요청이 여러 분산된 서비스로 전달될 때 발생하는 이벤트 또는 관련된 데이터를 말하며 이를 모니터링하고 분석하는 방법을 분산 트레이싱이라고 한다.

분산 트레이싱은 요청이 한 서비스에서 다른 서비스로 이동할 때 관련된 데이터를 수집하여 분산 시스템을 통해 흐르는 서비스 요청을 추적하고 관찰하는 기능이다. 이는 마이크로서비스 환경에서 요청의 흐름을 이해하고 시스템에서 장애나 성능 문제가 발생한 위치와 그 원인을 정확히 파악하는데 도움을 준다.


스프링 부트 애플리케이션의 모니터링

스프링 부트 애플리케이션을 모니터링할 수 있는 방법에는 여러 가지가 있다. 스프링 부트는 자체적으로 애플리케이션을 모니터링하고 관리하기 위한 여러 추가 기능들을 제공한다. HTTP 엔드포인트 또는 JMX를 사용하여 선택적으로 애플리케이션을 관리하고 모니터링할 수 있다.

스프링 부트 액추에이터(actuator) 모듈은 프로덕션 환경에서 사용 가능한 모니터링 기능을 제공한다. 이를 사용하면 손쉽게 애플리케이션 모니터링을 위한 관련 메트릭을 수집 및 시각화할 수 있다. 스프링 부트에는 여러 내장 액추에이터 엔드포인트가 포함되어 있으며 커스텀 엔드포인트를 추가할 수도 있다. 예를 들어 health 엔드포인트는 기본적인 애플리케이션 헬스 상태(health status) 정보를 제공한다.

여기서는 다음 방법들을 알아본다.

  1. JMX(Java Management Extention) API를 통한 애플리케이션 모니터링 및 관리
  2. HTTP 프로토콜을 통한 애플리케이션 모니터링 및 관리: 마이크로미터(Micrometer), 프로메테우스(Prometehus), 그라파나(Grafana) 사용
  3. 오픈텔레메트리(OpenTelemetry)를 사용하여 애플리케이션에 관찰 가능성 부여


JMX

JMX(Java Management Extention)란 자바 애플리케이션을 손쉽게 모니터링하고 관리하기 위해 제공되는 API이다. JMX는 관리 대상 리소스를 관리 애플리케이션에 노출하는 역할을 수행한다. JMX를 사용하여 웹 서버의 성능, JVM의 스레드 및 메모리 사용, 가비지 컬렉션 등의 메트릭 정보를 실시간 모니터링할 수 있다.

JMX를 사용하기 위해서는 관리 대상 클래스를 JMX가 인식할 수 있도록 특정 빈으로 만들어야 하는데 이를 관리 빈(managed beans) 또는 MBean이라고 한다. MBean은 애플리케이션의 모니터링 정보를 제공하는 객체이다. MBean은 핵심 관리 객체 서버인 MBean 서버에 등록된다.

스프링 프레임워크는 간단한 POJO를 MBean으로 만들고 이를 MBean 서버에 등록하여 JMX 모니터링에 사용할 수 있도록 간편한 방법을 제공한다. 기본적으로 JMX 기능은 활성화되어 있지 않다. JMX를 사용하려면 애플리케이션의 spring.jmx.enabled 구성 프로퍼티를 true로 설정하면 된다.

스프링 빈을 JMX이 노출하도록 하려면 먼저 스프링의 컨테이너에 MBeanExporter 빈을 구성하여 등록해야 한다. MBeanExporter 클래스는 JMX를 지원하는 주요 클래스이며 MBean 서버에 스프링 빈을 Mean으로 등록하는 역할을 한다. 스프링 빈을 MBean으로 등록하면 스프링은 서버 내에서 실행 중인 MBeanServer 인스턴스를 찾고 MBean을 해당 서버 인스턴스에 등록한다. 톰캣 서블릿 컨테이너에서는 MBeanServer 인스턴스가 자동으로 생성되므로 추가 구성은 필요 없다.

스프링 빈들을 MBean으로 등록하기 위해서는 빈을 정의하고 컨테이너에 등록한 이후에 MBeanExporter 빈의 프로퍼티로 설정하면 된다. 이 프로퍼티는 Map 타입이므로 여러 MBean을 키/값 형태로 저장한 후 키를 사용하여 참조할 수 있다. 기본적으로 빈의 모든 public 프로퍼티는 애트리뷰트(attribute)로 노출되고, 모든 public 메서드는 오퍼레이션(operation)으로 노출된다.

스프링 부트는 JMX 관련 의존성을 자동으로 구성하고 JMX MBean 서버인 MBeanServer 빈을 자동 생성한다. 구성 클래스에 @EnableMBeanExport 애너테이션을 설정한 후 MBean으로 등록할 클래스에 관련 JMX 어노테이션(@ManagedResource, @ManagedAttribute, @ManagedOperation)을 설정하면 MBean 서버에 스프링 빈을 MBean으로 등록하고 MBean을 손쉽게 관리 애플리케이션에 노출할 수 있다. @EnableMBeanExport 어노테이션은 mbeanExporter라는 이름의 MBeanExporter 빈을 생성하며 @ManagedResource 어노테이션이 사용된 빈 뿐만 아니라 스프링 컨텍스트에 있는 모든 표준 MBean의 기본 노출을 활성화한다. 기본적으로 스프링 부트는 org.springframework.boot 도메인에서 관리 엔드포인트를 MBean으로 노출한다.

스프링 빈을 MBean으로 등록 및 노출 설정하고 나면 해당 빈들을 관리(management) 애플리케이션을 통해 모니터링할 수 있다. 관리 애플리케이션에는 VisualVM, Zabbix, Nagios 등이 있다.


마이크로미터, 프로메테우스, 그라파나를 사용한 메트릭 수집 및 시각화

마이크로미터, 프로메테우스, 그라파나를 통해 스프링 부트 애플리케이션의 메트릭을 수집 및 시각화할 수 있다. 각 서비스의 사용 목적과 기능은 다음과 같다.

  • 스프링 부트 액추에이터: 스프링 부트 애플리케이션의 모니터링을 위한 메트릭 정보를 제공할 뿐만 아니라 애플리케이션의 관리 및 운영을 위한 헬스 체크, 애플리케이션 정보, 로깅 설정 정보 등을 제공한다.
  • 마이크로미터 (Micrometer): 스프링 부트를 포함한 JVM 기반 애플리케이션의 메트릭 정보를 수집하여 애플리케이션에 관찰 가능성을 제공하는 메트릭 계측(metric instrumentation) 라이브러리이다. 벤더에 관계 없이 JVM 기반 애플리케이션 코드를 계측하는 퍼사드 역할을 수행한다. 마이크로미터는 데이터독, 프로메테우스, JMX 등 다양한 모니터링 시스템을 위한 계측 클라이언트 상에 간단한 파사드를 제공한다. 마이크로미터는 차원 메트릭(dimensional metric) 기능을 지원하여 메트릭에 태그 또는 레이블 정보를 추가함으로써 다양한 차원을 기반으로 메트릭을 재구성하고 이를 분석할 수 있는 방법을 제공한다.
  • 프로메테우스 (Prometheus): 애플리케이션의 메트릭 정보를 수집(스크랩)하고 이를 시계열 데이터베이스에 저장한다. 저장된 메트릭 정보에 대해 자체 쿼리 언어인 PromQL로 쿼리를 적용하여 다양한 분석 기능을 제공한다.
  • 그라파나 (Grafana): 프로메테우스가 수집 및 저장한 메트릭 정보를 시각화한다. 대시보드를 사용자화하여 수집 및 가공된 메트릭 정보를 그래프, 차트, 표 등 다양한 형태로 시각화한다. 그라파나는 또한 메트릭 정보에 대한 조건을 지정하여 알람을 보내는 기능을 제공한다.


메트릭을 수집 및 시각화 과정은 다음과 같다.

  1. 스프링 부트 애플리케이션은 스프링 부트 액추에이터를 통해 애플리케이션의 다양한 메트릭 정보를 제공한다.
  2. 마이크로미터는 애플리케이션의 액추에이터가 제공하는 엔드포인트를 통해 메트릭을 수집한다.
  3. 마이크로미터는 수집한 메트릭 정보를 프로메테우스에게 제공한다. 프로메테우스는 수집한 메트릭 정보를 저장하고 분석한다.
  4. 그라파나는 프로메테우스로부터 받은 메트릭 정보를 시각화한다.


스프링 부트가 제공하는 스프링 부트 액추에이터 모듈을 마이크로미터와 통합함으로써 JVM 기반 애플리케이션의 메트릭 정보 뿐만 아니라 스프링 부트 액추에이터가 제공하는 부가적인 메트릭 정보를 수집 및 시각화할 수 있다.

스프링 부트 액추에이터는 외부 시스템이 애플리케이션의 메트릭 정보를 수집할 수 있도록 다양한 엔드포인트를 제공한다. 기본으로 여러 엔드포인트가 내장되어 있으며 엔드포인트를 직접 추가할 수도 있다. 예를 들어, health 엔드포인트는 애플리케이션의 기본적인 헬스 체크를 위한 정보들을 제공한다. 각각의 엔드포인트를 선택적으로 활성화하거나 비활성화할 수 있고, HTTP 또는 JMX를 통해 노출(외부 시스템이 원격으로 접근할 수 있도록)할 수 있다. 기본적으로 shutdown 엔드포인트를 제외한 모든 엔드포인트가 활성화되며, health 엔드포인트만 HTTP와 JMX를 통해 노출된다.

스프링 부트 액추에이터가 제공하는 엔드포인트 중에는 기술에 의존하지 않는 것이 있으며 애플리케이션이 웹 애플리케이션(스프링 MVC, 스프링 웹플럭스(Webflux) 또는 저지(Jersey))인 경우 사용할 수 있는 추가적인 엔드포인트도 있다. 예로 prometheus 엔드포인트는 프로메테우스 서버가 스크랩할 수 있는 형식으로 메트릭 정보를 노출한다. prometheus 엔드포인트를 노출하기 위해서는 프로메테우스를 위한 마이크로미터 모듈 의존성(io.micrometer.micrometer-registry-prometheus)을 추가해야 한다.

스프링 부트 버전 2부터 마이크로미터 모듈은 스프링 부트 액추에이터 모듈에 포함되어 제공되므로 두 모듈은 자동으로 통합되므로 프로젝트에 스프링 부트 액추에이터 모듈 의존성만 추가하면 마이크로미터의 기능을 사용할 수 있다. 모니터링 시스템이 결정된 상태라면 해당 모듈을 의존성으로 추가하면 되며, 모니터링 시스템이 결정되어 있지 않은 상태라면 micrometer-core 모듈을 사용하여 SimpleMeterRegistry를 구성하면 된다. 프로메테우스 엔드포인트(prometheus)는 스프링 부트 애플리케이션이 스프링 부트 액추에이터와 프로메테우스를 위한 마이크로미터 모듈을 포함하면 자동 구성된다.


마이크로미터와 스프링 부트 메트릭

미터(meter)는 애플리케이션에 대한 다양한 측정값을 수집하기 위한 인터페이스이다. 개별 측정값 각각을 메트릭이라고 하며 메트릭의 종류에는 JVM 메트릭, 시스템 메트릭, 웹 서버 메트릭, HTTP 클라이언트 메트릭 등이 있다. 메트릭과 차원(dimension)의 조합으로 시계열 데이터를 생성할 수 있다.

미터는 MeterRegistry라는 레지스트리에서 생성되어 보관된다. MeterRegistry는 마이크로미터에서 미터를 등록하는데 사용되는 핵심 구성 요소이다. 지원되는 모니터링 시스템 별로 MeterRegistry가 구현되어 있으며 레지스트리 생성 방법은 구현마다 다르다. 마이크로미터에는 각 미터의 최신값을 메모리에 보관하는 SimpleMeterRegistry가 포함되어 있다. 스프링 애플리케이션에서는 SimpleMeterRegistry가 자동으로 빈 등록된다.

여러 개의 레지스트리를 추가할 수 있는 복합 레지스트리인 CompositeMeterRegistry를 사용하면 메트릭을 둘 이상의 모니터링 시스템에 동시에 게시할 수 있다.

스프링 부트 액추에이터는 다양한 모니터링 시스템을 지원하는 애플리케이션 메트릭 파사드인 마이크로미터에 대한 종속성 관리 및 자동 구성을 제공한다. 스프링 부트는 CompositeMeterRegistry를 자동 구성하고 클래스 경로에서 찾은 지원 가능한 각 구현체에 대한 레지스트리를 추가한다. 런타임 클래스 경로에 micrometer-registry-{모니터링시스템} 종속성이 존재하면 스프링 부트는 해당 레지스트리를 자동 구성한다.

미터를 레지스트리에 등록하기 전에 공통 태그를 적용하는 등 레지스트리를 추가로 구성하기 위해 MeterRegistryCustomizer 빈을 여러 개 등록할 수 있다.


모니터링 시스템

모니터링 시스템은 세 가지 중요한 특성을 갖는다.

  • 차원성 (dimensionality): 시스템이 태그 키/값 쌍의 메트릭명을 지원하는지 여부이다. 시스템이 차원성을 갖지 않은 경우 계층적(hierarchical) 시스템이며 계층적 시스템은 평평한(flat)한 메트릭명만 지원한다. 마이크로미터는 계층적 시스템에 메트릭을 게시할 때 태그 키/값 쌍 집합을 평탄화하여 메트릭명에 추가한다.
  • 비율 집계 (rate aggregation): 지정된 시간 간격에 걸쳐 일련의 샘플을 집계하는 것을 의미한다. 일부 모니터링 시스템은 메트릭이 게시되기 전에 일부 개별 샘플 데이터(예: 카운트)의 경우 애플리케이션에 의해 비율로 변환되기를 기대하는 반면, 일부는 누적값(cumulative value)이 게시될 것으로 기대한다.
  • 게시 (publishing): 일부 모니터링 시스템은 애플리케이션으로부터 메트릭을 직접 폴링(polling)할 것으로 기대하는 반면(서버 풀 기반(server pull-based)), 일부는 애플리케이션으로부터 메트릭이 일정한 간격으로 푸시되기를 기대한다(클라이언트 푸시 기반(client push-based)).


기본 측정 단위(특히 시간)의 개념과 메트릭의 표준 명명 규칙 등 모니터링 시스템마다 요구사항이 조금씩 다를 수 있다. 마이크로미터는 레지스트리 별로 이러한 요구사항을 충족하도록 메트릭을 사용자화한다.


캐시 메트릭

스프링 부트 액추에이터의 자동 구성을 사용하면 애플리케이션 시작 시 사용 가능한 모든 Cache 인스턴스를 계측할 수 있다. 캐시 계측과 메트릭은 표준화되어 있으며 추가적인 캐시 전용 메트릭도 사용할 수 있다. 지원되는 캐시 라이브러리는 Cache2K, 카페인(Caffeine), 헤이즐캐스트(Hazelcast), 호환되는 모든 JCache(JSR-107) 구현체, 레디스(Redis)이다. 캐시 메트릭의 태그는 빈 이름에서 파생된 CacheManager의 이름과 캐시명으로 지정된다.

애플리케이션 시작 시 구성된 캐시만 MeterRegistry에 바인딩되며 캐시 구성에 정의되지 않은 캐시(예: 시작 단계 이후에 또는 프로그래밍 방식으로 생성된 캐시)의 경우 명시적인 등록이 필요하다. 캐시 메트릭 등록을 위해 CacheMetricsRegistrar 빈을 사용할 수 있다.

Cache cache = cacheManager.getCache("캐시명");
cacheMetricRegistrar.bindCacheToRegistry(cache);


오픈텔레메트리

오픈텔레메트리(OpenTelemetry)는 관찰 가능성 프레임워크이다. 서비스를 계측하여 로그, 메트릭, 트레이스와 같은 텔레메트리 데이터(텔레메트리 데이터를 시그널(signal)이라고도 한다)를 생성 및 수집하고 외부로 내보냄으로써 서비스를 계측 가능하게 만들어주는 여러 도구들을 다양한 언어와 프레임워크를 대상으로(벤더 중립적으로) 제공한다. 계측(instrumentation)이란 관찰 가능성 코드를 애플리케이션에 추가하는 작업 및 행위를 말한다. 오픈텔레메트리는 다양한 백엔드 시스템 및 데이터 형식을 지원하며 애플리케이션 코드를 계측하기 위한 API와 라이브러리를 제공한다. 오픈텔레메트리는 클라우드 네이티브 컴퓨팅 재단(Cloud Native Computing Foundation, CNCF)의 프로젝트 중 하나이며 현재 인큐베이팅(incubating) 레벨이다. 마이크로미터와 오픈텔레메트리 라이브러리는 기능 제공에 있어 일부 공통점이 있다.

오픈텔레메트리는 텔레메트리 데이터를 수집하여 특정 형태로 다시 생성하는 컬렉터(collector) 기능을 제공한다. 컬렉터는 예거, 집킨, 프로메테우스와 같은 관찰 가능성 백엔드(텔레메트리 백엔드) 서비스 대신 텔레메트리 데이터를 수신하여 별도 처리한 후 백엔드 서비스로 보내는 프록시(proxy) 역할을 수행함으로써 백엔드 서비스의 데이터 처리 기능을 오프로드(offload)하도록 도와준다. 가장 간단한 패턴은 컬렉터를 사용하지 않고 오픈텔레메트리 SDK를 통해 텔레메트리 데이터를 계측 대상 애플리케이션에서 텔레메트리 백엔드로 직접 내보내는 것이다. 이 구성의 장점은 개발/테스트 환경에서 간편하게 사용할 수 있으며 프로덕션 환경에서도 애플리케이션 계측을 위해 추가적인 요소를 운영할 필요가 없다는 것이지만, 텔레메트리 데이터의 수집, 처리 과정이 변경되면 코드를 변경해야 하고, 애플리케이션 코드와 백엔드 간의 강한 결합도가 생긴다는 점, 그리고 언어 구현 당 익스포터 수가 제한되어 있다는 단점이 있다.

오픈텔레메트리는 서비스의 다양한 텔레메트리 데이터를 외부로 전송하기 위한 도구를 제공하며, 분산 트레이싱 또는 모니터링 플랫폼은 텔레메트리 데이터를 제공 받아 이를 분석 및 시각화한다. 서비스의 텔레메트리 데이터를 외부로 전송하는 역할은 오픈텔레메트리 익스포터(exporter)가 수행한다. 익스포터는 오픈텔레메트리 라인 프로토콜(OTLP, OpenTelemetry Line Protocol)의 명세를 따른다. 오픈텔레메트리가 제공하는 opentelemetry-exporter-otlp 라이브러리를 사용하여 서비스의 텔레메트리 데이터를 분산 트레이싱 플랫폼이나 모니터링 플랫폼, 또는 오픈텔레메트리 컬렉터와 같은 OTLP 엔드포인트에 전송할 수 있다.

오픈텔레메트리가 생성한 텔레메트리 데이터를 전송 받아 분석 및 시각화하는 플랫폼인 텔레메트리 백엔드의 예는 다음과 같다. 이러한 서비스는 모두 OTLP 엔드포인트가 된다.

  • 트레이스 데이터를 수집 및 처리하는 오픈트레이싱(OpenTracing) 기반의 분산 트레이싱 플랫폼: 예거(Jaeger), 집킨(Zipkin), 그라파나 템포(Grafana Tempo) 등
  • 메트릭 데이터를 수집 및 처리하는 모니터링 플랫폼: 프로메테우스(Prometheus) 등
  • 로그 데이터를 수집 및 처리하는 로깅 플랫폼: 엘라스틱서치(Elasticsearch), 로키(Loki) 등
  • 통합 APM 플랫폼: 엘라스틱(Elastic) APM, 데이터독(DataDog), 뉴 렐릭(New Relic) 등


오픈텔레메트리는 크게 API와 SDK 두 가지 모듈을 가지고 있다. API는 텔레메트리 데이터를 생성 및 관리하기 위한 인터페이스(데이터 타입 정의, 데이터 생성 동작 인터페이스 정의 등)이며 SDK는 프로그래밍 언어 및 프레임워크에 따라 서로 다르게 구현 및 구성되는 구현체이다.

오픈텔레메트리의 자동 계측(automatic instrumentation) 기능을 사용하면 JVM 구동 시 오픈텔레메트리 자바 에이전트를 로드하는 것만으로 서비스의 텔레메트리 데이터 계측이 가능하다. 자동 계측은 자바 8버전 이상의 자바 애플리케이션에서 사용할 수 있는 자바 에이전트 jar 파일을 사용한다. 이 에이전트는 바이트코드를 동적으로 삽입하여 다양한 라이브러리 및 프레임워크로부터 텔레메트리 데이터를 캡쳐 및 추출하는 계측 라이브러리(instrumentation library)를 내부적으로 포함하고 있다. 바이트 코드 삽입은 오픈 소스 라이브러리인 바이트 버디(Byte Buddy)에 의해 수행된다.

이를 통해 애플리케이션의 HTTP 인바운드 및 아웃바운드 호출, 데이터베이스 아웃바운드 호출 등 애플리케이션의 엣지(edge)에서 텔레메트리 데이터를 캡쳐할 수 있다.

서비스의 텔레메트리 데이터를 사용자화하거나 라이브러리 형태의 서비스에 대한 계측이 필요하다면 자동 계측을 사용하는 대신 오픈텔레메트리 API와 SDK를 사용하는 수동 계측(manual instrumentation)을 위한 구성이 별도로 필요하다. 서비스를 위한 수동 계측을 위해서는 SDK 라이브러리를 사용하여 OpenTelemetrySdk 인스턴스를 직접 구성하고, 이를 사용하여 OpenTelemetry 인스턴스를 생성(스프링의 경우 빈 등록)한다. 그 후 SDK와 API를 사용하여 텔레메트리 데이터를 계측한다.

애플리케이션에서 사용되는 모든 라이브러리를 계측할 필요는 없다. 라이브러리가 오픈텔레메트리 API와 통합되어 이를 직접 호출한다면 바로 관찰 가능하지만 그렇지 않은 경우 오픈텔레메트리가 제공하는 언어 별 계측 라이브러리를 사용하면 된다. 대부분의 언어에서 수동 계측과 자동 계측을 동시에 사용할 수 있다. 자동 계측을 사용하면 애플리케이션에 관찰 가능성을 손쉽게 제공할 수 있으며, 수동 계측을 사용하면 애플리케이션에 보다 세분화된 관찰 가능성을 제공할 수 있다.

자바 언어에서 OpenTelemetry 인스턴스를 구성하는 방법에는 자동 구성과 수동 구성 두 가지가 있다. 자동 구성은 SDK가 제공하는 빌더를 이용하여 코드 상에서 관련 속성들을 직접 설정하는 것이고, 수동 구성은 환경 변수나 시스템 속성 값으로 OpenTelemetry 인스턴스를 구성하는 것이다. 라이브러리 계측을 위해서는 SDK 대신 API만 사용하는 것이 좋다. SDK를 사용하는 서비스가 해당 라이브러리의 API와 호환된다면 별다른 처리 없이 라이브러리의 텔레메트리 데이터가 계측된다.


수동 계측 구성

수동 계측은 오픈텔레메트리 API와 SDK를 사용하여 텔레메트리 데이터를 계측한다. 오픈텔레메트리 API 구현체인, 언어 별 오픈텔레메트리 SDK를 사용하여 수동 계측을 수행한다. 언어 별 제공되는 라이브러리를 사용하는 코드를 작성하여 텔레메트리 데이터인 로그, 메트릭, 트레이스 데이터에 대해 계측을 수동으로 수행한다.

라이브러리와 애플리케이션 계측 모두 수동 계측을 위해서는 오픈텔레메트리 API 의존성을 추가한 후 코드 상에서 SDK를 초기화하고 API가 제공하는 Opentelemetry 인스턴스를 초기화 및 빈 등록한다. 오픈텔레메트리 API는 텔레메트리 데이터 수집을 위한 일련의 인터페이스를 제공하며 구현이 없다면 데이터는 삭제된다. 빠른 구현을 위해서는 SDK의 자동 구성(automatic configuration) 기능을 사용하는 것이 좋다. 자동 구성은 계측을 위한 기본 설정값을 기반으로 오픈텔레메트리 SDK를 구성하여 텔레메트리 데이터 계측을 수행하며 구성 설정 변경은 코드 상에서 직접 수행하는 대신 환경 변수와 시스템 프로퍼티 값 변경을 통해 수행한다. 자동 구성을 위해서는 별도 의존성 추가가 필요하다.

텔레메트리 데이터에 대해 보다 상세한 수동 구성(예: 텔레메트리 데이터 익스포터 설정, 텔레메트리 데이터 프로세서 설정 등)을 위해서는 언어 별 SDK를 참고한다. 수동 계측을 위한 구성을 완료했다면 SDK를 사용하여 코드 레벨에서 텔레메트리 데이터를 직접 조작할 수 있다.


자동 계측과 수동 계측 동시 사용

자바 에이전트는 내부적으로 오픈텔레메트리 SDK, API, 익스포터를 포함하고 있다. 자바 에이전트를 사용한 자동 계측을 바이트코드(bytecode) 계측이라고도 한다. 자동 계측 기능을 그대로 사용하고 애플리케이션 내에서 오픈텔레메트리 API를 통해 수동 계측 기능을 추가적으로 적용할 수도 있다. 이때 두 계측 방법은 원활하게 상호 운용되어야 한다. 자바 계측의 경우 자동 계측을 위한 자바 에이전트 내의 내부(internal) SDK, API, 익스포터는 숨겨지고(shaded)(코드 레벨에서 접근 및 조작 불가능함을 의미한다) 애플리케이션 내에 로드한 SDK, API 라이브러리가 계측을 추가적으로 수행한다.

자동 계측과 수동 계측 동시 사용하는 경우 오픈텔레메트리 SDK를 수동 구성하지 않고 GlobalOpenTelemetry를 사용하여 자바 에이전트가 내부적으로 구성한 SDK에 접근할 수 있다. 자바 에이전트는 애플리케이션의 오픈텔레트리 API와 에이전트 내부 오픈텔레트리 API를 브릿지(bridge)하며 모든 텔레메트리 데이터는 자바 에이전트를 거쳐 내부 API, SDK, 익스포터로 전달된다. 이때, 익스포터 설정과 관련된 설정 값은 환경 변수 값을 따른다. 이 방법을 사용하여 자바 에이전트와 수동 계측에 의해 생성된 스팬을 동일한 트레이스에 표시할 수 있다.

수동 계측 시 자동 계측이 생성한 트레이스 및 스팬 데이터를 조회할 수 있으며 API와 SDK를 통한 수동 계측 과정을 통해 자동 계측이 수동 계측 데이터와 자동 계측 데이터를 함께 텔레메트리 백엔드로 전송한다. 주의할 점은 모든 수동 계측 코드는 오픈텔레메트리 API와 SDK를 사용하여 수동으로 인스턴스화한 Opentelemetry가 아닌 GlobalOpenTelemetry를 사용해야 한다는 것이다.


자바 계측 에이전트 확장

확장(extension)링크은 별도의 라이브러리 배포를 만들지 않고도 자바 계측 에이전트에 새로운 기능을 추가한다. 커스텀 샘플러, 프로세서, 익스포터를 만들어 기본값으로 설정하거나 계측 에이전트의 기능을 확장하여 단일 jar 파일을 얻을 수 있다.

확장은 자바 에이전트(업스트림 에이전트)가 제공하는 계측 기능을 재정의하거나 사용자 지정할 수 있도록 설계되었다. 예를 들어, 데이터베이스 호출당 스팬을 만들고 데이터베이스 연결에서 데이터를 추출하여 스팬 속성을 제공하는 계측된 데이터베이스 클라이언트 라이브러리의 경우, 확장을 사용하여 원치 않는 스팬 데이터가 생성되지 않도록 하거나 애트리뷰트를 수정/삭제 및 추가할 수 있다.

자바 계측 에이전트에 확장 기능을 추가하려면 다음 과정을 통해 jar 파일을 생성한다.

  1. 자바 계측 에이전트를 사용할 애플리케이션이 실행 중인 호스트에 jar 파일을 복사한다.
  2. 다음과 같이 시작 명령을 수정하여 확장 파일의 전체 경로를 추가한다. 여러 확장 파일을 로드하려면 otel.javaagent.extensions 값에 콤마로 구분된 확장 jar 파일 또는 확장 jar가 포함된 디렉터리를 지정할 수 있다.
     java -javaagent:경로/opentelemetry-javaagent.jar \.
      -Dotel.javaagent.extensions=build/libs/opentelemetry-java-instrumentation-extension-demo-1.0-all.jar
      -jar myapp.jar
    


확장을 사용하면 스프링의 AOP를 통해 특정 클래스의 특정 메서드를 대상으로 메서드의 정보(메서드명, 파라미터, 반환값 등)를 추출하여 스팬 애트리뷰트로 추가할 수 있다. 다음은 서블릿 컨테이너 기반으로 동작하는 웹 서버(예: 톰캣 기반의 스프링 프레임워크 MVC 프로젝트)에서 요청과 응답을 처리하는 서블릿의 필터(filter) 메서드를 대상으로 스팬 애트리뷰트를 추가하는 예이다.



AOP를 사용하여 특정 메서드 호출 시 하위 스팬을 생성하는 예는 다음과 같다.

코틀린의 인라인(inline) 함수의 경우 AOP가 적용되지 않는다.


OTLP 익스포터 설정

OTLP 익스포터는 텔트메트리 데이터를 오픈텔레메트리 컬렉터에 전송하거나 텔레메트리 백엔드 서비스에 직접 전송하는 역할을 수행한다. 프로덕션 환경에서는 컬렉터를 사용하는 것이 좋다. 텔레메트리 데이터를 분석 및 시각화하려면 예거, 집킨, 프로메테우스 또는 기타 오픈텔레메트리를 네이티브하게 지원하는 기타 텔레메트리 백엔드링크로 전송해야 한다.

익스포터 중 OTLP 익스포터는 오픈텔레메트리 데이터 모델을 기반으로 설계되어 데이터의 손실 없이 오픈텔레메트리의 텔레메트리 데이터를 전송한다. 텔레메트리 데이터로 동작하는 많은 도구들이 OTLP를 지원하므로 오픈텔레메트리 도구는 매우 높은 확장성과 유연성을 제공한다.

수동 계측을 위한 구성을 완료한 후에는 익스포터 라이브러리를 사용하여(자바의 경우 애플리케이션의 클래스 경로에 익스포터 라이브러리를 추가한다) 애플리케이션의 텔레메트리 데이터를 하나 이상의 텔레메트리 백엔드로 전송할 수 있다.

익스포터의 종류를 선택하기 위해 트레이스, 메트릭 또는 로그 익스포터 각각에 대해 OTEL_TRACES_EXPORTER, OTEL_METRICS_EXPORTEROTEL_LOGS_EXPORTER 환경 변수를 설정할 수 있다. 예를 들어 OTEL_TRACES_EXPORTER=logging은 모든 트레이스 데이터를 콘솔에 기록하는 로깅 익스포터를 사용하도록 애플리케이션을 구성한다. 디버깅 및 로컬 개발 목적으로 로깅 익스포터를 사용하는 것이 좋다.

적절한 익스포터를 선택했다면 해당 익스포터의 세부적인 동작을 설정하기 위해 익스포터를 위한 구성이 필요하다. 텔레메트리 데이터(시그널) 별로 구성 옵션의 기본값을 재정의하여 익스포터를 구성한다.

익스포터 구성 옵션은 다음과 같다.

  • 엔드포인트(endpoint) 설정: 익스포터가 텔레메트리 데이터를 전송할 대상 URL을 설정한다. URL 스킴, 호스트, 포트, 패스를 설정한다. http 프로토콜을 사용할 경우 포트는 4318이며 gRPC를 사용할 경우 4317이다.
    • 기본값: http://localhost:4318
    • 환경 변수
      • OTEL_EXPORTER_OTLP_ENDPOINT
      • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
      • OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
      • OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
  • 전송 보안(secure) 설정: 익스포터의 gRPC 연결에 대해 클라이언트 전송 보안을 사용할지 여부를 설정한다.
    • 기본값: false
    • 환경 변수
      • OTEL_EXPORTER_OTLP_INSECURE
      • OTEL_EXPORTER_OTLP_TRACES_INSECURE
      • OTEL_EXPORTER_OTLP_METRICS_INSECURE
      • OTEL_EXPORTER_OTLP_LOGS_INSECURE
  • 프로토콜(protocol) 설정: 전송 프로토콜을 설정한다. grpc, http/protobuf, http/json 중 하나여야 한다. HTTP/2 연결을 통해 gRPC 프로토콜을 사용하여 프로토버프 인코딩 데이터를 위해 grpc를, HTTP 연결을 통한 프로토버프 인코딩 데이터의 경우 http/protobuf를, HTTP 연결을 통한 JSON 인코딩 데이터의 경우 http/json를 사용한다.
    • 기본값: http/protobuf
    • 환경 변수
      • OTEL_EXPORTER_OTLP_PROTOCOL
      • OTEL_EXPORTER_OTLP_TRACES_PROTOCOL
      • OTEL_EXPORTER_OTLP_METRICS_PROTOCOL
      • OTEL_EXPORTER_OTLP_LOGS_PROTOCOL


OTLP/HTTP 익스포터를 위한 엔드포인트 URL 구성은 다음과 같다.

  • 시그널 별 환경 변수인 OTEL_EXPORTER_OTLP_<시그널>_ENDPOINT의 경우, URL을 수정하지 않고 그대로 사용해야 한다. URL에 경로 부분이 없는 경우 루트 경로인 /를 사용해야 한다.
  • 시그널 별 엔드포인트 구성이 없는 경우 OTEL_EXPORTER_OTLP_ENDPOINT가 기본 URL로 사용되며 해당 URL을 기준으로 아래 상대 경로로 해당 시그널이 전송된다. 예외적으로, 기본 URL이 슬래시로 끝나도록 한 다음 상대 URL을 문자열로 추가하여 구현할 수 있다.
    • 트레이스: v1/traces
    • 메트릭: v1/metrics
    • 로그: v1/logs


SDK는 위에 지정된 방식이 아닌 다른 방식으로 URL을 수정해서는 안 된다. 포트가 지정되지 않은 경우 해당 스킴에 대한 일반적인 규칙(RFC 7230)에 따라 http 스킴의 경우 TCP 포트 80이 기본값이고, https 스킴의 경우 TCP 포트 443이 기본값으로 설정된다.

모든 텔레메트리 데이터를 컬렉터로 전송하거나 일부 데이터는 컬렉터로, 나머지 데이터는 관찰 가능성 백엔드로 전송하도록 구성할 수 있다.

컬렉터만 구성하여 모든 시그널을 하나의 엔드포인트로 전송하는 경우 OTEL_EXPORTER_OTLP_ENDPOINT 환경 변수를 사용한다. OTLP를 통해 텔레메트리 데이터를 전송하는 경우 OTEL_TRACES_EXPORTER, OTEL_METRICS_EXPORTEROTEL_LOGS_EXPORTER 환경 변수를 별도로 설정할 필요는 없으며 기본값은 otlp이다.

OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318


OTLP/HTTP의 경우,OTEL_EXPORTER_OTLP_ENDPOINT 환경 변수가 설정되면 SDK의 익스포터는 시그널 별 URL을 구성하며 각각 다음과 같은 하위 경로를 사용한다.

  • 로그: /v1/logs
  • 메트릭: /v1/metrics
  • 트레이스: /v1/traces


따라서 트레이스 데이터는 http://collector:4318/v1/traces, 메트릭 데이터는 http://collector:4318/v1/metrics, 로그 데이터는 http://collector:4318/v1/logs로 전송된다. 시그널 별로 상세 경로가 자동으로 설정된다.


텔레메트리 데이터를 서로 다른 엔드포인트로 전송하는 경우 설정 예는 다음과 같다. 트레이스 데이터를 예거 백엔드 서비스의 컬렉터에, 메트릭 데이터는 다른 컬렉터에 전송하기 위해 시그널 별로 엔드포인트를 지정한다. 예거는 기본적으로 트레이스 데이터를 수신하기 위해 OTLP를 지원한다. ``` OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://collector:4318 OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://collector.example.com/v1/metrics OTEL_TRACES_EXPORTER=jaeger


<br>

위 경우 트레이스 데이터는 `http://collector:4318/v1/traces`가 아닌 루트 경로인 `http://collector:4318/`로 직접 전송된다. `/v1/traces`와 같은 상세 경로는 논시그널 특정 환경 변수(예: `OTEL_EXPORTER_OTLP_ENDPOINT`)를 사용할 때만 자동으로 추가된다. 메트릭 데이터는 기본 https 포트인 443을 사용하여 `https://collector.example.com/v1/metrics`으로 전송된다.

<br>

텔레메트리 데이터 중 일부만 다른 컬렉터로 전송하는 예는 다음과 같다. 메트릭 데이터만 다른 컬렉터로 전송한다.

OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318/mycollector/ export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=https://collector.example.com/v1/metrics/


<br>

위 경우 트레이스 데이터는 `http://collector:4318/mycollector/v1/traces`, 로그 데이터는 `http://collector:4318/mycollector/v1/logs`, 메트릭 데이터는 `https://collector.example.com/v1/metrics/`으로 전송되며, 기본 https 포트(443)를 사용한다. 기타 시그널은 `http://collector:4318/mycollector/`을 기준으로 해당 시그널에 대한 하위 경로로 전송된다.

<br>

하나의 시그널만 전송하려면 해당 엔드포인트만 설정한 후 다른 시그널에 대해서는 익스포터 설정을 비활성화한다. 트레이스 데이터만 전송하는 경우 `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` 환경 변수를 사용하여 트레이스 데이터의 하위 경로인 `/v1/traces`를 포함한 URL을 지정하고, 다른 시그널에 대해 `OTEL_LOGS_EXPORTER`, `OTEL_METRICS_EXPORTER` 환경 변수를 `none`으로 설정한다.

OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://collector/v1/traces OTEL_LOGS_EXPORTER=none OTEL_METRICS_EXPORTER=none ```


컬렉터

오픈텔레메트리 컬렉터(collector)는 벤더에 구애받지 않고 텔레메트리 데이터를 수집, 처리, 내보내는 방법을 구현할 수 있는 기능을 제공한다. 따라서 벤더 별로 서로 다른 컬렉터를 실행할 필요가 없다. 하나의 컬렉터에 벤더 별 컴포넌트(component)를 선택적으로 구성하여 익스포터를 설정함으로써 텔레메트리 데이터를 전송할 대상을

대부분의 언어 별 계측 라이브러리에는 다양한 백엔드 및 OTLP를 위한 익스포터가 존재하지만 컬렉터를 사용하면 애플리케이션과 데이터를 오프로드할 수 있으며 컬렉터가 재시도, 배치 처리, 암호화 또는 민감한 데이터 필터링과 같은 추가 처리를 처리할 수 있으므로 애플리케이션과 함께 컬렉터를 사용하는 것이 권장된다.

각 언어의 기본 OTLP 익스포터는 로컬 컬렉터 엔드포인트(http://localhost:4318)를 사용하도록 구성되어 있으며 컬렉터를 실행하면 컬렉터는 자동으로 텔레메트리 수신을 시작한다.

컬렉터는 로그, 메트릭, 트레이스 데이터를 수신하고, 이러한 텔레메트리 데이터를 처리한 다음 컴포넌트를 사용하여 다양한 관찰 가능성 백엔드로 내보낸다.

otel/opentelemetry-collector 도커 이미지를 사용하여 컬렉터를 컨테이너로 실행할 수 있으며 헬름 차트나 오퍼레이터도 사용 가능하다. 컬렉터 컨테이너의 OTLP HTTP 리시버의 포트 번호는 4318번이며, gRPC 리시버의 포트 번호는 4317번이다.

오픈텔레메트리 컬렉터의 공식 배포판에는 코어(core)와 컨트리뷰트(contribute) 두 가지가 있으며 코어에 해당하는 배포판 이름은 opentelemetry-collector, 컨트리뷰트에 해당하는 배포판 이름은 opentelemetry-collector-contrib이다. 일부 컴포넌트(예거 및 프로메테우스 컴포넌트 등)는 코어 배포판의 일부이며, 대부분의 컴포넌트는 컨트리뷰트 배포판에서만 사용할 수 있다. 예를 들어, 엘라스틱서치 익스포터는 컨트리뷰트 배포판에만 존재한다.

컬렉터의 OTLP 리시버는 텔레메트리 데이터를 OTLP 형식으로 수집하는 역할을 수행한다. 애플리케이션의 텔레메트리 데이터를 OTLP가 아닌 다른 형식으로 전송하는 경우 컬렉터에 해당 데이터 형식에 대한 별도의 리시버가 존재하는 것이 일반적이다. 예컨데 프로메테우스 형식의 메트릭 데이터를 컬렉터가 수집할 수 있도록 컬렉터에 프로메테우스 리시버를 위치시킬 수 있다. 데이터 형식에 맞는 리시버가 존재한다면 오픈텔레메트리 컬렉터는 다양한 시스템 또는 애플리케이션으로부터 서로 다른 형식의 텔레메트리 데이터를 수집하여 데이터 형식을 변환한 후 익스포터를 통해 다시 OTLP 엔드포인트로 내보낸다.


요청 및 응답 데이터 계측

현재 오픈텔레메트리 시맨틱 규칙에 HTTP나 데이터베이스의 페이로드(클라이언트의 요청 및 서버의 응답 데이터)와 관련된 내용은 정의되어 있지 않으며 관련된 PR이 열려있는 상태이다링크, 링크

애플이케이션의 엣지에서의 요청 및 응답 데이터를 텔레메트리 데이터에 포함시키려면 수동 계측 기능을 사용해야 한다. 예를 들어, HTTP 클라이언트의 요청 및 응답 데이터, JDBC 라이브러리의 쿼리 및 응답 데이터를 트레이스 데이터에 새로운 스팬 애트리뷰트로 추가할 수 있다. 또는 자바 계측 에이전트를 확장하여 내부적으로 AOP를 통해 라이브러리의 메서드 레벨에서 원하는 데이터를 새로운 스팬 애트리뷰트로 추가할 수도 있다.


메서드 호출 계측 어노테이션

메서드의 파라미터 및 반환 데이터에 대해서도 새로운 스팬 애트리뷰트 추가가 필요하다. 자동 계측을 사용하는 경우 어노테이션 라이브러리를 통해 메서드 호출 시 새로운 스팬을 생성하고 해당 스팬의 애트리뷰트에 메서드 호출 인자를 값으로 추가할 수 있다.

어노테이션 종류와 기능은 다음과 같다.

  • @WithSpan: 메서드 호출 시 새로운 스팬을 생성한다. 메서드에 설정한다. 어노테이션 파라미터로 스팬명을 지정할 수 있으며 지정하지 않을 경우 스팬명의 기본값은 <클래스명>.<메소드명>이다.
  • @SpanAttribute: 메서드에 대한 스팬이 생성되면 메서드 호출에 대한 인자 값을 생성된 스팬에 어트리뷰트로 추가한다. 메서드의 파라미터에 설정한다. 어노테이션 파라미터로 애트리뷰트명을 지정할 수 있으며 지정하지 않을 경우 파라미터명이 된다(javac 컴파일러에 -parameters 옵션을 전달하여 .class 파일로 컴파일되는 경우).


@WithSpan 어노테이션이 설정된 메서드를 호출할 때마다 매서드 소요 시간 및 호출 시 발생된 모든 예외 정보를 포함하는 스팬을 생성한다. @WithSpan 메서드의 반환 타입이 아래 나열된 퓨처(future) 또는 프로미스(promise) 중 하나(예: java.util.concurrent.CompletableFuture, reactor.core.publisher.Flux)이면 해당 타입이 완료 상태가 될 때까지 스팬이 종료되지 않는다.

스프링 프레임워크를 사용하는 경우 계측 어노테이션은 스프링의 AOP를 사용한다. 이 어노테이션은 스프링 애플리케이션 컨텍스트에서 관리하는 빈 메서드에만 적용할 수 있다.


샘플링

모든 요청의 대부분이 성공하고 낮은 지연 시간으로 오류 없이 완료된다면 모든 트레이스 데이터가 필요하지는 않으며 적절한 데이터 샘플링(sampling)이 필요하다. 샘플링의 기본 개념은 텔레메트리 데이터를 텔레메트리 백엔드로 전송하는 대상 및 범위를 제어하여 데이터 수집 비용을 낮추는 것이다. 샘플링을 하는 이유와 대상은 다양할 수 있으며 샘플링 전략을 다음과 같이 선택할 수 있다.

  • 비용 관리: 대량의 텔레메트리 데이터가 생성되는 경우 모든 스팬을 내보내고 저장한다면 텔레메트리 백엔드 벤더나 클라우드 벤더로부터 많은 비용이 발생할 위험이 있다. 따라서 비용을 절감하기 위해 관찰이 필요한 데이터만 선택적으로 샘플링 및 필터링할 필요성이 있다.
  • 특정 트레이스 데이터 관찰: 모든 트레이스 데이터 중 특정 데이터만 관찰할 필요성이 있다. 예를 들어, 특정 커스텀 속성이 있는 트레이스 데이터만 샘플링할 수 있다.
  • 노이즈 필터링: 분산 트레이스 정보를 생성하지 않는 요청일 경우 샘플링할 필요는 없다. 예를 들어, 헬스 체크를 위한 요청을 필터링할 필요성이 있다.


트레이스 또는 스팬 데이터는 샘플링되거나 또는 샘플링 되지 않은 두 상태로 표현한다.

  • 샘플링됨 (sampled): 트레이스 또는 스팬이 처리되어 익스포트된 상태이다. 샘플러가 모집단의 대표로 선택하므로 “샘플링된” 것으로 간주된다.
  • 샘플링되지 않음 (not sampled): 트레이스 또는 스팬이 처리되거나 익스포트되지 않은 상태이다. 샘플러에 의해 선택되지 않았으므로 “샘플링되지 않은”것으로 간주된다.


프로메테우스 메트릭 익스포터 구성

프로메테우스 버전 2.47 부터 오픈텔레메트리 네이티브 지원이 추가되었다. 오픈텔레메트리 프로토콜 기반으로 프로메테우스 서비스의 엔드포인트에 메트릭 데이터를 전송할 수 있다. 이 경우 애플리테이션이 프로메테우스 서비스에 메트릭 데이터를 직접 전송하므로 기존 풀 기반(pull-based)의 스크래핑(scraping) 방식이 아닌 푸시 기반(push-based) 방식으로 메트릭을 샘플링하게 된다.

대용량 데이터 환경에서 푸시 기반 방식은 메트릭 데이터를 수집하는 효율적인 방법은 아니므로 적은 크기의 데이터에 대해 사용하는 것이 권장된다. 기능 플래그 --enable-feature=otlp-write-receiver를 설정하여 OTLP 리시버를 활성화한 후 /api/v1/otlp/v1/metrics를 OTLP 리시버 엔드포인트로 사용한다.


엘라스틱서치 로그 익스포터 구성

이벤트는 JSON으로 인코딩된다. mapping 구성 옵션을 통해 사용자는 추가 매핑 규칙을 구성할 수 있다. mapping의 하위 구성 옵션에는 mode, field, file, dedup, dedot가 있다.

  • mode (기본값=ecs): 필드 이름을 지정하는 모드를 선택한다. 지정 가능한 유효한 모드는 none, ecs, raw가 있으며 기본값은 ecs이다.
    • none: OTLP 이벤트의 원본 필드와 이벤트 구조를 사용한다.
    • ecs: 오픈텔레메트리 시맨틱 규칙에 정의된 필드를 엘라스틱 공통 스키마(Elastic Common Schema, ECS)에 매핑한다.
    • raw: 로그 및 스팬 속성의 필드 이름 앞에 붙는 Attributes. 문자열을 생략하고 스팬 이벤트의 필드 이름 앞에 붙는 Events. 문자열을 생략한다.
  • field (선택): 추가 필드 매핑을 구성한다.
  • file (선택): 제공된 YAML 파일에서 추가 필드 매핑을 읽는다.
  • dedup (기본값=true): 엘라스틱서치에 게시하기 전에 이벤트에서 중복 필드/속성을 찾아서 제거한다. 일부 구조화된 로깅 라이브러리는 중복 필드를 생성할 수 있다(예: zap). 엘라스틱서치는 중복 필드가 있는 문서를 거부한다.
  • dedot (기본값=true): 활성화된 속성이 .을 포함하는 경우 적절한 JSON 객체로 분할된다.


스프링 부트 애플리케이션의 관찰 가능성

스프링 부트 애플리케이션의 관찰 가능성 중 메트릭 정보를 관찰하기 위해서는 마이크로미터와 프로메테우스를 사용하면 된다. 마이크로미터 대신 오픈텔레메트리를 사용할 수도 있다. 마이크로미터와 오픈텔레메트리 모두 공통적으로 서비스의 메트릭 계측을 위한 API를 제공한다. 분산된 서비스 간 트레이스 정보를 관찰하기 위해서는 오픈텔레메트리만 사용하거나 마이크로미터와 오픈텔레메트리를 통합하여 사용할 수도 있다.

마이크로미터는 마이크로미터 트레이싱링크)이라는 기능 확장을 통해 메트릭 정보 뿐만 아니라 분산 시스템을 위한 트레이스 정보를 제공한다. 마이크로미터 트레이싱은 다양한 트레이서 라이브러리를 위한 퍼사드 역할을 수행한다.

마이크로미터 트레이싱은 분산 시스템 트레이스 관찰을 위한 스프링 클라우드 슬루스(Spring Cloud Sleuth) 라이브러리를 대체한다. 스프링 클라우드 슬루스의 마지막 메이저 버전은 스프링 2.x 버전에서 동작하며 3.x 버전에서는 동작하지 않으므로 분산 트레이싱을 위해 스프링 클라우드 슬루스 대신 마이크로미터 트레이싱을 사용할 수 있다. 아니면 오픈텔레메트리를 사용할 수도 있다. 스프링 클라우드 슬루스의 오픈텔레메트리 지원은 현재(2024.03 기준) 실험 단계이다.

마이크로미터 트레이싱이 트레이스 관련 데이터를 제공하면 트레이서 브릿지는 트레이스 데이터를 수집 및 관리한다. 트레이서(tracer)란 분산 트레이스의 기본 구성 요소이자 논리적 작업 단위인 스팬(span)의 생명주기를 관리하는 라이브러리이다. 마이크로미터 트레이싱이 지원하는 트레이서에는 오픈집킨 브레이브(OpenZipkin Brave)와 오픈텔레메트리가 있다.


오픈텔레메트리로 스프링 부트를 애플리케이션을 계측하는 방법

스프링 애플리케이션 계측 시 바이트 코드 계측 기능이 있는 오픈텔레메트리 자바 에이전트를 사용하는 것만으로 충분하다. 다음과 같은 경우 오픈텔레메트리 스프링 부트 스타터를 사용할 수 있다.

  • 오픈텔레메트리 자바 에이전트가 작동하지 않는 스프링 부트 네이티브 이미지 애플리케이션
  • 오픈텔레메트리 자바 에이전트의 시작 오버헤드가 요구 사항을 초과하는 경우
  • 애플리케이션에서 이미 다른 자바 모니터링 에이전트를 사용하고 있는 경우 오픈텔레메트리 자바 에이전트가 작동하지 않는 경우
  • 스프링 부트 구성 파일(application.properties, application.yml)을 사용하여 오픈텔레메트리 구성 설정을 하려는 경우


오픈텔레메트리 자바 에이전트에는 스프링 부트 스타터보다 더 많은 자동 계측 기능이 포함되어 있다. 스타터에 없는 자동 계측 기능을 사용하기 위해서는 언어, 프레임워크, 애플리케이션 서버 등을 대상으로 제공되는 오픈텔레메트리 계측 라이브러리를 사용하여 스프링 부트 스타터의 자동 계측을 보완할 수 있다.


예거

예거(Jeager)는 오픈소스 분산 트레이스 백엔드 플랫폼이다. 마이크로서비스 환경에서 분산 트레이싱에 중점을 둔 도구로, 트레이스 데이터를 저장하고 시각화하는 기능을 제공한다. 예거는 오픈텔레메트리가 지원하는 분산 트레이싱 플랫폼 백엔드 중 하나이다. 오픈텔레메트리의 텔레메트리 데이터 중 트레이스 정보를 전달받아 이를 처리함으로써 분산 시스템에서 발생하는 요청과 요청에 따른 데이터의 전체 플로우를 매핑한다.

분산 시스템에서 하나의 요청은 여러 서비스를 호출할 수 있으며 요청 처리 도중 발생할 수 있는 서비스 간 지연이나 성능 병목 현상, 에러의 발생 지점 등의 문제점을 식별하고 이를 해결하는데 도움을 주며 분산 서비스 간 종속성, 서비스 내 코드 레벨에서의 종속성을 확인할 수 있도록 하여 분산 시스템의 안정성을 높인다. 예거를 오픈텔레메트리의 수동 계측 기능과 통합하면 분산 시스템의 전반적인 트레이스 정보 뿐만 아니라 서비스 내 메서드 호출 별 스팬 데이터를 커스텀하게 생성할 수 있으므로 보다 상세한 서비스 계측이 가능해진다.

예거는 클라우드 네이티브를 지원하므로 컨테이너 오케스트레이션 환경에서 높은 확장성을 갖는 분산 트레이스 백엔드를 구축하는데 도움을 준다.


예거 스팬 저장소 구성

트레이스 데이터를 영속화하기 위해 스팬 저장소 백엔드를 구성할 수 있다. 기본적으로 지원되는 분산 저장소 백엔드로는 카산드라(Cassandra)와 엘라스틱서치 또는 오픈서치(OpenSearch)가 있으며 이외에 로컬 파일 시스템, 몽고DB 등을 사용할 수도 있다링크. 카프카의 경우 컬렉터와 스팬 저장소 사이의 버퍼 역할을 위해 사용한다.

저장소 타입은 SPAN_STORAGE_TYPE 환경 변수를 통해 지정할 수 있으며 유효한 값은 cassandra, elasticsearch, kafka, badgermemory이다.

인메모리 저장소는 프로덕션 환경에서의 사용은 권장되지 않으며 프로세스가 중단되면 데이터가 손실된다. 기본적으로 메모리에 저장되는 트레이스 양에는 제한이 없으며 --memory.max-traces 플래그의 값을 설정하여 제한할 수 있다.

엘라스틱서치 저장소는 예거 v0.6.0부터 지원하며 지원되는 엘라스틱서치 버전은 7.x, 8.x이다. 8.x 버전은 예거 v1.52.0 이후에서 사용 가능하다. 예거는 루트/핑 엔드포인트에서 엘라스틱서치 버전을 자동으로 검색하며 이 버전을 기반으로 예거와 호환되는 인덱스 매핑과 엘라스틱서치 REST API를 사용한다. 버전은 --es.version 플래그를 통해 명시적으로 지정할 수 있다.

엘라스틱서치는 설치 및 실행한 후 별도의 초기화 과정이 필요하지는 않으며 실행이 완료되면 다음과 같이 올바른 구성 값을 jaeger-collectorjaeger-query에 전달하면 된다.

  • SPAN_STORAGE_TYPE: elasticsearch
  • ES_SERVER_URLS: 엘라스틱서치 서버 URL (예: http://elasticsearch:9200)


엘라스틱서치 저장소에 사용자 인증 설정이 되어 있는 경우 해당 인증 정보로 접속하도록 해야한다. 다음 환경 변수를 사용하여 인증 정보를 설정한다.

  • ES_PASSWORD: 비밀번호
  • ES_USERNAME: 아이디


쿠버네티스 환경에서 예거 오퍼레이터를 사용한 예거 백엔드 서비스 구성

예거 오퍼레이터(operator)는 쿠버네티스 오퍼레이터의 구현체이다. 오퍼레이터는 여러 소프트웨어 실행의 운영 복잡성을 완화하는 소프트웨어 조각이며, 쿠버네티스 애플리케이션을 패키징, 배포 및 관리하는 방법이다. 쿠버네티스를 최대한 활용하려면 쿠버네티스에서 실행되는 애플리케이션을 운영 및 관리하기 위해 응집력 있는, 확장 가능한 API가 필요하다. 오퍼레이터는 쿠버네티스에서 이러한 유형의 애플리케이션을 관리하는 런타임이다. 쿠퍼네티스 환경에서 오퍼레이터를 통한 자동화 기능을 사용하여 예거 백엔드 서비스와 관련된 다양한 리소스들을 손쉽게 구성할 수 있다.

예거 오퍼레이터는 쿠버네티스 기반 클러스터에 설치할 수 있으며 특정 네임스페이스 또는 전체 클러스터에서 새로운 예거 커스텀 리소스(custom resource, CR)를 감시할 수 있다. 일반적으로 클러스터 당 하나의 예거 오퍼레이터만 존재하지만, 멀티테넌트 시나리오에서는 네임스페이스당 최대 하나의 예거 오퍼레이터만 존재할 수 있다. 새로운 예거 CR이 감지되면 운영자는 자신을 리소스의 소유자로 설정하려고 시도하고, 운영자의 네임스페이스와 이름을 레이블 값으로 사용하여 새로운 CR에 jaegertracing.io/operated-by 레이블을 설정한다.

예거 오퍼레이터를 사용할 경우 관련된 다양한 백엔드 서비스들의 인스턴스 생성 방법을 디플로이먼트의 전략 선택을 통해 결정할 수 있다. 이 전략은 커스텀 리소스 파일에 정의되며 예거 백엔드 서비스의 아키텍처를 결정한다. 예거 백엔드 서비스를 구성하는 주요 컴포넌트는 예거 에이전트, 예거 컬렉터, 예거 쿼리 서비스이다. 디플로이먼트 전략에는 다음 세 가지가 있다.

  • 올인원 (all in one): 세 가지 컴포넌트들을 단일 실행 파일로 패키지화 및 배포하며 인메모리 스토리지를 사용하는 전략이다. 이 전략을 사용할 경우 하나의 레플리카(복제본) 이상으로 확장이 불가능하며 서비스 재시작 시 모든 데이터가 손실된다. 따라서 개발 및 테스트 용도이다. 올인원 전략은 트레이스 데이터의 볼륨이 단일 인스턴스로 처리할 수 있을 정도로 가벼운 경우 유용하다. 올인원 전략에서 다른 모든 스토리지 백엔드는 함께 사용할 수 있지만 메모리 스토리지와 배저(Badger) 스토리지(메모리 및 디스크 사용)는 인스턴스 간에 데이터를 공유할 수 없기 때문에 함께 사용할 수 없다.
  • 프로덕션 (production): 트레이싱 데이터의 장기 저장이 중요하고 백엔드 서비스들의 확장성과 가용성이 높은 아키텍처가 요구되는 프로덕션 환경을 위한 전략이다. 각 백엔드 컴포넌트는 개별적으로 배포되며 확장 가능하다. 기본적으로 지원되는 스토리지 백엔드로는 카산드라, 엘라스틱서치/오픈서치가 있으며 몽고DB, 인플럭스DB 등도 지원 목록에 있다.
  • 스트리밍 (streaming): 컬렉터와 백엔드 스토리지(예: 카산드라 또는 엘라스틱서치) 사이에 스트리밍 기능을 추가하여 프로덕션 전략을 보강하는 전략이다. 스트리밍을 통해 부하가 높은 상황에서 백엔드 스토리지에 대한 부담을 줄일 수 있으며, 다른 트레이스 후처리(post-processing) 기능이 스트리밍 플랫폼(예: 카프카)로부터 발생한 실시간 스팬 데이터를 직접 활용할 수 있다는 이점이 있다.


서비스의 리소스에 대한 구성을 변경하려면 예거 커스텀 리소스(Custom Resource, CR) 정의에서 spec을 수정한다. 예를 들어, 예거 쿼리 서비스(Service) 오브젝트의 포트를 변경하려면, 커스텀 리소스 specquery를 추가하고, 그 안에 service를 포함시켜 원하는 포트 번호를 지정한다.

예거 백엔드 서비스로 OTLP 데이터를 전송하기 위해


오픈텔레메트리와 예거를 사용한 스프링 부트 애플리케이션 분산 트레이싱


자동 계측 구성

  1. 예거 백엔드 서비스 실행
  2. 오픈텔레메트리 자바 에이전트opentelemetry-javaagent.jar 다운로드
  3. 스프링 부트 애플리케이션의 환경 변수 설정: 오픈텔레메트리 자바 에이전트 실행 설정, OTLP 익스포터< sup>링크</sup> 엔드포인트 설정
     JAVA_TOOL_OPTIONS=-javaagent:/opentelemetry-javaagent.jar
     OTEL_TRACES_EXPORTER=otlp
     OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
     OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
     OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
     OTEL_SERVICE_NAME=서비스명
    


수동 계측 구성


그라파나의 트레이스 통합

그라파나는 트레이스 통합 기능을 통해 트레이스 정보를 쿼리하고 시각화할 수 있다. 지원 가능한 데이터 소스로는 그라파나 템포(Grafana Tempo), 예거(Jaeger), 집킨(Zipkin) 등이 있다. 각 데이터 소스마다 고유한 쿼리 편집기가 존재하며 이를 사용하여 트레이스 데이터를 쿼리하고 검색할 수 있다.

분산 트레이싱 플랫폼을 데이터 소스로 설정한 후 데이터 탐색을 위한 Explore 메뉴에서 트레이스 데이터를 확인할 수 있다.

데이터 소스를 분산 트레이싱 플랫폼으로 설정하면 그라파나는 트레이스 뷰 섹션에서 다음 항목들을 통해 트레이스 정보를 요약 및 시각화하여 보여준다.

  • 헤더
  • 미니맵
  • 스팬 필터
  • 타임라인


헤더는 루트 스팬과 트레이스 ID의 이름을 보여주고, 검색된 텍스트를 포함하는 스팬을 강조하며 트레이스 대한 다양한 메타데이터 등을 제공한다. 미니맵은 트레이스 정보를 간소화하여 보여주거나 트레이스 타임라인을 표시한다. 타임라인 뷰어에서 스팬 필터를 사용하여 스팬을 필터링할 수 있다. 필터로 리소스 서비스 이름, 스팬 이름, 지속 시간, 태그 등을 추가할 수 있다. 타임라인은 트레이스 내의 스팬 목록을 표시한다. 각 스팬 행은 해당 스팬의 모든 하위 스팬을 확장하거나 축소하는 버튼을 제공하며, 스팬을 기록한 서비스명, 스팬이 나타내는 작업명, 트레이스 내의 작업 기간을 시각적으로 표시한다. 스팬 상세는 작업명, 스팬 메타데이터, 스팬과 연결된 모든 태그, 스팬을 로깅한 프로세스에 대한 메타데이터, 스팬에 의해 기록된 로그 및 관련 키 값의 목록을 표시한다.

트레이스 데이터는 로그 및 메트릭 데이터와 연결될 수 있다. 로그 및 메트릭 수집 플랫폼이 수집한 트레이스 데이터의 트레이스 ID와 분산 트레이싱 플랫폼이 수집한 트레이스 데이터의 트레이스 ID를 서로 연결함으로써 로그 또는 메트릭 데이터 계측이 발생한 시점에서 트레이스 정보를 확인할 수 있다.


그라파나에서 엘라스틱서치와 예거 서비스 통합

오픈텔레메트리를 사용하여 그라파나에서 엘라스틱서치와 예거 서비스 손쉽게 통합할 수 있다. 엘라스틱서치 데이터소스로 로그 데이터 계측 및 전송 시 트레이스 ID 필드를 추가한다.


그라파나에서 프로메테우스의 Exemplar를 사용하여 프로메테우스와 예거 서비스 통합

Exemplar란 주어진 시간 간격에 수행된 측정(measurement)을 나타내는 특정 트레이스 데이터이다. 텔레메트리 데이터 중 메트릭은 시스템에 대한 집계된 데이터의 시각화를 제공하는 반면, 트레이스는 단일 요청에 대한 세분화된 시각화를 제공하며 Exemplar는 이 두 가지를 연결하는 방법이다.

프로메테우스 데이터 소스 설정 화면의 Trace to metrics 항목에서 프로메테우스의 메트릭 데이터와 분산 트레이싱 플랫폼의 트레이스 데이터를 연결하기 위한 설정이 가능하다. 데이터 소스 항목에서는 메트릭 데이터와 연결할 트레이스 데이터를 수집하는 분산 트레이싱 플랫폼 데이터 소스를 설정하고, 트레이스 ID에 해당하는 레이블을 Label name 항목에 입력한다. 프로메테우스 대시보드에서 Exemplar 데이터의 레이블명을 확인할 수 있다.

오픈텔레메트리의 트레이스 데이터 중 트레이스 ID의 필드명은 trace_id이며, 그라파나 템포의 경우 traceId이다.


예거 서비스 모니터링

프로메테우스를 사용하여 예거 백엔드 서비스를 모니터링 할 수 있다. 기본적으로 예거 마이크로서비스는 프로메테우스 형식으로 메트릭 데이터를 노출한다.


오픈텔레메트리, 엘라스틱서치, 프로메테우스, 그라파나, 예거를 통한 텔레메트리 데이터 통합

오픈텔레메트리를 컬렉터 사용하는 경우

오픈텔레메트리를 컬렉터 사용하지 않는 경우

애플리케이션에서 프로메테우스로 메트릭 데이터 직접 푸시


프론트엔드 웹 클라이언트의 요청에 대한 백엔드 시스템의 관찰 가능성

서버 사이드 렌더링을 사용하는 경우 프론트엔드 백엔드 서버에서 텔레메트리 데이터를 생성하고 이후 백엔드 시스템에 컨텍스트 정보를 전파함으로써 특정 비지니스 트랜잭션에 대한 시스템의 텔레메트리 정보를 통합하여 관찰할 수 있다.

이를 사용할 경우 시스템의 프로덕션 반영 전 개발 및 스테이징 환경에서 수행하는 테스트 과정에서 사용자의 액션이 발생하였을 때 관련된 트랜잭션 정보를 토대로 시스템의 동작이 올바른지 확인할 수 있다.


하이퍼디엑스를 사용한 관찰 가능성

하이퍼디엑스(HyperDX)는 텔레메트리 데이터, 세션 리플레이(session replay)를 한 곳에서 중앙 집중화하고 이러한 데이터들을 서로 연관시켜 시스템의 중단 원인을 파악하는데 도움을 주는 도구이다. 통합 APM 도구인 데이터독(DataDog)과 뉴 렐릭(New Relic)을 대체하는 오픈 소스이다.

이 도구의 장점은 네이티브 오픈텔레메트리와 손쉽게 통합될 수 있다는 것이다. 프론트엔드와 백엔드 애플리테이션에서 오픈텔레메트리 프로토콜을 사용하여 텔레메트리 데이터를 하이퍼디엑스 서비스의 HTTP 엔드포인트인 4318 포트(grpc의 경우 4317)로 전송하기만 하면 하이퍼티엑스는 이벤트 발생 시 생성되는 트레이스 정보(트레이스 및 스팬)로 토대로 프론트엔드에서 첫 요청이 발생한 시점의 세션 리플레이 데이터와 로그, 메트릭, 트레이스 데이터를 서로 연결하여 한 눈에 분석할 수 있도록 도와준다.

세션 리플레이 기능을 사용하기 위해 하이퍼디엑스의 브라우저 SDK(hyperdx/browser)를 사용하여 프론트엔드에서 하이퍼디엑스로 세션 레코딩 및 텔레메트리 데이터를 전송한다. SDK는 내부적으로 웹 세션 레코더(hyperdx/otel-web-session-recorder)를 사용하여 세션 리플레이 데이터를 자동으로 생성한다. 이를 통해 프론트엔드에서의 요청에 대한 백엔드에서의 작업(메서드 실행, 예외 발생 정보 등)을 확인할 수 있으며, 이벤트 발생 시점에 프론트엔드 애플리케이션 사용자가 어떤 액션을 했는지 시각적으로 확인할 수 있다.


서비스 메시

서비스 메시(service mesh)란 클라우드 네이티브 환경에 구성된 마이크로서비스 아키텍처 기반 분산 시스템에서 서비스에 관찰 가능성을 부여하고 트래픽 관리(라우팅), 보안 기능(암호화, 인증, 권한 부여, 감사)을 제공하는 별도의 전용 인프라 계층, 또는 이러한 방식으로 구성된 시스템의 형태를 의미한다.

서비스 메시는 서비스의 코드를 변경하거나 런타임 환경에 새로운 기능을 추가할 필요 없이 프록시를 통해 서비스 간 통신을 관리하는 기능을 인프라 계층으로 추상화한다. 이러한 프록시를 사이드카(sidecar)라고 부르기도 한다. 각 서비스 마다 서비스와는 독립적인 프록시가 존재하며 프록시들이 모여 메시 네트워크를 형성한다. 이스티오(Istio)는 서비스 메시의 오픈소스 구현체이다.


센트리

센트리(Sentry)는 애플리케이션의 모니터링 도구이다. 백엔드 서버 뿐만 아니라 클라이언트 또는 사이드 렌더링을 위한 프론트엔드 서비스에 대한 모니터링 기능을 제공한다. 에러 및 성능 모니터링, 릴리즈 상태 모니터링 등이 가능하다. 다른 모니터링 도구 보다 특화된 부분은 코드 수준의 관찰 가능성을 제공하는 것이다. 애플리케이션에 에러가 발생하였을 때 개발자가 코드 관련 문제를 식별하고 수정하는데 도움을 준다.

주요 기능에 대한 설명은 다음과 같다.

  1. 에러 모니터링 (에러 트래킹): 애플리케이션에서 발생한 에러의 원인을 신속하게 파악하고 이를 수정할 수 있도록 도와준다. 처리되지 않은 예외(unhandled exception)를 자동으로 캡처하고 유사한 에러 이벤트를 자동으로 하나의 이슈(issues)링크로 그룹화하여 보다 효율적으로 분류하고 관리한다. 이벤트의 유사성은 스택 추적 및 기타 요인에 의해 결정된다.
    • 웹 서비스를 프로젝트로 구성하여 모니터링하는 경우 리플레이(replay) 항목에서 세션 리플레이 기능을 통해 사용자의 수행한 이벤트를 확인하고, 소스 맵(source map)링크으로 에러 발생 시 해당 세션을 에러와 관련이 있는 소스 코드 라인에 연결할 수 있다. 소스 맵이란 센트리가 에러에 대해 개발자가 읽을 수 있는 스택 트레이스 정보를 제공하기 위해 센트리 서버에 업로드하는 메타데이터 파일이다. 웹 애플리케이션의 경우 클라이언트인 웹 브라우저에서 더 효율적으로 실행되도록 자바스크립트 코드를 변환(transpilation) 및 축소(minification)하는 작업이 포함된다. 소스 맵 파일은 변환된 버전의 자바스크립트를 개발자가 작성한 코드로 다시 변환하는데 필요한 가이드 역할을 한다. 소스 맵 파일은 자바스크립트 빌드 도구에서 생성할 수 있다.
    • 프런트엔드와 백엔드 서비스에 모두 센트리를 구성할 경우 분산 추적을 사용하여 프론트엔드와 백엔드에 걸쳐 발생한 이벤트 시퀀스를 확인할 수 있다.
  2. 성능 모니터링:


센트리는 이외에도 릴리즈 상태 모니터링, 반복적인 잡 서비스 모니터링, 시스템의 상태에 대한 가시성 대시보드 구축, 코드 커버리지 등의 다양한 기능을 제공하고 있다.

프론트엔드와 백엔드 서비스가 분리된 시스템 구조에서는 에러 발생 시 에러를 일으킨 일련의 이벤트들을 추적하기 위한 별도의 분산 트레이싱 도구가 필요하다. 여러 다양한 백엔드 서비스가 연결된 마이크로서비스 아키텍처 구조의 시스템에 대해서도 동일하다. 센트리가 제공하는 성능 모니터링 기능을 사용하여 프론트엔드와 백엔드 서비스의 상호 작용을 트레이싱할 수 있다. 뿐만 아니라 애플리케이션의 처리량 및 지연 시간과 같은 메트릭과 성능 지표를 측정하여 에러 발생 시 관련된 영향도를 파악할 수 있다.

센트리의 기능을 최대한 활용하기 위해서는 다음 사항들이 권장된다.

  1. 데이터베이스 연결
  2. 알람 설정
  3. 디스커버, 대시보드 및 쿼리 사용자화


참고

Comments