DEV Community

Jaeyoun Nam
Jaeyoun Nam

Posted on

NestJS + Opentelemetry (Grafana Cloud)

Production환경에서 Opentelemetry 사용

Opentelemetry를 어플리케이션에 설정하고 로컬에 Otel Collector와 Loki, Tempo, Grafana를 띄워서 트레이스를 볼 수 있는 건 이 전 포스팅까지 마무리가 되었다.

이제 남은건 로컬 뿐 아니라 실제 Production 환경에서의 tracing을 보는 것이다.

그러기 위해 필요한 것은 '클라우드 상에 Log, Trace 를 저장하는 일'이다.

방법들

1. Opentelemetry Collector 를 배포하기

Opentelemetry Collector (+ Loki, Tempo 등)를 어디엔가 띄워 놓고 어플리케이션에서 쏘는 OLTP의 주소를 이 Collector로 설정하면 된다.

혹은 더 좋은 Scalability를 위해서 Load balancing을 위한 Gateway를 두고, 게이트웨이에서 OLTP를 받아서 내부의 Collectors에게 넘겨 주는 방법도 있다.

2. Grafana Alloy를 설치하여 배포하기

Grafana Alloy는 그라파나에서 제공하는 configurable한 opentelemetry collector 이다.

Docker로 배포하거나 기존에 Kubernates를 사용했다면 새로운 노드로 추가할 수 있다.

3. Collector 없이 바로 쏘기

Collector 없이 Backend(Loki, Tempo, Jaeger, 등...)로 OLTP를 바로 보내버리는 방법이다.

Backend로 Grafana Cloud의 Loki, Tempo 를 사용할 수 있어서 배포 없이 빠르게 도입 가능하다는 장점이 있다.

대신 Collector를 사용해서 얻을 수 있는 Scalability나 Processing등의 장점은 사라진다.

채택: Collector 없이 쏘기

멋지게 Collector를 배포해서 쓰고 싶으나, 기존에 Kubernetes도 쓰지 않는 환경에서 Collector따로 배포하고 설정하는데 시간이 너무 많이 소요될것 같아서 그냥 Grafana Cloud로 바로 쏘는 방법을 선택했다.

사실 실험용으로 도입해보는 거고 스타트업이어서 scalability가 크게 중요하게 작용하지 않고 (로깅이니까) 무엇보다 빠르게 해볼 수 있기 때문에, fancy하진 않지만 좋은 의사결정이다.

코드

코드 변경은 매우 심플하다. OLTP의 endpoint와 Protocol만 잘 설정해주면 된다.

Tracer

import { OTLPTraceExporter as PROTOOTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";

const oltpTraceExporter = new PROTOOTLPTraceExporter({
  url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT + "/v1/traces",
  headers: {
    Authorization: process.env.OTEL_EXPORTER_OTLP_HEADERS_AUTHORIZATION,
  },
});
Enter fullscreen mode Exit fullscreen mode

우리가 쏠 trace를 받을 endpoint(grafana cloud)는 http/protobuf 프로토콜을 받으므로 exporter-trace-otlp-proto에서 임포트해서 써야한다.

Logger

const logExporter = new OTLPLogExporter({
  url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT + "/v1/logs",
  headers: {
    Authorization: process.env.OTEL_EXPORTER_OTLP_HEADERS_AUTHORIZATION,
  },
});
Enter fullscreen mode Exit fullscreen mode

Logger는 기존에도 Http protocol을 쓰고 있었기 때문에 OTLPLogExporter는 그대로 사용하면 된다.

환경변수

참고로 NestJS에서 환경 변수는 AppModule을 Initialization할 때 설정되니, AppModule 만들기 전에 완료해야하는 tracer와 logger 세팅에서 사용할 수 없다.

만약 dotenv를 사용하고 있다면 먼저 불러주어야한다.

// eslint-disable-next-line import/order
import { config } from "dotenv";
// eslint-disable-next-line import/order
import { getEnvFilePath } from "@/lib/utils/env-loader";
config(); // load env before loading tracer and logger

// eslint-disable-next-line import/order
import otelSDK from "./tracer"; // otelSDK should be imported before any other imports
// eslint-disable-next-line import/order
import createLogger from "./logger";
Enter fullscreen mode Exit fullscreen mode

환경변수 값

은근 찾기 어려우니 잘 따라오자.

  1. 그라파나 접속
  2. 오른쪽 위 My Account 클릭
  3. 왼쪽 Navbar의 GRAFANA CLOUD 밑의 Stack 이름을 클릭 (없으면 new stack으로 만듬)
  4. 'Manage your stack' 화면에서 Opentelmetry 카드의 configure 누름
  5. 여기서 OTEL_EXPORTER_OTLP_ENDPOINT 를 얻을 수 있고,
  6. 아래 Password / API Token 에서 Generate Key를 눌러서 키를 만들면
  7. Environment Variables 칸에 OTEL_EXPORTER_OTLP_HEADERS에서 Basic으로 시작하는 부분이 OTEL_EXPORTER_OTLP_HEADERS_AUTHORIZATION 변수의 값이다.

환경 변수를 등록해주고 실행한다.

그라파나 클라우드 실행

그라파나에서 Grafana Launch 를 클릭하고 Explore에서 데이터를 살펴보자

Image description

Top comments (0)